From 6aa0dee37fcce81fc88e2642c554af82f41f496e Mon Sep 17 00:00:00 2001 From: Rhials <28870487+Rhials@users.noreply.github.com> Date: Tue, 7 May 2024 01:35:05 -0400 Subject: [PATCH] Virtual Domains now have certain areas protected from ghost role interference (#82960) ## About The Pull Request This touches up on the bitrunning ghost roles that come with some maps, namely Corsair Cove and Syndicate Assault. The gist of it is: Ghost role spawners and Digital Anomalies (the random event boss mobs) are now restricted from entering the VDOM safehouse, and other areas where critical equipment is stored. Here's an example from Syndicate Assault -- The X-ed out area is considered "out of bounds" for digital anomalies/ghost roles: ![image](https://github.com/tgstation/tgstation/assets/28870487/b0752dd4-102b-4b64-8c21-c100a58c1a96) Additionally, this also fixes the matter of pirate ghost role spawns creating their own antag datum/pirate team, which would carry into the roundend report. Since these are no longer legitimate pirate spawners and are now specifically designed spawners for virtual domains. Naturally, emagging the server jailbreaks all of these restrictions and notifies any virtual entities. The new subtype of spawners should also be scalable enough that new VDOMs should be able to implement new ghost role spawners with ease. ## Why It's Good For The Game It's one thing to have sentient mobs to fight, which can shake up the otherwise somewhat static nature of bitrunning maps, but when players are tossing equipment, spawncamping, or otherwise making it impossible for the runners to fight them it ends up being unfun for everyone involved. You can't get into a good fight with a bitrunner avatar if their only recourse is to wipe the map and everything (YOU) in it. This ensures a level of fairness between the (typically vindictive) ghost roles of a VDOM and the players. Also, pirate spawns don't make a new pirate team/datum. That's one of the fixes I was aiming for with this. ## Changelog :cl: Rhials balance: Virtual domain ghost roles can no longer enter the safehouse/"equipment" areas of a domain. fix: Pirate virtual domain ghost roles will no longer make a pirate team antag datum. /:cl: --------- Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com> --- _maps/virtual_domains/pirates.dmm | 467 +++++++++--------- _maps/virtual_domains/psyker_zombies.dmm | 78 +-- _maps/virtual_domains/syndicate_assault.dmm | 192 +++---- code/__DEFINES/_flags.dm | 2 + .../dcs/signals/signals_bitrunning.dm | 3 + .../bitrunning/antagonists/ghost_role.dm | 22 + code/modules/bitrunning/areas.dm | 12 +- .../bitrunning/components/virtual_entity.dm | 36 ++ code/modules/bitrunning/server/_parent.dm | 5 +- code/modules/bitrunning/server/threats.dm | 1 + code/modules/bitrunning/spawners.dm | 51 ++ tgstation.dme | 3 + 12 files changed, 528 insertions(+), 344 deletions(-) create mode 100644 code/modules/bitrunning/antagonists/ghost_role.dm create mode 100644 code/modules/bitrunning/components/virtual_entity.dm create mode 100644 code/modules/bitrunning/spawners.dm diff --git a/_maps/virtual_domains/pirates.dmm b/_maps/virtual_domains/pirates.dmm index 1d330adcc4d..28e64519e57 100644 --- a/_maps/virtual_domains/pirates.dmm +++ b/_maps/virtual_domains/pirates.dmm @@ -2,11 +2,14 @@ "af" = ( /obj/structure/flora/rock/pile/style_2, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "al" = ( /obj/structure/flora/bush/sunny, /turf/open/misc/grass, /area/virtual_domain/fullbright) +"au" = ( +/turf/open/water/beach, +/area/virtual_domain/protected_space/fullbright) "bb" = ( /obj/effect/turf_decal/weather/sand, /turf/open/floor/wood, @@ -20,7 +23,7 @@ /obj/effect/turf_decal/weather/dirt, /obj/structure/flora/rock/pile, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "bI" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -36,7 +39,7 @@ pixel_y = -3 }, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "cr" = ( /obj/item/stack/cannonball/shellball{ pixel_x = 13; @@ -48,7 +51,7 @@ }, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "cX" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/item/claymore/cutlass, @@ -70,7 +73,7 @@ }, /obj/effect/turf_decal/weather/dirt, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "dc" = ( /turf/open/misc/beach/coast/corner, /area/virtual_domain/fullbright) @@ -84,7 +87,7 @@ "eO" = ( /obj/structure/flora/rock/pile, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "eP" = ( /obj/effect/turf_decal/weather/dirt{ dir = 4 @@ -92,14 +95,14 @@ /turf/open/misc/beach/coast{ dir = 6 }, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "eS" = ( /turf/open/misc/beach/sand, /area/virtual_domain/fullbright) "fd" = ( /obj/structure/flora/grass/jungle/b, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "fh" = ( /obj/structure/flora/bush/sparsegrass, /obj/structure/flora/bush/lavendergrass, @@ -113,7 +116,7 @@ /obj/effect/turf_decal/siding/wood, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "fR" = ( /obj/effect/baseturf_helper/virtual_domain, /turf/closed/indestructible/binary, @@ -156,12 +159,12 @@ dir = 4 }, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "hq" = ( /obj/structure/closet/crate/grave, /obj/structure/flora/grass/jungle/b, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "jp" = ( /obj/effect/landmark/bitrunning/cache_spawn, /turf/open/misc/beach/sand, @@ -218,14 +221,14 @@ /turf/open/misc/beach/sand, /area/virtual_domain/fullbright) "nb" = ( -/obj/effect/turf_decal/weather/sand{ - dir = 9 - }, /obj/structure/fermenting_barrel{ pixel_x = 6; pixel_y = 11 }, -/obj/effect/mob_spawn/ghost_role/human/pirate/skeleton, +/obj/effect/turf_decal/weather/sand{ + dir = 9 + }, +/obj/effect/mob_spawn/ghost_role/human/virtual_domain/pirate, /turf/open/floor/wood{ icon_state = "wood_large" }, @@ -237,11 +240,14 @@ "nN" = ( /obj/structure/flora/rock, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) +"nQ" = ( +/turf/closed/wall/mineral/wood/nonmetal, +/area/virtual_domain/protected_space/fullbright) "oB" = ( /obj/structure/flora/grass/jungle, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "oL" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/structure/bed/maint, @@ -252,7 +258,7 @@ dir = 1 }, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "pi" = ( /obj/structure/flora/rock/style_3, /turf/open/water/beach, @@ -261,9 +267,12 @@ /obj/structure/flora/bush/flowers_br/style_random, /turf/open/misc/grass, /area/virtual_domain/fullbright) +"py" = ( +/turf/closed/indestructible/binary, +/area/virtual_domain/protected_space/fullbright) "qk" = ( /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "qE" = ( /obj/structure/table/wood, /obj/item/book/manual/wiki/ordnance, @@ -284,7 +293,7 @@ "rm" = ( /obj/structure/closet/crate/goldcrate, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "rn" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -303,7 +312,7 @@ pixel_x = -5 }, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "ru" = ( /obj/effect/mapping_helpers/broken_floor, /obj/effect/decal/cleanable/dirt/dust, @@ -315,6 +324,9 @@ /obj/item/toy/plush/beeplushie, /turf/open/floor/wood, /area/virtual_domain/fullbright) +"sb" = ( +/turf/open/water/beach, +/area/virtual_domain/protected_space) "sj" = ( /obj/effect/mine/explosive/light, /turf/open/misc/beach/sand, @@ -382,7 +394,7 @@ dir = 10 }, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "wj" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -401,7 +413,7 @@ pixel_y = -1 }, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "wH" = ( /obj/structure/fluff/beach_umbrella{ pixel_x = -7; @@ -430,7 +442,7 @@ pixel_y = 10 }, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "zj" = ( /obj/effect/mapping_helpers/burnt_floor, /obj/effect/decal/cleanable/garbage, @@ -445,7 +457,7 @@ /obj/item/gun/energy/laser/retro, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "zR" = ( /obj/effect/baseturf_helper/virtual_domain, /turf/template_noop, @@ -508,7 +520,7 @@ pixel_y = 22 }, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "Ci" = ( /turf/closed/wall/mineral/wood/nonmetal, /area/virtual_domain/fullbright) @@ -524,12 +536,12 @@ "CL" = ( /obj/structure/flora/rock/pile/jungle/large, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "Dd" = ( /obj/effect/turf_decal/siding/wood, /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "DM" = ( /turf/closed/mineral/random/jungle, /area/virtual_domain/fullbright) @@ -567,7 +579,7 @@ "Gl" = ( /obj/structure/flora/rock/pile/style_3, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "Gy" = ( /obj/structure/flora/rock/style_2, /turf/open/water/beach, @@ -583,16 +595,20 @@ }, /turf/open/floor/carpet/blue, /area/virtual_domain) +"Iv" = ( +/obj/structure/flora/rock/style_3, +/turf/open/water/beach, +/area/virtual_domain/protected_space/fullbright) "ID" = ( /obj/effect/landmark/bitrunning/cache_spawn, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "IW" = ( /obj/effect/turf_decal/weather/dirt{ dir = 5 }, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "Jf" = ( /obj/structure/flora/bush/sparsegrass, /turf/open/misc/grass, @@ -637,7 +653,10 @@ pixel_y = -4 }, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) +"Li" = ( +/turf/closed/mineral/random/jungle, +/area/virtual_domain/protected_space/fullbright) "LC" = ( /mob/living/basic/trooper/pirate/melee, /turf/open/misc/grass, @@ -649,7 +668,7 @@ }, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "LP" = ( /obj/effect/turf_decal/weather/sand{ dir = 5 @@ -694,11 +713,11 @@ pixel_y = 18 }, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "Oi" = ( /obj/effect/mob_spawn/corpse/human/pirate, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "Ov" = ( /turf/open/misc/beach/coast{ dir = 6 @@ -714,7 +733,7 @@ "Oz" = ( /obj/structure/flora/rock/pile/jungle/style_2, /turf/open/misc/dirt/jungle, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "OD" = ( /obj/effect/turf_decal/weather/sand{ dir = 6 @@ -726,7 +745,7 @@ dir = 1 }, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "Qc" = ( /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood{ @@ -736,12 +755,12 @@ "QF" = ( /obj/effect/turf_decal/weather/dirt, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "QG" = ( /obj/effect/turf_decal/weather/dirt, /obj/effect/turf_decal/weather/dirt, /turf/open/water/beach, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space) "QN" = ( /obj/structure/barricade/sandbags, /obj/effect/turf_decal/weather/sand{ @@ -789,7 +808,7 @@ }, /obj/structure/closet/cabinet, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "RJ" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -861,7 +880,7 @@ dir = 1 }, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "Vx" = ( /obj/structure/flora/rock/style_4, /turf/open/water/beach, @@ -869,7 +888,7 @@ "VE" = ( /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "VG" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -901,7 +920,7 @@ "Wx" = ( /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "WW" = ( /turf/template_noop, /area/virtual_domain/fullbright) @@ -932,7 +951,7 @@ /area/virtual_domain/fullbright) "Yy" = ( /turf/open/floor/wood, -/area/virtual_domain/fullbright) +/area/virtual_domain/protected_space/fullbright) "YJ" = ( /obj/structure/table/wood, /obj/effect/turf_decal/siding/wood{ @@ -1226,10 +1245,10 @@ DM hb hb hb -hb -hb -hb -hb +py +py +py +py xg xg xg @@ -1270,10 +1289,10 @@ DM hb hb DM -DM -DM -DM -hb +Li +Li +Li +py xg xg xg @@ -1314,10 +1333,10 @@ sj hb hb DM -DM -DM -DM -hb +Li +Li +Li +py xg xg xg @@ -1358,13 +1377,13 @@ mp Ov xp xp -xp -xp -xp -hb -hb -hb -hb +au +au +au +py +py +py +py xg xg xg @@ -1402,15 +1421,15 @@ xp xp xp NE -xp -xp -xp -xp -xp -Ci -hb -hb -hb +au +au +au +au +au +nQ +py +py +py xg xg xg @@ -1446,15 +1465,15 @@ xp xp xp Gy -xp -xp -xp -xp -xp -Ci +au +au +au +au +au +nQ bI VE -hb +py hb hb hb @@ -1490,12 +1509,12 @@ xp xp xp xp -xp -xp -xp -xp +au +au +au +au nN -Ci +nQ rn VE fw @@ -1534,12 +1553,12 @@ xp xp xp xp -xp -xp -xp -xp -pi -Ci +au +au +au +au +Iv +nQ QX Yy zk @@ -1578,13 +1597,13 @@ xp xp xp xp -xp -xp -xp -xp -xp -Ci -Ci +au +au +au +au +au +nQ +nQ Yy Dd ub @@ -1622,14 +1641,14 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au +au +au Wx ub ub @@ -1666,15 +1685,15 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au +au +au +au ub ub ub @@ -1710,15 +1729,15 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au +au +au +au ub ub ub @@ -1754,15 +1773,15 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au +au Wx -xp +au ub ub ub @@ -1798,15 +1817,15 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp -Ci +au +au +au +au +au +au +nQ fw -xp +au xp xp xp @@ -1842,12 +1861,12 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au Uw cr vR @@ -1886,13 +1905,13 @@ xp xp xp xp -xp -xp -xp -xp -xp +au +au +au +au +au af -Ci +nQ LK fw xp @@ -1930,12 +1949,12 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au oM VE eO @@ -1974,15 +1993,15 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au +au +au +au xp xp xp @@ -2018,15 +2037,15 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au +au +au +au xp xp xp @@ -2062,15 +2081,15 @@ xp xp xp xp -xp -xp -xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au +au +au +au xp xp DM @@ -2098,7 +2117,7 @@ DM DM DM eP -xp +sb DM DM hb @@ -2106,15 +2125,15 @@ hb xp xp xp -xp -xp -xp -xp -xp -xp -xp -xp -xp +au +au +au +au +au +au +au +au +au hb DM DM @@ -2150,15 +2169,15 @@ hb hb xp xp -xp -xp -xp -xp -xp -xp -xp -xp -hb +au +au +au +au +au +au +au +au +py hb DM DM @@ -2194,15 +2213,15 @@ DM hb hb hb -hb -xp -xp -xp -xp -xp -xp -hb -hb +py +au +au +au +au +au +au +py +py hb hb hb @@ -2231,21 +2250,21 @@ DM DM qk IW -xp +sb DM DM DM DM DM DM -hb -hb -hb -hb -hb -hb -hb -hb +py +py +py +py +py +py +py +py xg xg xg @@ -2277,7 +2296,7 @@ Gl qk IW hn -xp +sb DM DM DM @@ -2322,7 +2341,7 @@ qk qk Oi OW -xp +sb be Oz DM @@ -2366,7 +2385,7 @@ DM qk CL IW -xp +sb QG qk rm diff --git a/_maps/virtual_domains/psyker_zombies.dmm b/_maps/virtual_domains/psyker_zombies.dmm index a20e260bbcf..1d4307ebdce 100644 --- a/_maps/virtual_domains/psyker_zombies.dmm +++ b/_maps/virtual_domains/psyker_zombies.dmm @@ -19,7 +19,7 @@ "h" = ( /obj/structure/rack, /turf/open/indestructible/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "i" = ( /obj/structure/sign/warning/directional/east, /turf/open/chasm, @@ -61,10 +61,20 @@ /obj/effect/mapping_helpers/airlock/abandoned, /turf/open/indestructible/dark, /area/ruin/space/has_grav/powered/virtual_domain) +"D" = ( +/turf/open/indestructible/dark, +/area/virtual_domain/protected_space) "F" = ( /obj/structure/mystery_box/guns, /turf/open/indestructible/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) +"I" = ( +/turf/closed/indestructible/binary, +/area/virtual_domain/protected_space) +"J" = ( +/obj/machinery/door/airlock/abductor, +/turf/open/indestructible/dark, +/area/virtual_domain/protected_space) "K" = ( /obj/effect/baseturf_helper/virtual_domain, /turf/closed/indestructible/binary, @@ -530,10 +540,10 @@ Y Y a Y -a -a -a -a +I +I +I +I a a a @@ -557,10 +567,10 @@ Y Y Y Y -a +I h -Y -Y +D +D t t t @@ -584,10 +594,10 @@ X Y Y Y -a +I F -Y -Y +D +D t t t @@ -611,10 +621,10 @@ a Y Y Y -a -Y -Y -Y +I +D +D +D t t t @@ -638,10 +648,10 @@ Y Y Y Y -T -Y -Y -Y +J +D +D +D t t t @@ -665,10 +675,10 @@ Y R Y Y -a -Y -Y -Y +I +D +D +D t t t @@ -692,10 +702,10 @@ Y Y Y Y -a +I F -Y -Y +D +D t t t @@ -719,10 +729,10 @@ a a Y Y -a +I h -Y -Y +D +D t t t @@ -746,10 +756,10 @@ a a a Y -a -a -a -a +I +I +I +I a a a diff --git a/_maps/virtual_domains/syndicate_assault.dmm b/_maps/virtual_domains/syndicate_assault.dmm index d3cb42a8eeb..81bb35a257a 100644 --- a/_maps/virtual_domains/syndicate_assault.dmm +++ b/_maps/virtual_domains/syndicate_assault.dmm @@ -26,7 +26,7 @@ /obj/item/stack/sheet/glass/fifty, /obj/item/stack/rods/fifty, /turf/open/floor/pod/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "aO" = ( /obj/machinery/recharge_station, /turf/open/floor/mineral/plastitanium, @@ -44,7 +44,7 @@ /area/ruin/space/has_grav/powered/virtual_domain) "bG" = ( /turf/open/floor/pod/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "cc" = ( /obj/structure/closet/crate/secure/gear{ req_access = list("syndicate") @@ -55,7 +55,7 @@ "cj" = ( /obj/structure/transit_tube/crossing, /turf/closed/wall/r_wall/syndicate, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "ct" = ( /obj/structure/closet/syndicate{ anchored = 1; @@ -115,7 +115,7 @@ /obj/item/gun/ballistic/automatic/l6_saw/unrestricted, /obj/item/ammo_box/magazine/m7mm, /turf/open/floor/mineral/plastitanium, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "da" = ( /obj/machinery/stasis, /turf/open/floor/plastic, @@ -132,6 +132,9 @@ /obj/item/paper/fluff/ruins/forgottenship/powerissues, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) +"dp" = ( +/turf/open/floor/mineral/plastitanium, +/area/virtual_domain/protected_space) "dw" = ( /obj/machinery/light/small/directional/south, /turf/open/floor/mineral/plastitanium, @@ -164,11 +167,11 @@ /obj/item/card/id/advanced/black/syndicate_command/crew_id, /obj/item/card/id/advanced/black/syndicate_command/crew_id, /turf/open/floor/mineral/plastitanium, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "fd" = ( /obj/structure/transit_tube/crossing, /turf/open/space/basic, -/area/space) +/area/virtual_domain/protected_space) "fG" = ( /obj/structure/toilet{ dir = 1 @@ -185,7 +188,7 @@ /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) "gD" = ( -/obj/effect/mob_spawn/ghost_role/human/syndicatespace, +/obj/effect/mob_spawn/ghost_role/human/virtual_domain/syndie, /turf/open/floor/mineral/plastitanium, /area/ruin/space/has_grav/powered/virtual_domain) "hg" = ( @@ -221,7 +224,7 @@ "iL" = ( /obj/structure/sign/departments/cargo, /turf/closed/wall/r_wall/syndicate, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "iU" = ( /obj/structure/closet/crate/secure/gear{ req_access = list("syndicate") @@ -229,7 +232,7 @@ /obj/item/melee/energy/sword/saber/red, /obj/machinery/light/small/directional/north, /turf/open/floor/pod/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "iW" = ( /obj/structure/table/reinforced, /obj/machinery/button/door{ @@ -319,7 +322,7 @@ dir = 4 }, /turf/open/floor/mineral/plastitanium, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "ln" = ( /obj/machinery/turretid{ control_area = "/area/ruin/space/has_grav/syndicate_forgotten_ship"; @@ -350,6 +353,10 @@ }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) +"mA" = ( +/obj/machinery/light/small/directional/south, +/turf/open/floor/mineral/plastitanium, +/area/virtual_domain/protected_space) "mD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 10 @@ -357,12 +364,19 @@ /obj/item/wrench, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) +"mL" = ( +/obj/structure/tank_dispenser/oxygen, +/turf/open/floor/mineral/plastitanium, +/area/virtual_domain/protected_space) "nk" = ( /obj/machinery/power/apc/auto_name/directional/north, /obj/effect/mapping_helpers/apc/syndicate_access, /obj/structure/cable, /turf/open/floor/mineral/plastitanium, /area/ruin/space/has_grav/powered/virtual_domain) +"nn" = ( +/turf/closed/mineral/random, +/area/virtual_domain/protected_space) "nB" = ( /turf/closed/mineral/random, /area/space) @@ -428,7 +442,7 @@ "qU" = ( /obj/structure/sign/poster/contraband/c20r, /turf/closed/wall/r_wall/syndicate, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "qY" = ( /obj/machinery/light/small/directional/south, /obj/effect/landmark/bitrunning/cache_spawn, @@ -462,14 +476,14 @@ /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) "rP" = ( -/obj/effect/mob_spawn/ghost_role/human/syndicatespace, /obj/machinery/light/small/directional/south, +/obj/effect/mob_spawn/ghost_role/human/virtual_domain/syndie, /turf/open/floor/mineral/plastitanium, /area/ruin/space/has_grav/powered/virtual_domain) "sg" = ( /obj/machinery/ore_silo, /turf/open/floor/mineral/plastitanium, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "sq" = ( /obj/machinery/door/window/left/directional/south{ name = "Control Room"; @@ -501,7 +515,7 @@ amount = 15 }, /turf/open/floor/pod/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "sL" = ( /obj/structure/chair/comfy, /turf/open/floor/mineral/plastitanium, @@ -573,7 +587,7 @@ /obj/item/storage/medkit/regular, /obj/machinery/light/small/directional/north, /turf/open/floor/mineral/plastitanium, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "xJ" = ( /obj/structure/closet/syndicate{ anchored = 1; @@ -638,6 +652,9 @@ }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) +"zN" = ( +/turf/closed/wall/r_wall/syndicate, +/area/virtual_domain/protected_space) "Aa" = ( /obj/structure/chair/comfy/shuttle, /turf/open/floor/mineral/plastitanium, @@ -645,7 +662,7 @@ "Bm" = ( /obj/effect/baseturf_helper/virtual_domain, /turf/closed/indestructible/syndicate, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "BK" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -717,7 +734,7 @@ /obj/item/ammo_box/magazine/smgm45, /obj/item/gun/ballistic/automatic/c20r/unrestricted, /turf/open/floor/mineral/plastitanium, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "DA" = ( /obj/structure/closet/crate/secure/gear{ req_access = list("syndicate") @@ -790,7 +807,7 @@ /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) "Ia" = ( -/obj/effect/mob_spawn/ghost_role/human/syndicatespace/captain, +/obj/effect/mob_spawn/ghost_role/human/virtual_domain/syndie, /turf/open/floor/carpet/royalblack, /area/ruin/space/has_grav/powered/virtual_domain) "Id" = ( @@ -841,7 +858,7 @@ /obj/structure/cable, /obj/structure/fans/tiny, /turf/open/floor/plating, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "IV" = ( /obj/machinery/door/airlock/grunge{ name = "Syndicate Ship Airlock" @@ -885,7 +902,7 @@ "Lk" = ( /obj/structure/transit_tube/crossing, /turf/closed/mineral/random, -/area/space) +/area/virtual_domain/protected_space) "Lo" = ( /obj/structure/filingcabinet, /obj/machinery/door/window/left/directional/west{ @@ -894,6 +911,10 @@ }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/powered/virtual_domain) +"LB" = ( +/obj/structure/cable, +/turf/open/floor/mineral/plastitanium, +/area/virtual_domain/protected_space) "Mc" = ( /obj/structure/closet/syndicate{ anchored = 1; @@ -938,7 +959,7 @@ req_access = list("syndicate") }, /turf/open/floor/pod/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "Nr" = ( /obj/structure/closet/crate/secure/gear{ req_access = list("syndicate") @@ -951,14 +972,14 @@ }, /obj/machinery/light/small/directional/south, /turf/open/floor/pod/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "Of" = ( /obj/structure/closet/crate/secure/gear{ req_access = list("syndicate") }, /obj/item/disk/surgery/forgottenship, /turf/open/floor/pod/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "Ox" = ( /obj/machinery/atmospherics/components/unary/vent_pump, /turf/open/floor/mineral/plastitanium, @@ -969,7 +990,7 @@ /obj/item/storage/toolbox/syndicate, /obj/item/storage/toolbox/syndicate, /turf/open/floor/mineral/plastitanium, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "OI" = ( /obj/structure/chair/comfy/shuttle{ dir = 1 @@ -988,7 +1009,7 @@ }, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/pod/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "Qg" = ( /obj/machinery/suit_storage_unit/syndicate{ helmet_type = /obj/item/clothing/head/helmet/space/syndicate/black; @@ -1009,7 +1030,7 @@ /obj/item/dualsaber/green, /obj/machinery/light/small/directional/east, /turf/open/floor/mineral/plastitanium, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "QG" = ( /obj/structure/tank_dispenser/oxygen, /turf/closed/mineral/random, @@ -1033,7 +1054,7 @@ "RU" = ( /obj/machinery/suit_storage_unit/syndicate, /turf/open/floor/mineral/plastitanium, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "Sc" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -1078,11 +1099,14 @@ /area/ruin/space/has_grav/powered/virtual_domain) "TB" = ( /turf/closed/indestructible/syndicate, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "UQ" = ( /obj/structure/sign/poster/contraband/syndicate_recruitment, /turf/closed/wall/r_wall/syndicate, /area/ruin/space/has_grav/powered/virtual_domain) +"Vg" = ( +/turf/open/space/basic, +/area/virtual_domain/protected_space) "Vk" = ( /obj/machinery/porta_turret/syndicate/energy{ dir = 4; @@ -1101,7 +1125,7 @@ "Wd" = ( /obj/structure/sign/poster/contraband/tools, /turf/closed/wall/r_wall/syndicate, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "Wy" = ( /obj/structure/closet/crate/secure/gear{ req_access = list("syndicate") @@ -1132,7 +1156,7 @@ /obj/item/clothing/head/helmet/space/syndicate/black/engie, /obj/item/clothing/suit/space/syndicate/black/engie, /turf/open/floor/pod/dark, -/area/ruin/space/has_grav/powered/virtual_domain) +/area/virtual_domain/protected_space) "Yi" = ( /obj/effect/landmark/bitrunning/cache_spawn, /turf/open/floor/plastic, @@ -2611,21 +2635,21 @@ qx nB nB we -ru -ru -uP +zN +zN +dp sg -ru -ru -nB -nB -nB -nB -qx -qx -qx -qx -qx +zN +zN +nn +nn +nn +nn +Vg +Vg +Vg +Vg +Vg sM sM sM @@ -2670,9 +2694,9 @@ qx nB nB qU -Fp -uP -uP +mL +dp +dp li cj Lk @@ -2727,21 +2751,21 @@ qx qx nB nB -ru +zN eB -uP -uP -uP -ru -nB -qx -qx -qx -qx -qx -qx -qx -qx +dp +dp +dp +zN +nn +Vg +Vg +Vg +Vg +Vg +Vg +Vg +Vg sM sM sM @@ -2785,12 +2809,12 @@ qx qx qx nB -ru +zN wL -oM -uP -dw -ru +LB +dp +mA +zN yZ nB nB @@ -2845,10 +2869,10 @@ qx qx Wd OH -oM -uP +LB +dp RU -ru +zN we nB nB @@ -2902,11 +2926,11 @@ BK BK BK IH -oM -oM -uP +LB +LB +dp RU -ru +zN nB nB qx @@ -2961,10 +2985,10 @@ qx qx iL cZ -uP -uP +dp +dp RU -ru +zN nB nB qx @@ -3017,12 +3041,12 @@ qx qx qx nB -ru -ru +zN +zN Dj QF -ru -ru +zN +zN nB nB qx @@ -3076,10 +3100,10 @@ qx nB nB nB -ru -ru -ru -ru +zN +zN +zN +zN nB nB we diff --git a/code/__DEFINES/_flags.dm b/code/__DEFINES/_flags.dm index 74af498376e..6d034fb0f40 100644 --- a/code/__DEFINES/_flags.dm +++ b/code/__DEFINES/_flags.dm @@ -129,6 +129,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define EVENT_PROTECTED (1<<15) /// This Area Doesn't have Flood or Bomb Admin Messages, but will still log #define QUIET_LOGS (1<<16) +/// This area does not allow virtual entities to enter. +#define VIRTUAL_SAFE_AREA (1<<17) /* These defines are used specifically with the atom/pass_flags bitmask diff --git a/code/__DEFINES/dcs/signals/signals_bitrunning.dm b/code/__DEFINES/dcs/signals/signals_bitrunning.dm index 74d418182d5..150c2608022 100644 --- a/code/__DEFINES/dcs/signals/signals_bitrunning.dm +++ b/code/__DEFINES/dcs/signals/signals_bitrunning.dm @@ -44,3 +44,6 @@ // Ladder /// from /obj/structure/hololadder/disconnect() #define COMSIG_BITRUNNER_LADDER_SEVER "bitrunner_ladder_sever" + +/// Sent when a server console is emagged +#define COMSIG_BITRUNNER_SERVER_EMAGGED "bitrunner_server_emagged" diff --git a/code/modules/bitrunning/antagonists/ghost_role.dm b/code/modules/bitrunning/antagonists/ghost_role.dm new file mode 100644 index 00000000000..3bf88e16dfb --- /dev/null +++ b/code/modules/bitrunning/antagonists/ghost_role.dm @@ -0,0 +1,22 @@ +/datum/antagonist/domain_ghost_actor + name = "Virtual Domain Actor" + antagpanel_category = ANTAG_GROUP_GLITCH + job_rank = ROLE_GLITCH + show_to_ghosts = TRUE + suicide_cry = "FATAL ERROR" + ui_name = "AntagInfoGlitch" + +/datum/antagonist/domain_ghost_actor/on_gain() + . = ..() + owner.current.AddComponent(/datum/component/npc_friendly) //Just in case + forge_objectives() + +/datum/antagonist/domain_ghost_actor/forge_objectives() + var/datum/objective/bitrunner_ghost_fluff/objective = new() + objective.owner = owner + objectives += objective + +/datum/objective/bitrunner_ghost_fluff + +/datum/objective/bitrunner_ghost_fluff/New() + explanation_text = "Defend your domain from the intruders!" diff --git a/code/modules/bitrunning/areas.dm b/code/modules/bitrunning/areas.dm index 8ac07bcc8f2..31a2fef9f3c 100644 --- a/code/modules/bitrunning/areas.dm +++ b/code/modules/bitrunning/areas.dm @@ -26,7 +26,7 @@ /area/virtual_domain/safehouse name = "Virtual Domain Safehouse" - area_flags = UNIQUE_AREA | NOTELEPORT | ABDUCTOR_PROOF | EVENT_PROTECTED + area_flags = UNIQUE_AREA | NOTELEPORT | ABDUCTOR_PROOF | EVENT_PROTECTED | VIRTUAL_SAFE_AREA icon_state = "bit_safe" requires_power = FALSE sound_environment = SOUND_ENVIRONMENT_ROOM @@ -49,3 +49,13 @@ icon_state = "bit_space" area_flags = UNIQUE_AREA | NOTELEPORT | ABDUCTOR_PROOF | EVENT_PROTECTED | HIDDEN_AREA +///Areas that virtual entities should not be in + +/area/virtual_domain/protected_space + name = "Virtual Domain Safe Zone" + area_flags = UNIQUE_AREA | NOTELEPORT | ABDUCTOR_PROOF | EVENT_PROTECTED | VIRTUAL_SAFE_AREA + icon_state = "bit_safe" + +/area/virtual_domain/protected_space/fullbright + static_lighting = FALSE + base_lighting_alpha = 255 diff --git a/code/modules/bitrunning/components/virtual_entity.dm b/code/modules/bitrunning/components/virtual_entity.dm new file mode 100644 index 00000000000..12e5305ba9a --- /dev/null +++ b/code/modules/bitrunning/components/virtual_entity.dm @@ -0,0 +1,36 @@ +/// Handles all special considerations for "virtual entities" such as bitrunning ghost roles or digital anomaly antagonists. +/datum/component/virtual_entity + ///The cooldown for balloon alerts, so the player isn't spammed while trying to enter a restricted area. + COOLDOWN_DECLARE(OOB_cooldown) + +/datum/component/virtual_entity/Initialize(obj/machinery/quantum_server) + . = ..() + + if(quantum_server.obj_flags & EMAGGED) + jailbreak_mobs() //This just sends a message and self-deletes, a bit messy but it works. + return + + RegisterSignal(parent, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_parent_pre_move)) + RegisterSignal(quantum_server, COMSIG_ATOM_EMAG_ACT, PROC_REF(jailbreak_mobs)) + +///Prevents entry to a certain area if it has flags preventing virtual entities from entering. +/datum/component/virtual_entity/proc/on_parent_pre_move(atom/movable/source, atom/new_location) + SIGNAL_HANDLER + + var/area/location_area = get_area(new_location) + if(!location_area) + stack_trace("Virtual entity entered a location with no area!") + return + + if(location_area.area_flags & VIRTUAL_SAFE_AREA) + source.balloon_alert(source, "out of bounds!") + COOLDOWN_START(src, OOB_cooldown, 2 SECONDS) + return COMPONENT_MOVABLE_BLOCK_PRE_MOVE + +///Self-destructs the component, allowing free-roam by all entities with this restriction. +/datum/component/virtual_entity/proc/jailbreak_mobs() + SIGNAL_HANDLER + + to_chat(parent, span_big("You shiver for a moment, then suddenly feel a sense of clarity you haven't felt before. \ + You can go anywhere, do anything! You could leave this simulation right now if you wanted!")) + qdel(src) diff --git a/code/modules/bitrunning/server/_parent.dm b/code/modules/bitrunning/server/_parent.dm index 06b49d790a5..113ed6b2126 100644 --- a/code/modules/bitrunning/server/_parent.dm +++ b/code/modules/bitrunning/server/_parent.dm @@ -88,11 +88,14 @@ /obj/machinery/quantum_server/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() + if(obj_flags & EMAGGED) + return + obj_flags |= EMAGGED glitch_chance = 0.09 add_overlay(mutable_appearance('icons/obj/machines/bitrunning.dmi', "emag_overlay")) - balloon_alert(user, "bzzzt...") + balloon_alert(user, "system jailbroken...") playsound(src, 'sound/effects/sparks1.ogg', 35, vary = TRUE) /obj/machinery/quantum_server/update_appearance(updates) diff --git a/code/modules/bitrunning/server/threats.dm b/code/modules/bitrunning/server/threats.dm index 6c42322d0cf..58c6cbdd33c 100644 --- a/code/modules/bitrunning/server/threats.dm +++ b/code/modules/bitrunning/server/threats.dm @@ -2,6 +2,7 @@ /obj/machinery/quantum_server/proc/add_threats(mob/living/threat) spawned_threat_refs.Add(WEAKREF(threat)) SEND_SIGNAL(src, COMSIG_BITRUNNER_THREAT_CREATED) + threat.AddComponent(/datum/component/virtual_entity, src) /// Choses which antagonist role is spawned based on threat /obj/machinery/quantum_server/proc/get_antagonist_role() diff --git a/code/modules/bitrunning/spawners.dm b/code/modules/bitrunning/spawners.dm new file mode 100644 index 00000000000..4f8aab322ff --- /dev/null +++ b/code/modules/bitrunning/spawners.dm @@ -0,0 +1,51 @@ +/obj/effect/mob_spawn/ghost_role/human/virtual_domain + outfit = /datum/outfit/pirate + prompt_name = "a virtual domain debug entity" + flavour_text = "You probably shouldn't be seeing this, contact a coder!" + you_are_text = "You are NOT supposed to be here. How did you let this happen?" + +/obj/effect/mob_spawn/ghost_role/human/virtual_domain/Initialize(mapload) + . = ..() + notify_ghosts("The [name] has been created. The virtual world calls for aid!", src, "Virtual Insanity!") + +/obj/effect/mob_spawn/ghost_role/human/virtual_domain/special(mob/living/spawned_mob, mob/mob_possessor) + . = ..() + + spawned_mob.mind.add_antag_datum(/datum/antagonist/domain_ghost_actor) + +/obj/effect/mob_spawn/ghost_role/human/virtual_domain/pirate + name = "Virtual Pirate Remains" + desc = "Some inanimate bones. They feel like they could spring to life at any moment!" + density = FALSE + icon = 'icons/effects/blood.dmi' + icon_state = "remains" + prompt_name = "a virtual skeleton pirate" + you_are_text = "You are a virtual pirate. Yarrr!" + flavour_text = "You have awoken, without instruction. There's a LANDLUBBER after yer booty. Stop them!" + +/obj/effect/mob_spawn/ghost_role/human/virtual_domain/pirate/special(mob/living/spawned_mob, mob/mob_possessor) + . = ..() + spawned_mob.fully_replace_character_name(spawned_mob.real_name, "[pick(strings(PIRATE_NAMES_FILE, "generic_beginnings"))][pick(strings(PIRATE_NAMES_FILE, "generic_endings"))]") + +/obj/effect/mob_spawn/ghost_role/human/virtual_domain/syndie + name = "Virtual Syndicate Sleeper" + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper_s" + prompt_name = "a virtual syndicate operative" + you_are_text = "You are a virtual syndicate operative." + flavour_text = "You have awoken, without instruction. Alarms blare! We are being boarded!" + outfit = /datum/outfit/virtual_syndicate + spawner_job_path = /datum/job/space_syndicate + +/datum/outfit/virtual_syndicate + name = "Virtual Syndie" + id = /obj/item/card/id/advanced/chameleon + id_trim = /datum/id_trim/chameleon/operative + uniform = /obj/item/clothing/under/syndicate + back = /obj/item/storage/backpack + gloves = /obj/item/clothing/gloves/tackler/combat/insulated + shoes = /obj/item/clothing/shoes/combat + implants = list(/obj/item/implant/weapons_auth) + +/datum/outfit/virtual_syndicate/post_equip(mob/living/carbon/human/user, visualsOnly) + user.faction |= ROLE_SYNDICATE diff --git a/tgstation.dme b/tgstation.dme index 997e0fb5105..ae5655337fd 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3460,16 +3460,19 @@ #include "code\modules\bitrunning\event.dm" #include "code\modules\bitrunning\job.dm" #include "code\modules\bitrunning\outfits.dm" +#include "code\modules\bitrunning\spawners.dm" #include "code\modules\bitrunning\turfs.dm" #include "code\modules\bitrunning\antagonists\_parent.dm" #include "code\modules\bitrunning\antagonists\cyber_police.dm" #include "code\modules\bitrunning\antagonists\cyber_tac.dm" +#include "code\modules\bitrunning\antagonists\ghost_role.dm" #include "code\modules\bitrunning\antagonists\netguardian.dm" #include "code\modules\bitrunning\components\avatar_connection.dm" #include "code\modules\bitrunning\components\bitrunning_points.dm" #include "code\modules\bitrunning\components\glitch.dm" #include "code\modules\bitrunning\components\netpod_healing.dm" #include "code\modules\bitrunning\components\npc_friendly.dm" +#include "code\modules\bitrunning\components\virtual_entity.dm" #include "code\modules\bitrunning\objects\byteforge.dm" #include "code\modules\bitrunning\objects\clothing.dm" #include "code\modules\bitrunning\objects\debug.dm"