From 10aedabb19f230f6db1b5d237d3c68986e36b616 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Sun, 25 Jan 2026 03:31:21 -0500 Subject: [PATCH] refactor computerframe / circuitboard sources (#31408) --- .../game/machinery/computer/computer_frame.dm | 225 +++++++++++++++ .../items/circuitboards/circuitboard.dm | 41 +++ .../items/circuitboards/circuitboards.dm} | 268 ------------------ paradise.dme | 4 +- 4 files changed, 269 insertions(+), 269 deletions(-) create mode 100644 code/game/machinery/computer/computer_frame.dm create mode 100644 code/game/objects/items/circuitboards/circuitboard.dm rename code/game/{machinery/computer/buildandrepair.dm => objects/items/circuitboards/circuitboards.dm} (67%) diff --git a/code/game/machinery/computer/computer_frame.dm b/code/game/machinery/computer/computer_frame.dm new file mode 100644 index 00000000000..2dcfde791a4 --- /dev/null +++ b/code/game/machinery/computer/computer_frame.dm @@ -0,0 +1,225 @@ +// Construction | Deconstruction +#define STATE_EMPTY 1 // Add a circuitboard | Weld to destroy +#define STATE_CIRCUIT 2 // Screwdriver the cover closed | Crowbar the circuit +#define STATE_NOWIRES 3 // Add wires | Screwdriver the cover open +#define STATE_WIRES 4 // Add glass | Remove wires +#define STATE_GLASS 5 // Screwdriver to complete | Crowbar glass out + +/obj/structure/computerframe + name = "computer frame" + icon = 'icons/obj/computer.dmi' + icon_state = "computer_frame" + density = TRUE + anchored = TRUE + max_integrity = 100 + var/state = STATE_EMPTY + var/obj/item/circuitboard/circuit = null + +/obj/structure/computerframe/Initialize(mapload) + . = ..() + update_icon(UPDATE_OVERLAYS) + +/obj/structure/computerframe/examine(mob/user) + . = ..() + . += SPAN_NOTICE("It is [anchored ? "bolted to the floor" : "unbolted"].") + switch(state) + if(STATE_EMPTY) + . += SPAN_NOTICE("The frame is welded together, but it is missing a circuit board.") + if(STATE_CIRCUIT) + . += SPAN_NOTICE("A circuit board is firmly connected, but the cover is unscrewed and open.") + if(STATE_NOWIRES) + . += SPAN_NOTICE("The cover is screwed shut, but the frame is missing wiring.") + if(STATE_WIRES) + . += SPAN_NOTICE("The frame is wired, but the glass is missing.") + if(STATE_GLASS) + . += SPAN_NOTICE("The glass is loosely connected and needs to be screwed into place.") + if(!anchored) + . += SPAN_NOTICE("Alt-Click to rotate it.") + +/obj/structure/computerframe/deconstruct(disassembled = TRUE) + if(!(flags & NODECONSTRUCT)) + drop_computer_parts() + return ..() // will qdel the frame + +/obj/structure/computerframe/AltClick(mob/user) + if(user.incapacitated()) + to_chat(user, SPAN_WARNING("You can't do that right now!")) + return + if(!Adjacent(user)) + return + if(anchored) + to_chat(user, SPAN_WARNING("The frame is anchored to the floor!")) + return + setDir(turn(dir, 90)) + +/obj/structure/computerframe/obj_break(damage_flag) + deconstruct() + +/obj/structure/computerframe/proc/drop_computer_parts() + var/location = drop_location() + new /obj/item/stack/sheet/metal(location, 5) + if(circuit) + circuit.forceMove(location) + circuit = null + if(state >= STATE_WIRES) + var/obj/item/stack/cable_coil/C = new(location) + C.amount = 5 + if(state == STATE_GLASS) + new /obj/item/stack/sheet/glass(location, 2) + +/obj/structure/computerframe/update_overlays() + ..() + . += "comp_frame_[state]" + +/obj/structure/computerframe/welder_act(mob/user, obj/item/I) + if(state != STATE_EMPTY) + return + . = TRUE + if(!I.tool_use_check(user, 0)) + return + WELDER_ATTEMPT_SLICING_MESSAGE + if(I.use_tool(src, user, 50, volume = I.tool_volume)) + WELDER_SLICING_SUCCESS_MESSAGE + deconstruct(TRUE) + +/obj/structure/computerframe/wrench_act(mob/living/user, obj/item/I) + . = TRUE + default_unfasten_wrench(user, I, 2 SECONDS) + +/obj/structure/computerframe/crowbar_act(mob/living/user, obj/item/I) + . = TRUE + if(!I.use_tool(src, user)) + return + + if(state == STATE_CIRCUIT) + to_chat(user, SPAN_NOTICE("You remove the circuit board.")) + state = STATE_EMPTY + name = initial(name) + circuit.forceMove(drop_location()) + circuit = null + else if(state == STATE_GLASS) + to_chat(user, SPAN_NOTICE("You remove the glass panel.")) + state = STATE_WIRES + new /obj/item/stack/sheet/glass(drop_location(), 2) + else + return + + I.play_tool_sound(src) + update_icon() + +/obj/structure/computerframe/screwdriver_act(mob/living/user, obj/item/I) + . = TRUE + if(!I.use_tool(src, user)) + return + + switch(state) + if(STATE_CIRCUIT) + to_chat(user, SPAN_NOTICE("You screw the circuit board into place.")) + state = STATE_NOWIRES + I.play_tool_sound(src) + update_icon() + if(STATE_NOWIRES) + to_chat(user, SPAN_NOTICE("You unfasten the circuit board.")) + state = STATE_CIRCUIT + I.play_tool_sound(src) + update_icon() + if(STATE_GLASS) + to_chat(user, SPAN_NOTICE("You connect the monitor.")) + I.play_tool_sound(src) + var/obj/machinery/computer/B = new circuit.build_path(loc) + B.setDir(dir) + if(istype(circuit, /obj/item/circuitboard/supplycomp)) + var/obj/machinery/computer/supplycomp/SC = B + var/obj/item/circuitboard/supplycomp/C = circuit + SC.can_order_contraband = C.contraband_enabled + qdel(src) + +/obj/structure/computerframe/wirecutter_act(mob/living/user, obj/item/I) + . = TRUE + if(!I.use_tool(src, user)) + return + + if(state == STATE_WIRES) + to_chat(user, SPAN_NOTICE("You remove the cables.")) + var/obj/item/stack/cable_coil/C = new(drop_location()) + C.amount = 5 + state = STATE_NOWIRES + I.play_tool_sound(src) + update_icon() + +/obj/structure/computerframe/item_interaction(mob/living/user, obj/item/I, list/modifiers) + switch(state) + if(STATE_EMPTY) + if(!istype(I, /obj/item/circuitboard)) + return ..() + + var/obj/item/circuitboard/B = I + if(B.board_type != "computer") + to_chat(user, SPAN_WARNING("[src] does not accept circuit boards of this type!")) + return ITEM_INTERACT_COMPLETE + + if(!B.build_path) + to_chat(user, SPAN_WARNING("This is not a functional computer circuit board!")) + return ITEM_INTERACT_COMPLETE + + B.play_tool_sound(src) + to_chat(user, SPAN_NOTICE("You place [B] inside [src].")) + name += " ([B.board_name])" + state = STATE_CIRCUIT + user.drop_item() + B.forceMove(src) + circuit = B + update_icon() + return ITEM_INTERACT_COMPLETE + + if(STATE_NOWIRES) + if(!istype(I, /obj/item/stack/cable_coil)) + return ..() + + 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 wire the frame.")) + return ITEM_INTERACT_COMPLETE + + C.play_tool_sound(src) + to_chat(user, SPAN_NOTICE("You start to add cables to the frame.")) + if(!do_after(user, 2 SECONDS * C.toolspeed, target = src)) + return ITEM_INTERACT_COMPLETE + if(C.get_amount() < 5 || !C.use(5)) + to_chat(user, SPAN_WARNING("At some point during construction you lost some cable. Make sure you have five lengths before trying again.")) + return ITEM_INTERACT_COMPLETE + + to_chat(user, SPAN_NOTICE("You add cables to the frame.")) + state = STATE_WIRES + update_icon() + return ITEM_INTERACT_COMPLETE + + if(STATE_WIRES) + if(!istype(I, /obj/item/stack/sheet/glass)) + return ..() + + var/obj/item/stack/sheet/glass/G = I + if(G.get_amount() < 2) + to_chat(user, SPAN_WARNING("You need two sheets of glass for this.")) + return ITEM_INTERACT_COMPLETE + + G.play_tool_sound(src) + to_chat(user, SPAN_NOTICE("You start to add the glass panel to the frame.")) + if(!do_after(user, 2 SECONDS * G.toolspeed, target = src)) + return ITEM_INTERACT_COMPLETE + if(G.get_amount() < 2 || !G.use(2)) + to_chat(user, SPAN_WARNING("At some point during construction you lost some glass. Make sure you have two sheets before trying again.")) + return ITEM_INTERACT_COMPLETE + + to_chat(user, SPAN_NOTICE("You put in the glass panel.")) + state = STATE_GLASS + update_icon() + return ITEM_INTERACT_COMPLETE + + return ..() + +#undef STATE_EMPTY +#undef STATE_CIRCUIT +#undef STATE_NOWIRES +#undef STATE_WIRES +#undef STATE_GLASS diff --git a/code/game/objects/items/circuitboards/circuitboard.dm b/code/game/objects/items/circuitboards/circuitboard.dm new file mode 100644 index 00000000000..ffae08a6b95 --- /dev/null +++ b/code/game/objects/items/circuitboards/circuitboard.dm @@ -0,0 +1,41 @@ +/obj/item/circuitboard + /// Use `board_name` instead of this. + name = "circuit board" + icon = 'icons/obj/module.dmi' + icon_state = "id_mod" + inhand_icon_state = "electronic" + origin_tech = "programming=2" + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_GLASS=200) + usesound = 'sound/items/deconstruct.ogg' + /// Use this instead of `name`. Formats as: `circuit board ([board_name])` + var/board_name = null + var/build_path = null + var/board_type = "computer" + var/list/req_components = null + +/obj/item/circuitboard/computer + +/obj/item/circuitboard/machine + board_type = "machine" + +/obj/item/circuitboard/Initialize(mapload) + . = ..() + format_board_name() + +/obj/item/circuitboard/proc/format_board_name() + if(board_name) // Should always have this, but just in case. + name = "[initial(name)] ([board_name])" + else + name = "[initial(name)]" + +/obj/item/circuitboard/examine(mob/user) + . = ..() + if(LAZYLEN(req_components)) + var/list/nice_list = list() + for(var/B in req_components) + var/atom/A = B + if(!ispath(A)) + continue + nice_list += list("[req_components[A]] [initial(A.name)]\s") + . += SPAN_NOTICE("Required components: [english_list(nice_list)].") diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/objects/items/circuitboards/circuitboards.dm similarity index 67% rename from code/game/machinery/computer/buildandrepair.dm rename to code/game/objects/items/circuitboards/circuitboards.dm index 48ca34f8e21..52fd0d70549 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/objects/items/circuitboards/circuitboards.dm @@ -1,45 +1,3 @@ -/obj/item/circuitboard - /// Use `board_name` instead of this. - name = "circuit board" - icon = 'icons/obj/module.dmi' - icon_state = "id_mod" - inhand_icon_state = "electronic" - origin_tech = "programming=2" - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_GLASS=200) - usesound = 'sound/items/deconstruct.ogg' - /// Use this instead of `name`. Formats as: `circuit board ([board_name])` - var/board_name = null - var/build_path = null - var/board_type = "computer" - var/list/req_components = null - -/obj/item/circuitboard/computer - -/obj/item/circuitboard/machine - board_type = "machine" - -/obj/item/circuitboard/Initialize(mapload) - . = ..() - format_board_name() - -/obj/item/circuitboard/proc/format_board_name() - if(board_name) // Should always have this, but just in case. - name = "[initial(name)] ([board_name])" - else - name = "[initial(name)]" - -/obj/item/circuitboard/examine(mob/user) - . = ..() - if(LAZYLEN(req_components)) - var/list/nice_list = list() - for(var/B in req_components) - var/atom/A = B - if(!ispath(A)) - continue - nice_list += list("[req_components[A]] [initial(A.name)]\s") - . += SPAN_NOTICE("Required components: [english_list(nice_list)].") - /obj/item/circuitboard/message_monitor board_name = "Message Monitor" icon_state = "engineering" @@ -542,229 +500,3 @@ to_chat(user, SPAN_WARNING("Access Denied.")) return return ..() - -// Construction | Deconstruction -#define STATE_EMPTY 1 // Add a circuitboard | Weld to destroy -#define STATE_CIRCUIT 2 // Screwdriver the cover closed | Crowbar the circuit -#define STATE_NOWIRES 3 // Add wires | Screwdriver the cover open -#define STATE_WIRES 4 // Add glass | Remove wires -#define STATE_GLASS 5 // Screwdriver to complete | Crowbar glass out - -/obj/structure/computerframe - name = "computer frame" - icon = 'icons/obj/computer.dmi' - icon_state = "computer_frame" - density = TRUE - anchored = TRUE - max_integrity = 100 - var/state = STATE_EMPTY - var/obj/item/circuitboard/circuit = null - -/obj/structure/computerframe/Initialize(mapload) - . = ..() - update_icon(UPDATE_OVERLAYS) - -/obj/structure/computerframe/examine(mob/user) - . = ..() - . += SPAN_NOTICE("It is [anchored ? "bolted to the floor" : "unbolted"].") - switch(state) - if(STATE_EMPTY) - . += SPAN_NOTICE("The frame is welded together, but it is missing a circuit board.") - if(STATE_CIRCUIT) - . += SPAN_NOTICE("A circuit board is firmly connected, but the cover is unscrewed and open.") - if(STATE_NOWIRES) - . += SPAN_NOTICE("The cover is screwed shut, but the frame is missing wiring.") - if(STATE_WIRES) - . += SPAN_NOTICE("The frame is wired, but the glass is missing.") - if(STATE_GLASS) - . += SPAN_NOTICE("The glass is loosely connected and needs to be screwed into place.") - if(!anchored) - . += SPAN_NOTICE("Alt-Click to rotate it.") - -/obj/structure/computerframe/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - drop_computer_parts() - return ..() // will qdel the frame - -/obj/structure/computerframe/AltClick(mob/user) - if(user.incapacitated()) - to_chat(user, SPAN_WARNING("You can't do that right now!")) - return - if(!Adjacent(user)) - return - if(anchored) - to_chat(user, SPAN_WARNING("The frame is anchored to the floor!")) - return - setDir(turn(dir, 90)) - -/obj/structure/computerframe/obj_break(damage_flag) - deconstruct() - -/obj/structure/computerframe/proc/drop_computer_parts() - var/location = drop_location() - new /obj/item/stack/sheet/metal(location, 5) - if(circuit) - circuit.forceMove(location) - circuit = null - if(state >= STATE_WIRES) - var/obj/item/stack/cable_coil/C = new(location) - C.amount = 5 - if(state == STATE_GLASS) - new /obj/item/stack/sheet/glass(location, 2) - -/obj/structure/computerframe/update_overlays() - ..() - . += "comp_frame_[state]" - -/obj/structure/computerframe/welder_act(mob/user, obj/item/I) - if(state != STATE_EMPTY) - return - . = TRUE - if(!I.tool_use_check(user, 0)) - return - WELDER_ATTEMPT_SLICING_MESSAGE - if(I.use_tool(src, user, 50, volume = I.tool_volume)) - WELDER_SLICING_SUCCESS_MESSAGE - deconstruct(TRUE) - -/obj/structure/computerframe/wrench_act(mob/living/user, obj/item/I) - . = TRUE - default_unfasten_wrench(user, I, 2 SECONDS) - -/obj/structure/computerframe/crowbar_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user)) - return - - if(state == STATE_CIRCUIT) - to_chat(user, SPAN_NOTICE("You remove the circuit board.")) - state = STATE_EMPTY - name = initial(name) - circuit.forceMove(drop_location()) - circuit = null - else if(state == STATE_GLASS) - to_chat(user, SPAN_NOTICE("You remove the glass panel.")) - state = STATE_WIRES - new /obj/item/stack/sheet/glass(drop_location(), 2) - else - return - - I.play_tool_sound(src) - update_icon() - -/obj/structure/computerframe/screwdriver_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user)) - return - - switch(state) - if(STATE_CIRCUIT) - to_chat(user, SPAN_NOTICE("You screw the circuit board into place.")) - state = STATE_NOWIRES - I.play_tool_sound(src) - update_icon() - if(STATE_NOWIRES) - to_chat(user, SPAN_NOTICE("You unfasten the circuit board.")) - state = STATE_CIRCUIT - I.play_tool_sound(src) - update_icon() - if(STATE_GLASS) - to_chat(user, SPAN_NOTICE("You connect the monitor.")) - I.play_tool_sound(src) - var/obj/machinery/computer/B = new circuit.build_path(loc) - B.setDir(dir) - if(istype(circuit, /obj/item/circuitboard/supplycomp)) - var/obj/machinery/computer/supplycomp/SC = B - var/obj/item/circuitboard/supplycomp/C = circuit - SC.can_order_contraband = C.contraband_enabled - qdel(src) - -/obj/structure/computerframe/wirecutter_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user)) - return - - if(state == STATE_WIRES) - to_chat(user, SPAN_NOTICE("You remove the cables.")) - var/obj/item/stack/cable_coil/C = new(drop_location()) - C.amount = 5 - state = STATE_NOWIRES - I.play_tool_sound(src) - update_icon() - -/obj/structure/computerframe/item_interaction(mob/living/user, obj/item/I, list/modifiers) - switch(state) - if(STATE_EMPTY) - if(!istype(I, /obj/item/circuitboard)) - return ..() - - var/obj/item/circuitboard/B = I - if(B.board_type != "computer") - to_chat(user, SPAN_WARNING("[src] does not accept circuit boards of this type!")) - return ITEM_INTERACT_COMPLETE - - if(!B.build_path) - to_chat(user, SPAN_WARNING("This is not a functional computer circuit board!")) - return ITEM_INTERACT_COMPLETE - - B.play_tool_sound(src) - to_chat(user, SPAN_NOTICE("You place [B] inside [src].")) - name += " ([B.board_name])" - state = STATE_CIRCUIT - user.drop_item() - B.forceMove(src) - circuit = B - update_icon() - return ITEM_INTERACT_COMPLETE - - if(STATE_NOWIRES) - if(!istype(I, /obj/item/stack/cable_coil)) - return ..() - - 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 wire the frame.")) - return ITEM_INTERACT_COMPLETE - - C.play_tool_sound(src) - to_chat(user, SPAN_NOTICE("You start to add cables to the frame.")) - if(!do_after(user, 2 SECONDS * C.toolspeed, target = src)) - return ITEM_INTERACT_COMPLETE - if(C.get_amount() < 5 || !C.use(5)) - to_chat(user, SPAN_WARNING("At some point during construction you lost some cable. Make sure you have five lengths before trying again.")) - return ITEM_INTERACT_COMPLETE - - to_chat(user, SPAN_NOTICE("You add cables to the frame.")) - state = STATE_WIRES - update_icon() - return ITEM_INTERACT_COMPLETE - - if(STATE_WIRES) - if(!istype(I, /obj/item/stack/sheet/glass)) - return ..() - - var/obj/item/stack/sheet/glass/G = I - if(G.get_amount() < 2) - to_chat(user, SPAN_WARNING("You need two sheets of glass for this.")) - return ITEM_INTERACT_COMPLETE - - G.play_tool_sound(src) - to_chat(user, SPAN_NOTICE("You start to add the glass panel to the frame.")) - if(!do_after(user, 2 SECONDS * G.toolspeed, target = src)) - return ITEM_INTERACT_COMPLETE - if(G.get_amount() < 2 || !G.use(2)) - to_chat(user, SPAN_WARNING("At some point during construction you lost some glass. Make sure you have two sheets before trying again.")) - return ITEM_INTERACT_COMPLETE - - to_chat(user, SPAN_NOTICE("You put in the glass panel.")) - state = STATE_GLASS - update_icon() - return ITEM_INTERACT_COMPLETE - - return ..() - -#undef STATE_EMPTY -#undef STATE_CIRCUIT -#undef STATE_NOWIRES -#undef STATE_WIRES -#undef STATE_GLASS diff --git a/paradise.dme b/paradise.dme index b0cacd7be03..e146066a912 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1076,12 +1076,12 @@ #include "code\game\machinery\computer\atmos_alert.dm" #include "code\game\machinery\computer\atmos_controllers.dm" #include "code\game\machinery\computer\brigcells.dm" -#include "code\game\machinery\computer\buildandrepair.dm" #include "code\game\machinery\computer\camera_advanced.dm" #include "code\game\machinery\computer\camera_console.dm" #include "code\game\machinery\computer\cloning.dm" #include "code\game\machinery\computer\communications.dm" #include "code\game\machinery\computer\computer.dm" +#include "code\game\machinery\computer\computer_frame.dm" #include "code\game\machinery\computer\crew_monitoring.dm" #include "code\game\machinery\computer\depot_consoles.dm" #include "code\game\machinery\computer\HolodeckControl.dm" @@ -1331,6 +1331,8 @@ #include "code\game\objects\items\bio_chips\bio_chip_traitor.dm" #include "code\game\objects\items\bio_chips\bio_chip_uplink.dm" #include "code\game\objects\items\bio_chips\bio_chipper.dm" +#include "code\game\objects\items\circuitboards\circuitboard.dm" +#include "code\game\objects\items\circuitboards\circuitboards.dm" #include "code\game\objects\items\devices\aicard.dm" #include "code\game\objects\items\devices\autochef_remote.dm" #include "code\game\objects\items\devices\autopsy.dm"