From 235ebba7e0be6b50abc89cc0766c7cc29aebd173 Mon Sep 17 00:00:00 2001 From: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Date: Mon, 9 Oct 2023 00:26:16 -0400 Subject: [PATCH] Bitrunning hotfix 3 (#78818) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## About The Pull Request The next round of small changes to how bitrunning works - mostly from feedback, bug reports etc. - The loot crate delivery spot is now a buildable machine (the byteforge), making it replaceable in the event of a disaster - Same for netpods and quantum consoles. These boards are now researchable and buildable. - New icons for the byteforge and the health monitor - Some bug fixes around despawning avatars - Reimplements one of the bitrunning unit tests
Pictures ⬇️ Host monitor ![hostmon](https://github.com/tgstation/tgstation/assets/42397676/dc6811bc-7ce9-4eae-a91b-96975bd13c65) Byteforge ![dreamseeker_LewhZG8bEl](https://github.com/tgstation/tgstation/assets/42397676/3071bc5f-b2c1-47d5-8a56-b0e6c216be20) Spawning a crate ![dreamseeker_mHGSfoeMu5](https://github.com/tgstation/tgstation/assets/42397676/d5f84e91-b9bc-4bb8-8f1c-f8931154ff6d)
## Why It's Good For The Game Bitrunning bug fixes and personal requests Fixes #78571 Fixes an issue reported in discord - players stuck as gondola spawn ## Changelog :cl: fix: Added extra checks to bitrunning domain cleanup so avatars are deleted properly. add: Quantum servers now look for a new machine called a byteforge to spawn loot on- no longer on an invisible landmark. This should make the rooms rebuildable after disasters. add: *Most* bitrunning machinery is now researchable and buildable via circuits in the engineering protolathe. /:cl: --- _maps/map_files/Birdshot/birdshot.dmm | 16 +--- .../map_files/Deltastation/DeltaStation2.dmm | 25 ++--- .../map_files/IceBoxStation/IceBoxStation.dmm | 15 +-- _maps/map_files/MetaStation/MetaStation.dmm | 14 +-- _maps/map_files/NorthStar/north_star.dmm | 27 ++---- _maps/map_files/debug/runtimestation.dmm | 6 +- _maps/map_files/tramstation/tramstation.dmm | 14 +-- .../dcs/signals/signals_bitrunning.dm | 3 + .../circuitboards/computer_circuitboards.dm | 5 - .../machines/machine_circuitboards.dm | 18 ---- .../components/avatar_connection.dm | 4 +- code/modules/bitrunning/designs.dm | 87 ++++++++++++++++++ code/modules/bitrunning/objects/byteforge.dm | 55 +++++++++++ .../bitrunning/objects/host_monitor.dm | 4 +- code/modules/bitrunning/objects/landmarks.dm | 5 - code/modules/bitrunning/objects/netpod.dm | 30 +++--- .../objects/{bit_vendor.dm => vendor.dm} | 0 code/modules/bitrunning/server/loot.dm | 12 ++- .../modules/bitrunning/server/map_handling.dm | 5 +- .../bitrunning/server/quantum_server.dm | 7 +- code/modules/bitrunning/server/util.dm | 20 ++-- code/modules/unit_tests/_unit_tests.dm | 1 + code/modules/unit_tests/bitrunning.dm | 15 +++ icons/obj/device.dmi | Bin 84915 -> 85414 bytes icons/obj/machines/bitrunning.dmi | Bin 8248 -> 23871 bytes tgstation.dme | 4 +- 26 files changed, 238 insertions(+), 154 deletions(-) create mode 100644 code/modules/bitrunning/designs.dm create mode 100644 code/modules/bitrunning/objects/byteforge.dm rename code/modules/bitrunning/objects/{bit_vendor.dm => vendor.dm} (100%) create mode 100644 code/modules/unit_tests/bitrunning.dm diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 052aee9740c..0711e8dc96a 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -32991,15 +32991,10 @@ /turf/open/floor/iron, /area/station/security/checkpoint/escape) "lLq" = ( -/obj/effect/turf_decal/box/corners{ - dir = 1 - }, -/obj/effect/turf_decal/box/corners{ - dir = 4 - }, /obj/machinery/firealarm/directional/east, /obj/effect/decal/cleanable/oil, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "lLr" = ( @@ -37938,13 +37933,10 @@ /turf/open/floor/circuit/telecomms/mainframe, /area/station/science/xenobiology) "nyf" = ( -/obj/effect/turf_decal/box/corners{ - dir = 8 - }, -/obj/effect/turf_decal/box/corners, /obj/machinery/camera/autoname/directional/east, /obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/structure/table, +/obj/item/food/cornchips/green, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "nyi" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index ff106565a42..7ab412a4f3d 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -10151,12 +10151,9 @@ /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hop) "cwd" = ( -/obj/effect/turf_decal/box/corners, -/obj/effect/turf_decal/box/corners{ - dir = 4 - }, /obj/machinery/light/directional/south, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "cwe" = ( @@ -39286,15 +39283,15 @@ /turf/open/floor/iron/white, /area/station/command/heads_quarters/cmo) "jKY" = ( -/obj/effect/turf_decal/box/corners{ - dir = 8 - }, -/obj/effect/turf_decal/box/corners{ - dir = 1 - }, /obj/effect/decal/cleanable/oil/streak, /obj/machinery/camera/directional/south, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 7 + }, +/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{ + pixel_x = 5 + }, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "jLa" = ( @@ -86574,10 +86571,6 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt/dust, -/obj/item/storage/toolbox/mechanical{ - pixel_x = -8; - pixel_y = 17 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, /obj/machinery/holopad, diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 6aa6f438643..172a001020e 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -10091,15 +10091,10 @@ /area/mine/laborcamp) "cWa" = ( /obj/machinery/light_switch/directional/west, -/obj/effect/turf_decal/box/corners{ - dir = 1 - }, -/obj/effect/turf_decal/box/corners{ - dir = 4 - }, /obj/effect/decal/cleanable/cobweb, /obj/effect/decal/cleanable/dirt/dust, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "cWq" = ( @@ -62098,11 +62093,7 @@ /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) "sVW" = ( -/obj/effect/turf_decal/box/corners{ - dir = 8 - }, -/obj/effect/turf_decal/box/corners, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "sWl" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index f0550cb5fed..c4a4756f915 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -3343,16 +3343,9 @@ /turf/open/floor/iron, /area/station/hallway/primary/starboard) "bje" = ( -/obj/effect/turf_decal/box/corners{ - dir = 8 - }, -/obj/effect/turf_decal/box/corners{ - dir = 1 - }, /obj/effect/decal/cleanable/oil/streak, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/structure/extinguisher_cabinet/directional/north, -/obj/effect/landmark/bitrunning/station_reward_spawn, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "bjl" = ( @@ -29712,14 +29705,11 @@ /turf/open/floor/engine, /area/station/science/explab) "kHU" = ( -/obj/effect/turf_decal/box/corners, -/obj/effect/turf_decal/box/corners{ - dir = 4 - }, /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/light_switch/directional/north, /obj/effect/decal/cleanable/dirt/dust, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "kIG" = ( diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index 535f37974ba..60ccea505c0 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -17161,9 +17161,6 @@ /obj/item/cigbutt/cigarbutt{ pixel_x = 7 }, -/obj/effect/turf_decal/stripes{ - dir = 8 - }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 }, @@ -34844,12 +34841,10 @@ /turf/open/floor/pod/light, /area/station/maintenance/floor1/starboard/fore) "jhP" = ( -/obj/effect/turf_decal/box/corners, -/obj/effect/turf_decal/box/corners{ - dir = 4 - }, /obj/effect/decal/cleanable/dirt/dust, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/effect/turf_decal/stripes{ + dir = 8 + }, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "jhU" = ( @@ -50980,9 +50975,6 @@ /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/trimline/brown/line, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -55648,11 +55640,13 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, -/obj/effect/turf_decal/stripes, /obj/effect/turf_decal/trimline/brown/line, /obj/structure/disposalpipe/segment{ dir = 5 }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, /turf/open/floor/iron/dark/smooth_half, /area/station/bitrunning/den) "owo" = ( @@ -78519,16 +78513,11 @@ /turf/open/floor/iron, /area/station/hallway/floor2/aft) "uDm" = ( -/obj/effect/turf_decal/box/corners{ - dir = 8 - }, -/obj/effect/turf_decal/box/corners{ - dir = 1 - }, /obj/machinery/firealarm/directional/south, /obj/machinery/light/directional/south, /obj/effect/decal/cleanable/oil/streak, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "uDr" = ( diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index 3b86ffcfc20..dff02b2abd7 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -2184,7 +2184,7 @@ /turf/open/floor/iron, /area/station/command/bridge) "FW" = ( -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/machinery/byteforge, /turf/open/floor/circuit/green, /area/station/bitrunning/den) "Ht" = ( @@ -3196,7 +3196,7 @@ aa aa aa uI -FW +hU hU jR Oq @@ -3288,8 +3288,8 @@ aa aa aa uI -FW hU +FW jR Oq uI diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 638f7512d67..9ce8d37d988 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -42017,14 +42017,9 @@ /turf/open/floor/iron/white, /area/station/science/lobby) "nUF" = ( -/obj/effect/turf_decal/box/corners, -/obj/effect/turf_decal/box/corners{ - dir = 4 - }, /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/light/directional/north, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/obj/effect/landmark/bitrunning/station_reward_spawn, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "nUM" = ( @@ -45391,17 +45386,12 @@ /turf/open/floor/plating, /area/station/commons/vacant_room) "plH" = ( -/obj/effect/turf_decal/box/corners{ - dir = 8 - }, -/obj/effect/turf_decal/box/corners{ - dir = 1 - }, /obj/effect/decal/cleanable/oil/streak, /obj/structure/sign/poster/random/directional/north, /obj/machinery/power/apc/auto_name/directional/west, /obj/structure/cable, -/obj/effect/landmark/bitrunning/station_reward_spawn, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, /turf/open/floor/iron/dark/smooth_large, /area/station/bitrunning/den) "plQ" = ( diff --git a/code/__DEFINES/dcs/signals/signals_bitrunning.dm b/code/__DEFINES/dcs/signals/signals_bitrunning.dm index 3d008449ee7..957e61ae303 100644 --- a/code/__DEFINES/dcs/signals/signals_bitrunning.dm +++ b/code/__DEFINES/dcs/signals/signals_bitrunning.dm @@ -29,3 +29,6 @@ /// from /obj/machinery/quantum_server/refreshParts(): (servo rating) #define COMSIG_BITRUNNER_SERVER_UPGRADED "bitrunner_server_upgraded" + +/// from /obj/machinery/quantum_server/scrub_vdom() +#define COMSIG_BITRUNNER_DOMAIN_SCRUBBED "bitrunner_domain_scrubbed" diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index 0338da6b4fa..79efe62a225 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -605,8 +605,3 @@ name = "Medical Order" greyscale_colors = CIRCUIT_COLOR_SUPPLY build_path = /obj/machinery/computer/department_orders/medical - -/obj/item/circuitboard/computer/quantum_console - name = "Quantum Server Console" - greyscale_colors = CIRCUIT_COLOR_SUPPLY - build_path = /obj/machinery/computer/quantum_console diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index 4bea5b1335c..9ca1095ee4b 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -1529,21 +1529,3 @@ /obj/item/stack/sheet/plasteel = 2, ) -/obj/item/circuitboard/machine/quantum_server - name = "Quantum Server" - greyscale_colors = CIRCUIT_COLOR_SUPPLY - build_path = /obj/machinery/quantum_server - req_components = list( - /datum/stock_part/servo = 2, - /datum/stock_part/scanning_module = 1, - /datum/stock_part/capacitor = 1, - ) - -/obj/item/circuitboard/machine/netpod - name = "Netpod" - greyscale_colors = CIRCUIT_COLOR_SUPPLY - build_path = /obj/machinery/netpod - req_components = list( - /datum/stock_part/servo = 1, - /datum/stock_part/matter_bin = 2, - ) diff --git a/code/modules/bitrunning/components/avatar_connection.dm b/code/modules/bitrunning/components/avatar_connection.dm index 2a151d05066..24f42d8f3e5 100644 --- a/code/modules/bitrunning/components/avatar_connection.dm +++ b/code/modules/bitrunning/components/avatar_connection.dm @@ -68,7 +68,7 @@ /datum/component/avatar_connection/RegisterWithParent() ADD_TRAIT(parent, TRAIT_TEMPORARY_BODY, REF(src)) RegisterSignal(parent, COMSIG_BITRUNNER_SAFE_DISCONNECT, PROC_REF(on_safe_disconnect)) - RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_sever_connection), override = TRUE) + RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_sever_connection)) RegisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_linked_damage)) /datum/component/avatar_connection/UnregisterFromParent() @@ -79,7 +79,9 @@ /// Disconnects the avatar and returns the mind to the old_body. /datum/component/avatar_connection/proc/full_avatar_disconnect(forced = FALSE, datum/source) +#ifndef UNIT_TESTS return_to_old_body() +#endif var/obj/machinery/netpod/hosting_netpod = netpod_ref?.resolve() if(isnull(hosting_netpod) && istype(source, /obj/machinery/netpod)) diff --git a/code/modules/bitrunning/designs.dm b/code/modules/bitrunning/designs.dm new file mode 100644 index 00000000000..4e7bca1c1a8 --- /dev/null +++ b/code/modules/bitrunning/designs.dm @@ -0,0 +1,87 @@ +// Quantum server + +/obj/item/circuitboard/machine/quantum_server + name = "Quantum Server" + greyscale_colors = CIRCUIT_COLOR_SUPPLY + build_path = /obj/machinery/quantum_server + req_components = list( + /datum/stock_part/servo = 2, + /datum/stock_part/scanning_module = 1, + /datum/stock_part/capacitor = 1, + ) + +/** + * quantum server design + * are you absolutely sure?? + */ + +// Netpod + +/obj/item/circuitboard/machine/netpod + name = "Netpod" + greyscale_colors = CIRCUIT_COLOR_SUPPLY + build_path = /obj/machinery/netpod + req_components = list( + /datum/stock_part/servo = 1, + /datum/stock_part/matter_bin = 2, + ) + +/datum/design/board/netpod + name = "Netpod Board" + desc = "The circuit board for a netpod." + id = "netpod" + build_path = /obj/item/circuitboard/machine/netpod + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_CARGO + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + +// Quantum console + +/obj/item/circuitboard/computer/quantum_console + name = "Quantum Console" + greyscale_colors = CIRCUIT_COLOR_SUPPLY + build_path = /obj/machinery/computer/quantum_console + +/datum/design/board/quantum_console + name = "Quantum Console Board" + desc = "Allows for the construction of circuit boards used to build a Quantum Console." + id = "quantum_console" + build_path = /obj/item/circuitboard/computer/quantum_console + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_COMPUTER_CARGO + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + +// Byteforge + +/obj/item/circuitboard/machine/byteforge + name = "Byteforge" + greyscale_colors = CIRCUIT_COLOR_SUPPLY + build_path = /obj/machinery/byteforge + req_components = list( + /datum/stock_part/micro_laser = 1, + ) + +/datum/design/board/byteforge + name = "Byteforge Board" + desc = "Allows for the construction of circuit boards used to build a Byteforge." + id = "byteforge" + build_path = /obj/item/circuitboard/machine/byteforge + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_COMPUTER_CARGO + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + + +/datum/techweb_node/bitrunning + id = "bitrunning" + display_name = "Bitrunning Technology" + description = "Bluespace technology has led to the development of quantum-scale computing, which unlocks the means to materialize atomic structures while executing advanced programs." + prereq_ids = list("practical_bluespace") + design_ids = list( + "byteforge", + "quantum_console", + "netpod", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) diff --git a/code/modules/bitrunning/objects/byteforge.dm b/code/modules/bitrunning/objects/byteforge.dm new file mode 100644 index 00000000000..e4543601ce9 --- /dev/null +++ b/code/modules/bitrunning/objects/byteforge.dm @@ -0,0 +1,55 @@ +/obj/machinery/byteforge + name = "byteforge" + + circuit = /obj/item/circuitboard/machine/byteforge + desc = "A machine used by the quantum server. Quantum code converges here, materializing decrypted assets from the virtual abyss." + icon = 'icons/obj/machines/bitrunning.dmi' + icon_state = "byteforge" + obj_flags = BLOCKS_CONSTRUCTION + /// Idle particles + var/mutable_appearance/byteforge_particles + +/obj/machinery/byteforge/Initialize(mapload) + . = ..() + + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/byteforge/LateInitialize() + . = ..() + + byteforge_particles = mutable_appearance(initial(icon), "on_particles", ABOVE_MOB_LAYER) + setup_particles() + +/obj/machinery/byteforge/update_appearance(updates) + . = ..() + + setup_particles() + +/// Adds the particle overlays to the byteforge +/obj/machinery/byteforge/proc/setup_particles() + cut_overlays() + + if(is_operational) + add_overlay(byteforge_particles) + +/// Begins spawning the crate - lights, overlays, etc +/obj/machinery/byteforge/proc/start_to_spawn(obj/structure/closet/crate/secure/bitrunning/encrypted/cache) + addtimer(CALLBACK(src, PROC_REF(spawn_crate), cache), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) + + var/mutable_appearance/lighting = mutable_appearance(initial(icon), "on_overlay") + flick_overlay_view(lighting, 1 SECONDS) + + set_light(l_range = 2, l_power = 1.5, l_color = LIGHT_COLOR_BABY_BLUE, l_on = TRUE) + +/// Sparks, moves the crate to the location +/obj/machinery/byteforge/proc/spawn_crate(obj/structure/closet/crate/secure/bitrunning/encrypted/cache) + if(QDELETED(cache)) + return + + playsound(src, 'sound/magic/blink.ogg', 50, TRUE) + var/datum/effect_system/spark_spread/quantum/sparks = new() + sparks.set_up(5, 1, loc) + sparks.start() + + cache.forceMove(loc) + set_light(l_on = FALSE) diff --git a/code/modules/bitrunning/objects/host_monitor.dm b/code/modules/bitrunning/objects/host_monitor.dm index f59ca61cbd0..c35edea6319 100644 --- a/code/modules/bitrunning/objects/host_monitor.dm +++ b/code/modules/bitrunning/objects/host_monitor.dm @@ -2,10 +2,10 @@ name = "host monitor" custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 2) - desc = "A complex medical device that, when attached to an avatar's data stream, can detect the user of their host's health." + desc = "A complex electronic that will analyze the connection health between host and avatar." flags_1 = CONDUCT_1 icon = 'icons/obj/device.dmi' - icon_state = "gps-b" + icon_state = "host_monitor" inhand_icon_state = "electronic" item_flags = NOBLUDGEON lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' diff --git a/code/modules/bitrunning/objects/landmarks.dm b/code/modules/bitrunning/objects/landmarks.dm index d78283c6a8b..a4539c7c3da 100644 --- a/code/modules/bitrunning/objects/landmarks.dm +++ b/code/modules/bitrunning/objects/landmarks.dm @@ -44,11 +44,6 @@ qdel(src) -/// Where the crates get ported to station -/obj/effect/landmark/bitrunning/station_reward_spawn - name = "Bitrunning rewards spawn" - icon_state = "station" - /// Where the exit hololadder spawns /obj/effect/landmark/bitrunning/hololadder_spawn name = "Bitrunning hololadder spawn" diff --git a/code/modules/bitrunning/objects/netpod.dm b/code/modules/bitrunning/objects/netpod.dm index 349a304f04b..d92da961b86 100644 --- a/code/modules/bitrunning/objects/netpod.dm +++ b/code/modules/bitrunning/objects/netpod.dm @@ -189,7 +189,7 @@ return TRUE /obj/machinery/netpod/ui_interact(mob/user, datum/tgui/ui) - if(!is_operational) + if(!is_operational || occupant) return ui = SStgui.try_update_ui(user, src, ui) @@ -242,20 +242,12 @@ to_chat(player, span_notice("The machine disconnects itself and begins to drain.")) open_machine() -/** - * ### Disconnect occupant - * If this goes smoothly, should reconnect a receiving mind to the occupant's body - * - * This is the second stage of the process - if you want to disconn avatars start at the mind first - */ +/// Handles occupant post-disconnection effects like damage, sounds, etc /obj/machinery/netpod/proc/disconnect_occupant(forced = FALSE) - var/mob/living/mob_occupant = occupant - if(isnull(occupant) || !isliving(occupant)) - return - connected = FALSE - if(mob_occupant.stat == DEAD) + var/mob/living/mob_occupant = occupant + if(isnull(occupant) || !isliving(occupant) || mob_occupant.stat == DEAD) open_machine() return @@ -347,8 +339,9 @@ return server_ref = WEAKREF(server) - RegisterSignal(server, COMSIG_BITRUNNER_SERVER_UPGRADED, PROC_REF(on_server_upgraded), override = TRUE) - RegisterSignal(server, COMSIG_BITRUNNER_DOMAIN_COMPLETE, PROC_REF(on_domain_complete), override = TRUE) + RegisterSignal(server, COMSIG_BITRUNNER_SERVER_UPGRADED, PROC_REF(on_server_upgraded)) + RegisterSignal(server, COMSIG_BITRUNNER_DOMAIN_COMPLETE, PROC_REF(on_domain_complete)) + RegisterSignal(server, COMSIG_BITRUNNER_DOMAIN_SCRUBBED, PROC_REF(on_domain_scrubbed)) return server @@ -395,6 +388,7 @@ account.bitrunning_points += reward_points * 100 +/// User inspects the machine /obj/machinery/netpod/proc/on_examine(datum/source, mob/examiner, list/examine_text) SIGNAL_HANDLER @@ -409,7 +403,15 @@ examine_text += span_notice("It is currently occupied by [occupant].") examine_text += span_notice("It can be pried open with a crowbar, but its safety mechanisms will alert the occupant.") +/// The domain has been fully purged, so we should double check our avatar is deleted +/obj/machinery/netpod/proc/on_domain_scrubbed(datum/source) + SIGNAL_HANDLER + var/mob/living/current_avatar = avatar_ref?.resolve() + if(isnull(current_avatar)) + return + + QDEL_NULL(current_avatar) /// When the server is upgraded, drops brain damage a little /obj/machinery/netpod/proc/on_server_upgraded(datum/source, servo_rating) diff --git a/code/modules/bitrunning/objects/bit_vendor.dm b/code/modules/bitrunning/objects/vendor.dm similarity index 100% rename from code/modules/bitrunning/objects/bit_vendor.dm rename to code/modules/bitrunning/objects/vendor.dm diff --git a/code/modules/bitrunning/server/loot.dm b/code/modules/bitrunning/server/loot.dm index 29b730aae78..8b3af95607c 100644 --- a/code/modules/bitrunning/server/loot.dm +++ b/code/modules/bitrunning/server/loot.dm @@ -16,14 +16,16 @@ /// Generates a reward based on the given domain /obj/machinery/quantum_server/proc/generate_loot() - if(!length(receive_turfs) && !locate_receive_turfs()) + var/list/obj/machinery/byteforge/nearby_forges = get_nearby_forges() + if(isnull(nearby_forges)) + say(src, "No nearby byteforges detected.") return FALSE points += generated_domain.reward_points playsound(src, 'sound/machines/terminal_success.ogg', 30, 2) - var/turf/dest_turf = pick(receive_turfs) - if(isnull(dest_turf)) + var/obj/machinery/byteforge/chosen_forge = pick(nearby_forges) + if(isnull(chosen_forge)) stack_trace("Failed to find a turf to spawn loot crate on.") return FALSE @@ -34,11 +36,11 @@ certificate.name = "certificate of domain completion" certificate.update_appearance() - var/obj/structure/closet/crate/secure/bitrunning/decrypted/reward_crate = new(dest_turf, generated_domain, bonus) + var/obj/structure/closet/crate/secure/bitrunning/decrypted/reward_crate = new(src, generated_domain, bonus) reward_crate.manifest = certificate reward_crate.update_appearance() - spark_at_location(reward_crate) + chosen_forge.start_to_spawn(reward_crate) return TRUE /// Returns the markdown text containing domain completion information diff --git a/code/modules/bitrunning/server/map_handling.dm b/code/modules/bitrunning/server/map_handling.dm index 02126c290f7..741fad476f0 100644 --- a/code/modules/bitrunning/server/map_handling.dm +++ b/code/modules/bitrunning/server/map_handling.dm @@ -1,3 +1,4 @@ +#define ONLY_TURF 1 /// Gives all current occupants a notification that the server is going down /obj/machinery/quantum_server/proc/begin_shutdown(mob/user) @@ -119,7 +120,6 @@ new /obj/structure/closet/crate/secure/bitrunning/encrypted(pick(crate_turfs)) return TRUE -#define ONLY_TURF 1 // There should only ever be one turf at the bottom left of the map. /// Loads the safehouse /obj/machinery/quantum_server/proc/initialize_safehouse() @@ -160,7 +160,8 @@ /// Deletes all the tile contents /obj/machinery/quantum_server/proc/scrub_vdom() - SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) // just in case + SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) /// just in case someone's connected + SEND_SIGNAL(src, COMSIG_BITRUNNER_DOMAIN_SCRUBBED) // avatar cleanup just in case if(length(generated_domain.reservations)) var/datum/turf_reservation/res = generated_domain.reservations[1] diff --git a/code/modules/bitrunning/server/quantum_server.dm b/code/modules/bitrunning/server/quantum_server.dm index 404a31cca6a..b869fb7f02e 100644 --- a/code/modules/bitrunning/server/quantum_server.dm +++ b/code/modules/bitrunning/server/quantum_server.dm @@ -48,8 +48,6 @@ var/servo_bonus = 0 /// The turfs we can place a hololadder on. var/turf/exit_turfs = list() - /// The turfs on station where we generate loot. - var/turf/receive_turfs = list() /obj/machinery/quantum_server/Initialize(mapload) . = ..() @@ -84,18 +82,17 @@ avatar_connection_refs.Cut() spawned_threat_refs.Cut() QDEL_NULL(exit_turfs) - QDEL_NULL(receive_turfs) QDEL_NULL(generated_domain) QDEL_NULL(generated_safehouse) QDEL_NULL(radio) /obj/machinery/quantum_server/update_appearance(updates) if(isnull(generated_domain) || !is_operational) - set_light(0) + set_light(l_on = FALSE) return ..() set_light_color(is_ready ? LIGHT_COLOR_BABY_BLUE : LIGHT_COLOR_FIRE) - set_light(2, 1.5) + set_light(l_range = 2, l_power = 1.5, l_on = TRUE) return ..() diff --git a/code/modules/bitrunning/server/util.dm b/code/modules/bitrunning/server/util.dm index c4f1319cd12..f4dbada9ef6 100644 --- a/code/modules/bitrunning/server/util.dm +++ b/code/modules/bitrunning/server/util.dm @@ -107,14 +107,14 @@ return shuffle(mutation_candidate_refs) -/// Locates any turfs with crate out landmarks -/obj/machinery/quantum_server/proc/locate_receive_turfs() - for(var/obj/effect/landmark/bitrunning/station_reward_spawn/spawner in GLOB.landmarks_list) - if(IN_GIVEN_RANGE(src, spawner, MAX_DISTANCE)) - receive_turfs += get_turf(spawner) - qdel(spawner) +/// Locates any turfs with forges on them +/obj/machinery/quantum_server/proc/get_nearby_forges() + var/list/obj/machinery/byteforge/nearby_forges = list() - return length(receive_turfs) > 0 + for(var/obj/machinery/byteforge/forge in oview(MAX_DISTANCE, src)) + nearby_forges += forge + + return nearby_forges /// Finds any mobs with minds in the zones and gives them the bad news /obj/machinery/quantum_server/proc/notify_spawned_threats() @@ -132,10 +132,10 @@ to_chat(baddie, span_userdanger("You have been flagged for deletion! Thank you for your service.")) /// Do some magic teleport sparks -/obj/machinery/quantum_server/proc/spark_at_location(obj/crate) - playsound(crate, 'sound/magic/blink.ogg', 50, TRUE) +/obj/machinery/quantum_server/proc/spark_at_location(obj/cache) + playsound(cache, 'sound/magic/blink.ogg', 50, TRUE) var/datum/effect_system/spark_spread/quantum/sparks = new() - sparks.set_up(5, 1, get_turf(crate)) + sparks.set_up(5, 1, get_turf(cache)) sparks.start() #undef REDACTED diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index d4839542122..c6fdecbd29b 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -100,6 +100,7 @@ #include "baseturfs.dm" #include "bespoke_id.dm" #include "binary_insert.dm" +#include "bitrunning.dm" #include "blindness.dm" #include "bloody_footprints.dm" #include "breath.dm" diff --git a/code/modules/unit_tests/bitrunning.dm b/code/modules/unit_tests/bitrunning.dm new file mode 100644 index 00000000000..568eeeed8c1 --- /dev/null +++ b/code/modules/unit_tests/bitrunning.dm @@ -0,0 +1,15 @@ +/// Ensures settings on vdoms are correct +/datum/unit_test/bitrunner_vdom_settings + +/datum/unit_test/bitrunner_vdom_settings/Run() + var/obj/structure/closet/crate/secure/bitrunning/decrypted/cache = allocate(/obj/structure/closet/crate/secure/bitrunning/decrypted) + + for(var/path in subtypesof(/datum/lazy_template/virtual_domain)) + var/datum/lazy_template/virtual_domain/vdom = new path + TEST_ASSERT_NOTNULL(vdom.key, "[path] should have a key") + TEST_ASSERT_NOTNULL(vdom.map_name, "[path] should have a map name") + + if(!length(vdom.extra_loot)) + continue + + TEST_ASSERT_EQUAL(cache.spawn_loot(vdom.extra_loot), TRUE, "[path] didn't spawn loot. Extra loot should be an associative list") diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index d89ee6e5d6408ff981d5220b03864b6341748f1f..fe74b6c11c5c7d2ed0172c41bbfcfc1f5377d357 100644 GIT binary patch delta 4250 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 delta 3757 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 NLA9Q1R%pP({|`ZnK}-Mu diff --git a/icons/obj/machines/bitrunning.dmi b/icons/obj/machines/bitrunning.dmi index a910a16b35cf8c36847ce2b3481c57d2150f5e05..b3f8ad63a6c9937b287abab9b981dc4c08b0d74b 100644 GIT binary patch literal 23871 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 HIqH7^drr!| literal 8248 zcma)BXH-*NvreG~5R@Vyn%F_QfFSJzMG!2YNRbW}nm`aR)FcoDRN89;rGz5I3cjK= zApyiFC`D9MN~B>?DIT(X3owH`_tA^2xSBW0+F&g zZh000ffB&OTMQ0Lu6uY&Lm;qP`;+I6-MxGFfVQQn<$1S@k=u9a?kRFMX?IQCqgkr0 zWbuvgx_oR`jtEKg256@W4)$~J#j%E=#X4f8?h31)ECD~ptwZ)a&COkQNCfF(a zl~Y!=)14ZBzl77N6<%eHUWH9w#mxq$cElI;#8-{PH}8lI9mLno#QIj^+jio|K4RlX zV$Vu@k2+6Wh9o--d|ahlzs>Elq118y~a4`({D+&HQuB0v_5%7u!ab*kVha z(yE+NtDJ7UI*lv!%5Ctv|JLh4qmMT>LGQT!gFvBql;n)Py_t(XQXj2;?6l$8K>NUi z%Q*9W0M^hJYjO&!YmYT>%Ch&)w7QsiBEa*AYk6RFxp!>&B?8tpEXVP39sX7wHoY$9 zw%}H>;La^Uc8;K+L~!r6Apf3#R4jN^CnzcuG&TyzZG!f0C*Z8$*)u_Fo1m>j(D_Y& zoA$ZGC$VZ)SamDxJ{zp+sZ78v)7Uf9)Vtg@y!>2bxl?qGl}{Zer7qw`UGS~YvzPAf z)G^6&-i^}L);OYnz#02t7AnvpjPT|L2ZXlvw!55NWug$V=yiy7g8R7vn1Nj zajVkK!en39)0Q%u<&PZJ*Hblmc)Zlm5GZhZj*yTt-)nYVMZ-4d6!yT8hkMmX$K3>y zkhsK@EnBwQJGy%q20jhX=t}9`y-PLFDE?ZF4>HKxp|a@49b!=4{nQWS zD!gA{aY%gLePY06x9CJ~a!pxgkpDF=$IKA7Yu={=uGm{7f4H5Dd0+D+HWAm-@VNPP z`OBvz?`tbARSPz6+Jr!C+NGj=+We@Gv(2epr=pDsZ*6m_Rkw@{&9P@L=H3s#eKWB9 z2DbT4SqAR%gT&zSTbKvLfR=_A44p#`DQEL9^s+HW!ryDY1(+fe{P4hQB4Qe7^EtJtfX?G?1~YSeVbM zcz!QroEy+~ALD=7Ex4c_e!7i9?x`%BvAAHD;jK!sQ6S@f!kY(}D}6^(@#+B|534g0atXKY^P_&P`)yQ#n6d*Y?bBh|0&=gw-B{g6{T`{=K&YHhxM zo!wc0f__a(LECD4H_sj|+GDM=7kxZKMt3+-+kI|k@3O4zOYXMLPjlvaCY23(uk<(r zbMqfJU!~&p zN)s8D;O$5JH1ua4WI0(OADtmKyo1MNWfY5GQ$!^ao3m~op-gJ6Un@E0>J!!OcopY>Ht(loDbs?JAjB^0c4?(>R$6|E^#ib zge|IRbo|-mv3H*wwvwusmZV8x@3o0WqiNElrlm)1lDG-$PUC53bYA3l>&~yuUHr-R zdt`*~czb4nha%wjb0NITM8Nfezq~pg&Cv3iP&9mohm_l>J7pm*3X3Udo8`;Vmr9W( zEWM8+=C6!!ht4;@x;4Vk01Sf*7rTJ@f$(hnfM$p*{@ec7-YlD~?#vq!+T2K)t)6Q) zB(w_Ulh*cY*H0Rv-6MMTFEi~t;#i@HwQD1G0rU>7y0PADPqrIMt8u9}+x_nu6>6;y z&$0KBH)|yGlCSP5?=-xrY#WQ#nG`$ljPI?CFwcM8QnWK-y{00-A5wNETl4(Y_1hg< zNAFa0JP0^P%pJCnlS+8JKQH|aTBo<$yQjE=@^$L!8r*lYUV0!#PbC9-l>Qp>w)O%V z#IPh*zV(cvCIpylYqB6_r?v+8PyD&Np&du+-oBVX`6zk@9S}f89`}W4Zz#UCI7Ra&&;&euAC3-MyUcSO)ZV>5(9cTcW z=Aznoi;LS==Q1n*O<0S?$AOCcwffP++}WpAPJX@@9f|#|;cKhT&s~=rED3m5Dn2vy zAd|MgSkk>s+XVj_kH5GqA7maoeh&{BX;%jtCT@P)t--H*`htB_#@S=}@b+VY;}R{F`;sN3<-kqncjYn<8YL>U1)AIsmHYBJBQ-@#9Bm}9HUUCT)GEDLstjGr?I83kvqshVU*iDwniE6iX8wYn!DorP#36rE|4L+1Nl_y= zsK~9OZe-r_Dy_#uH*kvh*0}10i_jG z_~>m_!tI3?5!;U31@-n5>#tyn?EV0#H*)`H2;oE}3Oqm^CL*KbmL6(9SqHvwFMGjH zSZAq*3fq$)ToM(^Pc_*hdB!W(PgIN_8{>Va;$(2g8-zbw>VWDiVISkv?* z29!OY(Fqz0_0uaf5UNQ!uI4TL>!*2Dv$%>u)eUm~XM>aJv&KR#<-xrAfF!Hv0@& zI;=65C@1faafR&0n=ptjXq=1K@F3-yYl5cK>EVimQ{36S^D=G;r*0y?E2b1JREDYy zuGrC+w=-`N^|SxJfR;NpNfdd34wVTE4Zt9*VXEBeZ8gEMze%KDD}(cK*nWq}wgX4g;J578A1KhT{4L{}e^f2O-b0<~HhI$$NNj*hEw)j+4+ zQg`uE5iewd!kql%A*)R2kJXl~kWnt;yHbkJSZE3vm2OSIV8V%v_h;ZI$akITx)yOn zM|WtNw*EWEd9O%Z0mOPJYiPSS; z0&W~No--Ph={x`c0#+c05kyEyC)1D_Wj29$e2m`X7(N?E9fqcn@#=_~(9oJu$s3{j zq|Dex2w2xZ$fXWFe#{fo(aOp*>ti98m0yxc`v|LteIzBX+~Bd&(C=oQPOqn-^A;Xd z&iq(-1^{ja%Z$}C>n@OXn%!ng#Y|tk=^({28Po13M8CJcQs#8@camMccW%qA`+i*B zrVc$AYBAtGp?OL~L@5z-cjuMp-xA_);@(JH=y31~?5IS)F%2qsZomF0;T0culhCY| zC^ove($pYXXIu^XW8tUyUA3-Rat;JGojnKgpzP9SGv64xocGVPVQyHo79&66b0`!h9i=zqMRUL_eWI%axfwM1^PYBGcvDTMxp$@ zj6zq&PRY~hJJSTD-=h-4dFolL8t3icP|c4ehv`aC7t`FG_xnU2Ip@5i(dLcXWfVUu zwrp0_OI8)~4f~EOKr-U9if6y^GOQIdqm0awtBiINj>Q`LDYP7Jj!y4=rICS-NS2d5 zo*d5pk-AdTh0RkwstAs~DdcZ+f`i4x4HpBdPcq81Q>J4j;+o8;Q&neF66<(3<$V7S{)TF+u?%Xmru4CMBTJ~h0;av~UI&<_i;{M3B zj@%b^OphjikqR1mnTzije>&7w(XQSnDz`#@T0jb|i~Bh(+pbmVj`SW2#S%E4Wbd0` z>)qe@8t{Si=RuV>Ul2wEEr(657r~!!~0bX2ur)WN|b(|xblq?~sLT~DmR;&cSi z&KAUbH9uK+!V|yC+4f<@n(o~FTtHqDIW&MozXlSn;^9B}VqCfKX@Pd*tuuF>XSE9l zNa)w(ge!QVIr%J08a=sd^&ja=azX@N$WvHiy`KYdo|P^f@Y=B9i-%9Kp+n+EUP$i+ zE>C5?@)r_aM<)2TF7*t+F9%A*IkyVLZls z%5MgTiwadj-8=u*7yA{W-b)n^M0ye`#fQ zbab@8C+K7x+d{|cnCQ`bt&r@H6wL!IvrNt^wIeJGDPEv*U9Xh$X_aJEIZwp{y|c%z z#%$;2zVy@6{oW>d09tQ?X_!T|pC1Oj8ZC|50YyugN(mNEVy%@2tEXbfim~_o6JMr5 z2DiIF{!S2wjvRzRPp%!6WAj(yYMU3A$6@at0|i`FWpobourU21;V|C6O;9j&Wpvc4 zt1ktX)PssE5?JosN%^7oK=IBYh`bVX%_9v_)7*vgX<_%js=0F>AGZ=xy1ux4q3$fy z^}#ft=LXyVnwYA43~o<7=xo&6_Q+ys%;RcWRdbiV4wY6=m;Z@9TC^x3T<;bzyv}Bc zzPBVeq3sfPX;3yDNL?Hhm;Ui{9Q||OE+LuA1bc`Cw;E!KH;KL;&Sh=JMTA})UuP>p z6@-X8<;@&UmHF7qlpCrLfOp!HAM_tRkrwhPnsBUSG}^KUS& z4Les_tVv}BYd8^DVMUPQtN9FZHX~x~f%#ilSD#-4imRLOJJGnyOu$_fu;Ww;p~ekZ z0faln+*WuZ&wMY%C~ZWE!W2Lp3n9Q@N_Kaf9InYcA9_+oirG@I)hi}?UY+APAXpgM zS_r8SrU*{9h~#`CK}Q!Pf2e&RIC~A?QAPM!#|7Ajj;=#l0>-poS&>9ys`7Qw-NjJP zAK@544Ly(0&_LgYBuXkOT%EQ&7GD6r$tdmDemGo{X>{}Gm z=?wBt^i#b5VC*8~tAO?rlBadN6M29;y$SP}jC@46qKs%L^h7dYhsEYh<%CkMB?@BW z8PkV_Quium`%(62!(-S-p*I&(5Q2KR`|o*CC5Y&-d}FF2bd!vSOjCx01jNEYkv(k z{FJ0D$yWYmz9K%F2mJ)r_h_Q;Mqd*8@!HQ9md7#g-XyyZ_AXu~@{X1|`pcbe*wWNI*>=X)B61SUC8Z#Nv(rPQaYubkR|Jf&>2)P5m=fh`SnRx{|!4{R@95u!R-_#r@b8>?*v*)LcmkL>QYc8L_(ldk?d zvFtXsU<>|E*+--yIu2fo;KwMZz_Oqws%If{@{##mr0em z>W`C@*!Pn_%AH=5G`I(Lil&pgx|zFUG0TSpFlRDD*LdvFZMaLqw#!sQE{?~N!t)WB z7XTO835vK>zV zd`!I&`6WO`Fpw@w)YXAzVcvSL&K2frKbx>4p$y=wu9VFk{-s-$V%MREeh2g}?wgMe zD;vedQ)Y&o`TL7#K!1-5lAvD5$OLXSK0Xe4jzB?g3#onph|AWnT2G|Tt>sMN?mEbA z?b7qG#N%U`Kn!zy$N+PfCOp2tunSt~QW0V!_Z+0K*o2=%v>>|*avdyd<-3=u$hK+O zLP#fXUC#xtN(kqle+I~*GXbRo)m#>u0Jq$lRJq%lABUnqizTjhN(&jGBP?RL@ARKl zfqq|`DAM}y8o-P6mS}x25NMQHdt@o#ZzsC)qii8@!bS@W2bd9~T&R0=-UI3phM16} z)B#=(pnDh9^-$8lj-+?;gcK&1)$-30e0&n$qytxBN$3@d;SWmnE>I=(P|wlj?*AtC zre_Mkv?Hw-@9lcfd28WkJ2B=&nkY_#lKWNBo`Cd#KIE@?{MbRJrffK7_bG}_yFRrV zM8ancN%SzO^DQe;+I+4@&X6=v*2kd67cL<_>~nTaz-@pFFsDEiZD2l#`wZ|#PaZSB zaj`{|`;@MOi04ppLG)8X$9{sFWPHlTE*ZCp$J)mo?XSrUoeu{&^JJzAZ~Pd_?XBd3 z_1iwKC45PfjK#kd7eoyRhos=y_h^5*fsK)jKbvb{Yuw=ab;MK5$JrlE3k=SLo%G@Y zH|{9Ei3Xsa6Xutp-`A$!n0s%Eb?_>f&iT>0yq3BA_M`T^+4nHAIo&AkTEs~~J1Zk) z85$lH58HwUOVfP<-DkiS$}*cU3dVg%-!yz;)7-QNJe;dlaSqSdt;R$Cf@buIs-&<5 zViMj}=HABZf4M_d@LUy75=0m?*99amr-1MQ8Q?|nxpdCl%|3r|-hW_)T{<*|JLO`Q zzK8A%iGTW@MeXtl+VeZnowJzf6Z2KLZUV@dI!LItJeBC40FtL3>lVrg zB8=f`?Rb@5hYM&ZE_I>0tvBjYWbyQVCE#IV;q@e6RBf>vLVJpXWDrU2%Wp8{295|A!;?KJr?1 z+xwmQaWw9fPZMvwX;r#=ICMq2s@j~QK+fjDw>ZByx8sQJ85)bf%n|ip=$eb4#mmOv zIigvxs2>2`;4FkEfzHG$OwWf32usS$YCI(-F}^aF%k@KbUZ4J~4XGz*!Iq);EgzPGr<7byc1GoH?7>$H1@r ztYMOB+!x&>X#A*PoGXON{oYaoc;=EeQ#8r1Hw@%ASf^=JC5Va;7u^16> zhg2b~IPkeN1g3(jN5ySF42Jp(1UGPq@**&`eDVo;#NtDZ`Efa5Nk_j6`uk-j-9rA Jal||EzW@|(a^L^} diff --git a/tgstation.dme b/tgstation.dme index 9b2f8c4c1d8..2c499469869 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3244,6 +3244,7 @@ #include "code\modules\bitrunning\abilities.dm" #include "code\modules\bitrunning\alerts.dm" #include "code\modules\bitrunning\areas.dm" +#include "code\modules\bitrunning\designs.dm" #include "code\modules\bitrunning\event.dm" #include "code\modules\bitrunning\job.dm" #include "code\modules\bitrunning\turfs.dm" @@ -3252,7 +3253,7 @@ #include "code\modules\bitrunning\components\avatar_connection.dm" #include "code\modules\bitrunning\components\bitrunning_points.dm" #include "code\modules\bitrunning\components\netpod_healing.dm" -#include "code\modules\bitrunning\objects\bit_vendor.dm" +#include "code\modules\bitrunning\objects\byteforge.dm" #include "code\modules\bitrunning\objects\clothing.dm" #include "code\modules\bitrunning\objects\disks.dm" #include "code\modules\bitrunning\objects\hololadder.dm" @@ -3261,6 +3262,7 @@ #include "code\modules\bitrunning\objects\loot_crate.dm" #include "code\modules\bitrunning\objects\netpod.dm" #include "code\modules\bitrunning\objects\quantum_console.dm" +#include "code\modules\bitrunning\objects\vendor.dm" #include "code\modules\bitrunning\orders\disks.dm" #include "code\modules\bitrunning\orders\flair.dm" #include "code\modules\bitrunning\orders\tech.dm"