From 69d50605396288dd2c06279e096d82a18978fbae Mon Sep 17 00:00:00 2001 From: Spookerton Date: Wed, 31 Jan 2024 16:32:52 +0000 Subject: [PATCH] add a cut down version of eris bidons --- code/__defines/flags.dm | 3 + code/game/atoms.dm | 3 + .../machinery/dispenser/reagent_tank.dm | 20 +-- .../reagent_containers/_reagent_containers.dm | 20 ++- .../reagents/reagent_containers/bidon.dm | 158 ++++++++++++++++++ .../reagents/reagent_containers/glass.dm | 5 + code/modules/research/designs/bio_devices.dm | 15 ++ icons/obj/structures/bidon.dmi | Bin 0 -> 3034 bytes polaris.dme | 1 + 9 files changed, 208 insertions(+), 17 deletions(-) create mode 100644 code/modules/reagents/reagent_containers/bidon.dm create mode 100644 icons/obj/structures/bidon.dmi diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm index 0bad588e678..7a8151ef7fd 100644 --- a/code/__defines/flags.dm +++ b/code/__defines/flags.dm @@ -32,6 +32,9 @@ /// This atom is queued for an overlay update. #define ATOM_AWAITING_OVERLAY_UPDATE (1<<5) +///The Reagent cannot be refilled +#define ATOM_REAGENTS_NO_REFILL (1<<6) + /* -- /turf/var/turf_flags -- */ diff --git a/code/game/atoms.dm b/code/game/atoms.dm index e63a02358aa..9e59e0f1ae3 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -129,6 +129,9 @@ var/global/list/pre_init_created_atoms // atom creation ordering means some stuf /atom/proc/is_open_container() return atom_flags & ATOM_REAGENTS_IS_OPEN +/atom/proc/can_refill() + return atom_flags & ~ATOM_REAGENTS_NO_REFILL + /*//Convenience proc to see whether a container can be accessed in a certain way. proc/can_subract_container() diff --git a/code/modules/reagents/machinery/dispenser/reagent_tank.dm b/code/modules/reagents/machinery/dispenser/reagent_tank.dm index bfe7dc58114..ae03e2999c9 100644 --- a/code/modules/reagents/machinery/dispenser/reagent_tank.dm +++ b/code/modules/reagents/machinery/dispenser/reagent_tank.dm @@ -9,10 +9,11 @@ density = 1 anchored = 0 pressure_resistance = 2*ONE_ATMOSPHERE - + atom_flags = ATOM_REAGENTS_NO_REFILL + var/volume = 5000 + var/has_hose = TRUE var/obj/item/hose_connector/input/active/InputSocket var/obj/item/hose_connector/output/active/OutputSocket - var/amount_per_transfer_from_this = 10 var/possible_transfer_amounts = list(10,25,50,100) @@ -22,21 +23,20 @@ /obj/structure/reagent_dispensers/Destroy() QDEL_NULL(InputSocket) QDEL_NULL(OutputSocket) - - ..() + return ..() /obj/structure/reagent_dispensers/Initialize() - var/datum/reagents/R = new/datum/reagents(5000) + var/datum/reagents/R = new/datum/reagents(volume) reagents = R R.my_atom = src if (!possible_transfer_amounts) src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT - InputSocket = new(src) - InputSocket.carrier = src - OutputSocket = new(src) - OutputSocket.carrier = src - + if(has_hose) + InputSocket = new(src) + InputSocket.carrier = src + OutputSocket = new(src) + OutputSocket.carrier = src . = ..() /obj/structure/reagent_dispensers/examine(mob/user) diff --git a/code/modules/reagents/reagent_containers/_reagent_containers.dm b/code/modules/reagents/reagent_containers/_reagent_containers.dm index 322fe5389dc..85f8e3e251a 100644 --- a/code/modules/reagents/reagent_containers/_reagent_containers.dm +++ b/code/modules/reagents/reagent_containers/_reagent_containers.dm @@ -22,6 +22,9 @@ src.verbs -= /obj/item/reagent_containers/verb/set_APTFT create_reagents(volume) +/obj/item/reagent_containers/on_reagent_change() + update_icon() + /obj/item/reagent_containers/attack_self(mob/user as mob) return @@ -38,12 +41,14 @@ return 0 if(!target.reagents || !target.reagents.total_volume) - to_chat(user, "[target] is empty.") - return 1 + if(target.can_refill()) + return 0 + else + to_chat(user, "[target] is empty.") + return 1 if(reagents && !reagents.get_free_space()) - to_chat(user, "[src] is full.") - return 1 + return 0 var/trans = target.reagents.trans_to_obj(src, target:amount_per_transfer_from_this) to_chat(user, "You fill [src] with [trans] units of the contents of [target].") @@ -116,8 +121,8 @@ feed_sound(user) return TRUE -/obj/item/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level - if(!target.is_open_container() || !target.reagents) +/obj/item/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target, var/pour_all = FALSE) // This goes into afterattack and yes, it's atom-level + if(!target.is_open_container() || !target.reagents || !target.can_refill()) return 0 if(!reagents || !reagents.total_volume) @@ -128,6 +133,7 @@ to_chat(user, "[target] is full.") return 1 - var/trans = reagents.trans_to(target, amount_per_transfer_from_this) + var/trans = pour_all ? reagents.total_volume : amount_per_transfer_from_this + trans = reagents.trans_to(target, trans) to_chat(user, "You transfer [trans] units of the solution to [target].") return 1 diff --git a/code/modules/reagents/reagent_containers/bidon.dm b/code/modules/reagents/reagent_containers/bidon.dm new file mode 100644 index 00000000000..59667050583 --- /dev/null +++ b/code/modules/reagents/reagent_containers/bidon.dm @@ -0,0 +1,158 @@ +/obj/structure/reagent_dispensers/bidon + name = "bidon canister" + desc = "A canister for handling large volumes of chemicals." + icon = 'icons/obj/structures/bidon.dmi' + icon_state = "bidon" + possible_transfer_amounts = list(10, 30, 60, 120, 200, 300) + unacidable = TRUE + has_hose = FALSE + var/use_reagent_color = TRUE + var/fill_step = 10 + + +/obj/structure/reagent_dispensers/bidon/Initialize() + . = ..() + update_icon() + + +/obj/structure/reagent_dispensers/bidon/update_icon() + cut_overlays() + if (!is_open_container()) + add_overlay("[icon_state]_lid") + var/fill_state = ceil(round(reagents.total_volume / volume * 100, fill_step), 0, 100) + if (!fill_state) + return + if (use_reagent_color) + var/image/image = image(icon, icon_state = "[icon_state][fill_state]") + image.color = reagents.get_color() + add_overlay(image) + else + add_overlay("[icon_state][fill_state]") + + +/obj/structure/reagent_dispensers/bidon/examine(mob/user, distance, infix, suffix) + . = ..() + if (distance > 5) + return + . += "The lid is [is_open_container() ? "off" : "on"]." + if (distance < 3) + . += "It holds [round(reagents.total_volume, 0.1)]/[volume] units of reagents." + + +/obj/structure/reagent_dispensers/bidon/attack_hand(mob/living/user) + playsound(src, 'sound/items/trayhit2.ogg', 50, TRUE) + atom_flags ^= ATOM_REAGENTS_IS_OPEN + if (is_open_container()) + to_chat(user, SPAN_ITALIC("You open the lid of \the [src].")) + else + to_chat(user, SPAN_ITALIC("You close the lid of \the [src].")) + update_icon() + + +/obj/structure/reagent_dispensers/bidon/attackby(obj/item/item, mob/living/user) + if (!is_open_container() && istype(item, /obj/item/reagent_containers)) + to_chat(user, SPAN_WARNING("Remove the lid first.")) + return TRUE + return ..() + + +/obj/structure/reagent_dispensers/bidon/stasis + name = "stasis bidon canister" + desc = "A canister for handling large volumes of chemicals. This one has a stasis field." + icon_state = "bidon_stasis" + atom_flags = ATOM_REAGENTS_SKIP_REACTIONS + use_reagent_color = FALSE + fill_step = 20 + var/timer_seconds + var/timer_handle + + +/obj/structure/reagent_dispensers/bidon/stasis/update_icon() + ..() + if (timer_handle) + add_overlay("timer_active") + else if (timer_seconds) + add_overlay("timer_idle") + + +/obj/structure/reagent_dispensers/bidon/stasis/examine(mob/user, distance, infix, suffix) + . = ..() + if (distance > 5 || !timer_seconds) + return + var/timer_display = "a timer" + if (timer_handle) + timer_display = "an active timer" + if (distance > 3) + . += "It has [timer_display] attached." + else + . += "It has [timer_display] attached set for [timer_seconds] seconds." + + +/obj/structure/reagent_dispensers/bidon/stasis/attackby(obj/item/item, mob/living/user) + if (istype(item, /obj/item/assembly/timer)) + if (timer_seconds) + to_chat(user, SPAN_WARNING("\The [src] already has a timer attached.")) + else if (user.unEquip(item)) + var/obj/item/assembly/timer/timer = item + timer_seconds = timer.time + qdel(item) + playsound(src, 'sound/items/Screwdriver.ogg', 50, TRUE) + user.visible_message( + SPAN_ITALIC("\The [user] attaches \a [item] to \a [src]."), + SPAN_ITALIC("You attach \the [item] to \the [src]."), + SPAN_ITALIC("You hear metal clicking together."), + range = 5 + ) + return TRUE + if (item.is_screwdriver()) + if (!timer_seconds) + to_chat(user, SPAN_WARNING("\The [src] doesn't have a timer attached.")) + else if (timer_handle) + to_chat(user, SPAN_WARNING("\The [src]'s timer is active.")) + else + user.visible_message( + SPAN_ITALIC("\The [user] removes the timer from \the [src]."), + SPAN_ITALIC("You remove the timer from \the [src]."), + SPAN_ITALIC("You hear metal clicking together."), + range = 5 + ) + playsound(src, item.usesound, 50, TRUE) + var/obj/item/assembly/timer/timer = new (loc) + user.put_in_hands(timer) + timer.time = timer_seconds + timer_seconds = 0 + return TRUE + if (item.is_multitool()) + if (!timer_seconds) + to_chat(user, SPAN_WARNING("\The [src] doesn't have a timer attached.")) + return TRUE + else if (timer_handle) + deltimer(timer_handle) + timer_handle = null + user.visible_message( + SPAN_ITALIC("\The [user] disables the timer on \the [src]."), + SPAN_ITALIC("You disable the timer on \the [src]."), + SPAN_ITALIC("You hear soft beeping."), + range = 5 + ) + update_icon() + else + timer_handle = addtimer(CALLBACK(src, .proc/timer_end), timer_seconds SECONDS, TIMER_STOPPABLE) + user.visible_message( + SPAN_ITALIC("\The [user] activates the timer on \the [src]."), + SPAN_ITALIC("You activate the timer on \the [src]."), + SPAN_ITALIC("You hear soft beeping."), + range = 5 + ) + playsound(src, item.usesound, 50, TRUE) + update_icon() + return TRUE + return ..() + + +/obj/structure/reagent_dispensers/bidon/stasis/proc/timer_end() + atom_flags &= ~(ATOM_REAGENTS_SKIP_REACTIONS) + reagents.handle_reactions() + atom_flags |= ATOM_REAGENTS_SKIP_REACTIONS + timer_handle = null + update_icon() diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index ad6877fd37f..ebf920734bb 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -106,6 +106,11 @@ for(var/type in can_be_placed_into) //Is it something it can be placed into? if(istype(target, type)) return 1 + + //Disarm intent tries to empty the beaker + if(user.a_intent == I_DISARM && standard_pour_into(user, target, TRUE)) + return TRUE + if(standard_dispenser_refill(user, target)) //Are they clicking a water tank/some dispenser? return 1 if(standard_pour_into(user, target)) //Pouring into another beaker? diff --git a/code/modules/research/designs/bio_devices.dm b/code/modules/research/designs/bio_devices.dm index f3aa33845ff..7c6a26c6a88 100644 --- a/code/modules/research/designs/bio_devices.dm +++ b/code/modules/research/designs/bio_devices.dm @@ -59,3 +59,18 @@ build_path = /obj/item/analyzer/plant_analyzer sort_string = "JAADA" +/datum/design/item/biotech/bidon + desc = "A canister for handling large volumes of chemicals." + id = "bidon" + req_tech = list(TECH_MATERIAL = 4, TECH_BIO = 4) + materials = list(MAT_STEEL = 2000, "glass" = 1000) + build_path = /obj/structure/reagent_dispensers/bidon + sort_string = "JAADB" + +/datum/design/item/biotech/bidon_stasis + desc = "A stasis canister for handling large volumes of chemicals." + id = "bidon_stasis" + req_tech = list(TECH_MATERIAL = 6, TECH_BIO = 4, TECH_DATA = 5) + materials = list(MAT_STEEL = 2000, "glass" = 1000, MAT_SILVER = 100) + build_path = /obj/structure/reagent_dispensers/bidon/stasis + sort_string = "JAADC" diff --git a/icons/obj/structures/bidon.dmi b/icons/obj/structures/bidon.dmi new file mode 100644 index 0000000000000000000000000000000000000000..6dea9015bf73d19c33cabd7835795e110a08a053 GIT binary patch literal 3034 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