Skip to content

Commit

Permalink
[MIRROR] Click Refactor - Machinery States (#2860)
Browse files Browse the repository at this point in the history
Co-authored-by: SierraKomodo <[email protected]>
Co-authored-by: Lexanx <[email protected]>
  • Loading branch information
3 people authored Nov 26, 2024
1 parent ed2b289 commit 0fb5a09
Show file tree
Hide file tree
Showing 7 changed files with 385 additions and 184 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,23 @@
machine.attack_hand(user)
return TRUE

/*
This returning FALSE means if component_attackby under use_tool called this it will also return FALSE; which means the use_tool call will proceed.
In that same vein, the attackby() children of this proc will also continue the rest of its code if this crashes; since this check is called at the beginning.
*/
/singleton/machine_construction/proc/attackby(obj/item/I, mob/user, obj/machinery/machine)
if(!validate_state(machine))

/**
* Handles tool usage on the parent machine. Has the same return rules as `/atom/proc/use_tool()`.
*
* **Parameters**:
* - `tool` - The item being used.
* - `user` - The mob performing the interaction.
* - `machine` - The parent machine being interacted with.
*
* Returns boolean. Indicates whether the interaction was handled or not. If `TRUE`, no other interactions will occur.
*/
/singleton/machine_construction/proc/use_tool(obj/item/tool, mob/user, obj/machinery/machine)
if (!validate_state(machine))
crash_with("Machine [log_info_line(machine)] violated the state assumptions of the construction state [type]!")
return FALSE


/singleton/machine_construction/proc/mechanics_info()

// Used to transfer state as needed post-construction.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
down_state = /singleton/machine_construction/default/panel_open/computer
needs_board = "computer"

/singleton/machine_construction/default/panel_closed/computer/no_deconstruct/attackby(obj/item/I, mob/user, obj/machinery/machine)
/singleton/machine_construction/default/panel_closed/computer/no_deconstruct/use_tool(obj/item/tool, mob/user, obj/machinery/machine)
return FALSE

/singleton/machine_construction/default/panel_open/computer
Expand Down
84 changes: 59 additions & 25 deletions code/game/machinery/_machines_base/machine_construction/default.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
var/up_state
var/down_state

/singleton/machine_construction/default/no_deconstruct/attackby(obj/item/I, mob/user, obj/machinery/machine)
. = FALSE

/singleton/machine_construction/default/no_deconstruct/use_tool(obj/item/tool, mob/user, obj/machinery/machine)
return FALSE


/singleton/machine_construction/default/panel_closed
down_state = /singleton/machine_construction/default/panel_open
Expand All @@ -19,23 +21,38 @@
if(!.)
try_change_state(machine, down_state)

/singleton/machine_construction/default/panel_closed/attackby(obj/item/I, mob/user, obj/machinery/machine)
if((. = ..()))
return

/singleton/machine_construction/default/panel_closed/use_tool(obj/item/tool, mob/user, obj/machinery/machine)
. = ..()
if (.)
return TRUE

if (!machine.can_use_tools)
to_chat(user, SPAN_WARNING("\The [src] cannot be modified!"))
USE_FEEDBACK_FAILURE("\The [src] cannot be modified.")
return TRUE
if(isScrewdriver(I))

// Screwdriver - Open maintenance panel
if (isScrewdriver(tool))
TRANSFER_STATE(down_state)
playsound(get_turf(machine), 'sound/items/Screwdriver.ogg', 50, 1)
playsound(machine, 'sound/items/Screwdriver.ogg', 50, TRUE)
machine.panel_open = TRUE
to_chat(user, SPAN_NOTICE("You open the maintenance hatch of \the [machine]."))
user.visible_message(
SPAN_NOTICE("\The [user] opens \a [machine]'s maintenance panel with \a [tool]."),
SPAN_NOTICE("You open \the [machine]'s maintenance panel with \the [tool].")
)
machine.update_icon()
return
if(istype(I, /obj/item/storage/part_replacer))
return TRUE

// Part Replacer - List parts.
if (istype(tool, /obj/item/storage/part_replacer))
user.visible_message(
SPAN_NOTICE("\The [user] scans \a [machine] with \a [tool]."),
SPAN_NOTICE("You scan \the [machine] with \the [tool].")
)
machine.display_parts(user)
return TRUE


/singleton/machine_construction/default/panel_closed/post_construct(obj/machinery/machine)
try_change_state(machine, down_state)
machine.panel_open = TRUE
Expand All @@ -61,29 +78,46 @@
if(!.)
try_change_state(machine, up_state)

/singleton/machine_construction/default/panel_open/attackby(obj/item/I, mob/user, obj/machinery/machine)
if((. = ..()))

/singleton/machine_construction/default/panel_open/use_tool(obj/item/tool, mob/user, obj/machinery/machine)
. = ..()
if (.)
return
if(isCrowbar(I))

// Crowbar - Dismantle machine.
if (isCrowbar(tool))
TRANSFER_STATE(down_state)
user.visible_message(
SPAN_NOTICE("\The [user] dismantles \a [machine] with \a [tool]."),
SPAN_NOTICE("You dismantle \the [machine] with \the [tool].")
)
machine.dismantle()
return
if(isScrewdriver(I))
return TRUE

// Screwdriver - Close panel.
if (isScrewdriver(tool))
TRANSFER_STATE(up_state)
playsound(get_turf(machine), 'sound/items/Screwdriver.ogg', 50, 1)
playsound(machine, 'sound/items/Screwdriver.ogg', 50, TRUE)
machine.panel_open = FALSE
to_chat(user, SPAN_NOTICE("You close the maintenance hatch of \the [machine]."))
user.visible_message(
SPAN_NOTICE("\The [user] closes \a [machine]'s maintenance hatch with \a [tool]."),
SPAN_NOTICE("You close \the [machine]'s maintenance panel with \the [tool].")
)
machine.update_icon()
return
return TRUE

// Part replacer - Replace parts.
if (istype(tool, /obj/item/storage/part_replacer))
return machine.part_replacement(user, tool)

if(istype(I, /obj/item/storage/part_replacer))
return machine.part_replacement(user, I)
// Wrench - Remove individual part.
if (isWrench(tool))
return machine.part_removal(user, tool)

if(isWrench(I))
return machine.part_removal(user)
// Items - Attempt part insertion.
if (istype(tool))
return machine.part_insertion(user, tool)

if(istype(I))
return machine.part_insertion(user, I)

/singleton/machine_construction/default/panel_open/mechanics_info()
. = list()
Expand Down
183 changes: 125 additions & 58 deletions code/game/machinery/_machines_base/machine_construction/frame.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,46 @@
else
try_change_state(machine, /singleton/machine_construction/frame/wrenched)

/singleton/machine_construction/frame/unwrenched/attackby(obj/item/I, mob/user, obj/machinery/machine)
if(isWrench(I))
playsound(machine.loc, 'sound/items/Ratchet.ogg', 50, 1)
if(do_after(user, (I.toolspeed * 2) SECONDS, machine, DO_REPAIR_CONSTRUCT))
TRANSFER_STATE(/singleton/machine_construction/frame/wrenched)
to_chat(user, SPAN_NOTICE("You wrench \the [machine] into place."))
machine.anchored = TRUE
if(isWelder(I))
var/obj/item/weldingtool/WT = I
if(!WT.can_use(3, user))

/singleton/machine_construction/frame/unwrenched/use_tool(obj/item/tool, mob/user, obj/machinery/machine)
// Wrench - Anchor machine.
if (isWrench(tool))
user.visible_message(
SPAN_NOTICE("\The [user] begins securing \the [machine] to the floor with \a [tool]."),
SPAN_NOTICE("You begin securing \the [machine] to the floor with \the [tool].")
)
playsound(machine, 'sound/items/Ratchet.ogg', 50, TRUE)
if (!user.do_skilled((tool.toolspeed * 2 SECONDS), SKILL_CONSTRUCTION, machine, do_flags = DO_REPAIR_CONSTRUCT) || !user.use_sanity_check(machine, tool))
return TRUE
TRANSFER_STATE(/singleton/machine_construction/frame/unwrenched)
user.visible_message(
SPAN_NOTICE("\The [user] secures \a [machine] to the floor with \a [tool]."),
SPAN_NOTICE("You secure \the [machine] to the floor with \the [tool].")
)
machine.anchored = FALSE
machine.post_anchor_change()
return TRUE

if (isWelder(tool))
var/obj/item/weldingtool/welder = tool
if (!welder.can_use(3, user))
return TRUE
playsound(machine, 'sound/items/Welder.ogg', 50, TRUE)
user.visible_message(
SPAN_NOTICE("\The [user] starts dismantling \a [machine] with \a [tool]."),
SPAN_NOTICE("You start dismantling \the [machine] with \the [tool].")
)
if (!user.do_skilled(tool.toolspeed * 2 SECONDS, SKILL_CONSTRUCTION, machine, do_flags = DO_REPAIR_CONSTRUCT) || !user.use_sanity_check(machine, tool))
return TRUE
if (!welder.remove_fuel(3, user))
return TRUE
playsound(machine.loc, 'sound/items/Welder.ogg', 50, 1)
if(do_after(user, (I.toolspeed * 2) SECONDS, machine, DO_REPAIR_CONSTRUCT))
if (!WT.remove_fuel(3, user))
return TRUE
TRANSFER_STATE(/singleton/machine_construction/default/deconstructed)
to_chat(user, SPAN_NOTICE("You deconstruct \the [machine]."))
machine.dismantle()
TRANSFER_STATE(/singleton/machine_construction/default/deconstructed)
user.visible_message(
SPAN_NOTICE("\The [user] dismantles \a [machine] with \a [tool]."),
SPAN_NOTICE("You dismantle \the [machine] with \the [tool].")
)
machine.dismantle()
return TRUE


/singleton/machine_construction/frame/unwrenched/mechanics_info()
Expand All @@ -47,24 +69,47 @@
else
try_change_state(machine, /singleton/machine_construction/frame/unwrenched)

/singleton/machine_construction/frame/wrenched/attackby(obj/item/I, mob/user, obj/machinery/machine)
if(isWrench(I))
playsound(machine.loc, 'sound/items/Ratchet.ogg', 50, 1)
if(do_after(user, (I.toolspeed * 2) SECONDS, machine, DO_REPAIR_CONSTRUCT))
TRANSFER_STATE(/singleton/machine_construction/frame/unwrenched)
to_chat(user, SPAN_NOTICE("You unfasten \the [machine]."))
machine.anchored = FALSE
return
if(isCoil(I))
var/obj/item/stack/cable_coil/C = I
if(C.get_amount() < 5)
to_chat(user, SPAN_WARNING("You need five lengths of cable to add them to \the [machine]."))

/singleton/machine_construction/frame/wrenched/use_tool(obj/item/tool, mob/user, obj/machinery/machine)
// Wrench. Anchor machine.
if (isWrench(tool))
user.visible_message(
SPAN_NOTICE("\The [user] begins unsecuring \the [machine] from the floor with \a [tool]."),
SPAN_NOTICE("You begin unsecuring \the [machine] from the floor with \the [tool].")
)
playsound(machine, 'sound/items/Ratchet.ogg', 50, TRUE)
if (!user.do_skilled((tool.toolspeed * 2 SECONDS), SKILL_CONSTRUCTION, machine, do_flags = DO_REPAIR_CONSTRUCT) || !user.use_sanity_check(machine, tool))
return TRUE
playsound(machine.loc, 'sound/items/Deconstruct.ogg', 50, 1)
to_chat(user, SPAN_NOTICE("You start to add cables to the frame."))
if(do_after(user, 2 SECONDS, machine, DO_REPAIR_CONSTRUCT) && C.use(5))
TRANSFER_STATE(/singleton/machine_construction/frame/awaiting_circuit)
to_chat(user, SPAN_NOTICE("You add cables to the frame."))
TRANSFER_STATE(/singleton/machine_construction/frame/unwrenched)
user.visible_message(
SPAN_NOTICE("\The [user] unsecures \a [machine] from the floor with \a [tool]."),
SPAN_NOTICE("You unsecure \the [machine] from the floor with \the [tool].")
)
machine.anchored = FALSE
machine.post_anchor_change()
return TRUE

// Cable coil. Wire machine.
if (isCoil(tool))
var/obj/item/stack/cable_coil/cable_coil = tool
if (!cable_coil.can_use(5))
USE_FEEDBACK_STACK_NOT_ENOUGH(cable_coil, 5, "to wire \the [machine].")
return TRUE
playsound(machine, 'sound/items/Deconstruct.ogg', 50, TRUE)
user.visible_message(
SPAN_NOTICE("\The [user] starts wiring \a [machine] with [cable_coil.get_vague_name(TRUE)]."),
SPAN_NOTICE("You start wiring \the [machine] with [cable_coil.get_exact_name(5)].")
)
if (!user.do_skilled(2 SECONDS, SKILL_ELECTRICAL, machine, do_flags = DO_REPAIR_CONSTRUCT) || !user.use_sanity_check(machine, tool))
return TRUE
if (!cable_coil.use(5))
USE_FEEDBACK_STACK_NOT_ENOUGH(cable_coil, 5, "to wire \the [machine].")
return TRUE
TRANSFER_STATE(/singleton/machine_construction/frame/awaiting_circuit)
user.visible_message(
SPAN_NOTICE("\The [user] wires \a [machine] with [cable_coil.get_vague_name(TRUE)]."),
SPAN_NOTICE("You wire \the [machine] with [cable_coil.get_exact_name(5)].")
)
return TRUE


Expand All @@ -84,26 +129,38 @@
else
try_change_state(machine, /singleton/machine_construction/frame/unwrenched)

/singleton/machine_construction/frame/awaiting_circuit/attackby(obj/item/I, mob/user, obj/machinery/constructable_frame/machine)
if(istype(I, /obj/item/stock_parts/circuitboard))
var/obj/item/stock_parts/circuitboard/circuit = I
if(circuit.board_type == machine.expected_machine_type)
if(!user.canUnEquip(I))
return FALSE
TRANSFER_STATE(/singleton/machine_construction/frame/awaiting_parts)
user.unEquip(I, machine)
playsound(machine.loc, 'sound/items/Deconstruct.ogg', 50, 1)
to_chat(user, SPAN_NOTICE("You add the circuit board to \the [machine]."))
machine.circuit = I
return
else
to_chat(user, SPAN_WARNING("This frame does not accept circuit boards of this type!"))

/singleton/machine_construction/frame/awaiting_circuit/use_tool(obj/item/tool, mob/user, obj/machinery/constructable_frame/machine)
// Circuitboard - Install circuits.
if (istype(tool, /obj/item/stock_parts/circuitboard))
var/obj/item/stock_parts/circuitboard/circuit = tool
if (circuit.board_type != machine.expected_machine_type)
USE_FEEDBACK_FAILURE("\The [machine] does not accept \the [circuit]'s board type.")
return TRUE
if (!user.canUnEquip(tool))
FEEDBACK_UNEQUIP_FAILURE(user, tool)
return TRUE
if(isWirecutter(I))
TRANSFER_STATE(/singleton/machine_construction/frame/awaiting_parts)
user.unEquip(tool, machine)
playsound(machine, 'sound/items/Deconstruct.ogg', 50, TRUE)
user.visible_message(
SPAN_NOTICE("\The [user] adds \a [tool] to \a [machine]."),
SPAN_NOTICE("You add \the [tool] to \the [machine].")
)
machine.circuit = tool
return TRUE

// Wirecutter - Remove wiring.
if (isWirecutter(tool))
TRANSFER_STATE(/singleton/machine_construction/frame/wrenched)
playsound(machine.loc, 'sound/items/Wirecutter.ogg', 50, 1)
to_chat(user, SPAN_NOTICE("You remove the cables."))
playsound(machine, 'sound/items/Wirecutter.ogg', 50, TRUE)
user.visible_message(
SPAN_NOTICE("\The [user] removes \a [machine]'s wiring with \a [tool]."),
SPAN_NOTICE("You remove \the [machine]'s wiring with \the [tool].")
)
new /obj/item/stack/cable_coil(machine.loc, 5)
return TRUE


/singleton/machine_construction/frame/awaiting_circuit/mechanics_info()
. = list()
Expand All @@ -121,16 +178,22 @@
else
try_change_state(machine, /singleton/machine_construction/frame/unwrenched)

/singleton/machine_construction/frame/awaiting_parts/attackby(obj/item/I, mob/user, obj/machinery/constructable_frame/machine)
if(isCrowbar(I))
/singleton/machine_construction/frame/awaiting_parts/use_tool(obj/item/tool, mob/user, obj/machinery/constructable_frame/machine)
// Crowbar. Remove circuit board.
if (isCrowbar(tool))
TRANSFER_STATE(/singleton/machine_construction/frame/awaiting_circuit)
playsound(machine.loc, 'sound/items/Crowbar.ogg', 50, 1)
playsound(machine, 'sound/items/Crowbar.ogg', 50, TRUE)
user.visible_message(
SPAN_NOTICE("\The [user] removes \a [machine]'s circuit board with \a [tool]."),
SPAN_NOTICE("You remove \the [machine]'s [machine.circuit.name] with \the [tool].")
)
machine.circuit.dropInto(machine.loc)
machine.circuit = null
to_chat(user, SPAN_NOTICE("You remove the circuit board."))
return
if(isScrewdriver(I))
playsound(machine.loc, 'sound/items/Screwdriver.ogg', 50, 1)
return TRUE

// Screwdriver. Finish construction.
if (isScrewdriver(tool))
playsound(machine, 'sound/items/Screwdriver.ogg', 50, TRUE)
var/obj/machinery/new_machine = new machine.circuit.build_path(machine.loc, machine.dir, FALSE)
machine.circuit.construct(new_machine)
new_machine.install_component(machine.circuit, refresh_parts = FALSE)
Expand All @@ -140,6 +203,10 @@
new_machine.construct_state.post_construct(new_machine)
else
crash_with("Machine of type [new_machine.type] was built from a circuit and frame, but had no construct state set.")
user.visible_message(
SPAN_NOTICE("\The [user] finishes \a [new_machine] with \a [tool]."),
SPAN_NOTICE("You finish \the [new_machine] with \the [tool].")
)
qdel(machine)
return TRUE

Expand Down
Loading

0 comments on commit 0fb5a09

Please sign in to comment.