From 6f37db300bdc6695ea172b408f8718d005ff397b Mon Sep 17 00:00:00 2001 From: Y0SH1M4S73R Date: Tue, 3 Feb 2026 22:23:20 -0500 Subject: [PATCH] Gives non-standard nullrods the rest of the features common to regular null rods (#94980) ## About The Pull Request Non-standard null-rods (the skateboard, bow, revolver, carpsie plush, and eswords) did not receive all the common characteristics of regular null rods in #93394. In particular, they were not given the `UNIQUE_RENAME` obj flag, and they did not receive the ability to track how many cultists they've crit/killed and be turned into cult weapons when sacrificed. This PR corrects that by extracting the cult kill tracking behavior to a component, while doing the following refactors to ensure complete compatibility: - Skateboard items now move themselves into the skateboard vehicle they spawn on use, instead of deleting themselves. This was necessary for the holy board to keep its custom name/desc and cultist kill count. - Guns (which the bow technically is) will track cultists killed/crit with bullets fired from them by a mob with a holy role. - A signal can now be used for an item to provide an arbitrary response when an offer rune underneath it is activated. ## Why It's Good For The Game I just wanted the holy eswords to be renameable for chaplains to provide plausible deniability for the possession of actual eswords, but after I discovered this consistency issue, and felt the need to fix it. ## Changelog :cl: fix: The holy energy swords and the carp-sie plushie can once again be renamed fix: The holy energy swords and the carp-sie plushie can once again be sacrificed by cultists to spawn different weapons based on how many unique cultists the chaplain has crit or killed with them qol: The holy skateboard can be renamed like other null rod variants can fix: Unusual null rod variants like the holy skateboard and bow can now be sacrificed by cultists to spawn different weapons based on how many unique cultists the chaplain has crit or killed with them. The bow and the burdened chaplain's revolver, in particular, also count cultists crit or killed by arrows/bullets fired from them by the chaplain. /:cl: --- code/__DEFINES/dcs/signals/signals_object.dm | 8 ++ code/datums/components/cult_kill_tracker.dm | 85 +++++++++++++++++++ code/datums/elements/nullrod_core.dm | 1 + code/game/objects/items/skateboards.dm | 7 +- .../objects/items/weaponry/melee/energy.dm | 1 + code/modules/antagonists/cult/runes.dm | 65 +++++--------- .../job_types/chaplain/chaplain_nullrod.dm | 23 +---- .../chaplain/chaplain_vorpal_scythe.dm | 1 + code/modules/mob/living/living_defense.dm | 4 + code/modules/religion/burdened/psyker.dm | 20 +---- code/modules/vehicles/scooter.dm | 10 ++- tgstation.dme | 1 + 12 files changed, 138 insertions(+), 88 deletions(-) create mode 100644 code/datums/components/cult_kill_tracker.dm diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 2298976d955..d666a93f0d6 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -429,6 +429,10 @@ #define COMSIG_PROJECTILE_RANGE_OUT "projectile_range_out" ///from the base of /obj/projectile/process(): () #define COMSIG_PROJECTILE_BEFORE_MOVE "projectile_before_move" +///sent to firer at the end of /mob/living/apply_projectile_effects(): (mob/living/target, hit_limb, blocked) +#define COMSIG_PROJECTILE_POST_HIT_LIVING "projectile_post_hit_living" +///sent to projectile at the end of /mob/living/apply_projectile_effects(): (mob/living/target, hit_limb, blocked) +#define COMSIG_PROJECTILE_SELF_POST_HIT_LIVING "projectile_post_hit_living" // FROM [/obj/item/proc/set_embed] sent when an item's embedding properties are changed : () #define COMSIG_ITEM_EMBEDDING_UPDATE "item_embedding_update" @@ -634,3 +638,7 @@ /// Sent from /obj/item/mob_holder/purple_raptor/proc/toggle_wings() : (mob/living/carbon/human/user) #define COMSIG_RAPTOR_WINGS_CLOSED "raptor_wings_closed" + +/// Sent from /obj/effect/rune/convert/try_sacrifice_item(obj/effect/rune/convert/rune) +#define COMSIG_ITEM_CULT_SACRIFICE "item_cult_sacrifice" + #define COMPONENT_SACRIFICE_SUCCESSFUL (1<<0) diff --git a/code/datums/components/cult_kill_tracker.dm b/code/datums/components/cult_kill_tracker.dm new file mode 100644 index 00000000000..00023ab23e3 --- /dev/null +++ b/code/datums/components/cult_kill_tracker.dm @@ -0,0 +1,85 @@ +/// Component to handle the behavior of a nullrod keeping track of cultists it has crit or killed, and converting the item into a cult weapon when sacrificed +/datum/component/cult_kill_tracker + /// Lazylist, tracks weakrefs()s to all cultists which have been crit or killed by this nullrod. + var/list/cultists_slain + /// Ref to the last mob hit with this rod. + var/last_ref + /// The stat of the target being hit with this rod, before actually performing damage calculations. + var/last_stat = DEAD + +/datum/component/cult_kill_tracker/Initialize(...) + if(!istype(parent, /obj/item)) + return COMPONENT_INCOMPATIBLE + +/datum/component/cult_kill_tracker/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_ITEM_ATTACK_ZONE, PROC_REF(on_attack_zone)) + RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, PROC_REF(post_hit)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent, COMSIG_ITEM_CULT_SACRIFICE, PROC_REF(on_sacrificed)) + if(isgun(parent)) + RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, PROC_REF(on_projectile_hit)) + RegisterSignal(parent, COMSIG_PROJECTILE_POST_HIT_LIVING, PROC_REF(post_hit)) + +/datum/component/cult_kill_tracker/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, list(COMSIG_ITEM_ATTACK_ZONE, COMSIG_ITEM_AFTERATTACK, COMSIG_ATOM_EXAMINE, COMSIG_ITEM_CULT_SACRIFICE, COMSIG_PROJECTILE_ON_HIT, COMSIG_PROJECTILE_POST_HIT_LIVING)) + +/datum/component/cult_kill_tracker/proc/on_attack_zone(obj/item/source, mob/living/target, mob/living/user) + SIGNAL_HANDLER + if(!user.mind?.holy_role) + return + if(!IS_CULTIST(target) || istype(target, /mob/living/carbon/human/cult_ghost)) + return + last_ref = WEAKREF(target) + last_stat = target.stat + +/datum/component/cult_kill_tracker/proc/post_hit(source, mob/living/target) + SIGNAL_HANDLER + if(!last_ref) + return + var/mob/living/resolved_mob = locate(last_ref) + //If they got deleted during the processing of the attack, they're probably fucking dead. + if(!istype(resolved_mob) || (resolved_mob == target && resolved_mob.stat > last_stat)) + LAZYOR(cultists_slain, last_ref) + last_ref = null + last_stat = DEAD + +/datum/component/cult_kill_tracker/proc/on_examine(obj/item/source, mob/viewer, list/examine_list) + SIGNAL_HANDLER + if(!IS_CULTIST(viewer) || !GET_ATOM_BLOOD_DNA_LENGTH(source)) + return + + var/num_slain = LAZYLEN(cultists_slain) + examine_list += span_cult_italic("It has the blood of [num_slain] fallen cultist[num_slain == 1 ? "" : "s"] on it. \ + Offering it to Nar'sie will transform it into a [num_slain >= 3 ? "powerful" : "standard"] cult weapon.") + +/datum/component/cult_kill_tracker/proc/on_sacrificed(obj/item/source, obj/effect/rune/convert/rune) + SIGNAL_HANDLER + var/num_slain = LAZYLEN(cultists_slain) + var/displayed_message = "[source] glows an unholy red and begins to transform..." + if(num_slain && GET_ATOM_BLOOD_DNA_LENGTH(source)) + displayed_message += " The blood of [num_slain] fallen cultist[num_slain == 1 ? "":"s"] is absorbed into [source]!" + + source.visible_message(span_cult_italic(displayed_message)) + switch(num_slain) + if(0) + rune.animate_convert_item(source, /obj/item/melee/cultblade/dagger) + if(1) + rune.animate_convert_item(source, /obj/item/melee/cultblade) + else + rune.animate_convert_item(source, /obj/item/melee/cultblade/halberd) + return COMPONENT_SACRIFICE_SUCCESSFUL + +/datum/component/cult_kill_tracker/proc/on_projectile_hit(obj/projectile/source, atom/movable/firer, atom/target) + SIGNAL_HANDLER + if(!isliving(firer) || !isliving(target)) + return + var/mob/living/firer_mob = firer + var/mob/living/target_mob = target + if(!firer_mob.mind.holy_role) + return + if(!IS_CULTIST(target_mob) || istype(target_mob, /mob/living/carbon/human/cult_ghost)) + return + last_ref = WEAKREF(target_mob) + last_stat = target_mob.stat diff --git a/code/datums/elements/nullrod_core.dm b/code/datums/elements/nullrod_core.dm index 020874777d5..fa48e421f8e 100644 --- a/code/datums/elements/nullrod_core.dm +++ b/code/datums/elements/nullrod_core.dm @@ -18,6 +18,7 @@ on_clear_callback = CALLBACK(src, PROC_REF(on_cult_rune_removed), target), \ effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune, /obj/effect/cosmic_rune), \ ) + target.AddComponent(/datum/component/cult_kill_tracker) target.AddElement(/datum/element/bane, mob_biotypes = MOB_SPIRIT, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) ADD_TRAIT(target, TRAIT_NULLROD_ITEM, ELEMENT_TRAIT(type)) diff --git a/code/game/objects/items/skateboards.dm b/code/game/objects/items/skateboards.dm index 0d860ef11f9..9f18d42ebe0 100644 --- a/code/game/objects/items/skateboards.dm +++ b/code/game/objects/items/skateboards.dm @@ -15,9 +15,9 @@ var/board_item_type = /obj/vehicle/ridden/scooter/skateboard /obj/item/melee/skateboard/attack_self(mob/user) - var/obj/vehicle/ridden/scooter/skateboard/S = new board_item_type(get_turf(user))//this probably has fucky interactions with telekinesis but for the record it wasn't my fault - S.buckle_mob(user) - qdel(src) + var/obj/vehicle/ridden/scooter/skateboard/board = new board_item_type(get_turf(user), src)//this probably has fucky interactions with telekinesis but for the record it wasn't my fault + board.buckle_mob(user) + forceMove(board) /obj/item/melee/skateboard/improvised name = "improvised skateboard" @@ -55,6 +55,7 @@ force = 18 throwforce = 6 w_class = WEIGHT_CLASS_NORMAL + obj_flags = parent_type::obj_flags | UNIQUE_RENAME attack_verb_continuous = list("bashes", "crashes", "grinds", "skates") attack_verb_simple = list("bash", "crash", "grind", "skate") board_item_type = /obj/vehicle/ridden/scooter/skateboard/hoverboard/holyboarded diff --git a/code/game/objects/items/weaponry/melee/energy.dm b/code/game/objects/items/weaponry/melee/energy.dm index 0c6ed38d674..ca7f75e93a9 100644 --- a/code/game/objects/items/weaponry/melee/energy.dm +++ b/code/game/objects/items/weaponry/melee/energy.dm @@ -556,6 +556,7 @@ armour_penetration = 0 wound_bonus = -10 demolition_mod = 1 + obj_flags = parent_type::obj_flags | UNIQUE_RENAME sword_color_icon = "blue" light_color = LIGHT_COLOR_LIGHT_CYAN active_force = 18 diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index fbadeba3518..be3a5b92d2d 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -242,7 +242,7 @@ structure_check() searches for nearby cultist structures required for the invoca if(!IS_CULTIST(non_cultist)) myriad_targets += non_cultist - if(!length(myriad_targets) && !try_spawn_sword()) + if(!length(myriad_targets) && !try_sacrifice_item()) fail_invoke() return @@ -400,57 +400,38 @@ structure_check() searches for nearby cultist structures required for the invoca sacrificial.investigate_log("has been sacrificially gibbed by the cult.", INVESTIGATE_DEATHS) sacrificial.gib(DROP_ALL_REMAINS) - try_spawn_sword() // after sharding and gibbing, which potentially dropped a null rod + try_sacrifice_item() // after sharding and gibbing, which potentially dropped a sacrificable item return TRUE -/// Tries to convert a null rod over the rune to a cult sword -/obj/effect/rune/convert/proc/try_spawn_sword() - for(var/obj/item/potential_rod in loc) - if(!HAS_TRAIT(potential_rod, TRAIT_NULLROD_ITEM)) +/// Tries to convert a valid item over the rune to something else +/obj/effect/rune/convert/proc/try_sacrifice_item() + for(var/obj/item/checked_item in loc) + if(checked_item.anchored || (checked_item.resistance_flags & INDESTRUCTIBLE)) continue - if(potential_rod.anchored || (potential_rod.resistance_flags & INDESTRUCTIBLE)) - continue - - var/num_slain = 0 - if (istype(potential_rod, /obj/item/nullrod)) - var/obj/item/nullrod/actual_rod = potential_rod - num_slain = LAZYLEN(actual_rod.cultists_slain) - - var/displayed_message = "[potential_rod] glows an unholy red and begins to transform..." - if(num_slain && GET_ATOM_BLOOD_DNA_LENGTH(potential_rod)) - displayed_message += " The blood of [num_slain] fallen cultist[num_slain == 1 ? "":"s"] is absorbed into [potential_rod]!" - - potential_rod.visible_message(span_cult_italic(displayed_message)) - switch(num_slain) - if(0) - animate_spawn_sword(potential_rod, /obj/item/melee/cultblade/dagger) - if(1) - animate_spawn_sword(potential_rod, /obj/item/melee/cultblade) - else - animate_spawn_sword(potential_rod, /obj/item/melee/cultblade/halberd) - return TRUE + if(SEND_SIGNAL(checked_item, COMSIG_ITEM_CULT_SACRIFICE, src) & COMPONENT_SACRIFICE_SUCCESSFUL) + return TRUE return FALSE -/// Does an animation of a null rod transforming into a cult sword -/obj/effect/rune/convert/proc/animate_spawn_sword(obj/item/former_rod, new_blade_typepath) +/// Does an animation of a sacrificable item transforming into something else +/obj/effect/rune/convert/proc/animate_convert_item(obj/item/old_item, new_movable_typepath) playsound(src, 'sound/effects/magic.ogg', 33, vary = TRUE, extrarange = SILENCED_SOUND_EXTRARANGE, frequency = 0.66) - former_rod.anchored = TRUE - former_rod.Shake() - animate(former_rod, alpha = 0, transform = matrix(former_rod.transform).Scale(0.01), time = 2 SECONDS, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) - QDEL_IN(former_rod, 2 SECONDS) + old_item.anchored = TRUE + old_item.Shake() + animate(old_item, alpha = 0, transform = matrix(old_item.transform).Scale(0.01), time = 2 SECONDS, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) + QDEL_IN(old_item, 2 SECONDS) - var/obj/item/new_blade = new new_blade_typepath(loc) - var/matrix/blade_matrix_on_spawn = matrix(new_blade.transform) - new_blade.name = "converted [new_blade.name]" - new_blade.anchored = TRUE - new_blade.alpha = 0 - new_blade.transform = matrix(new_blade.transform).Scale(0.01) - new_blade.Shake() - animate(new_blade, alpha = 255, transform = blade_matrix_on_spawn, time = 2 SECONDS, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) - addtimer(VARSET_CALLBACK(new_blade, anchored, FALSE), 2 SECONDS) + var/atom/movable/new_movable = new new_movable_typepath(loc) + var/matrix/matrix_on_spawn = matrix(new_movable.transform) + new_movable.name = "converted [new_movable.name]" + new_movable.anchored = TRUE + new_movable.alpha = 0 + new_movable.transform = matrix(new_movable.transform).Scale(0.01) + new_movable.Shake() + animate(new_movable, alpha = 255, transform = matrix_on_spawn, time = 2 SECONDS, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) + addtimer(VARSET_CALLBACK(new_movable, anchored, FALSE), 2 SECONDS) /obj/effect/rune/empower cultist_name = "Empower" diff --git a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm index becd993f5e8..5e67c8de35b 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm @@ -47,8 +47,6 @@ GLOBAL_LIST_INIT(nullrod_variants, init_nullrod_variants()) var/chaplain_spawnable = TRUE /// Short description of what this item is capable of, for radial menu uses. var/menu_description = "A standard chaplain's weapon. Fits in pockets. Can be worn on the belt." - /// Lazylist, tracks refs()s to all cultists which have been crit or killed by this nullrod. - var/list/cultists_slain /// Affects GLOB.holy_weapon_type. Disable to allow null rods to change at will and without affecting the station's type. var/station_holy_item = TRUE @@ -72,26 +70,6 @@ GLOBAL_LIST_INIT(nullrod_variants, init_nullrod_variants()) user.visible_message(span_suicide("[user] is killing [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to get closer to god!")) return (BRUTELOSS|FIRELOSS) -/obj/item/nullrod/attack(mob/living/target_mob, mob/living/user, list/modifiers, list/attack_modifiers) - if(!user.mind?.holy_role) - return ..() - if(!IS_CULTIST(target_mob) || istype(target_mob, /mob/living/carbon/human/cult_ghost)) - return ..() - - var/old_stat = target_mob.stat - . = ..() - if(old_stat < target_mob.stat) - LAZYOR(cultists_slain, REF(target_mob)) - return . - -/obj/item/nullrod/examine(mob/user) - . = ..() - if(!IS_CULTIST(user) || !GET_ATOM_BLOOD_DNA_LENGTH(src)) - return - - var/num_slain = LAZYLEN(cultists_slain) - . += span_cult_italic("It has the blood of [num_slain] fallen cultist[num_slain == 1 ? "" : "s"] on it. \ - Offering it to Nar'sie will transform it into a [num_slain >= 3 ? "powerful" : "standard"] cult weapon.") /obj/item/nullrod/non_station station_holy_item = FALSE @@ -613,6 +591,7 @@ GLOBAL_LIST_INIT(nullrod_variants, init_nullrod_variants()) lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' righthand_file = 'icons/mob/inhands/items_righthand.dmi' force = 15 + obj_flags = parent_type::obj_flags | UNIQUE_RENAME offspring_type = /obj/item/toy/plush/carpplushie divine = TRUE diff --git a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm index f2c7ed53d40..91823a073c8 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm @@ -45,6 +45,7 @@ If the scythe isn't empowered when you sheath it, you take a heap of damage and armour_penetration = 50 //Very good armor penetration to make up for our abysmal force reach = 2 //why yes, this does have reach slot_flags = null + obj_flags = UNIQUE_RENAME sharpness = SHARP_EDGED attack_verb_continuous = list("chops", "slices", "cuts", "reaps") attack_verb_simple = list("chop", "slice", "cut", "reap") diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 884fbe51d8e..68bcf1fee29 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -179,6 +179,10 @@ if (proj.damage && armor_check < 100) create_projectile_hit_effects(proj, def_zone, armor_check) + if(proj.fired_from) + SEND_SIGNAL(proj.fired_from, COMSIG_PROJECTILE_POST_HIT_LIVING, src, def_zone, armor_check) + SEND_SIGNAL(proj, COMSIG_PROJECTILE_SELF_POST_HIT_LIVING, src, def_zone, armor_check) + /mob/living/proc/create_projectile_hit_effects(obj/projectile/proj, def_zone, blocked) if (proj.damage_type != BRUTE) return diff --git a/code/modules/religion/burdened/psyker.dm b/code/modules/religion/burdened/psyker.dm index 1e4ac046762..5d1cc61f92c 100644 --- a/code/modules/religion/burdened/psyker.dm +++ b/code/modules/religion/burdened/psyker.dm @@ -181,28 +181,10 @@ /obj/item/gun/ballistic/revolver/chaplain/Initialize(mapload) . = ..() - AddComponent(/datum/component/anti_magic, MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY) - AddComponent(/datum/component/effect_remover, \ - success_feedback = "You disrupt the magic of %THEEFFECT with %THEWEAPON.", \ - success_forcesay = "BEGONE FOUL MAGIKS!!", \ - tip_text = "Clear rune", \ - on_clear_callback = CALLBACK(src, PROC_REF(on_cult_rune_removed)), \ - effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune, /obj/effect/cosmic_rune), \ - ) - AddElement(/datum/element/bane, mob_biotypes = MOB_SPIRIT, damage_multiplier = 0, added_damage = 25) + AddElement(/datum/element/nullrod_core, FALSE) name = pick(possible_names) desc = possible_names[name] -/obj/item/gun/ballistic/revolver/chaplain/proc/on_cult_rune_removed(obj/effect/target, mob/living/user) - SIGNAL_HANDLER - if(!istype(target, /obj/effect/rune)) - return - - var/obj/effect/rune/target_rune = target - if(target_rune.log_when_erased) - user.log_message("erased [target_rune.cultist_name] rune using [src]", LOG_GAME) - SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_NARNAR] = TRUE - /obj/item/gun/ballistic/revolver/chaplain/suicide_act(mob/living/user) . = ..() name = "Habemus Papam" diff --git a/code/modules/vehicles/scooter.dm b/code/modules/vehicles/scooter.dm index 3e1b6cf86cb..16d084cf518 100644 --- a/code/modules/vehicles/scooter.dm +++ b/code/modules/vehicles/scooter.dm @@ -53,11 +53,17 @@ var/instability = 10 ///If true, riding the skateboard with walk intent on will prevent crashing. var/can_slow_down = TRUE + ///The actual item for the skateboard + var/obj/item/melee/skateboard/board_item -/obj/vehicle/ridden/scooter/skateboard/Initialize(mapload) +/obj/vehicle/ridden/scooter/skateboard/Initialize(mapload, obj/item/melee/skateboard/board_item) . = ..() sparks = new(src, 1, FALSE) sparks.attach(src) + if(!istype(board_item)) + src.board_item = new board_item_type(src) + else + src.board_item = board_item /obj/vehicle/ridden/scooter/skateboard/make_ridable() AddElement(/datum/element/ridable, /datum/component/riding/vehicle/scooter/skateboard) @@ -174,7 +180,7 @@ if(has_buckled_mobs()) to_chat(skater, span_warning("You can't lift this up when somebody's on it.")) return - skater.put_in_hands(new board_item_type(get_turf(skater))) + skater.put_in_hands(board_item) qdel(src) /obj/vehicle/ridden/scooter/skateboard/pro diff --git a/tgstation.dme b/tgstation.dme index fa648bd841c..39baa1f4c1a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1152,6 +1152,7 @@ #include "code\datums\components\crank_recharge.dm" #include "code\datums\components\crate_carrier.dm" #include "code\datums\components\cuff_n_stun.dm" +#include "code\datums\components\cult_kill_tracker.dm" #include "code\datums\components\cult_ritual_item.dm" #include "code\datums\components\curse_of_hunger.dm" #include "code\datums\components\curse_of_polymorph.dm"