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}