Fixes various issues related to machine component contents. (#53943)

Fixes machines not referencing their circuits in their component parts when built manually, causing them to vomit out their circuit board when opened. This also fixes Runtime in _machinery.dm, line 607: Cannot read null.req_components from using the B/RPEDs.
Fixes computers not storing circuits in the contents.
Fixes smartfridges vending their components.
This commit is contained in:
Timberpoes
2020-09-26 00:25:24 -03:00
committed by GitHub
parent 3ad3dc4c75
commit 46d64f7d21
4 changed files with 83 additions and 10 deletions
+39 -3
View File
@@ -113,9 +113,45 @@
if(P.tool_behaviour == TOOL_SCREWDRIVER)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
var/obj/B = new circuit.build_path(loc)
B.setDir(dir)
transfer_fingerprints_to(B)
var/obj/machinery/new_machine = new circuit.build_path(loc)
new_machine.setDir(dir)
transfer_fingerprints_to(new_machine)
if(istype(new_machine, /obj/machinery/computer))
var/obj/machinery/computer/new_computer = new_machine
// Machines will init with a set of default components.
// Triggering handle_atom_del will make the machine realise it has lost a component_parts and then deconstruct.
// Move to nullspace so we don't trigger handle_atom_del, then qdel.
// Finally, replace new machine's parts with this frame's parts.
if(new_computer.circuit)
// Move to nullspace and delete.
new_computer.circuit.moveToNullspace()
QDEL_NULL(new_computer.circuit)
for(var/old_part in new_computer.component_parts)
var/atom/movable/movable_part = old_part
// Move to nullspace and delete.
movable_part.moveToNullspace()
qdel(movable_part)
// Set anchor state and move the frame's parts over to the new machine.
// Then refresh parts and call on_construction().
new_computer.set_anchored(anchored)
new_computer.component_parts = list()
circuit.forceMove(new_computer)
new_computer.component_parts += circuit
new_computer.circuit = circuit
for(var/new_part in src)
var/atom/movable/movable_part = new_part
movable_part.forceMove(new_computer)
new_computer.component_parts += movable_part
new_computer.RefreshParts()
new_computer.on_construction()
qdel(src)
return
if(user.a_intent == INTENT_HARM)
+13 -5
View File
@@ -185,25 +185,33 @@
P.play_tool_sound(src)
var/obj/machinery/new_machine = new circuit.build_path(loc)
if(istype(new_machine))
// Machines will init with a set of default components. Move to nullspace to we don't trigger handle_atom_del, then qdel.
// Machines will init with a set of default components. Move to nullspace so we don't trigger handle_atom_del, then qdel.
// Finally, replace with this frame's parts.
if(new_machine.circuit)
// Move to nullspace and delete.
new_machine.circuit.moveToNullspace()
QDEL_NULL(new_machine.circuit)
circuit.forceMove(new_machine)
new_machine.circuit = circuit
new_machine.set_anchored(anchored)
new_machine.on_construction()
for(var/obj/old_part in new_machine.component_parts)
// Move to nullspace and delete.
old_part.moveToNullspace()
qdel(old_part)
// Set anchor state and move the frame's parts over to the new machine.
// Then refresh parts and call on_construction().
new_machine.set_anchored(anchored)
new_machine.component_parts = list()
circuit.forceMove(new_machine)
new_machine.component_parts += circuit
new_machine.circuit = circuit
for(var/obj/new_part in src)
new_part.forceMove(new_machine)
new_machine.component_parts += new_part
new_machine.RefreshParts()
new_machine.on_construction()
qdel(src)
return
@@ -16,6 +16,28 @@
var/build_path = null
/obj/item/circuitboard/proc/apply_default_parts(obj/machinery/M)
if(LAZYLEN(M.component_parts))
// This really shouldn't happen. If it somehow does, print out a stack trace and gracefully handle it.
stack_trace("apply_defauly_parts called on machine that already had component_parts: [M]")
// Move to nullspace so you don't trigger handle_atom_del logic and remove existing parts.
for(var/obj/item/part in M.component_parts)
part.moveToNullspace(loc)
qdel(part)
// List of components always contains the circuit board used to build it.
M.component_parts = list(src)
forceMove(M)
if(M.circuit != src)
// This really shouldn't happen. If it somehow does, print out a stack trace and gracefully handle it.
stack_trace("apply_default_parts called from a circuit board that does not belong to machine: [M]")
// Move to nullspace so you don't trigger handle_atom_del logic, remove old circuit, add new circuit.
M.circuit.moveToNullspace()
qdel(M.circuit)
M.circuit = src
return
// Circuitboard/machine
@@ -36,8 +58,7 @@ micro-manipulator, console screen, beaker, Microlaser, matter bin, power cells.
if(!req_components)
return
M.component_parts = list(src) // List of components always contains a board
forceMove(M)
. = ..()
for(var/comp_path in req_components)
var/comp_amt = req_components[comp_path]
@@ -173,6 +173,10 @@
var/listofitems = list()
for (var/I in src)
// We do not vend our own components.
if(I in component_parts)
continue
var/atom/movable/O = I
if (!QDELETED(O))
var/md5name = md5(O.name) // This needs to happen because of a bug in a TGUI component, https://github.com/ractivejs/ractive/issues/744
@@ -213,6 +217,8 @@
if(desired == 1 && Adjacent(usr) && !issilicon(usr))
for(var/obj/item/O in src)
if(O.name == params["name"])
if(O in component_parts)
CRASH("Attempted removal of [O] component_part from vending machine via vending interface.")
dispense(O, usr)
break
if (visible_contents)
@@ -223,6 +229,8 @@
if(desired <= 0)
break
if(O.name == params["name"])
if(O in component_parts)
CRASH("Attempted removal of [O] component_part from vending machine via vending interface.")
dispense(O, usr)
desired--
if (visible_contents)