diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm index bb5b344a89a..e7c048dbed7 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm @@ -95,3 +95,6 @@ /// signal sent when a mouse is hovering over us, sent by atom/proc/on_mouse_entered #define COMSIG_ATOM_MOUSE_ENTERED "mouse_entered" + +/// Sent from [/datum/element/burn_on_item_ignition] to an atom being ignited by something: (mob/living/user, obj/item/burning_thing) +#define COMSIG_ATOM_IGNITED_BY_ITEM "atom_ignited_by_item" diff --git a/code/datums/components/crafting/equipment.dm b/code/datums/components/crafting/equipment.dm index ef8f1b24787..1c3dc2be0ec 100644 --- a/code/datums/components/crafting/equipment.dm +++ b/code/datums/components/crafting/equipment.dm @@ -164,6 +164,10 @@ ) category = CAT_EQUIPMENT +/datum/crafting_recipe/flashlight_eyes/New() + . = ..() + blacklist += typesof(/obj/item/flashlight/flare) + /datum/crafting_recipe/extendohand_r name = "Extendo-Hand (Right Arm)" reqs = list( diff --git a/code/datums/elements/burn_when_item_ignition.dm b/code/datums/elements/burn_when_item_ignition.dm new file mode 100644 index 00000000000..7ab1291e951 --- /dev/null +++ b/code/datums/elements/burn_when_item_ignition.dm @@ -0,0 +1,68 @@ +/** + * This item will be set on fire if a mob clicks on it with something that can ignite objects, + * OR if a mob clicks it on something else that can ignite objects. + */ +/datum/element/burn_on_item_ignition + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + /// If TRUE clumsy people can't burn themselves + var/bypass_clumsy = FALSE + +/datum/element/burn_on_item_ignition/Attach(datum/target, bypass_clumsy = FALSE) + . = ..() + src.bypass_clumsy = bypass_clumsy + RegisterSignal(target, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(try_burn)) + RegisterSignal(target, COMSIG_ITEM_INTERACTING_WITH_ATOM, PROC_REF(try_hold_burn)) + +/datum/element/burn_on_item_ignition/Detach(datum/target) + . = ..() + UnregisterSignal(target, COMSIG_ATOM_ITEM_INTERACTION) + UnregisterSignal(target, COMSIG_ITEM_INTERACTING_WITH_ATOM) + +/datum/element/burn_on_item_ignition/proc/try_burn(atom/source, mob/living/user, obj/item/tool, list/modifiers) + SIGNAL_HANDLER + + //can't be put on fire! + if((source.resistance_flags & FIRE_PROOF) || !(source.resistance_flags & FLAMMABLE)) + return NONE + //already on fire! + if(source.resistance_flags & ON_FIRE) + return NONE + + var/ignition_message = tool.ignition_effect(source, user) + if(!ignition_message) + return NONE + if(!bypass_clumsy && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10) && source.Adjacent(user)) + if(user.is_holding(tool)) //checking if they're holding it in case TK is involved + user.dropItemToGround(tool) + var/firestacks = tool.get_temperature() / 200 + user.adjust_fire_stacks(clamp(firestacks, 1, 10)) + user.apply_damage(clamp(firestacks, 4, 12), BURN, user.get_active_hand(), attacking_item = tool) + user.ignite_mob() + if(user.on_fire) + user.visible_message( + span_warning("[user] accidentally ignites [user.p_them()]self!"), + span_userdanger("You miss [src] and accidentally light yourself on fire!"), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) + else + user.visible_message( + span_warning("[user] accidentally burns [user.p_them()]self!"), + span_userdanger("You miss [src] and accidentally burn yourself!"), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) + return ITEM_INTERACT_SUCCESS + + if(user.is_holding(source)) //no TK shit here. + user.dropItemToGround(source) + source.add_fingerprint(user) + user.visible_message(ignition_message) + source.fire_act(tool.get_temperature()) + SEND_SIGNAL(source, COMSIG_ATOM_IGNITED_BY_ITEM, user, tool) + return ITEM_INTERACT_SUCCESS + +// Represents holding a paper over a cigarette like a badass +/datum/element/burn_on_item_ignition/proc/try_hold_burn(atom/source, mob/living/user, atom/interacting_with, list/modifiers) + SIGNAL_HANDLER + + return try_burn(source, user, interacting_with, modifiers) diff --git a/code/game/machinery/newscaster/newspaper.dm b/code/game/machinery/newscaster/newspaper.dm index 5beb17b958f..7c1369940e7 100644 --- a/code/game/machinery/newscaster/newspaper.dm +++ b/code/game/machinery/newscaster/newspaper.dm @@ -54,6 +54,8 @@ saved_wanted_body = GLOB.news_network.wanted_issue.body if(GLOB.news_network.wanted_issue.img) saved_wanted_icon = GLOB.news_network.wanted_issue.img + AddElement(/datum/element/burn_on_item_ignition) + RegisterSignal(src, COMSIG_ATOM_IGNITED_BY_ITEM, PROC_REF(close_paper_ui)) /obj/item/newspaper/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) if(held_item) @@ -64,6 +66,10 @@ context[SCREENTIP_CONTEXT_LMB] = "Burn" return CONTEXTUAL_SCREENTIP_SET +/obj/item/newspaper/proc/close_paper_ui() + SIGNAL_HANDLER + SStgui.close_uis(src) + /obj/item/newspaper/suicide_act(mob/living/user) user.visible_message(span_suicide(\ "[user] is focusing intently on [src]! It looks like [user.p_theyre()] trying to commit sudoku... \ @@ -77,10 +83,6 @@ return TOXLOSS /obj/item/newspaper/item_interaction(mob/living/user, obj/item/tool, list/modifiers) - if (burn_paper_product_attackby_check(tool, user)) - SStgui.close_uis(src) - return ITEM_INTERACT_SKIP_TO_ATTACK - if (tool.tool_behaviour == TOOL_SCREWDRIVER || tool.tool_behaviour == TOOL_WIRECUTTER || tool.sharpness) if (punctured) balloon_alert(user, "already has holes!") @@ -190,6 +192,8 @@ identity[VISIBLE_NAME_ID] = "" /obj/item/newspaper/ui_interact(mob/user, datum/tgui/ui) + if(resistance_flags & ON_FIRE) + return ui = SStgui.try_update_ui(user, src, ui) if(ui) return diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 209d194927f..4ca9aa7e4a1 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -44,7 +44,9 @@ set_light_on(TRUE) update_brightness() register_context() + init_slapcrafting() +/obj/item/flashlight/proc/init_slapcrafting() var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/flashlight_eyes) AddElement( @@ -446,20 +448,21 @@ damtype = BURN update_brightness() +/obj/item/flashlight/flare/init_slapcrafting() + return + /obj/item/flashlight/flare/Destroy() STOP_PROCESSING(SSobj, src) return ..() -/obj/item/flashlight/flare/attack(mob/living/carbon/victim, mob/living/carbon/user) - if(!isliving(victim)) - return ..() - - if(light_on && victim.ignite_mob()) +/obj/item/flashlight/flare/afterattack(atom/target, mob/user, click_parameters) + if(!isliving(target)) + return + var/mob/living/victim = target + if(get_temperature() && victim.ignite_mob()) message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(victim)] on fire with [src] at [AREACOORD(user)]") user.log_message("set [key_name(victim)] on fire with [src]", LOG_ATTACK) - return ..() - /obj/item/flashlight/flare/toggle_light() if(light_on || !fuel) return FALSE @@ -592,10 +595,8 @@ * Arguments: * * obj/item/fire_starter - the item being used to ignite the candle. * * mob/user - the user to display a message to. - * * quiet - suppresses the to_chat message. - * * silent - suppresses the balloon alerts as well as the to_chat message. */ -/obj/item/flashlight/flare/candle/proc/try_light_candle(obj/item/fire_starter, mob/user, quiet, silent) +/obj/item/flashlight/flare/candle/proc/try_light_candle(obj/item/fire_starter, mob/user) if(!istype(fire_starter)) return if(!istype(user)) @@ -610,34 +611,53 @@ switch(ignition_result) if(SUCCESS) update_appearance(UPDATE_ICON | UPDATE_NAME) - if(!quiet && !silent) - user.visible_message(success_msg) + user.visible_message(success_msg) return SUCCESS if(ALREADY_LIT) - if(!silent) - balloon_alert(user, "already lit!") + balloon_alert(user, "already lit!") return ALREADY_LIT if(NO_FUEL) - if(!silent) - balloon_alert(user, "out of fuel!") + balloon_alert(user, "out of fuel!") return NO_FUEL -/// allows lighting an unlit candle from some fire source by left clicking the candle with the source -/obj/item/flashlight/flare/candle/attackby(obj/item/attacking_item, mob/user, params) - if(try_light_candle(attacking_item, user, silent = istype(attacking_item, src.type))) // so we don't double balloon alerts when a candle is used to light another candle - return COMPONENT_CANCEL_ATTACK_CHAIN - else - return ..() +/obj/item/flashlight/flare/candle/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(get_temperature()) + if(istype(tool, /obj/item/cigarette)) + var/obj/item/cigarette/cig = tool + if(cig.lit) + return NONE + cig.light() + if(cig.loc == user) + user.visible_message( + span_rose("[user] holds [user.p_their()] [cig.name] to [src] and lights it, like a true romantic."), + span_rose("You hold your [cig.name] to [src] and light it, like a true romantic."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) + else + user.visible_message( + span_rose("[user] lights [cig] with [src], like a true romantic."), + span_rose("You light [cig] with [src], like a true romantic."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) + return ITEM_INTERACT_SUCCESS + return NONE + if(try_light_candle(tool, user)) + return ITEM_INTERACT_SUCCESS + return NONE -// allows lighting an unlit candle from some fire source by left clicking the source with the candle -/obj/item/flashlight/flare/candle/pre_attack(atom/target, mob/living/user, params) - if(ismob(target)) - return ..() +/obj/item/flashlight/flare/candle/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + if(get_temperature()) + return NONE + if(try_light_candle(interacting_with, user)) + return ITEM_INTERACT_SUCCESS + return NONE - if(try_light_candle(target, user, quiet = TRUE)) - return COMPONENT_CANCEL_ATTACK_CHAIN - - return ..() +/obj/item/flashlight/flare/candle/ignition_effect(atom/A, mob/user) + if(!get_temperature()) + return "" + if(isitem(A) && A.loc == user) + return span_rose("[user] holds [A] in the flame of [src], letting it catch fire.") + return span_rose("[user] lights [A] ablaze with [src], like a true romantic.") /obj/item/flashlight/flare/candle/attack_self(mob/user) if(light_on && (fuel != INFINITY || !can_be_extinguished)) // can't extinguish eternal candles diff --git a/code/game/objects/items/virgin_mary.dm b/code/game/objects/items/virgin_mary.dm index 46264dc2814..5ae4d33df2b 100644 --- a/code/game/objects/items/virgin_mary.dm +++ b/code/game/objects/items/virgin_mary.dm @@ -7,20 +7,24 @@ ///Has this item been used already. var/used_up = FALSE -#define NICKNAME_CAP (MAX_NAME_LEN/2) -/obj/item/virgin_mary/attackby(obj/item/potential_lighter, mob/living/user, params) +/obj/item/virgin_mary/Initialize(mapload) . = ..() - if(resistance_flags & ON_FIRE) - return - if(!istype(user) || !user.mind) //A sentient mob needs to be burning it, ya cheezit. - return + AddElement(/datum/element/burn_on_item_ignition, bypass_clumsy = TRUE) + RegisterSignal(src, COMSIG_ATOM_IGNITED_BY_ITEM, PROC_REF(induct_new_initiate)) +#define NICKNAME_CAP (MAX_NAME_LEN/2) + +/obj/item/virgin_mary/proc/induct_new_initiate(datum/source, mob/living/user, obj/item/burning_tool) + SIGNAL_HANDLER + + INVOKE_ASYNC(src, PROC_REF(induct_new_initiate_async), user, burning_tool) + +/obj/item/virgin_mary/proc/induct_new_initiate_async(mob/living/user, obj/item/burning_tool) + if(isnull(user.mind)) + return if(HAS_TRAIT(user, TRAIT_MAFIAINITIATE)) //Only one nickname fuckhead to_chat(user, span_warning("You have already been initiated into the mafioso life.")) return - - if(!burn_paper_product_attackby_check(potential_lighter, user, TRUE)) - return if(used_up) return diff --git a/code/modules/library/bibles.dm b/code/modules/library/bibles.dm index b14c9baa56b..e0714c6860c 100644 --- a/code/modules/library/bibles.dm +++ b/code/modules/library/bibles.dm @@ -87,6 +87,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list( on_intercepted = CALLBACK(src, PROC_REF(on_intercepted_bullet)),\ block_charges = 1,\ ) + RegisterSignal(src, COMSIG_ATOM_IGNITED_BY_ITEM, PROC_REF(curse_heathen)) /// Destroy the bible when it's shot by a bullet /obj/item/book/bible/proc/on_intercepted_bullet(mob/living/victim, obj/projectile/bullet) @@ -113,22 +114,22 @@ GLOBAL_LIST_INIT(bibleitemstates, list( else . += span_notice("[src] can be unpacked by hitting the floor of a holy area with it.") -/obj/item/book/bible/burn_paper_product_attackby_check(obj/item/attacking_item, mob/living/user, bypass_clumsy) - . = ..() +/obj/item/book/bible/proc/curse_heathen(datum/source, mob/living/user, obj/item/burning_tool) + SIGNAL_HANDLER + // no deity to cast a curse upon thee if(!deity_name) return - if(. && (resistance_flags & ON_FIRE)) - var/datum/component/omen/existing_omen = user.GetComponent(/datum/component/omen) - //DOUBLE CURSED?! Just straight up gib the guy. - if(existing_omen) - to_chat(user, span_userdanger("[deity_name] SMITE thee!")) - add_memory_in_range(user, 7, /datum/memory/witnessed_gods_wrath, protagonist = user, deuteragonist = src, antagonist = deity_name) - user.client?.give_award(/datum/award/achievement/misc/gods_wrath, user) - user.gib(DROP_ALL_REMAINS) - else - to_chat(user, span_userdanger("[deity_name] cast a curse upon thee!")) - user.AddComponent(/datum/component/omen/bible) + var/datum/component/omen/existing_omen = user.GetComponent(/datum/component/omen) + //DOUBLE CURSED?! Just straight up gib the guy. + if(existing_omen) + to_chat(user, span_userdanger("[deity_name] SMITE thee!")) + add_memory_in_range(user, 7, /datum/memory/witnessed_gods_wrath, protagonist = user, deuteragonist = src, antagonist = deity_name) + user.client?.give_award(/datum/award/achievement/misc/gods_wrath, user) + user.gib(DROP_ALL_REMAINS) + else + to_chat(user, span_userdanger("[deity_name] cast a curse upon thee!")) + user.AddComponent(/datum/component/omen/bible) /obj/item/book/bible/carve_out(obj/item/carving_item, mob/living/user) . = ..() diff --git a/code/modules/library/book.dm b/code/modules/library/book.dm index 3a95bf56aaa..ff36fc53ea5 100644 --- a/code/modules/library/book.dm +++ b/code/modules/library/book.dm @@ -35,6 +35,7 @@ book_data = new(starting_title, starting_author, starting_content) AddElement(/datum/element/falling_hazard, damage = 5, wound_bonus = 0, hardhat_safety = TRUE, crushes = FALSE, impact_sound = drop_sound) + AddElement(/datum/element/burn_on_item_ignition) /obj/item/book/examine(mob/user) . = ..() @@ -98,9 +99,6 @@ display_content(user) /obj/item/book/attackby(obj/item/attacking_item, mob/living/user, params) - if(burn_paper_product_attackby_check(attacking_item, user)) - return - if(IS_WRITING_UTENSIL(attacking_item)) if(!user.can_perform_action(src) || !user.can_write(attacking_item)) return diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 37ab17a7e48..db422a389b2 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -27,6 +27,7 @@ /obj/item/folder/Initialize(mapload) update_icon() . = ..() + AddElement(/datum/element/burn_on_item_ignition) /obj/item/folder/Destroy() for(var/obj/important_thing in contents) @@ -79,8 +80,6 @@ return paper_overlay /obj/item/folder/attackby(obj/item/weapon, mob/user, params) - if(burn_paper_product_attackby_check(weapon, user)) - return if(is_type_in_typecache(weapon, folder_insertables)) //Add paper, photo or documents into the folder if(!user.transferItemToLoc(weapon, src)) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 2b827707c5c..c540a42561d 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -79,6 +79,9 @@ if(can_become_message_in_bottle && !mapload && prob(MESSAGE_BOTTLE_CHANCE)) LAZYADD(SSpersistence.queued_message_bottles, src) + AddElement(/datum/element/burn_on_item_ignition) + RegisterSignal(src, COMSIG_ATOM_IGNITED_BY_ITEM, PROC_REF(close_paper_ui)) + /obj/item/paper/Destroy() camera_holder = null clear_paper() @@ -90,6 +93,10 @@ custom_fire_overlay = mutable_appearance('icons/obj/service/bureaucracy.dmi', "paper_onfire_overlay", appearance_flags = RESET_COLOR|KEEP_APART) return custom_fire_overlay +/obj/item/paper/proc/close_paper_ui() + SIGNAL_HANDLER + SStgui.close_uis(src) + /// Determines whether this paper has been written or stamped to. /obj/item/paper/proc/is_empty() return !(LAZYLEN(raw_text_inputs) || LAZYLEN(raw_stamp_data)) @@ -407,37 +414,7 @@ user.put_in_hands(new_plane) return new_plane -/obj/item/proc/burn_paper_product_attackby_check(obj/item/attacking_item, mob/living/user, bypass_clumsy = FALSE) - //can't be put on fire! - if((resistance_flags & FIRE_PROOF) || !(resistance_flags & FLAMMABLE)) - return FALSE - //already on fire! - if(resistance_flags & ON_FIRE) - return FALSE - var/ignition_message = attacking_item.ignition_effect(src, user) - if(!ignition_message) - return FALSE - if(!bypass_clumsy && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10) && Adjacent(user)) - user.visible_message(span_warning("[user] accidentally ignites [user.p_them()]self!"), \ - span_userdanger("You miss [src] and accidentally light yourself on fire!")) - if(user.is_holding(attacking_item)) //checking if they're holding it in case TK is involved - user.dropItemToGround(attacking_item) - user.adjust_fire_stacks(attacking_item) - user.ignite_mob() - return TRUE - - if(user.is_holding(src)) //no TK shit here. - user.dropItemToGround(src) - user.visible_message(ignition_message) - add_fingerprint(user) - fire_act(attacking_item.get_temperature()) - return TRUE - /obj/item/paper/attackby(obj/item/attacking_item, mob/living/user, params) - if(burn_paper_product_attackby_check(attacking_item, user)) - SStgui.close_uis(src) - return - // Enable picking paper up by clicking on it with the clipboard or folder if(istype(attacking_item, /obj/item/clipboard) || istype(attacking_item, /obj/item/folder) || istype(attacking_item, /obj/item/paper_bin)) attacking_item.attackby(src, user) @@ -530,6 +507,8 @@ ) /obj/item/paper/ui_interact(mob/user, datum/tgui/ui) + if(resistance_flags & ON_FIRE) + return ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "PaperSheet", name) diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index 5351b08d822..62ee4ad419d 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -35,6 +35,7 @@ if(istype(internal_paper, /obj/item/paper/carbon_copy)) icon_state = "[base_icon_state]_carbon" update_appearance(UPDATE_ICON) + AddElement(/datum/element/burn_on_item_ignition) /obj/item/paperplane/Exited(atom/movable/gone, direction) . = ..() @@ -80,8 +81,6 @@ user.put_in_hands(released_paper) /obj/item/paperplane/attackby(obj/item/attacking_item, mob/user, params) - if(burn_paper_product_attackby_check(attacking_item, user)) - return if(IS_WRITING_UTENSIL(attacking_item)) to_chat(user, span_warning("You should unfold [src] before changing it!")) return diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index 5b3d4911f52..d2aa7b9a867 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -253,6 +253,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/ticket_machine, 32) name += " #[num]" saved_maptext = MAPTEXT(num) maptext = saved_maptext + AddElement(/datum/element/burn_on_item_ignition) /obj/item/ticket_machine_ticket/examine(mob/user) . = ..() @@ -265,12 +266,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/ticket_machine, 32) . = ..() maptext = saved_maptext //For some reason, storage code removes all maptext off objs, this stops its number from being wiped off when taken out of storage. -/obj/item/ticket_machine_ticket/attackby(obj/item/P, mob/living/carbon/human/user, params) //Stolen from papercode - if(burn_paper_product_attackby_check(P, user)) - return - - return ..() - /obj/item/ticket_machine_ticket/Destroy() if(source) source.ticket_holders -= owner_ref diff --git a/code/modules/photography/photos/photo.dm b/code/modules/photography/photos/photo.dm index 3cac28663ff..185c81f5d5a 100644 --- a/code/modules/photography/photos/photo.dm +++ b/code/modules/photography/photos/photo.dm @@ -20,7 +20,8 @@ //Photos are quite rarer than papers, so they're more likely to be added to the queue to make things even. if(!mapload && prob(MESSAGE_BOTTLE_CHANCE * 5) && picture?.id) LAZYADD(SSpersistence.queued_message_bottles, src) - return ..() + . = ..() + AddElement(/datum/element/burn_on_item_ignition) /obj/item/photo/Destroy() LAZYREMOVE(SSpersistence.queued_message_bottles, src) @@ -75,8 +76,6 @@ user.examinate(src) /obj/item/photo/attackby(obj/item/P, mob/user, params) - if(burn_paper_product_attackby_check(P, user)) - return if(IS_WRITING_UTENSIL(P)) if(!user.can_write(P)) return diff --git a/tgstation.dme b/tgstation.dme index 7e8afba9f7f..da3780f9ee9 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1479,6 +1479,7 @@ #include "code\datums\elements\bsa_blocker.dm" #include "code\datums\elements\bugkiller_reagent.dm" #include "code\datums\elements\bump_click.dm" +#include "code\datums\elements\burn_when_item_ignition.dm" #include "code\datums\elements\can_barricade.dm" #include "code\datums\elements\can_shatter.dm" #include "code\datums\elements\caseless.dm"