From d06d92b71714c2525263cb005d6f7bc54576c808 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Wed, 15 May 2024 09:22:46 +0530 Subject: [PATCH] General maintenance for smoke machine (#83158) ## About The Pull Request **1. Qol** - Adds examines & screentips for screwdriver, crowbar, wrench acts & inserting reagents - Adds examines for viewing reagents present & efficiency of the smoke machine - Removes power cell from smoke machine required component parts. It's used nowhere in operation & is a waste of a good cell **2. Code Improvements** - Replaced `attackby()` with `item_interaction()` - Begins & ends processing only when the player turns the machine on/off & not just when power is available - Removed unused vars like `cooldown` & `user_amount` - Correctly autodocs remaining vars - Improved UI code to use existing `BeakerDisplay` props **3. Fixes** - You no longer hit the smoke machine when inserting reagents into it via beaker or other open containers - You can hit the smoke machine with tools like screwdriver, crowbar, wrench & open containers when in combat mode - No abstract & hologram item interactions with smoke machine ## Changelog :cl: qol: adds examines & screentips for tool & container actions on the smoke machine qol: smoke machine no longer requires a power cell for construction code: autodocs & removes vars for some machine, Updated attack chain to latest standards for smoke machine fix: You no longer hit the smoke machine with the beaker fix: You can hit the smoke machine with tools & beakers when in combat mode fix: no abstract & hologram item interactions allowed with smoke machine /:cl: --------- Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- .../machines/machine_circuitboards.dm | 3 +- .../chemistry/machinery/smoke_machine.dm | 251 +++++++++++------- .../packages/tgui/interfaces/SmokeMachine.tsx | 27 +- 3 files changed, 169 insertions(+), 112 deletions(-) diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index 3afc7a9a03b..61b17cd25d6 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -914,8 +914,7 @@ /datum/stock_part/matter_bin = 2, /datum/stock_part/capacitor = 1, /datum/stock_part/servo = 1, - /obj/item/stack/sheet/glass = 1, - /obj/item/stock_parts/cell = 1) + /obj/item/stack/sheet/glass = 1) needs_anchored = FALSE /obj/item/circuitboard/machine/stasis diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm index c103457025d..6f58fb90193 100644 --- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm +++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm @@ -1,4 +1,5 @@ -#define REAGENTS_BASE_VOLUME 100 // actual volume is REAGENTS_BASE_VOLUME plus REAGENTS_BASE_VOLUME * rating for each matterbin +/// Actual volume is REAGENTS_BASE_VOLUME plus REAGENTS_BASE_VOLUME * rating for each matterbin +#define REAGENTS_BASE_VOLUME 100 /obj/machinery/smoke_machine name = "smoke machine" @@ -8,21 +9,17 @@ base_icon_state = "smoke" density = TRUE circuit = /obj/item/circuitboard/machine/smoke_machine - processing_flags = NONE + interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_REQUIRES_ANCHORED + processing_flags = START_PROCESSING_MANUALLY + ///Divided against the amount of smoke to produce. Higher values equals lesser amount of reagents consumed to create smoke var/efficiency = 20 + ///Is this machine on or off var/on = FALSE - var/cooldown = 0 - var/useramount = 30 // Last used amount - var/setting = 1 // displayed range is 3 * setting - var/max_range = 3 // displayed max range is 3 * max range - -/datum/effect_system/fluid_spread/smoke/chem/smoke_machine/set_up(range = 1, amount = DIAMOND_AREA(range), atom/holder, atom/location = null, datum/reagents/carry = null, efficiency = 10, silent=FALSE) - src.holder = holder - src.location = get_turf(location) - src.amount = amount - carry?.copy_to(chemholder, 20) - carry?.remove_all(amount / efficiency) + ///Higher values mean larger smoke pufs but also more power & reagents consumed + var/setting = 1 + ///Max setting acheived from upgraded capacitors + var/max_range = 3 /// A factory which produces clouds of smoke for the smoke machine. /datum/effect_system/fluid_spread/smoke/chem/smoke_machine @@ -33,88 +30,145 @@ opacity = FALSE alpha = 100 +/datum/effect_system/fluid_spread/smoke/chem/smoke_machine/set_up(range = 1, amount = DIAMOND_AREA(range), atom/holder, atom/location, datum/reagents/carry, efficiency = 10, silent = FALSE) + src.holder = holder + src.location = get_turf(location) + src.amount = amount + if(carry) + carry.copy_to(chemholder, 20) + carry.remove_all(amount / efficiency) + /obj/machinery/smoke_machine/Initialize(mapload) - . = ..() create_reagents(REAGENTS_BASE_VOLUME, INJECTABLE) + + . = ..() + AddComponent(/datum/component/plumbing/simple_demand) AddComponent(/datum/component/simple_rotation) - for(var/datum/stock_part/matter_bin/B in component_parts) - reagents.maximum_volume += REAGENTS_BASE_VOLUME * B.tier - if(is_operational) - begin_processing() + register_context() + +/obj/machinery/smoke_machine/on_deconstruction(disassembled) + reagents.expose(loc, TOUCH) + reagents.clear_reagents() + +/obj/machinery/smoke_machine/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = NONE + if(isnull(held_item)) + return + + if(is_reagent_container(held_item) && held_item.is_open_container()) + context[SCREENTIP_CONTEXT_LMB] = "Inject reagents" + return CONTEXTUAL_SCREENTIP_SET + + if(held_item.tool_behaviour == TOOL_SCREWDRIVER) + context[SCREENTIP_CONTEXT_LMB] = "[panel_open ? "Close" : "Open"] panel" + return CONTEXTUAL_SCREENTIP_SET + else if(held_item.tool_behaviour == TOOL_WRENCH) + context[SCREENTIP_CONTEXT_LMB] = "[anchored ? "Una" : "A"]nchor" + return CONTEXTUAL_SCREENTIP_SET + else if(held_item.tool_behaviour == TOOL_CROWBAR && panel_open) + context[SCREENTIP_CONTEXT_LMB] = "Deconstruct" + return CONTEXTUAL_SCREENTIP_SET + +/obj/machinery/smoke_machine/examine(mob/user) + . = ..() + + . += span_notice("Reagent capacity [reagents.total_volume]/[reagents.maximum_volume].") + . += span_notice("Operating at [round((efficiency / 26) * 100)]% efficiency.") + + . += span_notice("Its maintainence panel can be [EXAMINE_HINT("screwed")] [panel_open ? "closed" : "open"].") + if(panel_open) + . += span_notice("It can be [EXAMINE_HINT("pried")] apart.") + + if(anchored) + . += span_notice("It can be [EXAMINE_HINT("wrenched")] loose.") + else + . += span_warning("It needs to be [EXAMINE_HINT("anchored")] in place to work.") /obj/machinery/smoke_machine/update_icon_state() - if((!is_operational) || (!on) || (reagents.total_volume == 0)) - icon_state = "[base_icon_state]0[panel_open ? "-o" : null]" + if(!is_operational || !on || !reagents.total_volume) + icon_state = "[base_icon_state]0[panel_open ? "-o" : ""]" return ..() + icon_state = "[base_icon_state]1" return ..() /obj/machinery/smoke_machine/RefreshParts() . = ..() + + //new capacity to store reagents from matter bins var/new_volume = REAGENTS_BASE_VOLUME for(var/datum/stock_part/matter_bin/matter_bin in component_parts) new_volume += REAGENTS_BASE_VOLUME * matter_bin.tier - if(!reagents) - create_reagents(new_volume, INJECTABLE) reagents.maximum_volume = new_volume - if(new_volume < reagents.total_volume) - reagents.expose(loc, TOUCH) // if someone manages to downgrade it without deconstructing - reagents.clear_reagents() + + //new efficiency from capacitors efficiency = 18 for(var/datum/stock_part/capacitor/capacitor in component_parts) efficiency += 2 * capacitor.tier + + //new maximum range from servos max_range = 1 for(var/datum/stock_part/servo/servo in component_parts) max_range += servo.tier max_range = max(3, max_range) -/obj/machinery/smoke_machine/on_set_is_operational(old_value) - if(old_value) //Turned off - end_processing() - else //Turned on - begin_processing() +/obj/machinery/smoke_machine/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = NONE + if(user.combat_mode || tool.item_flags & ABSTRACT || tool.flags_1 & HOLOGRAM_1 || !user.can_perform_action(src, ALLOW_SILICON_REACH)) + return ITEM_INTERACT_SKIP_TO_ATTACK - -/obj/machinery/smoke_machine/process() - if(reagents.total_volume == 0) - on = FALSE - update_appearance() - return - var/turf/location = get_turf(src) - var/smoke_test = locate(/obj/effect/particle_effect/fluid/smoke) in location - if(on && !smoke_test) - update_appearance() - var/datum/effect_system/fluid_spread/smoke/chem/smoke_machine/smoke = new() - smoke.set_up(setting * 3, holder = src, location = location, carry = reagents, efficiency = efficiency) - smoke.start() - use_energy(active_power_usage) - -/obj/machinery/smoke_machine/wrench_act(mob/living/user, obj/item/tool) - . = ..() - if(default_unfasten_wrench(user, tool, time = 4 SECONDS)) - on = FALSE - return ITEM_INTERACT_SUCCESS - return FALSE - -/obj/machinery/smoke_machine/attackby(obj/item/I, mob/user, params) - add_fingerprint(user) - if(is_reagent_container(I) && I.is_open_container()) - var/obj/item/reagent_containers/RC = I + //transfer reagents from an open container into machine + if(is_reagent_container(tool) && tool.is_open_container()) + var/obj/item/reagent_containers/RC = tool var/units = RC.reagents.trans_to(src, RC.amount_per_transfer_from_this, transferred_by = user) if(units) to_chat(user, span_notice("You transfer [units] units of the solution to [src].")) - return - if(default_deconstruction_screwdriver(user, "smoke0-o", "smoke0", I)) - return - if(default_deconstruction_crowbar(I)) - return - return ..() + return ITEM_INTERACT_SUCCESS + return ITEM_INTERACT_BLOCKING -/obj/machinery/smoke_machine/on_deconstruction(disassembled) - reagents.expose(loc, TOUCH) - reagents.clear_reagents() +/obj/machinery/smoke_machine/wrench_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(on) + balloon_alert(user, "turn off first!") + return + + if(default_unfasten_wrench(user, tool, time = 4 SECONDS) == SUCCESSFUL_UNFASTEN) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/smoke_machine/screwdriver_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(on) + balloon_alert(user, "turn off first!") + return + + if(default_deconstruction_screwdriver(user, "smoke0-o", "smoke0", tool)) + update_appearance(UPDATE_ICON_STATE) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/smoke_machine/crowbar_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(on) + balloon_alert(user, "turn off first!") + return + + if(default_deconstruction_crowbar(tool)) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/smoke_machine/process() + if(!reagents.total_volume || !anchored || !on || !is_operational) + on = FALSE + update_appearance(UPDATE_ICON_STATE) + return PROCESS_KILL + + var/turf/location = get_turf(src) + if(!(locate(/obj/effect/particle_effect/fluid/smoke) in location)) + var/datum/effect_system/fluid_spread/smoke/chem/smoke_machine/smoke = new() + smoke.set_up(setting * 3, holder = src, location = location, carry = reagents, efficiency = efficiency) + smoke.start() + use_energy(active_power_usage * (setting / max_range)) + update_appearance(UPDATE_ICON_STATE) /obj/machinery/smoke_machine/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -123,41 +177,58 @@ ui.open() /obj/machinery/smoke_machine/ui_data(mob/user) - var/data = list() - var/tank_contents = list() - var/tank_current_volume = 0 - for(var/datum/reagent/R in reagents.reagent_list) - tank_contents += list(list("name" = R.name, "volume" = R.volume)) // list in a list because Byond merges the first list... - tank_current_volume += R.volume - data["tankContents"] = tank_contents - data["tankCurrentVolume"] = reagents.total_volume ? reagents.total_volume : null - data["tankMaxVolume"] = reagents.maximum_volume - data["active"] = on - data["setting"] = setting - data["maxSetting"] = max_range - return data + . = list() -/obj/machinery/smoke_machine/ui_act(action, params) + var/list/tank_data = list() + tank_data["maxVolume"] = reagents.maximum_volume + tank_data["currentVolume"] = round(reagents.total_volume, CHEMICAL_VOLUME_ROUNDING) + var/list/tankContents = list() + for(var/datum/reagent/reagent in reagents.reagent_list) + tankContents += list(list("name" = reagent.name, "volume" = round(reagent.volume, CHEMICAL_VOLUME_ROUNDING))) + tank_data["contents"] = tankContents + .["tank"] = tank_data + + .["active"] = on + .["setting"] = setting + .["maxSetting"] = max_range + +/obj/machinery/smoke_machine/ui_act(action, params, datum/tgui/ui, datum/ui_state/state) . = ..() - - if(. || !anchored) + if(.) return + switch(action) if("purge") reagents.clear_reagents() - update_appearance() - . = TRUE + update_appearance(UPDATE_ICON_STATE) + return TRUE + if("setting") - var/amount = text2num(params["amount"]) + var/amount = params["amount"] + if(isnull(amount)) + return FALSE + + amount = text2num(amount) + if(isnull(amount)) + return FALSE + if(amount in 1 to max_range) setting = amount - . = TRUE + return TRUE + if("power") on = !on - update_appearance() - if(on) - message_admins("[ADMIN_LOOKUPFLW(usr)] activated a smoke machine that contains [english_list(reagents.reagent_list)] at [ADMIN_VERBOSEJMP(src)].") - usr.log_message("activated a smoke machine that contains [english_list(reagents.reagent_list)]", LOG_GAME) - log_combat(usr, src, "has activated [src] which contains [english_list(reagents.reagent_list)] at [AREACOORD(src)].") + if(on && reagents.total_volume) + var/mob/user = ui.user + var/list/english_list = english_list(reagents.reagent_list) + message_admins("[ADMIN_LOOKUPFLW(user)] activated a smoke machine that contains [english_list] at [ADMIN_VERBOSEJMP(src)].") + user.log_message("activated a smoke machine that contains [english_list]", LOG_GAME) + log_combat(user, src, "has activated [src] which contains [english_list] at [AREACOORD(src)].") + begin_processing() + else + on = FALSE + end_processing() + update_appearance(UPDATE_ICON_STATE) + return TRUE #undef REAGENTS_BASE_VOLUME diff --git a/tgui/packages/tgui/interfaces/SmokeMachine.tsx b/tgui/packages/tgui/interfaces/SmokeMachine.tsx index 6832583fd6b..4ee825ef2e8 100644 --- a/tgui/packages/tgui/interfaces/SmokeMachine.tsx +++ b/tgui/packages/tgui/interfaces/SmokeMachine.tsx @@ -10,31 +10,18 @@ import { Section, } from '../components'; import { Window } from '../layouts'; +import { Beaker } from './common/BeakerDisplay'; type Data = { active: BooleanLike; maxSetting: number; setting: number; - tankContents: Reagent[]; - tankCurrentVolume: number; - tankMaxVolume: number; -}; - -type Reagent = { - name: string; - volume: number; + tank: Beaker; }; export const SmokeMachine = (props) => { const { act, data } = useBackend(); - const { - tankContents, - tankCurrentVolume, - tankMaxVolume, - active, - setting, - maxSetting, - } = data; + const { tank, active, setting, maxSetting } = data; return ( @@ -52,13 +39,13 @@ export const SmokeMachine = (props) => { } > - - {' / ' + tankMaxVolume} + + {' / ' + tank.maxVolume} @@ -86,7 +73,7 @@ export const SmokeMachine = (props) => { } > - {tankContents.map((chemical) => ( + {tank.contents.map((chemical) => ( units of{' '} {chemical.name}