Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Machines now store components in contents + dumping inventory cleanup #9314

Merged
merged 18 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 80 additions & 25 deletions code/game/machinery/_machinery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Class Procs:
GLOB.machines += src

if(ispath(circuit, /obj/item/circuitboard))
circuit = new circuit
circuit = new circuit(src)
circuit.apply_default_parts(src)

if(processing_flags & START_PROCESSING_ON_INIT)
Expand Down Expand Up @@ -192,11 +192,9 @@ Class Procs:
GLOB.machines.Remove(src)
if(datum_flags & DF_ISPROCESSING) // A sizeable portion of machines stops processing before qdel
end_processing()
dropContents()
if(length(component_parts))
for(var/atom/A in component_parts)
qdel(A)
component_parts.Cut()
dump_inventory_contents()
QDEL_LIST(component_parts)
QDEL_NULL(circuit)
return ..()

/obj/machinery/proc/locate_machinery()
Expand Down Expand Up @@ -240,26 +238,65 @@ Class Procs:
//Update power
power_change()

/**
* Opens the machine.
*
* Will update the machine icon and any user interfaces currently open.
* Arguments:
* * drop - Boolean. Whether to drop any stored items in the machine. Does not include components.
*/
/obj/machinery/proc/open_machine(drop = TRUE)
SEND_SIGNAL(src, COMSIG_MACHINE_OPEN, drop)
state_open = TRUE
set_density(FALSE)
if(drop)
dropContents()
dump_inventory_contents()
update_icon()
updateUsrDialog()
ui_update()

/obj/machinery/proc/dropContents(list/subset = null)
var/turf/T = get_turf(src)
for(var/atom/movable/A in contents)
if(subset && !(A in subset))
continue
A.forceMove(T)
if(isliving(A))
var/mob/living/L = A
L.update_mobility()
/**
* Drop every movable atom in the machine's contents list, including any components and circuit.
*/
/obj/machinery/dump_contents()
// Start by calling the dump_inventory_contents proc. Will allow machines with special contents
// to handle their dropping.
dump_inventory_contents()

// Then we can clean up and drop everything else.
var/turf/this_turf = get_turf(src)
for(var/atom/movable/movable_atom in contents)
movable_atom.forceMove(this_turf)

// We'll have dropped the occupant, circuit and component parts as part of this.
set_occupant(null)
circuit = null
LAZYCLEARLIST(component_parts)

/**
* Drop every movable atom in the machine's contents list that is not a component_part.
*
* Proc does not drop components and will skip over anything in the component_parts list.
* Call dump_contents() to drop all contents including components.
* Arguments:
* * subset - If this is not null, only atoms that are also contained within the subset list will be dropped.
*/
/obj/machinery/proc/dump_inventory_contents(list/subset = null)
var/turf/this_turf = get_turf(src)
for(var/atom/movable/movable_atom in contents)
if(subset && !(movable_atom in subset))
continue

if(movable_atom in component_parts)
continue

movable_atom.forceMove(this_turf)
if(isliving(movable_atom))
var/mob/living/living_mob = movable_atom
living_mob.update_mobility()

if(occupant == movable_atom)
occupant = null

/obj/machinery/proc/can_be_occupant(atom/movable/am)
return occupant_typecache ? is_type_in_typecache(am, occupant_typecache) : isliving(am)
Expand Down Expand Up @@ -461,14 +498,18 @@ Class Procs:
deconstruct(TRUE)

/obj/machinery/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
on_deconstruction()
if(component_parts?.len)
spawn_frame(disassembled)
for(var/obj/item/I in component_parts)
I.forceMove(loc)
component_parts.Cut()
qdel(src)
if(flags_1 & NODECONSTRUCT_1)
return ..()

on_deconstruction()
if(!LAZYLEN(component_parts))
return ..() //We have no parts
spawn_frame(disassembled)

for(var/obj/item/I in component_parts)
I.forceMove(loc)
LAZYCLEARLIST(component_parts)
return ..()

/**
* Spawns a frame where this machine is. If the machine was not disassmbled, the
Expand Down Expand Up @@ -514,6 +555,17 @@ Class Procs:
if(A == occupant)
set_occupant(null)
update_icon()
updateUsrDialog()
return ..()

// The circuit should also be in component parts, so don't early return.
if(A == circuit)
circuit = null
if((A in component_parts) && !QDELETED(src))
component_parts.Remove(A)
// It would be unusual for a component_part to be qdel'd ordinarily.
deconstruct(FALSE)
return ..()

/obj/machinery/run_obj_armor(damage_amount, damage_type, damage_flag = NONE, attack_dir)
if(damage_flag == MELEE && damage_amount < damage_deflection)
Expand Down Expand Up @@ -632,7 +684,7 @@ Class Procs:
else
if(SEND_SIGNAL(W, COMSIG_TRY_STORAGE_TAKE, B, src))
component_parts += B
B.moveToNullspace()
B.forceMove(src)
SEND_SIGNAL(W, COMSIG_TRY_STORAGE_INSERT, A, null, null, TRUE)
component_parts -= A
to_chat(user, "<span class='notice'>[capitalize(A.name)] replaced with [B.name].</span>")
Expand Down Expand Up @@ -697,6 +749,9 @@ Class Procs:
. = ..()
if (gone == occupant)
set_occupant(null)
if(gone == circuit)
LAZYREMOVE(component_parts, gone)
circuit = null

/obj/machinery/proc/adjust_item_drop_location(atom/movable/AM) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8
var/md5 = rustg_hash_string(RUSTG_HASH_MD5, AM.name) // Oh, and it's deterministic too. A specific item will always drop from the same slot.
Expand Down
10 changes: 3 additions & 7 deletions code/game/machinery/computer/_computer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,13 @@
///Should the [icon_state]_broken overlay be shown as an emissive or regular overlay?
var/broken_overlay_emissive = FALSE

/obj/machinery/computer/Initialize(mapload, obj/item/circuitboard/C)
/obj/machinery/computer/Initialize(mapload)
. = ..()
QUEUE_SMOOTH(src)
QUEUE_SMOOTH_NEIGHBORS(src)
power_change()
if(!QDELETED(C))
qdel(circuit)
circuit = C
C.moveToNullspace()
Tsar-Salat marked this conversation as resolved.
Show resolved Hide resolved

/obj/machinery/computer/Destroy()
QDEL_NULL(circuit)
QUEUE_SMOOTH_NEIGHBORS(src)
return ..()

Expand Down Expand Up @@ -149,6 +144,8 @@
var/obj/structure/frame/computer/A = new /obj/structure/frame/computer(src.loc)
A.setDir(dir)
A.circuit = circuit
// Circuit removal code is handled in /obj/machinery/Exited()
circuit.forceMove(A)
A.setAnchored(TRUE)
if(machine_stat & BROKEN)
if(user)
Expand All @@ -164,7 +161,6 @@
to_chat(user, "<span class='notice'>You disconnect the monitor.</span>")
A.state = 4
A.icon_state = "4"
circuit = null
for(var/obj/C in src)
C.forceMove(loc)
qdel(src)
11 changes: 5 additions & 6 deletions code/game/machinery/computer/arcade.dm
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,16 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
return

/obj/machinery/computer/arcade/Initialize(mapload)
. = ..()
// If it's a generic arcade machine, pick a random arcade
// circuit board for it and make the new machine
// circuit board for it
if(!circuit)
var/list/gameodds = list(/obj/item/circuitboard/computer/arcade/battle = 49,
/obj/item/circuitboard/computer/arcade/orion_trail = 49,
/obj/item/circuitboard/computer/arcade/amputation = 2)
var/thegame = pick_weight(gameodds)
var/obj/item/circuitboard/CB = new thegame()
new CB.build_path(loc, CB)
return INITIALIZE_HINT_QDEL
circuit = pick_weight(gameodds)

. = ..()

Reset()

/obj/machinery/computer/arcade/proc/prizevend(mob/user)
Expand Down
42 changes: 39 additions & 3 deletions code/game/machinery/computer/buildandrepair.dm
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,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, circuit)
B.setDir(dir)
transfer_fingerprints_to(B)

var/obj/machinery/new_machine = new circuit.build_path(loc)
Tsar-Salat marked this conversation as resolved.
Show resolved Hide resolved
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.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)
Expand Down
46 changes: 31 additions & 15 deletions code/game/machinery/constructable_frame.dm
Original file line number Diff line number Diff line change
Expand Up @@ -172,27 +172,42 @@
return

if(P.tool_behaviour == TOOL_SCREWDRIVER)
var/component_check = 1
var/component_check = TRUE
for(var/R in req_components)
if(req_components[R] > 0)
component_check = 0
component_check = FALSE
break
if(component_check)
P.play_tool_sound(src)
var/obj/machinery/new_machine = new circuit.build_path(loc)
if(new_machine.circuit)
QDEL_NULL(new_machine.circuit)
new_machine.circuit = circuit
new_machine.setAnchored(anchored)
new_machine.on_construction()
for(var/obj/O in new_machine.component_parts)
qdel(O)
new_machine.component_parts = list()
for(var/obj/O in src)
O.moveToNullspace()
new_machine.component_parts += O
circuit.moveToNullspace()
new_machine.RefreshParts()
if(istype(new_machine))
// 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)
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.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

Expand Down Expand Up @@ -232,6 +247,7 @@
S.merge(NS)
if(!QDELETED(part)) //If we're a stack and we merged we might not exist anymore
components += part
part.forceMove(src)
to_chat(user, "<span class='notice'>You add [part] to [src].</span>")
if(added_components.len)
replacer.play_rped_sound()
Expand Down
Loading
Loading