diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 42201e992e5..f76e216af78 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -821,3 +821,7 @@ #define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" ///from monkey CtrlClickOn(): (/mob) #define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" + +// /datum/component/container_item +/// (atom/container, mob/user) - returns bool +#define COMSIG_CONTAINER_TRY_ATTACH "container_try_attach" diff --git a/code/datums/components/container_item/container_item.dm b/code/datums/components/container_item/container_item.dm new file mode 100644 index 00000000000..fda012cb0ea --- /dev/null +++ b/code/datums/components/container_item/container_item.dm @@ -0,0 +1,10 @@ +/// Container item, an item which can be stored by specialized containers. +/datum/component/container_item + +/datum/component/container_item/Initialize() + . = ..() + RegisterSignal(parent, COMSIG_CONTAINER_TRY_ATTACH, .proc/try_attach) + +/// Called when parent is added to the container. +/datum/component/container_item/proc/try_attach(datum/source, atom/container, mob/user) + return FALSE diff --git a/code/datums/components/container_item/tank_holder.dm b/code/datums/components/container_item/tank_holder.dm new file mode 100644 index 00000000000..b68c413519c --- /dev/null +++ b/code/datums/components/container_item/tank_holder.dm @@ -0,0 +1,31 @@ +/// Tank holder item - Added to an object which can be added to a tank holder. +/datum/component/container_item/tank_holder + var/tank_holder_icon_state + var/make_density + +/datum/component/container_item/tank_holder/Initialize(state, density = TRUE) + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + + tank_holder_icon_state = state + make_density = density + return ..() + +/datum/component/container_item/tank_holder/try_attach(datum/source, obj/structure/tank_holder/container, mob/user) + if(!container || !istype(container)) + return FALSE + var/obj/item/I = parent + if(container.contents.len) + if(user) + to_chat(user, "There's already something in [container].") + return TRUE + if(user) + if(!user.transferItemToLoc(I, container)) + return TRUE + to_chat(user, "You put [I] into [container].") + else + I.forceMove(container) + container.tank = I + container.density = make_density + container.icon_state = tank_holder_icon_state + return TRUE diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index bd4b3334867..c1c5599a2bc 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -187,9 +187,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb var/canMouseDown = FALSE - /// Item state of tank holder when inside tank holder. null makes it unable to enter a tank holder. - var/tank_holder_icon_state = null - /obj/item/Initialize() if(attack_verb_continuous) diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index 47aedf15ca7..f4902e9cd90 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -5,7 +5,6 @@ icon_state = "fire_extinguisher0" inhand_icon_state = "fire_extinguisher" hitsound = 'sound/weapons/smash.ogg' - tank_holder_icon_state = "holder_extinguisher" flags_1 = CONDUCT_1 throwforce = 10 w_class = WEIGHT_CLASS_NORMAL @@ -27,12 +26,13 @@ var/power = 5 //Maximum distance launched water will travel var/precision = FALSE //By default, turfs picked from a spray are random, set to 1 to make it always have at least one water effect per row var/cooling_power = 2 //Sets the cooling_temperature of the water reagent datum inside of the extinguisher when it is refilled + /// Icon state when inside a tank holder + var/tank_holder_icon_state = "holder_extinguisher" /obj/item/extinguisher/mini name = "pocket fire extinguisher" desc = "A light and compact fibreglass-framed model fire extinguisher." icon_state = "miniFE0" - tank_holder_icon_state = "holder_extinguisher" inhand_icon_state = "miniFE" hitsound = null //it is much lighter, after all. flags_1 = null //doesn't CONDUCT_1 @@ -54,6 +54,11 @@ . = ..() refill() +/obj/item/extinguisher/ComponentInitialize() + . = ..() + if(tank_holder_icon_state) + AddComponent(/datum/component/container_item/tank_holder, tank_holder_icon_state) + /obj/item/extinguisher/advanced name = "advanced fire extinguisher" desc = "Used to stop thermonuclear fires from spreading inside your engine." diff --git a/code/game/objects/items/miscellaneous.dm b/code/game/objects/items/miscellaneous.dm index aed7b07413b..78f18e0a3d7 100644 --- a/code/game/objects/items/miscellaneous.dm +++ b/code/game/objects/items/miscellaneous.dm @@ -319,11 +319,14 @@ name = "skub" icon = 'icons/obj/items_and_weapons.dmi' icon_state = "skub" - tank_holder_icon_state = "holder_skub" w_class = WEIGHT_CLASS_BULKY attack_verb_continuous = list("skubs") attack_verb_simple = list("skub") +/obj/item/skub/ComponentInitialize() + . = ..() + AddComponent(/datum/component/container_item/tank_holder, "holder_skub", FALSE) + /obj/item/skub/suicide_act(mob/living/user) user.visible_message("[user] has declared themself as anti-skub! The skub tears them apart!") diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index b29fbae6489..3aba2a129bf 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -4,7 +4,6 @@ icon_state = "generic" lefthand_file = 'icons/mob/inhands/equipment/tanks_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tanks_righthand.dmi' - tank_holder_icon_state = "holder_generic" flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BACK worn_icon = 'icons/mob/clothing/back.dmi' //since these can also get thrown into suit storage slots. if something goes on the belt, set this to null. @@ -21,6 +20,8 @@ var/distribute_pressure = ONE_ATMOSPHERE var/integrity = 3 var/volume = 70 + /// Icon state when in a tank holder. Null makes it incompatible with tank holder. + var/tank_holder_icon_state = "holder_generic" /obj/item/tank/ui_action_click(mob/user) toggle_internals(user) @@ -75,6 +76,11 @@ STOP_PROCESSING(SSobj, src) . = ..() +/obj/item/tank/ComponentInitialize() + . = ..() + if(tank_holder_icon_state) + AddComponent(/datum/component/container_item/tank_holder, tank_holder_icon_state) + /obj/item/tank/examine(mob/user) var/obj/icon = src . = ..() diff --git a/code/game/objects/structures/tank_holder.dm b/code/game/objects/structures/tank_holder.dm index d631bd45ec8..b03c17b2f12 100644 --- a/code/game/objects/structures/tank_holder.dm +++ b/code/game/objects/structures/tank_holder.dm @@ -1,3 +1,4 @@ +///? /obj/structure/tank_holder name = "tank holder" desc = "A metallic frame that can hold tanks and extinguishers." @@ -19,10 +20,13 @@ /obj/structure/tank_holder/Initialize() . = ..() if(tank) - after_put_tank(new tank) + var/obj/item/tank_ = new tank(null) + tank = null + SEND_SIGNAL(tank_, COMSIG_CONTAINER_TRY_ATTACH, src, null) /obj/structure/tank_holder/Destroy() if(tank) + contents.Cut() QDEL_NULL(tank) return ..() @@ -38,18 +42,8 @@ /obj/structure/tank_holder/attackby(obj/item/W, mob/user, params) if(user.a_intent == INTENT_HARM) return ..() - if(contents.len) - to_chat(user, "There's already something in [src].") - return - - if(!W.tank_holder_icon_state) + if(!SEND_SIGNAL(W, COMSIG_CONTAINER_TRY_ATTACH, src, user)) to_chat(user, "[W] does not fit in [src].") - return - - if(!user.transferItemToLoc(W, src)) - return - to_chat(user, "You put [W] into [src].") - after_put_tank(W) /obj/structure/tank_holder/screwdriver_act(mob/living/user, obj/item/I) if(..()) @@ -64,7 +58,7 @@ new /obj/item/stack/rods(get_turf(src), 2) if(tank) tank.forceMove(get_turf(src)) - tank = null + after_detach_tank() qdel(src) /obj/structure/tank_holder/attack_paw(mob/user) @@ -77,31 +71,25 @@ return ..() to_chat(user, "You take [tank] from [src].") add_fingerprint(user) + tank.add_fingerprint(user) user.put_in_hands(tank) - after_remove_tank() + after_detach_tank() /obj/structure/tank_holder/handle_atom_del(atom/A) if(A == tank) - after_remove_tank() + after_detach_tank() return ..() /obj/structure/tank_holder/contents_explosion(severity, target) if(tank) tank.ex_act(severity, target) -/// Call this after inserting the tank into contents in order to update references, icon -/// and density. -/obj/structure/tank_holder/proc/after_put_tank(obj/item/tank_) - tank = tank_ - icon_state = tank.tank_holder_icon_state - density = TRUE - /// Call this after taking the tank from contents in order to update references, icon /// and density. -/obj/structure/tank_holder/proc/after_remove_tank() +/obj/structure/tank_holder/proc/after_detach_tank() tank = null - icon_state = "holder" density = FALSE + icon_state = "holder" /obj/structure/tank_holder/oxygen icon_state = "holder_oxygen" diff --git a/tgstation.dme b/tgstation.dme index 218214fbb31..84c1758f9af 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -483,6 +483,8 @@ #include "code\datums\components\uplink.dm" #include "code\datums\components\wearertargeting.dm" #include "code\datums\components\wet_floor.dm" +#include "code\datums\components\container_item\container_item.dm" +#include "code\datums\components\container_item\tank_holder.dm" #include "code\datums\components\crafting\crafting.dm" #include "code\datums\components\crafting\guncrafting.dm" #include "code\datums\components\crafting\recipes.dm"