diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/mistake_inevitable.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/mistake_inevitable.dmm
index 1deee17aee2e..091c1b2f53b1 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/mistake_inevitable.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/mistake_inevitable.dmm
@@ -197,8 +197,8 @@
/turf/open/floor/engine,
/area/ruin/syndicate_lava_base/testlab)
"rX" = (
-/obj/machinery/atmospherics/components/unary/passive_vent,
/obj/structure/lattice/catwalk,
+/obj/machinery/atmospherics/components/unary/outlet_injector/on,
/turf/template_noop,
/area/ruin/syndicate_lava_base/testlab)
"sa" = (
diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm
index 81e6e4e6245b..9771c0342e11 100644
--- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm
+++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm
@@ -4847,10 +4847,13 @@
/area/ruin/space/ancientstation/beta/medbay)
"ui" = (
/obj/effect/decal/cleanable/shreds,
-/obj/structure/alien/weeds,
/obj/structure/closet/crate/secure/science{
req_access = list("away_science")
},
+/obj/item/encryptionkey/headset_uncommon,
+/obj/item/encryptionkey/headset_uncommon,
+/obj/item/encryptionkey/headset_uncommon,
+/obj/structure/alien/weeds,
/obj/item/transfer_valve,
/obj/item/raw_anomaly_core/bluespace,
/obj/item/raw_anomaly_core/random,
@@ -8624,13 +8627,13 @@
/turf/open/floor/iron/solarpanel/airless,
/area/ruin/space/solars/ancientstation/charlie/solars)
"Uh" = (
-/obj/machinery/power/supermatter_crystal/shard,
/obj/structure/closet/crate/engineering{
name = "supermatter shard crate";
secure = 1;
locked = 1;
icon_state = "engi_secure_crate"
},
+/obj/machinery/power/supermatter_crystal/shard/oldstation,
/turf/open/floor/iron/white/textured,
/area/ruin/space/ancientstation/delta/proto)
"Uj" = (
diff --git a/_maps/map_files/Blueshift/Blueshift.dmm b/_maps/map_files/Blueshift/Blueshift.dmm
index 12e55043d40d..96658451b2c6 100644
--- a/_maps/map_files/Blueshift/Blueshift.dmm
+++ b/_maps/map_files/Blueshift/Blueshift.dmm
@@ -4701,6 +4701,10 @@
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
+"aWw" = (
+/obj/structure/fans/tiny,
+/turf/open/floor/plating,
+/area/station/hallway/secondary/entry)
"aWA" = (
/obj/structure/cable,
/obj/effect/landmark/start/hangover,
@@ -52113,9 +52117,6 @@
/obj/effect/turf_decal/trimline/red/line{
dir = 8
},
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
/turf/open/floor/iron/dark/textured,
/area/station/ai_monitored/security/armory)
"kdO" = (
@@ -55522,6 +55523,7 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 8
},
+/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"kKp" = (
@@ -170234,7 +170236,7 @@ ahn
cXo
cXo
rMe
-ivx
+aWw
rMe
gLc
gLc
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 82cec3c519f6..8be6a9fced01 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -26105,15 +26105,6 @@
pixel_x = 3;
pixel_y = -3
},
-/obj/item/gun/energy/taser{
- pixel_y = 3;
- pixel_x = -3
- },
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser{
- pixel_y = -3;
- pixel_x = 3
- },
/turf/open/floor/iron/dark,
/area/station/ai_monitored/security/armory)
"iuJ" = (
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index ef6c57926b9b..d1615ee5cb8e 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -48942,9 +48942,6 @@
},
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/security/armory)
"lzH" = (
diff --git a/_maps/map_files/Graveyard/Graveyard.dmm b/_maps/map_files/Graveyard/Graveyard.dmm
index 5d56e33ab206..3ddc9961a7bf 100644
--- a/_maps/map_files/Graveyard/Graveyard.dmm
+++ b/_maps/map_files/Graveyard/Graveyard.dmm
@@ -32366,9 +32366,6 @@
/obj/item/gun/ballistic/automatic/pistol/paco/no_mag{
pixel_y = 6
},
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
/obj/effect/turf_decal/tile/dark_red/half{
dir = 1
},
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index fbd64deb4e24..73d3fce608a4 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -8895,9 +8895,6 @@
/obj/item/gun/ballistic/automatic/pistol/paco/no_mag{
pixel_y = 0
},
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
/turf/open/floor/iron/dark/textured,
/area/station/ai_monitored/security/armory/upper)
"cIH" = (
diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm
index 4d310a600bef..2905e94873ef 100644
--- a/_maps/map_files/KiloStation/KiloStation.dmm
+++ b/_maps/map_files/KiloStation/KiloStation.dmm
@@ -15352,9 +15352,6 @@
/obj/structure/window/reinforced/spawner/directional/south,
/obj/structure/window/reinforced/spawner/directional/west,
/obj/effect/turf_decal/tile/neutral/anticorner/contrasted,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
/turf/open/floor/iron/dark/textured_large,
/area/station/ai_monitored/security/armory)
"eRh" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 75b2cdf82042..427bd05d6564 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -33406,9 +33406,6 @@
/obj/item/gun/ballistic/automatic/pistol/paco/no_mag{
pixel_y = 6
},
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/security/armory)
"lFo" = (
diff --git a/_maps/map_files/Ouroboros/Ouroboros.dmm b/_maps/map_files/Ouroboros/Ouroboros.dmm
index fd7f4d0f0e21..593c6d5967e5 100644
--- a/_maps/map_files/Ouroboros/Ouroboros.dmm
+++ b/_maps/map_files/Ouroboros/Ouroboros.dmm
@@ -28538,9 +28538,6 @@
c_tag = "Security - Armory"
},
/obj/effect/spawner/random/armory/disablers,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
/turf/open/floor/engine,
/area/station/ai_monitored/security/armory)
"ixo" = (
diff --git a/_maps/map_files/Theseus/Theseus.dmm b/_maps/map_files/Theseus/Theseus.dmm
index a8b4e408725a..dad22ba8ccd3 100644
--- a/_maps/map_files/Theseus/Theseus.dmm
+++ b/_maps/map_files/Theseus/Theseus.dmm
@@ -4443,6 +4443,15 @@
},
/turf/open/floor/iron/dark,
/area/station/security/range)
+"bqW" = (
+/obj/effect/turf_decal/tile/neutral/full,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/closet/emcloset,
+/turf/open/floor/iron,
+/area/station/security/processing)
"brm" = (
/obj/machinery/chem_master/condimaster{
name = "CondiMaster Neo"
@@ -9450,7 +9459,6 @@
/obj/machinery/door/airlock/external{
name = "Gulag Shuttle Airlock"
},
-/obj/effect/mapping_helpers/airlock/access/all/security/brig,
/turf/open/floor/plating,
/area/station/security/processing)
"cQj" = (
@@ -19743,10 +19751,6 @@
/turf/open/floor/iron,
/area/station/construction)
"fVH" = (
-/obj/machinery/computer/prisoner/gulag_teleporter_computer{
- dir = 8
- },
-/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 4
},
@@ -19756,6 +19760,9 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
+/obj/machinery/gulag_teleporter,
+/obj/effect/turf_decal/bot,
+/obj/machinery/light/directional/east,
/turf/open/floor/iron,
/area/station/security/processing)
"fVQ" = (
@@ -21898,21 +21905,16 @@
/turf/open/floor/iron/dark,
/area/station/security/warden)
"gFe" = (
-/obj/machinery/gulag_teleporter,
-/obj/effect/turf_decal/bot,
-/obj/machinery/gulag_item_reclaimer{
- pixel_x = 31
- },
-/obj/effect/turf_decal/trimline/red/filled/line{
- dir = 4
- },
/obj/effect/turf_decal/tile/neutral/half{
dir = 8
},
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/obj/machinery/light/directional/east,
+/obj/effect/turf_decal/trimline/red/filled/corner,
+/obj/effect/turf_decal/trimline/red/filled/corner{
+ dir = 4
+ },
/turf/open/floor/iron,
/area/station/security/processing)
"gFf" = (
@@ -33984,6 +33986,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/effect/spawner/xmastree,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
"kgT" = (
@@ -42128,13 +42131,15 @@
/turf/closed/wall,
/area/station/commons/fitness/recreation/entertainment)
"mxA" = (
-/obj/structure/closet/emcloset,
-/obj/effect/turf_decal/delivery,
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 6
},
/obj/machinery/power/apc/auto_name/directional/east,
/obj/structure/cable,
+/obj/machinery/computer/prisoner/gulag_teleporter_computer{
+ dir = 8
+ },
+/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/station/security/processing)
"mxD" = (
@@ -55293,12 +55298,13 @@
/area/station/hallway/primary/central/fore)
"qtB" = (
/obj/structure/table,
-/obj/item/knife{
+/obj/item/knife/kitchen{
pixel_x = -1;
pixel_y = 5
},
-/obj/item/knife{
- pixel_x = -10
+/obj/item/knife/kitchen{
+ pixel_x = -10;
+ pixel_y = 0
},
/obj/item/reagent_containers/cup/rag{
pixel_y = 5;
@@ -58457,6 +58463,17 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/plating,
/area/station/maintenance/starboard/central)
+"roL" = (
+/obj/machinery/door/airlock/security,
+/obj/effect/mapping_helpers/airlock/access/all/security/brig,
+/obj/effect/mapping_helpers/airlock/unres{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/red/filled/end{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/maintenance/port/fore)
"rpb" = (
/turf/open/floor/engine/plasma,
/area/station/engineering/atmos)
@@ -67254,7 +67271,6 @@
/turf/open/floor/carpet,
/area/station/hallway/secondary/exit/departure_lounge)
"tQX" = (
-/obj/item/kirbyplants/random,
/obj/effect/turf_decal/stripes/line{
dir = 5
},
@@ -67263,6 +67279,10 @@
},
/obj/structure/cable,
/obj/machinery/camera/directional/east,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/gulag_item_reclaimer{
+ pixel_x = 31
+ },
/turf/open/floor/iron,
/area/station/security/processing)
"tQY" = (
@@ -77835,7 +77855,6 @@
/obj/machinery/door/airlock/external{
name = "Gulag Shuttle Airlock"
},
-/obj/effect/mapping_helpers/airlock/access/all/security/brig,
/obj/machinery/light/floor/has_bulb,
/turf/open/floor/plating,
/area/station/security/processing)
@@ -109295,7 +109314,7 @@ fTB
ctl
fTB
rtt
-cze
+bqW
mBO
gxT
xhM
@@ -110066,7 +110085,7 @@ ijL
ijL
ijL
ijL
-ijL
+roL
ijL
ijL
xhM
diff --git a/_maps/map_files/Voidraptor/VoidRaptor.dmm b/_maps/map_files/Voidraptor/VoidRaptor.dmm
index dbae07341eae..167607ecb8c0 100644
--- a/_maps/map_files/Voidraptor/VoidRaptor.dmm
+++ b/_maps/map_files/Voidraptor/VoidRaptor.dmm
@@ -27190,9 +27190,6 @@
dir = 8
},
/obj/effect/turf_decal/delivery,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
/turf/open/floor/iron/dark/textured_large,
/area/station/ai_monitored/security/armory)
"hPi" = (
diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm
index d733578cad42..bbd27a42418e 100644
--- a/_maps/map_files/generic/CentCom.dmm
+++ b/_maps/map_files/generic/CentCom.dmm
@@ -19367,6 +19367,11 @@
},
/turf/open/floor/carpet/red,
/area/cruiser_dock)
+"bhS" = (
+/obj/structure/table/wood,
+/obj/machinery/microwave,
+/turf/open/floor/iron/vaporwave,
+/area/centcom/central_command_areas/adminroom)
"bip" = (
/obj/effect/spawner/random/vending/snackvend,
/obj/effect/turf_decal/bot_white,
@@ -19542,6 +19547,12 @@
},
/turf/open/water/arena,
/area/centcom/central_command_areas/admin)
+"bxX" = (
+/obj/effect/spawner/random/trash/hobo_squat,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"bys" = (
/obj/structure/sign/departments/chemistry/alt/directional/east,
/obj/effect/turf_decal/tile/orange/half/contrasted{
@@ -19738,6 +19749,20 @@
},
/turf/open/floor/iron/dark,
/area/centcom/central_command_areas/hall)
+"bYc" = (
+/obj/effect/turf_decal/siding/white{
+ dir = 5
+ },
+/obj/effect/spawner/random/trash/caution_sign,
+/turf/open/floor/grass,
+/area/centcom/central_command_areas/admin)
+"bYp" = (
+/obj/effect/turf_decal/siding/white{
+ dir = 1
+ },
+/obj/effect/spawner/random/trash/caution_sign,
+/turf/open/floor/grass,
+/area/centcom/central_command_areas/admin)
"bYA" = (
/obj/machinery/light/neon_lining{
dir = 1;
@@ -20170,6 +20195,11 @@
},
/turf/open/floor/iron/white/textured,
/area/centcom/central_command_areas/admin)
+"cYr" = (
+/obj/structure/bonfire/prelit,
+/obj/effect/spawner/random/trash/cigbutt,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"dbJ" = (
/obj/machinery/door/airlock/centcom{
name = "Veth's Plantery"
@@ -20686,6 +20716,13 @@
"exa" = (
/turf/open/floor/sandy_dirt,
/area/centcom/central_command_areas/admin)
+"exj" = (
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/iron/vaporwave,
+/area/centcom/central_command_areas/adminroom)
"exk" = (
/obj/structure/chair/office/light{
dir = 1
@@ -21732,6 +21769,25 @@
/obj/item/clothing/under/costume/gondola,
/turf/open/floor/eighties/red,
/area/centcom/central_command_areas/admin)
+"gUv" = (
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/graffiti,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
+"gWc" = (
+/obj/effect/turf_decal/caution/red{
+ pixel_y = -15
+ },
+/obj/effect/turf_decal/caution/red,
+/obj/effect/turf_decal/caution/red{
+ pixel_y = -8
+ },
+/turf/open/floor/iron/dark/smooth_large,
+/area/centcom/central_command_areas/admin)
"gXp" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -22224,6 +22280,13 @@
dir = 8
},
/area/centcom/central_command_areas/adminroom)
+"hPF" = (
+/obj/effect/turf_decal/siding/white{
+ dir = 9
+ },
+/obj/effect/spawner/random/trash/caution_sign,
+/turf/open/floor/grass,
+/area/centcom/central_command_areas/admin)
"hQH" = (
/obj/effect/turf_decal/plaque{
icon_state = "L13"
@@ -23029,6 +23092,13 @@
/obj/structure/fake_stairs/wood/directional/north,
/turf/open/misc/dirt/station,
/area/centcom/central_command_areas/retirement_yard)
+"jUo" = (
+/obj/machinery/computer/camera_advanced{
+ dir = 8
+ },
+/obj/effect/spawner/random/trash/cigbutt,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"jUG" = (
/mob/living/basic/xenofauna/meatbeast,
/turf/open/floor/material/meat,
@@ -23351,6 +23421,10 @@
/obj/machinery/light/directional/north,
/turf/open/water/arena,
/area/centcom/central_command_areas/admin)
+"kSK" = (
+/obj/structure/mineral_door/wood,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"kSU" = (
/obj/structure/mineral_door/wood{
color = "543e27";
@@ -23773,6 +23847,12 @@
},
/turf/open/floor/wood/large,
/area/centcom/central_command_areas/adminroom)
+"msE" = (
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"mvd" = (
/obj/effect/decal/cleanable/blood/gibs/limb{
dir = 8;
@@ -24164,6 +24244,12 @@
/obj/machinery/scanner_gate,
/turf/open/floor/sandy_dirt,
/area/centcom/central_command_areas/admin)
+"nGN" = (
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/iron/vaporwave,
+/area/centcom/central_command_areas/adminroom)
"nHl" = (
/obj/structure/flora/grass/jungle/b/style_2,
/turf/open/misc/dirt/station,
@@ -24473,6 +24559,10 @@
},
/turf/open/floor/iron/dark,
/area/centcom/central_command_areas/admin)
+"oBb" = (
+/obj/structure/barricade/wooden/crude,
+/turf/closed/indestructible/fakeglass,
+/area/centcom/central_command_areas/adminroom)
"oBm" = (
/obj/effect/turf_decal/trimline/dark_blue/line{
dir = 4
@@ -24759,6 +24849,13 @@
/obj/structure/mop_bucket,
/turf/open/floor/iron/dark/textured_large,
/area/cruiser_dock)
+"ptP" = (
+/obj/machinery/computer/communications/syndicate{
+ dir = 8
+ },
+/obj/effect/spawner/random/trash/cigbutt,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"pvq" = (
/obj/machinery/biomass_recycler,
/obj/item/stack/biomass,
@@ -25342,6 +25439,13 @@
},
/turf/open/misc/sandy_dirt,
/area/centcom/central_command_areas/admin)
+"qNR" = (
+/obj/structure/chair/comfy/teal{
+ dir = 4
+ },
+/obj/effect/spawner/random/trash/cigbutt,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"qOJ" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 1
@@ -25972,6 +26076,10 @@
},
/turf/open/floor/carpet/neon/simple/green/nodots,
/area/centcom/central_command_areas/admin)
+"sHS" = (
+/obj/structure/bed/maint,
+/turf/open/floor/iron/vaporwave,
+/area/centcom/central_command_areas/adminroom)
"sIk" = (
/obj/machinery/light/floor/has_bulb,
/obj/structure/window/reinforced/spawner/directional/west{
@@ -26029,6 +26137,12 @@
},
/turf/open/floor/carpet/orange,
/area/centcom/central_command_areas/admin)
+"sRa" = (
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/iron/vaporwave,
+/area/centcom/central_command_areas/adminroom)
"sRv" = (
/obj/effect/turf_decal/box/corners{
dir = 1
@@ -26036,6 +26150,11 @@
/obj/structure/shipping_container/vitezstvi,
/turf/open/floor/iron/dark/textured_large,
/area/cruiser_dock)
+"sSL" = (
+/obj/structure/barricade/wooden/crude,
+/obj/effect/spawner/random/trash/cigbutt,
+/turf/closed/indestructible/fakeglass,
+/area/centcom/central_command_areas/adminroom)
"sTV" = (
/obj/effect/turf_decal/tile/purple/half/contrasted{
dir = 4
@@ -26688,6 +26807,14 @@
},
/turf/open/floor/glass/plasma,
/area/centcom/central_command_areas/adminroom)
+"uFf" = (
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/mess,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"uGL" = (
/obj/structure/reagent_dispensers/water_cooler,
/obj/effect/turf_decal/bot_white,
@@ -26696,6 +26823,13 @@
},
/turf/open/floor/iron/dark/textured_large,
/area/cruiser_dock)
+"uHB" = (
+/obj/structure/table/wood,
+/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{
+ dir = 4
+ },
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"uIG" = (
/obj/machinery/door/airlock/centcom{
name = "NT Helpdesk"
@@ -26740,6 +26874,12 @@
/obj/effect/mapping_helpers/airlock/access/any/admin/captain,
/turf/open/floor/iron/dark/smooth_large,
/area/centcom/central_command_areas/admin)
+"uPO" = (
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/iron/vaporwave,
+/area/centcom/central_command_areas/adminroom)
"uPS" = (
/obj/effect/turf_decal/siding/dark_green{
dir = 8
@@ -26751,6 +26891,12 @@
/obj/machinery/light/dim/directional/south,
/turf/open/floor/wood/tile,
/area/centcom/central_command_areas/admin)
+"uRb" = (
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/graffiti,
+/obj/effect/spawner/random/trash/cigbutt,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"uSs" = (
/obj/structure/statue/sandstone/venus{
dir = 1;
@@ -27079,6 +27225,16 @@
"vFm" = (
/turf/open/floor/mineral/titanium/purple,
/area/centcom/central_command_areas/adminroom)
+"vFv" = (
+/obj/structure/closet/secure_closet/freezer/fridge,
+/obj/item/food/meat/slab/human,
+/obj/item/food/meat/slab/human,
+/obj/item/food/meat/slab/human,
+/obj/item/food/meat/slab/human,
+/obj/item/food/meat/slab/human,
+/obj/effect/spawner/random/trash/graffiti,
+/turf/open/floor/iron/vaporwave,
+/area/centcom/central_command_areas/adminroom)
"vFK" = (
/obj/structure/window/reinforced/spawner/directional/south,
/obj/machinery/chem_heater/debug,
@@ -27318,11 +27474,23 @@
},
/turf/open/floor/iron/dark/herringbone,
/area/centcom/central_command_areas/evacuation)
+"wdA" = (
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"wel" = (
/obj/effect/turf_decal/stripes/line,
/obj/structure/flora/bush/pale/style_3,
/turf/open/misc/dirt/station,
/area/centcom/central_command_areas/admin)
+"wfx" = (
+/obj/structure/barricade/wooden/crude,
+/obj/structure/curtain/cloth,
+/turf/closed/indestructible/fakeglass,
+/area/centcom/central_command_areas/adminroom)
"wge" = (
/obj/effect/turf_decal/siding/wood{
dir = 4
@@ -27660,6 +27828,11 @@
dir = 8
},
/area/cruiser_dock)
+"wTG" = (
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/iron/vaporwave,
+/area/centcom/central_command_areas/adminroom)
"wTZ" = (
/obj/machinery/vending/coffee,
/obj/effect/turf_decal/bot_white,
@@ -27992,6 +28165,14 @@
},
/turf/closed/indestructible/wood,
/area/centcom/central_command_areas/admin)
+"xQP" = (
+/obj/effect/spawner/random/trash/bacteria,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/spawner/random/trash/mess,
+/turf/open/floor/plating/rust,
+/area/centcom/central_command_areas/adminroom)
"xRr" = (
/obj/structure/chair/office/light{
dir = 1
@@ -53192,17 +53373,17 @@ aaa
aaa
aaa
aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
+aOn
+aOn
+aOn
+aOn
+aOn
+kpH
+kpH
+kpH
+kpH
+kpH
+kpH
aaa
aaa
aaa
@@ -53449,17 +53630,17 @@ aaa
aaa
aaa
aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
+aOn
+yhF
+mUv
+yhF
+bYp
+wfx
+exj
+uHB
+vFv
+cYr
+kpH
aaa
aaa
aaa
@@ -53706,17 +53887,17 @@ aaa
aaa
aaa
aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
+aOn
+yhF
+mUv
+yhF
+bYc
+wfx
+msE
+uFf
+xQP
+wTG
+kpH
aaa
aaa
aaa
@@ -53963,17 +54144,17 @@ aaa
aaa
aaa
aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
+aOn
+yhF
+mUv
+yhF
+gWc
+kSK
+nGN
+uRb
+sRa
+bhS
+kpH
aaa
aaa
aaa
@@ -54220,17 +54401,17 @@ aaa
aaa
aaa
aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
+aOn
+yhF
+mUv
+yhF
+hPF
+wfx
+bxX
+qNR
+gUv
+wdA
+kpH
aaa
aaa
aaa
@@ -54477,17 +54658,17 @@ aaa
aaa
aaa
aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
-aaa
+aOn
+yhF
+mUv
+yhF
+bYp
+wfx
+uPO
+ptP
+jUo
+sHS
+kpH
aaa
aaa
aaa
@@ -54735,14 +54916,14 @@ kpH
kpH
kpH
aOn
+yhF
+mUv
+yhF
aOn
-aOn
-aOn
-aOn
-kpH
-kpH
kpH
+sSL
kpH
+oBb
kpH
kpH
aaa
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index c5c9f195b510..2d35e94b2274 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -51354,9 +51354,6 @@
},
/obj/structure/window/reinforced/spawner/directional/north,
/obj/structure/window/reinforced/spawner/directional/south,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
-/obj/item/gun/energy/taser,
/turf/open/floor/iron,
/area/station/ai_monitored/security/armory)
"pph" = (
diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm
index 6be8af3db530..844faad63cba 100644
--- a/code/__DEFINES/access.dm
+++ b/code/__DEFINES/access.dm
@@ -474,6 +474,7 @@
#define REGION_RESEARCH "Research"
/// Used to seed the accesses_by_region list in SSid_access. A list of all research regional accesses that are overseen by the RD.
#define REGION_ACCESS_RESEARCH list( \
+ ACCESS_AI_UPLOAD, \
ACCESS_GENETICS, \
ACCESS_MECH_SCIENCE, \
ACCESS_MINISAT, \
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index 020efe8d0858..47d703974ae3 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -226,6 +226,9 @@ GLOBAL_LIST_INIT(ai_employers, list(
/// Checks if the given mob is either a heretic, heretic monster or a lunatic.
#define IS_HERETIC_OR_MONSTER(mob) (IS_HERETIC(mob) || IS_HERETIC_MONSTER(mob) || IS_LUNATIC(mob))
+/// Checks if the given mob is in the mansus realm
+#define IS_IN_MANSUS(mob) (istype(get_area(mob), /area/centcom/heretic_sacrifice))
+
/// Checks if the given mob is a wizard
#define IS_WIZARD(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/wizard))
diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm
index d59e0477c798..1bccfebfc558 100644
--- a/code/__DEFINES/maps.dm
+++ b/code/__DEFINES/maps.dm
@@ -61,7 +61,7 @@ Always compile, always use that verb, and always make sure that it works for wha
#define MAP_MAXZ 6
/// Path for the next_map.json file, if someone, for some messed up reason, wants to change it.
-#define PATH_TO_NEXT_MAP_JSON "data/next_map.json"
+#define PATH_TO_NEXT_MAP_JSON (world.GetConfig("env", "AUXTOOLS_DEBUG_DLL") ? "data/next_map.json" : "data/next_map.[world.port].json") // monkestation edit: messed up cat here, i changed it (added world.port to it if there's no debugger attached)
/// List of directories we can load map .json files from
#define MAP_DIRECTORY_MAPS "_maps"
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index c9d51b852c76..77b3092cfc68 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -7,6 +7,16 @@
/// if it only allows one, and new instances just instead refresh the timer
#define STATUS_EFFECT_REFRESH 3
+/// Use in status effect "duration" to make it last forever
+#define STATUS_EFFECT_PERMANENT -1
+/// Use in status effect "tick_interval" to prevent it from calling tick()
+#define STATUS_EFFECT_NO_TICK -1
+
+/// Indicates this status effect is an abstract type, ie not instantiated
+/// Doesn't actually do anything in practice, primarily just a marker / used in unit tests,
+/// so don't worry if your abstract status effect doesn't actually set this
+#define STATUS_EFFECT_ID_ABSTRACT "abstract"
+
///Processing flags - used to define the speed at which the status will work
///This is fast - 0.2s between ticks (I believe!)
#define STATUS_EFFECT_FAST_PROCESS 0
diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index 42f2d5fc31fe..7e1ba820dd8b 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -1,7 +1,7 @@
// tgstation-server DMAPI
// The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in IETF RFC 2119.
-#define TGS_DMAPI_VERSION "7.3.0"
+#define TGS_DMAPI_VERSION "7.3.1"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -58,6 +58,11 @@
#define TGS_FILE2TEXT_NATIVE file2text
#endif
+// SpacemanDMM compatibility
+#ifndef CAN_BE_REDEFINED
+#define CAN_BE_REDEFINED(X)
+#endif
+
// EVENT CODES
/// Before a reboot mode change, extras parameters are the current and new reboot mode enums.
@@ -160,6 +165,7 @@
* * http_handler - Optional user defined [/datum/tgs_http_handler].
*/
/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE, datum/tgs_http_handler/http_handler)
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -170,6 +176,7 @@
* This function should not be called before ..() in [/world/proc/New].
*/
/world/proc/TgsInitializationComplete()
+ CAN_BE_REDEFINED(TRUE)
return
/// Consumers MUST run this macro at the start of [/world/proc/Topic].
@@ -177,6 +184,7 @@
/// Consumers MUST call this as late as possible in [world/proc/Reboot] (BEFORE ..()).
/world/proc/TgsReboot()
+ CAN_BE_REDEFINED(TRUE)
return
// DATUM DEFINITIONS
@@ -214,6 +222,7 @@
* Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards.
*/
/datum/tgs_version/proc/Wildcard()
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -222,6 +231,7 @@
* other_version - The [/datum/tgs_version] to compare against.
*/
/datum/tgs_version/proc/Equals(datum/tgs_version/other_version)
+ CAN_BE_REDEFINED(TRUE)
return
/// Represents a merge of a GitHub pull request.
@@ -459,16 +469,19 @@
/// Returns the maximum supported [/datum/tgs_version] of the DMAPI.
/world/proc/TgsMaximumApiVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the minimum supported [/datum/tgs_version] of the DMAPI.
/world/proc/TgsMinimumApiVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/**
* Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise.
*/
/world/proc/TgsAvailable()
+ CAN_BE_REDEFINED(TRUE)
return
// No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called.
@@ -480,6 +493,7 @@
* If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again.
*/
/world/proc/TgsEndProcess()
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -490,6 +504,7 @@
* admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
*/
/world/proc/TgsTargetedChatBroadcast(datum/tgs_message_content/message, admin_only = FALSE)
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -500,6 +515,7 @@
* user: The [/datum/tgs_chat_user] to PM.
*/
/world/proc/TgsChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user)
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -510,42 +526,52 @@
* channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
*/
/world/proc/TgsChatBroadcast(datum/tgs_message_content/message, list/channels = null)
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the running engine type
/world/proc/TgsEngine()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsApiVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the name of the TGS instance running the game if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsInstanceName()
+ CAN_BE_REDEFINED(TRUE)
return
/// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsRevision()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsSecurityLevel()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current BYOND visibility level as a TGS_VISIBILITY_ define if TGS is present, null otherwise. Requires TGS to be using interop API version 5 or higher otherwise the string "___unimplemented" wil be returned. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsVisibility()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsTestMerges()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsChatChannelInfo()
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -556,6 +582,7 @@
* wait_for_completion - If set, this function will not return until the event has run to completion.
*/
/world/proc/TgsTriggerEvent(event_name, list/parameters, wait_for_completion = FALSE)
+ CAN_BE_REDEFINED(TRUE)
return
/*
diff --git a/code/__DEFINES/traits/monkestation/declarations.dm b/code/__DEFINES/traits/monkestation/declarations.dm
index 8a07f00fb954..a26127eb0ff5 100644
--- a/code/__DEFINES/traits/monkestation/declarations.dm
+++ b/code/__DEFINES/traits/monkestation/declarations.dm
@@ -121,6 +121,8 @@
#define TRAIT_BYPASS_COMPRESS_CHECK "can_compress_anyways"
/// This item is considered "trash" (and will be eaten by cleaner slimes)
#define TRAIT_TRASH_ITEM "trash_item"
+/// This item came from a gift.
+#define TRAIT_GIFT_ITEM "gift_item"
// /atom/movable
/// Things with this trait can pass through wooden barricades.
diff --git a/code/__DEFINES/~monkestation/vv.dm b/code/__DEFINES/~monkestation/vv.dm
new file mode 100644
index 000000000000..8acf0c7ef495
--- /dev/null
+++ b/code/__DEFINES/~monkestation/vv.dm
@@ -0,0 +1 @@
+#define VV_HK_EXAMINE_GIFT "examine_gift"
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index e367535713bc..7112c0447ae6 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -301,6 +301,7 @@ GLOBAL_LIST_INIT(round_end_images, world.file2list("data/image_urls.txt")) // MO
// monkestation start: token backups, monkecoin rewards, challenges, and roundend webhook
save_tokens()
+ refund_cassette()
distribute_rewards()
sleep(5 SECONDS)
ready_for_reboot = TRUE
diff --git a/code/__HELPERS/~monkestation-helpers/atoms.dm b/code/__HELPERS/~monkestation-helpers/atoms.dm
index 67b81a50dafb..44f26ac804e0 100644
--- a/code/__HELPERS/~monkestation-helpers/atoms.dm
+++ b/code/__HELPERS/~monkestation-helpers/atoms.dm
@@ -26,3 +26,11 @@
default_typecache ||= typecacheof(list(/obj/effect, /atom/movable/screen))
typecache = default_typecache
return typecache_filter_list_reverse(src.contents, typecache)
+
+/// Returns a list of all items in our contents that were obtained from gifts.
+/atom/proc/get_all_gift_contents() as /list
+ RETURN_TYPE(/list/obj/item)
+ . = list()
+ for(var/obj/item/thing as anything in get_all_contents_type(/obj/item))
+ if(!QDELETED(thing) && HAS_TRAIT(thing, TRAIT_GIFT_ITEM))
+ . += thing
diff --git a/code/__HELPERS/~monkestation-helpers/icons.dm b/code/__HELPERS/~monkestation-helpers/icons.dm
index 73b6900edc93..ec8d795bdf4b 100644
--- a/code/__HELPERS/~monkestation-helpers/icons.dm
+++ b/code/__HELPERS/~monkestation-helpers/icons.dm
@@ -19,3 +19,47 @@
fdel(TMP_UPSCALE_PATH)
#undef TMP_UPSCALE_PATH
+
+/// Returns the (isolated) security HUD icon for the given job.
+/proc/get_job_hud_icon(datum/job/job, include_unknown = FALSE) as /icon
+ RETURN_TYPE(/icon)
+ var/static/list/icon_cache
+ var/static/list/unknown_huds
+ if(isnull(job))
+ return
+ else if(!is_job(job))
+ if(ispath(job, /datum/job))
+ job = locate(job) in SSjob.all_occupations
+ else if(istext(job))
+ job_loop:
+ for(var/datum/job/job_instance as anything in SSjob.all_occupations)
+ if(cmptext(job_instance.title, job) || cmptext(job_instance.config_tag, job))
+ job = job_instance
+ break
+ for(var/alt_title in job_instance.alt_titles)
+ if(cmptext(alt_title, job))
+ job = job_instance
+ break job_loop
+ if(!job)
+ return null
+
+ // populate the cache if it hasn't been already
+ if(isnull(icon_cache))
+ icon_cache = list()
+ unknown_huds = list()
+ for(var/datum/job/job_instance as anything in SSjob.all_occupations)
+ var/datum/outfit/job_outfit = job_instance.outfit
+ if(!job_outfit || !job_outfit::id_trim)
+ continue
+ var/datum/id_trim/job_trim = job_outfit::id_trim
+ var/icon_state = job_trim::sechud_icon_state
+ if(!icon_state || icon_state == SECHUD_UNKNOWN)
+ icon_state = "hud_noid"
+ unknown_huds[job_instance.type] = TRUE
+ var/icon/sechud_icon = icon('icons/mob/huds/hud.dmi', icon_state)
+ sechud_icon.Crop(1, 17, 8, 24)
+ icon_cache[job_instance.type] = sechud_icon
+
+ var/job_type = job.type
+ if(icon_cache[job_type] && (include_unknown || !unknown_huds[job_type]))
+ return icon(icon_cache[job_type])
diff --git a/code/__HELPERS/~monkestation-helpers/roundend.dm b/code/__HELPERS/~monkestation-helpers/roundend.dm
index 082c3aaeca38..b6bfb7fc59f0 100644
--- a/code/__HELPERS/~monkestation-helpers/roundend.dm
+++ b/code/__HELPERS/~monkestation-helpers/roundend.dm
@@ -36,3 +36,26 @@
total_payout += listed_challenge.challenge_payout
if(total_payout)
client?.prefs?.adjust_metacoins(client?.ckey, total_payout, "Challenge rewards.")
+
+/datum/controller/subsystem/ticker/proc/refund_cassette()
+ if(!length(GLOB.cassette_reviews))
+ return
+
+ for(var/id in GLOB.cassette_reviews)
+ var/datum/cassette_review/review = GLOB.cassette_reviews[id]
+ if(!review || review.action_taken) // Skip if review doesn't exist or already handled (denied / approved)
+ continue
+
+ var/ownerckey = review.submitted_ckey // ckey of who made the cassette.
+ if(!ownerckey)
+ continue
+
+ var/client/client = GLOB.directory[ownerckey] // Use directory for direct lookup (Client might be a differnet mob than when review was made.)
+ if(client && !QDELETED(client?.prefs))
+ var/adjusted = client?.prefs?.adjust_metacoins(
+ client?.ckey, 5000,
+ reason = "No action taken on cassette:\[[review.submitted_tape.name]\] before round end.",
+ announces = TRUE, donator_multipler = FALSE
+ )
+ if(adjusted)
+ qdel(review)
diff --git a/code/_experiments.dm b/code/_experiments.dm
index ef2240406ed2..c7fdad2f7887 100644
--- a/code/_experiments.dm
+++ b/code/_experiments.dm
@@ -3,11 +3,8 @@
// Any flag you see here can be flipped with the `-D` CLI argument.
// For example, if you want to enable EXPERIMENT_MY_COOL_FEATURE, compile with -DEXPERIMENT_MY_COOL_FEATURE
-// EXPERIMENT_515_QDEL_HARD_REFERENCE
-// - Hold a hard reference for qdeleted items, and check ref_count, rather than using refs. Requires 515+.
-
-// EXPERIMENT_515_DONT_CACHE_REF
-// - Avoids `text_ref` caching, aided by improvements to ref() speed in 515.
+// EXPERIMENT_MY_COOL_FEATURE
+// - Does something really cool, just so neat, absolutely banging, gaming and chill
#if DM_VERSION < 515
@@ -20,6 +17,6 @@
#define EXPERIMENT_MY_COOL_FEATURE
#endif
-#if DM_VERSION >= 516
- #error "Remove all 515 experiments"
+#if DM_VERSION >= 517
+ #error "Remove all 516 experiments"
#endif
diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm
index c60c9105f541..bcb83d5d97e5 100644
--- a/code/_globalvars/lists/maintenance_loot.dm
+++ b/code/_globalvars/lists/maintenance_loot.dm
@@ -400,7 +400,7 @@ GLOBAL_LIST_INIT(maint_fauna, list(//fauna: there be critters living in yer main
#define maint_uncommon_weight 900
#define maint_rarity_weight 99
#define maint_oddity_weight 4 //1 out of 10,000 would give metastation (180 spawns) a 2 in 111 chance of spawning an oddity per round, similar to xeno egg, monkestation edit: from 1 to 4
-#define maint_holiday_weight 2500 // When holiday loot is enabled, it'll give every loot item a 25% chance of being a holiday item
+#define maint_holiday_weight 3500 // When holiday loot is enabled, it'll give every loot item a 25% chance of being a holiday item
#define maint_fauna_weight 150 //monkestation edit: adds friendly maintenance bees, also allows for other maintenance fauna to be coded in.
//Loot pool used by default maintenance loot spawners
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index 7734282dd4d7..12590729049c 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -611,24 +611,31 @@ GLOBAL_LIST_INIT(traits_by_type, list(
),
/obj/item = list(
"TRAIT_APC_SHOCKING" = TRAIT_APC_SHOCKING,
+ "TRAIT_ASSISTED_BREATHING" = TRAIT_ASSISTED_BREATHING,
"TRAIT_BASIC_QUALITY_BAIT" = TRAIT_BASIC_QUALITY_BAIT,
"TRAIT_BELT_SATCHEL" = TRAIT_BELT_SATCHEL,
"TRAIT_BLIND_TOOL" = TRAIT_BLIND_TOOL,
"TRAIT_BYPASS_COMPRESS_CHECK" = TRAIT_BYPASS_COMPRESS_CHECK,
"TRAIT_CUSTOM_TAP_SOUND" = TRAIT_CUSTOM_TAP_SOUND,
"TRAIT_DANGEROUS_OBJECT" = TRAIT_DANGEROUS_OBJECT,
+ "TRAIT_FEATHERED" = TRAIT_FEATHERED,
"TRAIT_FISHING_BAIT" = TRAIT_FISHING_BAIT,
"TRAIT_FOOD_GRILLED" = TRAIT_FOOD_GRILLED,
+ "TRAIT_GIFT_ITEM" = TRAIT_GIFT_ITEM,
"TRAIT_GOOD_QUALITY_BAIT" = TRAIT_GOOD_QUALITY_BAIT,
"TRAIT_GREAT_QUALITY_BAIT" = TRAIT_GREAT_QUALITY_BAIT,
"TRAIT_HAUNTED" = TRAIT_HAUNTED,
"TRAIT_HONKSPAMMING" = TRAIT_HONKSPAMMING,
"TRAIT_INNATELY_FANTASTICAL_ITEM" = TRAIT_INNATELY_FANTASTICAL_ITEM,
+ "TRAIT_INSTANTLY_PROCESSES_BOULDERS" = TRAIT_INSTANTLY_PROCESSES_BOULDERS,
+ "TRAIT_LABOURED_BREATHING" = TRAIT_LABOURED_BREATHING,
"TRAIT_MAT_TRANSMUTED" = TRAIT_MAT_TRANSMUTED,
"TRAIT_MAY_CONTAIN_BLENDED_DUST" = TRAIT_MAY_CONTAIN_BLENDED_DUST,
"TRAIT_NEEDS_TWO_HANDS" = TRAIT_NEEDS_TWO_HANDS,
"TRAIT_NODROP" = TRAIT_NODROP,
+ "TRAIT_NON_IMPORTANT_SHOE_BLOCK" = TRAIT_NON_IMPORTANT_SHOE_BLOCK,
"TRAIT_NO_BARCODES" = TRAIT_NO_BARCODES,
+ "TRAIT_NO_ORGAN_DECAY" = TRAIT_NO_ORGAN_DECAY,
"TRAIT_NO_STORAGE_INSERT" = TRAIT_NO_STORAGE_INSERT,
"TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT,
"TRAIT_OMNI_BAIT" = TRAIT_OMNI_BAIT,
@@ -639,17 +646,11 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_T_RAY_VISIBLE" = TRAIT_T_RAY_VISIBLE,
"TRAIT_UNCATCHABLE" = TRAIT_UNCATCHABLE,
"TRAIT_WIELDED" = TRAIT_WIELDED,
- "TRAIT_FEATHERED" = TRAIT_FEATHERED,
- "TRAIT_NON_IMPORTANT_SHOE_BLOCK" = TRAIT_NON_IMPORTANT_SHOE_BLOCK,
- "TRAIT_LABOURED_BREATHING" = TRAIT_LABOURED_BREATHING,
- "TRAIT_ASSISTED_BREATHING" = TRAIT_ASSISTED_BREATHING,
- "TRAIT_NO_ORGAN_DECAY" = TRAIT_NO_ORGAN_DECAY,
/* "TRAIT_BAIT_UNCONSUMABLE" = TRAIT_BAIT_UNCONSUMABLE, */
/* "TRAIT_BAKEABLE" = TRAIT_BAKEABLE, */
/* "TRAIT_BYPASS_RANGED_ARMOR" = TRAIT_BYPASS_RANGED_ARMOR, */
/* "TRAIT_CONTRABAND_BLOCKER" = TRAIT_CONTRABAND_BLOCKER, */
/* "TRAIT_GERM_SENSITIVE" = TRAIT_GERM_SENSITIVE, */
- "TRAIT_INSTANTLY_PROCESSES_BOULDERS" = TRAIT_INSTANTLY_PROCESSES_BOULDERS,
/* "TRAIT_ITEM_OBJECTIVE_BLOCKED" = TRAIT_ITEM_OBJECTIVE_BLOCKED, */
/* "TRAIT_NO_SIDE_KICK" = TRAIT_NO_SIDE_KICK, */
),
diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm
index d5bee6641c3d..b50f4184c73f 100644
--- a/code/_onclick/hud/new_player.dm
+++ b/code/_onclick/hud/new_player.dm
@@ -160,6 +160,10 @@
if(!.)
return
var/mob/dead/new_player/new_player = hud.mymob
+ var/datum/station_trait/overflow_job_bureaucracy/overflow = locate() in SSstation.station_traits
+ if(!ready && overflow?.picked_job && new_player.client?.prefs?.read_preference(/datum/preference/toggle/verify_overflow))
+ if(tgui_alert(new_player, "The current overflow role is [overflow.picked_job.title], are you sure you would like to ready up?", "Overflow Notice", list("Yes", "No")) != "Yes")
+ return
ready = !ready
if(ready)
new_player.ready = PLAYER_READY_TO_PLAY
@@ -574,3 +578,76 @@
. = ..()
if(.)
SEND_SOUND(usr, 'monkestation/sound/misc/menumonkey.ogg')
+
+/atom/movable/screen/lobby/overflow_alert
+ screen_loc = "TOP:-48,CENTER-2.7"
+ icon = 'icons/hud/lobby/overflow.dmi'
+ icon_state = ""
+ base_icon_state = "overflow"
+ var/datum/job/overflow_job
+ var/static/disabled = FALSE
+ var/static/mutable_appearance/job_overlay
+
+/atom/movable/screen/lobby/overflow_alert/Initialize(mapload)
+ . = ..()
+ if(SSticker.current_state == GAME_STATE_STARTUP)
+ RegisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, PROC_REF(initial_setup))
+ else
+ generate_and_set_icon()
+ update_appearance(UPDATE_ICON)
+
+/atom/movable/screen/lobby/overflow_alert/Destroy()
+ overflow_job = null
+ UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME)
+ return ..()
+
+/atom/movable/screen/lobby/overflow_alert/update_icon_state()
+ if(!disabled && !isnull(job_overlay))
+ icon_state = base_icon_state
+ else
+ icon_state = ""
+ return ..()
+
+/atom/movable/screen/lobby/overflow_alert/update_overlays()
+ . = ..()
+ if(!disabled && job_overlay)
+ . += job_overlay
+
+/atom/movable/screen/lobby/overflow_alert/MouseEntered(location,control,params)
+ . = ..()
+ if(!disabled && overflow_job && !QDELETED(src))
+ openToolTip(usr, src, params, title = "Job Overflow", content = "The overflow role this round is [html_encode(overflow_job.title)]!")
+
+/atom/movable/screen/lobby/overflow_alert/MouseExited()
+ closeToolTip(usr)
+
+/atom/movable/screen/lobby/overflow_alert/proc/initial_setup(datum/source)
+ SIGNAL_HANDLER
+ UnregisterSignal(SSstation, COMSIG_TICKER_ENTER_PREGAME)
+ var/datum/station_trait/overflow_job_bureaucracy/overflow = locate() in SSstation.station_traits
+ overflow_job = overflow?.picked_job
+ if(overflow_job)
+ generate_and_set_icon()
+ else
+ disabled = TRUE
+ update_appearance(UPDATE_ICON)
+
+/atom/movable/screen/lobby/overflow_alert/proc/generate_and_set_icon()
+ if(disabled || SSticker.current_state == GAME_STATE_STARTUP || !isnull(job_overlay))
+ return
+ var/datum/station_trait/overflow_job_bureaucracy/overflow = locate() in SSstation.station_traits
+ overflow_job = overflow?.picked_job
+ if(!overflow_job)
+ disabled = TRUE
+ return
+ var/icon/job_icon = get_job_hud_icon(overflow_job, include_unknown = TRUE)
+ if(!job_icon)
+ return
+ var/icon/resized_icon = resize_icon(job_icon, 16, 16)
+ if(!resized_icon)
+ stack_trace("Failed to upscale icon for [overflow_job], upscaling using BYOND!")
+ job_icon.Scale(16, 16)
+ resized_icon = job_icon
+ job_overlay = mutable_appearance(resized_icon)
+ job_overlay.pixel_x = 8
+ job_overlay.pixel_y = 18
diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm
index 08a26d9a79cf..3dba3b00faab 100644
--- a/code/controllers/subsystem/statpanel.dm
+++ b/code/controllers/subsystem/statpanel.dm
@@ -99,11 +99,12 @@ SUBSYSTEM_DEF(statpanels)
return
/datum/controller/subsystem/statpanels/proc/set_status_tab(client/target)
+ var/static/list/beta_notice = list("", "You are on the BYOND 516 beta, various UIs and such may be broken!", "Please report issues, and switch back to BYOND 515 if things are causing too many issues for you.")
if(!global_data)//statbrowser hasnt fired yet and we were called from immediate_send_stat_data()
return
target.stat_panel.send_message("update_stat", list(
- "global_data" = global_data,
+ "global_data" = (target.byond_version < 516) ? global_data : (global_data + beta_notice),
"ping_str" = "Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)",
"other_str" = target.mob?.get_status_tab_items(),
))
diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm
index 8966193abff9..48b0f1a9db46 100644
--- a/code/datums/ai/_ai_controller.dm
+++ b/code/datums/ai/_ai_controller.dm
@@ -232,9 +232,10 @@ multiple modular subtrees with behaviors
///Called when the AI controller pawn changes z levels, we check if there's any clients on the new one and wake up the AI if there is.
/datum/ai_controller/proc/on_changed_z_level(atom/source, turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
SIGNAL_HANDLER
- var/mob/mob_pawn = pawn
- if((mob_pawn?.client && !continue_processing_when_client))
- return
+ if (ismob(pawn))
+ var/mob/mob_pawn = pawn
+ if((mob_pawn?.client && !continue_processing_when_client))
+ return
if(old_turf)
SSai_controllers.ai_controllers_by_zlevel[old_turf.z] -= src
if(new_turf)
diff --git a/code/datums/elements/corrupted_organ.dm b/code/datums/elements/corrupted_organ.dm
new file mode 100644
index 000000000000..ee4cf3a1003d
--- /dev/null
+++ b/code/datums/elements/corrupted_organ.dm
@@ -0,0 +1,66 @@
+/// Component applying shared behaviour by cursed organs granted when sacrificed by a heretic
+/// Mostly just does something spooky when it is removed
+/datum/element/corrupted_organ
+
+/datum/element/corrupted_organ/Attach(datum/target)
+ . = ..()
+ if (!isinternalorgan(target))
+ return ELEMENT_INCOMPATIBLE
+
+ RegisterSignal(target, COMSIG_ORGAN_REMOVED, PROC_REF(on_removed))
+
+ var/atom/atom_parent = target
+ atom_parent.color = COLOR_VOID_PURPLE
+
+ atom_parent.add_filter(name = "ray", priority = 1, params = list(
+ type = "rays",
+ size = 12,
+ color = COLOR_VOID_PURPLE,
+ density = 12
+ ))
+ var/ray_filter = atom_parent.get_filter("ray")
+ animate(ray_filter, offset = 100, time = 2 MINUTES, loop = -1, flags = ANIMATION_PARALLEL) // Absurdly long animate so nobody notices it hitching when it loops
+ animate(offset = 0, time = 2 MINUTES) // I sure hope duration of animate doesnt have any performance effect
+
+/datum/element/corrupted_organ/Detach(datum/source)
+ UnregisterSignal(source, list(COMSIG_ORGAN_REMOVED))
+ return ..()
+
+/// When we're taken out of someone, do something spooky
+/datum/element/corrupted_organ/proc/on_removed(atom/organ, mob/living/carbon/loser)
+ SIGNAL_HANDLER
+ if (loser.has_reagent(/datum/reagent/water/holywater) || loser.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY) || prob(20))
+ return
+ if (prob(75))
+ organ.AddComponent(\
+ /datum/component/haunted_item,\
+ haunt_color = "#00000000", \
+ aggro_radius = 4, \
+ spawn_message = span_revenwarning("[organ] hovers ominously into the air, pulsating with unnatural vigour!"), \
+ despawn_message = span_revenwarning("[organ] falls motionless to the ground."), \
+ )
+ return
+ var/turf/origin_turf = get_turf(organ)
+ playsound(organ, 'sound/magic/forcewall.ogg', vol = 100)
+ new /obj/effect/temp_visual/curse_blast(origin_turf)
+ organ.visible_message(span_revenwarning("[organ] explodes in a burst of dark energy!"))
+ for(var/mob/living/target in range(1, origin_turf))
+ var/armor = target.run_armor_check(attack_flag = BOMB)
+ target.apply_damage(30, damagetype = BURN, blocked = armor, spread_damage = TRUE)
+ qdel(organ)
+
+/obj/effect/temp_visual/curse_blast
+ icon = 'icons/effects/64x64.dmi'
+ pixel_x = -16
+ pixel_y = -16
+ icon_state = "curse"
+ duration = 0.3 SECONDS
+
+/obj/effect/temp_visual/curse_blast/Initialize(mapload)
+ . = ..()
+ animate(src, transform = matrix() * 0.2, time = 0, flags = ANIMATION_PARALLEL)
+ animate(transform = matrix() * 2, time = duration, easing = EASE_IN)
+
+ animate(src, alpha = 255, time = 0, flags = ANIMATION_PARALLEL)
+ animate(alpha = 255, time = 0.2 SECONDS)
+ animate(alpha = 0, time = 0.1 SECONDS)
diff --git a/code/datums/elements/organ_set_bonus.dm b/code/datums/elements/organ_set_bonus.dm
index aeb63356fb48..2859f7b802c5 100644
--- a/code/datums/elements/organ_set_bonus.dm
+++ b/code/datums/elements/organ_set_bonus.dm
@@ -42,8 +42,8 @@
/datum/status_effect/organ_set_bonus
id = "organ_set_bonus"
- duration = -1
- tick_interval = -1
+ duration = STATUS_EFFECT_PERMANENT
+ tick_interval = STATUS_EFFECT_NO_TICK
alert_type = null
///how many organs the carbon with this has in the set
var/organs = 0
diff --git a/code/datums/elements/relay_attackers.dm b/code/datums/elements/relay_attackers.dm
index cdc86e6058cb..83e83a40e7ce 100644
--- a/code/datums/elements/relay_attackers.dm
+++ b/code/datums/elements/relay_attackers.dm
@@ -7,14 +7,15 @@
/datum/element/relay_attackers/Attach(datum/target)
. = ..()
- // Boy this sure is a lot of ways to tell us that someone tried to attack us
- RegisterSignal(target, COMSIG_ATOM_AFTER_ATTACKEDBY, PROC_REF(after_attackby))
- RegisterSignals(target, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW, COMSIG_MOB_ATTACK_ALIEN), PROC_REF(on_attack_generic))
- RegisterSignals(target, list(COMSIG_ATOM_ATTACK_BASIC_MOB, COMSIG_ATOM_ATTACK_ANIMAL), PROC_REF(on_attack_npc))
- RegisterSignal(target, COMSIG_PROJECTILE_PREHIT, PROC_REF(on_bullet_act))
- RegisterSignal(target, COMSIG_ATOM_PREHITBY, PROC_REF(on_hitby))
- RegisterSignal(target, COMSIG_ATOM_HULK_ATTACK, PROC_REF(on_attack_hulk))
- RegisterSignal(target, COMSIG_ATOM_ATTACK_MECH, PROC_REF(on_attack_mech))
+ if (!HAS_TRAIT(target, TRAIT_RELAYING_ATTACKER)) // Little bit gross but we want to just apply this shit from a bunch of places
+ // Boy this sure is a lot of ways to tell us that someone tried to attack us
+ RegisterSignal(target, COMSIG_ATOM_AFTER_ATTACKEDBY, PROC_REF(after_attackby))
+ RegisterSignals(target, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW, COMSIG_MOB_ATTACK_ALIEN), PROC_REF(on_attack_generic))
+ RegisterSignals(target, list(COMSIG_ATOM_ATTACK_BASIC_MOB, COMSIG_ATOM_ATTACK_ANIMAL), PROC_REF(on_attack_npc))
+ RegisterSignal(target, COMSIG_PROJECTILE_PREHIT, PROC_REF(on_bullet_act))
+ RegisterSignal(target, COMSIG_ATOM_PREHITBY, PROC_REF(on_hitby))
+ RegisterSignal(target, COMSIG_ATOM_HULK_ATTACK, PROC_REF(on_attack_hulk))
+ RegisterSignal(target, COMSIG_ATOM_ATTACK_MECH, PROC_REF(on_attack_mech))
ADD_TRAIT(target, TRAIT_RELAYING_ATTACKER, REF(src))
/datum/element/relay_attackers/Detach(datum/source, ...)
diff --git a/code/datums/id_trim/jobs.dm b/code/datums/id_trim/jobs.dm
index e8227001977e..460000a14994 100644
--- a/code/datums/id_trim/jobs.dm
+++ b/code/datums/id_trim/jobs.dm
@@ -175,7 +175,7 @@
template_access = list(
ACCESS_CAPTAIN,
ACCESS_CHANGE_IDS,
- ACCESS_QM,
+ ACCESS_HOP,
)
job = /datum/job/bitrunner
diff --git a/code/datums/quirks/neutral_quirks/pride_pin.dm b/code/datums/quirks/neutral_quirks/pride_pin.dm
index 0bdb26260109..64fbe43c55ea 100644
--- a/code/datums/quirks/neutral_quirks/pride_pin.dm
+++ b/code/datums/quirks/neutral_quirks/pride_pin.dm
@@ -18,6 +18,7 @@
pin.current_skin = pride_choice
pin.icon_state = pride_reskin
+ pin.post_reskin()
//MONKESTATION EDIT START
var/mob/living/carbon/human/H = quirk_holder
if (istype(H))
diff --git a/code/datums/status_effects/_status_effect.dm b/code/datums/status_effects/_status_effect.dm
index 49ba273c24db..b95504702c28 100644
--- a/code/datums/status_effects/_status_effect.dm
+++ b/code/datums/status_effects/_status_effect.dm
@@ -6,7 +6,7 @@
/// When set initially / in on_creation, this is how long the status effect lasts in deciseconds.
/// While processing, this becomes the world.time when the status effect will expire.
/// -1 = infinite duration.
- var/duration = -1
+ var/duration = STATUS_EFFECT_PERMANENT
/// When set initially / in on_creation, this is how long between [proc/tick] calls in deciseconds.
/// While processing, this becomes the world.time when the next tick will occur.
/// -1 = will stop processing, if duration is also unlimited (-1).
diff --git a/code/datums/status_effects/agent_pinpointer.dm b/code/datums/status_effects/agent_pinpointer.dm
index 3f64ff252a02..7afb85805f05 100644
--- a/code/datums/status_effects/agent_pinpointer.dm
+++ b/code/datums/status_effects/agent_pinpointer.dm
@@ -10,7 +10,7 @@
/datum/status_effect/agent_pinpointer
id = "agent_pinpointer"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
tick_interval = PINPOINTER_PING_TIME
alert_type = /atom/movable/screen/alert/status_effect/agent_pinpointer
///The minimum range to start pointing towards your target.
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index e4edd4997c62..a2352c34b15d 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -2,7 +2,7 @@
/datum/status_effect/his_grace
id = "his_grace"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
tick_interval = 4
alert_type = /atom/movable/screen/alert/status_effect/his_grace
var/bloodlust = 0
@@ -86,7 +86,7 @@
/datum/status_effect/cult_master
id = "The Cult Master"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
alert_type = null
on_remove_on_mob_delete = TRUE
var/alive = TRUE
@@ -116,7 +116,7 @@
/datum/status_effect/blooddrunk
id = "blooddrunk"
duration = 10
- tick_interval = -1 // monkestation edit
+ tick_interval = STATUS_EFFECT_NO_TICK // monkestation edit
alert_type = /atom/movable/screen/alert/status_effect/blooddrunk
/atom/movable/screen/alert/status_effect/blooddrunk
@@ -211,7 +211,7 @@
/datum/status_effect/hippocratic_oath
id = "Hippocratic Oath"
status_type = STATUS_EFFECT_UNIQUE
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
tick_interval = 25
alert_type = null
@@ -423,6 +423,7 @@
duration = 2 SECONDS
status_type = STATUS_EFFECT_REPLACE
show_duration = TRUE
+ alert_type = null
/datum/status_effect/speed_boost/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
@@ -475,7 +476,7 @@
/datum/status_effect/nest_sustenance
id = "nest_sustenance"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
tick_interval = 0.4 SECONDS
alert_type = /atom/movable/screen/alert/status_effect/nest_sustenance
@@ -504,8 +505,8 @@
*/
/datum/status_effect/blessing_of_insanity
id = "blessing_of_insanity"
- duration = -1
- tick_interval = -1
+ duration = STATUS_EFFECT_PERMANENT
+ tick_interval = STATUS_EFFECT_NO_TICK
alert_type = /atom/movable/screen/alert/status_effect/blessing_of_insanity
/atom/movable/screen/alert/status_effect/blessing_of_insanity
diff --git a/code/datums/status_effects/buffs/stun_asorption.dm b/code/datums/status_effects/buffs/stun_asorption.dm
index d68f2f7408cc..f6212bc88421 100644
--- a/code/datums/status_effects/buffs/stun_asorption.dm
+++ b/code/datums/status_effects/buffs/stun_asorption.dm
@@ -9,7 +9,7 @@
*/
/datum/status_effect/stun_absorption
id = "absorb_stun"
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
alert_type = null
status_type = STATUS_EFFECT_MULTIPLE
diff --git a/code/datums/status_effects/debuffs/blindness.dm b/code/datums/status_effects/debuffs/blindness.dm
index 0bfaaee7485b..310b995090c8 100644
--- a/code/datums/status_effects/debuffs/blindness.dm
+++ b/code/datums/status_effects/debuffs/blindness.dm
@@ -5,7 +5,7 @@
/// Nearsighted
/datum/status_effect/grouped/nearsighted
id = "nearsighted"
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
alert_type = null
// This is not "remove on fullheal" as in practice,
// fullheal should instead remove all the sources and in turn cure this
@@ -55,7 +55,7 @@
/// Blindness
/datum/status_effect/grouped/blindness
id = "blindness"
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
alert_type = /atom/movable/screen/alert/status_effect/blind
// This is not "remove on fullheal" as in practice,
// fullheal should instead remove all the sources and in turn cure this
diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm
index 83572e56630c..3e6491813387 100644
--- a/code/datums/status_effects/debuffs/debuffs.dm
+++ b/code/datums/status_effects/debuffs/debuffs.dm
@@ -1,7 +1,8 @@
//Largely negative status effects go here, even if they have small benificial effects
//STUN EFFECTS
/datum/status_effect/incapacitating
- tick_interval = -1 // monkestation edit
+ id = STATUS_EFFECT_ID_ABSTRACT
+ tick_interval = STATUS_EFFECT_NO_TICK // monkestation edit
status_type = STATUS_EFFECT_REPLACE
alert_type = null
remove_on_fullheal = TRUE
@@ -134,7 +135,7 @@
if(!.)
return
if(HAS_TRAIT(owner, TRAIT_SLEEPIMMUNE))
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
else
ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_SLEEPIMMUNE), PROC_REF(on_owner_insomniac))
@@ -156,7 +157,7 @@
/datum/status_effect/incapacitating/sleeping/proc/on_owner_insomniac(mob/living/source)
SIGNAL_HANDLER
REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
///If the mob has the TRAIT_SLEEPIMMUNE but somehow looses it we make him sleep and restart the tick()
/datum/status_effect/incapacitating/sleeping/proc/on_owner_sleepy(mob/living/source)
@@ -237,7 +238,7 @@
//STASIS
/datum/status_effect/grouped/stasis
id = "stasis"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
alert_type = /atom/movable/screen/alert/status_effect/stasis
var/last_dead_time
@@ -289,7 +290,7 @@
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
id = "his_wrath"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
tick_interval = 4
alert_type = /atom/movable/screen/alert/status_effect/his_wrath
@@ -309,7 +310,7 @@
/datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
id = "cult_ghost"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
alert_type = null
/datum/status_effect/cultghost/on_apply()
@@ -386,7 +387,7 @@
id = "neck_slice"
status_type = STATUS_EFFECT_UNIQUE
alert_type = null
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
/datum/status_effect/neck_slice/on_apply()
if(!ishuman(owner))
@@ -511,7 +512,7 @@
/datum/status_effect/gonbola_pacify
id = "gonbolaPacify"
status_type = STATUS_EFFECT_MULTIPLE
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
alert_type = null
/datum/status_effect/gonbola_pacify/on_apply()
@@ -693,9 +694,9 @@
/datum/status_effect/go_away
id = "go_away"
- duration = 100
+ duration = 10 SECONDS
status_type = STATUS_EFFECT_REPLACE
- tick_interval = 1
+ tick_interval = 0.2 SECONDS
alert_type = /atom/movable/screen/alert/status_effect/go_away
var/direction
@@ -716,11 +717,11 @@
/datum/status_effect/fake_virus
id = "fake_virus"
- duration = 1800//3 minutes
+ duration = 3 MINUTES //3 minutes
status_type = STATUS_EFFECT_REPLACE
- tick_interval = 1
+ tick_interval = 0.2 SECONDS
alert_type = null
- var/msg_stage = 0//so you dont get the most intense messages immediately
+ var/msg_stage = 0//so you don't get the most intense messages immediately
/datum/status_effect/fake_virus/on_apply()
if(HAS_TRAIT(owner, TRAIT_VIRUSIMMUNE))
@@ -937,7 +938,8 @@
id = "teleport_madness"
duration = 10 SECONDS
status_type = STATUS_EFFECT_REPLACE
- tick_interval = 0.1 SECONDS
+ tick_interval = 0.2 SECONDS
+ alert_type = null
/datum/status_effect/teleport_madness/tick()
dump_in_space(owner)
diff --git a/code/datums/status_effects/debuffs/dna_transformation.dm b/code/datums/status_effects/debuffs/dna_transformation.dm
index 1ffcc2f5929d..f38c88c3f2bb 100644
--- a/code/datums/status_effects/debuffs/dna_transformation.dm
+++ b/code/datums/status_effects/debuffs/dna_transformation.dm
@@ -2,7 +2,7 @@
/// then turns them back to how they were before transformation.
/datum/status_effect/temporary_transformation
id = "temp_dna_transformation"
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
duration = 1 MINUTES // set in on creation, this just needs to be any value to process
alert_type = null
remove_on_fullheal = TRUE
@@ -85,7 +85,7 @@
return // Already paused
time_before_pause = duration - world.time
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
// Resume if we're none of the above and also were paused
else if(time_before_pause != -1)
diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm
index 026577fdc972..4ccc273b0b2b 100644
--- a/code/datums/status_effects/debuffs/drunk.dm
+++ b/code/datums/status_effects/debuffs/drunk.dm
@@ -15,6 +15,7 @@
tick_interval = 2 SECONDS
status_type = STATUS_EFFECT_REPLACE
remove_on_fullheal = TRUE
+ alert_type = null
/// The level of drunkness we are currently at.
var/drunk_value = 0
diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm
index d00d0c348439..81d81deee4af 100644
--- a/code/datums/status_effects/debuffs/fire_stacks.dm
+++ b/code/datums/status_effects/debuffs/fire_stacks.dm
@@ -1,5 +1,6 @@
/datum/status_effect/fire_handler
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
+ id = STATUS_EFFECT_ID_ABSTRACT
alert_type = null
status_type = STATUS_EFFECT_REFRESH //Custom code
on_remove_on_mob_delete = TRUE
diff --git a/code/datums/status_effects/debuffs/genetic_damage.dm b/code/datums/status_effects/debuffs/genetic_damage.dm
index 438bcc7c6905..12512efd06af 100644
--- a/code/datums/status_effects/debuffs/genetic_damage.dm
+++ b/code/datums/status_effects/debuffs/genetic_damage.dm
@@ -5,7 +5,7 @@
id = "genetic_damage"
alert_type = null
status_type = STATUS_EFFECT_REFRESH // New effects will add to total_damage
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
tick_interval = 2 SECONDS
on_remove_on_mob_delete = TRUE // Need to unregister from owner, be_replaced() would cause runtimes
remove_on_fullheal = TRUE
diff --git a/code/datums/status_effects/debuffs/hallucination.dm b/code/datums/status_effects/debuffs/hallucination.dm
index 4c5e1c305e1b..942ab9deb0ed 100644
--- a/code/datums/status_effects/debuffs/hallucination.dm
+++ b/code/datums/status_effects/debuffs/hallucination.dm
@@ -82,7 +82,7 @@
/datum/status_effect/hallucination/sanity
id = "low sanity"
status_type = STATUS_EFFECT_REFRESH
- duration = -1 // This lasts "forever", only goes away with sanity gain
+ duration = STATUS_EFFECT_PERMANENT // This lasts "forever", only goes away with sanity gain
/datum/status_effect/hallucination/sanity/on_apply()
if(!owner.mob_mood)
diff --git a/code/datums/status_effects/debuffs/speech_debuffs.dm b/code/datums/status_effects/debuffs/speech_debuffs.dm
index 2b095bf6047f..607f78c64af2 100644
--- a/code/datums/status_effects/debuffs/speech_debuffs.dm
+++ b/code/datums/status_effects/debuffs/speech_debuffs.dm
@@ -1,5 +1,5 @@
/datum/status_effect/speech
- id = null
+ id = STATUS_EFFECT_ID_ABSTRACT
alert_type = null
remove_on_fullheal = TRUE
diff --git a/code/datums/status_effects/debuffs/tower_of_babel.dm b/code/datums/status_effects/debuffs/tower_of_babel.dm
index 1ba46d0b87b5..923938185d77 100644
--- a/code/datums/status_effects/debuffs/tower_of_babel.dm
+++ b/code/datums/status_effects/debuffs/tower_of_babel.dm
@@ -33,7 +33,7 @@
// Used by wizard magic and tower of babel event
/datum/status_effect/tower_of_babel/magical
id = "tower_of_babel_magic" // do we need a new id?
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
trait_source = TRAUMA_TRAIT
/datum/status_effect/tower_of_babel/magical/on_apply()
diff --git a/code/datums/status_effects/drug_effects.dm b/code/datums/status_effects/drug_effects.dm
index d01a92743b58..949c00d2edff 100644
--- a/code/datums/status_effects/drug_effects.dm
+++ b/code/datums/status_effects/drug_effects.dm
@@ -1,6 +1,6 @@
/datum/status_effect/woozy
id = "woozy"
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/woozy
@@ -14,7 +14,7 @@
/datum/status_effect/high_blood_pressure
id = "high_blood_pressure"
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/high_blood_pressure
@@ -40,7 +40,7 @@
/datum/status_effect/seizure
id = "seizure"
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/seizure
diff --git a/code/datums/status_effects/gas.dm b/code/datums/status_effects/gas.dm
index bf0822d879f8..f7b8cf2b375b 100644
--- a/code/datums/status_effects/gas.dm
+++ b/code/datums/status_effects/gas.dm
@@ -57,7 +57,7 @@
/datum/status_effect/freon/lasting
id = "lasting_frozen"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
/datum/status_effect/hypernob_protection
id = "hypernob_protection"
diff --git a/code/datums/status_effects/grouped_effect.dm b/code/datums/status_effects/grouped_effect.dm
index ade0a187e0db..403f1c740913 100644
--- a/code/datums/status_effects/grouped_effect.dm
+++ b/code/datums/status_effects/grouped_effect.dm
@@ -1,5 +1,7 @@
/// Status effect from multiple sources, when all sources are removed, so is the effect
/datum/status_effect/grouped
+ id = STATUS_EFFECT_ID_ABSTRACT
+ alert_type = null
// Grouped effects adds itself to [var/sources] and destroys itself if one exists already, there are never actually multiple
status_type = STATUS_EFFECT_MULTIPLE
/// A list of all sources applying this status effect. Sources are a list of keys
diff --git a/code/datums/status_effects/limited_effect.dm b/code/datums/status_effects/limited_effect.dm
index 0f56e72da52f..047a7a5ae07c 100644
--- a/code/datums/status_effects/limited_effect.dm
+++ b/code/datums/status_effects/limited_effect.dm
@@ -1,8 +1,9 @@
/// These effects reapply their on_apply() effect when refreshed while stacks < max_stacks.
/datum/status_effect/limited_buff
id = "limited_buff"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
status_type = STATUS_EFFECT_REFRESH
+ alert_type = null
///How many stacks we currently have
var/stacks = 1
///How many stacks we can have maximum
diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm
index a92823293182..062108241f86 100644
--- a/code/datums/status_effects/neutral.dm
+++ b/code/datums/status_effects/neutral.dm
@@ -2,8 +2,8 @@
/datum/status_effect/crusher_damage //tracks the damage dealt to this mob by kinetic crushers
id = "crusher_damage"
- duration = -1
- tick_interval = -1
+ duration = STATUS_EFFECT_PERMANENT
+ tick_interval = STATUS_EFFECT_NO_TICK
status_type = STATUS_EFFECT_UNIQUE
alert_type = null
var/total_damage = 0
@@ -46,7 +46,7 @@
/datum/status_effect/in_love
id = "in_love"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/in_love
var/hearts
@@ -84,6 +84,7 @@
/datum/status_effect/bounty
id = "bounty"
status_type = STATUS_EFFECT_UNIQUE
+ alert_type = null
var/mob/living/rewarded
/datum/status_effect/bounty/on_creation(mob/living/new_owner, mob/living/caster)
@@ -118,8 +119,8 @@
// heldup is for the person being aimed at
/datum/status_effect/grouped/heldup
id = "heldup"
- duration = -1
- tick_interval = -1
+ duration = STATUS_EFFECT_PERMANENT
+ tick_interval = STATUS_EFFECT_NO_TICK
status_type = STATUS_EFFECT_MULTIPLE
alert_type = /atom/movable/screen/alert/status_effect/heldup
@@ -139,8 +140,8 @@
// holdup is for the person aiming
/datum/status_effect/holdup
id = "holdup"
- duration = -1
- tick_interval = -1
+ duration = STATUS_EFFECT_PERMANENT
+ tick_interval = STATUS_EFFECT_NO_TICK
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/holdup
@@ -152,8 +153,8 @@
// this status effect is used to negotiate the high-fiving capabilities of all concerned parties
/datum/status_effect/offering
id = "offering"
- duration = -1
- tick_interval = -1
+ duration = STATUS_EFFECT_PERMANENT
+ tick_interval = STATUS_EFFECT_NO_TICK
status_type = STATUS_EFFECT_UNIQUE
alert_type = null
/// The people who were offered this item at the start
@@ -315,8 +316,8 @@
//this effect gives the user an alert they can use to surrender quickly
/datum/status_effect/grouped/surrender
id = "surrender"
- duration = -1
- tick_interval = -1
+ duration = STATUS_EFFECT_PERMANENT
+ tick_interval = STATUS_EFFECT_NO_TICK
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/surrender
@@ -344,7 +345,7 @@
/datum/status_effect/caltropped
id = "caltropped"
duration = 1 SECONDS
- tick_interval = -1 // monkestation edit
+ tick_interval = STATUS_EFFECT_NO_TICK // monkestation edit
status_type = STATUS_EFFECT_REFRESH
alert_type = null
diff --git a/code/datums/status_effects/stacking_effect.dm b/code/datums/status_effects/stacking_effect.dm
index 783d9334b215..5cc598f8710c 100644
--- a/code/datums/status_effects/stacking_effect.dm
+++ b/code/datums/status_effects/stacking_effect.dm
@@ -1,8 +1,8 @@
/// Status effects that can stack.
/datum/status_effect/stacking
- id = "stacking_base"
- duration = -1 // Only removed under specific conditions.
+ id = STATUS_EFFECT_ID_ABSTRACT
+ duration = STATUS_EFFECT_PERMANENT // Only removed under specific conditions.
tick_interval = 1 SECONDS // Deciseconds between decays, once decay starts
alert_type = null
/// How many stacks are currently accumulated.
diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm
index e1929bbdc26b..42843ffbbd46 100644
--- a/code/datums/status_effects/wound_effects.dm
+++ b/code/datums/status_effects/wound_effects.dm
@@ -72,7 +72,7 @@
id = "determination_crash"
alert_type = null
remove_on_fullheal = TRUE
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
duration = 10 SECONDS
/datum/status_effect/determination_crash/on_apply()
@@ -101,7 +101,7 @@
/datum/status_effect/limp
id = "limp"
status_type = STATUS_EFFECT_REPLACE
- tick_interval = -1 // monkestation edit
+ tick_interval = STATUS_EFFECT_NO_TICK // monkestation edit
on_remove_on_mob_delete = TRUE
alert_type = /atom/movable/screen/alert/status_effect/limp
var/msg_stage = 0//so you dont get the most intense messages immediately
@@ -216,6 +216,7 @@
id = "wound"
status_type = STATUS_EFFECT_MULTIPLE
on_remove_on_mob_delete = TRUE
+ alert_type = null
var/obj/item/bodypart/linked_limb
var/datum/wound/linked_wound
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index 3f2dde1cc0ab..e9c83f11ad6a 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -225,7 +225,9 @@ Medical HUD! Basic mode needs suit sensors on.
var/virus_threat = check_virus()
holder.pixel_y = get_cached_height() - world.icon_size
- if(HAS_TRAIT(src, TRAIT_XENO_HOST))
+ if(HAS_TRAIT(src, TRAIT_BLOB_ALLY)) //Monkestation edit: In the edge where case a blob host has a xeno in them. I think the fact they are a blob host is more important.
+ holder.icon_state = "hudill5"
+ else if(HAS_TRAIT(src, TRAIT_XENO_HOST))
holder.icon_state = "hudxeno"
else if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH)))
if((key || get_ghost(FALSE, TRUE)) && (can_defib() & DEFIB_REVIVABLE_STATES))
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index 091bb5407fad..965e0417f6f9 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -174,6 +174,14 @@
reagents.trans_to(H, reagents.total_volume, transfered_by = user, methods = INGEST)
qdel(src)
+/// Nebula vomit with extra guests
+/obj/effect/decal/cleanable/vomit/nebula/worms
+
+/obj/effect/decal/cleanable/vomit/nebula/worms/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ for (var/i in 1 to rand(2, 3))
+ new /mob/living/basic/hivelord_brood(loc)
+
/obj/effect/decal/cleanable/vomit/old
name = "crusty dried vomit"
desc = "You try not to look at the chunks, and fail."
diff --git a/code/game/objects/items/gift.dm b/code/game/objects/items/gift.dm
index 1b419999f47c..16913a80c04d 100644
--- a/code/game/objects/items/gift.dm
+++ b/code/game/objects/items/gift.dm
@@ -50,6 +50,7 @@ GLOBAL_LIST_EMPTY(possible_gifts)
M.investigate_log("has unwrapped a present containing [I.type].", INVESTIGATE_PRESENTS)
M.put_in_hands(I)
I.add_fingerprint(M)
+ I.AddComponent(/datum/component/gift_item, M) // monkestation edit: gift item info component
else
M.visible_message(span_danger("Oh no! The present that [M] opened had nothing inside it!"))
@@ -116,17 +117,24 @@ GLOBAL_LIST_EMPTY(possible_gifts)
//
// Subtypes of these items will also be blocked.
var/list/blocked_items = list(
- // Can crash people if too many are spawned.
- // NOTE: Not likely to be an issue if the amount is kept low - perhaps a limited variant
- // of this (i.e. can only spawn up to 25 humans) could be added for players to use?
- /obj/item/debug/human_spawner,
// Just leaves the coordinates everywhere
/obj/item/gps/visible_debug,
// Can lag the hell out of the server
/obj/item/gun/energy/recharge/kinetic_accelerator/meme,
// Per Biddi's suggestion; plus doesn't seem to do much anyways?
/obj/item/research,
- )
+ //only upsets people consistantly
+ /obj/item/gun/magic/wand/death,
+ /obj/item/gun/magic/wand/resurrection/debug,
+ //holy fuck why was this enabled
+ /obj/item/debug,
+ /obj/item/storage/box/debugtools,
+ /obj/item/gun/energy/beam_rifle/debug,
+ /obj/item/multitool/field_debug,
+ /obj/item/bounty_cube/debug_cube,
+ /obj/item/organ/internal/cyberimp/brain/nif/debug,
+ /obj/item/spellbook_charge/debug,
+ )
for(var/blocked_item as anything in blocked_items)
// Block the item listed, and any subtypes too.
gift_types_list -= typesof(blocked_item)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
index 526c91dbb0a4..7f758a7a6cea 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
@@ -17,6 +17,7 @@
new /obj/item/storage/bag/garment/quartermaster(src)
new /obj/item/encryptionkey/headset_cargo(src) // monkestation edit - An extra encryption key for someone joining Cargyptia
new /obj/item/cargo_teleporter(src) // monkestation edit - singular roundstart cargo teleporter
+ new /obj/item/gun/energy/disabler/cargo(src) // monkestation edit - a single disabler that can only be used in parts of cargo
/obj/structure/closet/secure_closet/quartermaster/populate_contents_immediate()
. = ..()
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 0030e5543b4e..d3c0482462e7 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -462,10 +462,10 @@
if(!unlimited)
took_presents[user.ckey] = TRUE
- if(prob(50))
+ if(prob(5))
user.put_in_hands(new gift_type(drop_location()))
return
- if(prob(1))
+ if(prob(1)) //evil pooba monke moment
new /mob/living/carbon/human/species/monkey/angry(drop_location())
to_chat(user, span_warning("A live monkey crawls out of the gift... its PISSED!!!"))
return
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 3a6bf818b77b..1c5bd2a86d9f 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -19,6 +19,7 @@ GLOBAL_PROTECT(admin_verbs_default)
/client/proc/reload_admins,
/client/proc/requests,
/client/proc/secrets,
+ /client/proc/review_cassettes, /*monkestation addition Opens the Cassette Review menu*/
/client/proc/stop_sounds,
/client/proc/tag_datum_mapview,
)
@@ -159,7 +160,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
/client/proc/toggle_random_events,
))
GLOBAL_PROTECT(admin_verbs_fun)
-GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/podspawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character, /datum/admins/proc/beaker_panel, /client/proc/spawn_mixtape)) //Monkestation Addition: mixtape spawner
+GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/podspawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character, /datum/admins/proc/beaker_panel, /client/proc/spawn_mixtape,)) //Monkestation Addition: mixtape spawner
GLOBAL_PROTECT(admin_verbs_spawn)
GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer())
GLOBAL_PROTECT(admin_verbs_server)
@@ -550,6 +551,9 @@ GLOBAL_PROTECT(admin_verbs_poll)
mob.alpha = 0 //JUUUUST IN CASE
mob.name = " "
mob.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ var/image/invisible = image(icon = 'icons/mob/simple/mob.dmi', icon_state = null, loc = mob)
+ invisible.override = TRUE
+ mob.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/actually_everyone, "stealthmin", invisible)
ADD_TRAIT(mob, TRAIT_ORBITING_FORBIDDEN, STEALTH_MODE_TRAIT)
QDEL_NULL(mob.orbiters)
@@ -560,6 +564,7 @@ GLOBAL_PROTECT(admin_verbs_poll)
/client/proc/disable_stealth_mode()
holder.fakekey = null
if(isobserver(mob))
+ mob.remove_alt_appearance("stealthmin")
mob.invisibility = initial(mob.invisibility)
mob.alpha = initial(mob.alpha)
if(mob.mind)
diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm
index 57179bd89bfc..94fde875336c 100644
--- a/code/modules/admin/holder2.dm
+++ b/code/modules/admin/holder2.dm
@@ -407,7 +407,7 @@ GLOBAL_PROTECT(href_token)
/datum/admins/proc/try_give_devtools()
if(!(rank_flags() & R_DEBUG) || owner.byond_version < 516)
return
- winset(owner, null, "browser-options=byondstorage,find,devtools")
+ winset(owner, null, "browser-options=byondstorage,find,refresh,devtools")
/datum/admins/proc/try_give_profiling()
if (CONFIG_GET(flag/forbid_admin_profiling))
diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm
index 670b2c76ec76..340cc3d17faa 100644
--- a/code/modules/admin/verbs/admingame.dm
+++ b/code/modules/admin/verbs/admingame.dm
@@ -45,6 +45,18 @@
full_version = "[M.client.byond_version].[M.client.byond_build ? M.client.byond_build : "xxx"]"
body += "
\[Byond version: [full_version]\]
"
+ // monkestation start: gift info
+ var/list/gifts = M.get_all_gift_contents()
+ var/gift_amt = length(gifts)
+ if(gift_amt)
+ body += "
Gift items in contents:
"
+ for(var/idx in 1 to gift_amt)
+ var/obj/item/gift = gifts[idx]
+ body += VV_HREF_TARGET(gift, VV_HK_EXAMINE_GIFT, "[gift.name] ([gift.type])")
+ if(idx < gift_amt)
+ body += "
"
+ // monkestation end
+
body += "
\[ "
body += "VV - "
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 6b0dcccf084d..f54444001678 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -55,6 +55,7 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
/client/proc/station_food_debug,
/client/proc/station_stack_debug,
/client/proc/check_for_obstructed_atmospherics,
+ /client/proc/export_lighting_info, // monkestation addition
))
GLOBAL_PROTECT(admin_verbs_debug_mapping)
diff --git a/code/modules/antagonists/heretic/items/corrupted_organs.dm b/code/modules/antagonists/heretic/items/corrupted_organs.dm
new file mode 100644
index 000000000000..4923487c03a3
--- /dev/null
+++ b/code/modules/antagonists/heretic/items/corrupted_organs.dm
@@ -0,0 +1,243 @@
+/// Renders you unable to see people who were heretics at the time that this organ is gained
+/obj/item/organ/internal/eyes/corrupt
+ name = "corrupt orbs"
+ desc = "These eyes have seen something they shouldn't have."
+ /// The override images we are applying
+ var/list/hallucinations
+
+/obj/item/organ/internal/eyes/corrupt/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/corrupted_organ)
+ AddElement(/datum/element/noticable_organ, "eyes have wide dilated pupils, and no iris. Something is moving in the darkness.", BODY_ZONE_PRECISE_EYES)
+
+/obj/item/organ/internal/eyes/corrupt/Insert(mob/living/carbon/organ_owner, special, drop_if_replaced)
+ . = ..()
+ if (!organ_owner.client)
+ return
+
+ var/list/human_mobs = GLOB.human_list.Copy()
+ human_mobs -= organ_owner
+ for (var/mob/living/carbon/human/check_human as anything in human_mobs)
+ if (!IS_HERETIC(check_human) && !prob(5)) // Throw in some false positives
+ continue
+ var/image/invisible_man = image('icons/blanks/32x32.dmi', check_human, "nothing")
+ invisible_man.override = TRUE
+ LAZYADD(hallucinations, invisible_man)
+
+ if (LAZYLEN(hallucinations))
+ organ_owner.client.images |= hallucinations
+
+/obj/item/organ/internal/eyes/corrupt/Remove(mob/living/carbon/organ_owner, special)
+ . = ..()
+ if (!LAZYLEN(hallucinations))
+ return
+ organ_owner.client?.images -= hallucinations
+ QDEL_NULL(hallucinations)
+
+
+/// Sometimes speak in incomprehensible tongues
+/obj/item/organ/internal/tongue/corrupt
+ name = "corrupt tongue"
+ desc = "This one tells only lies."
+
+/obj/item/organ/internal/tongue/corrupt/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/corrupted_organ)
+ AddElement(/datum/element/noticable_organ, "mouth is full of stars.", BODY_ZONE_PRECISE_MOUTH)
+
+/obj/item/organ/internal/tongue/corrupt/Insert(mob/living/carbon/organ_owner, special, drop_if_replaced)
+ . = ..()
+ RegisterSignal(organ_owner, COMSIG_MOB_SAY, PROC_REF(on_spoken))
+
+/obj/item/organ/internal/tongue/corrupt/Remove(mob/living/carbon/organ_owner, special)
+ . = ..()
+ UnregisterSignal(organ_owner, COMSIG_MOB_SAY)
+
+/// When the mob speaks, sometimes put it in a different language
+/obj/item/organ/internal/tongue/corrupt/proc/on_spoken(mob/living/organ_owner, list/speech_args)
+ SIGNAL_HANDLER
+ if (organ_owner.has_reagent(/datum/reagent/water/holywater) || prob(60))
+ return
+ speech_args[SPEECH_LANGUAGE] = /datum/language/shadowtongue
+
+
+/// Randomly secretes alcohol or hallucinogens when you're drinking something
+/obj/item/organ/internal/liver/corrupt
+ name = "corrupt liver"
+ desc = "After what you've seen you could really go for a drink."
+ /// How much extra ingredients to add?
+ var/amount_added = 5
+ /// What extra ingredients can we add?
+ var/list/extra_ingredients = list(
+ /datum/reagent/consumable/ethanol/pina_olivada,
+ /datum/reagent/consumable/ethanol/rum,
+ /datum/reagent/consumable/ethanol/thirteenloko,
+ /datum/reagent/consumable/ethanol/vodka,
+ /datum/reagent/consumable/superlaughter,
+ /datum/reagent/drug/bath_salts,
+ /datum/reagent/drug/blastoff,
+ /datum/reagent/drug/happiness,
+ /datum/reagent/drug/mushroomhallucinogen,
+ )
+
+/obj/item/organ/internal/liver/corrupt/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/corrupted_organ)
+
+/obj/item/organ/internal/liver/corrupt/Insert(mob/living/carbon/organ_owner, special, drop_if_replaced)
+ . = ..()
+ RegisterSignal(organ_owner, COMSIG_ATOM_EXPOSE_REAGENTS, PROC_REF(on_drank))
+
+/obj/item/organ/internal/liver/corrupt/Remove(mob/living/carbon/organ_owner, special)
+ . = ..()
+ UnregisterSignal(organ_owner, COMSIG_ATOM_EXPOSE_REAGENTS)
+
+/// If we drank something, add a little extra
+/obj/item/organ/internal/liver/corrupt/proc/on_drank(atom/source, list/reagents, datum/reagents/source_reagents, methods)
+ SIGNAL_HANDLER
+ if (!(methods & INGEST))
+ return
+ var/datum/reagents/extra_reagents = new()
+ extra_reagents.add_reagent(pick(extra_ingredients), amount_added)
+ extra_reagents.trans_to(source, amount_added, methods = INJECT)
+ if (prob(20))
+ to_chat(source, span_warning("As you take a sip, you feel something bubbling in your stomach..."))
+
+
+/// Rapidly become hungry if you are not digesting blood
+/obj/item/organ/internal/stomach/corrupt
+ name = "corrupt stomach"
+ desc = "This parasite demands an unwholesome diet in order to be satisfied."
+ /// Do we have an unholy thirst?
+ var/thirst_satiated = FALSE
+ /// Timer for when we get thirsty again
+ var/thirst_timer
+ /// How long until we prompt the player to drink blood again?
+ COOLDOWN_DECLARE(message_cooldown)
+
+/obj/item/organ/internal/stomach/corrupt/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/corrupted_organ)
+ AddElement(/datum/element/noticable_organ, "appear%PRONOUN_S to have an unhealthy pallor.")
+
+/obj/item/organ/internal/stomach/corrupt/Insert(mob/living/carbon/organ_owner, special, drop_if_replaced)
+ . = ..()
+ RegisterSignal(organ_owner, COMSIG_ATOM_EXPOSE_REAGENTS, PROC_REF(on_drank))
+
+/obj/item/organ/internal/stomach/corrupt/Remove(mob/living/carbon/organ_owner, special)
+ . = ..()
+ UnregisterSignal(organ_owner, COMSIG_ATOM_EXPOSE_REAGENTS)
+
+/// Check if we drank a little blood
+/obj/item/organ/internal/stomach/corrupt/proc/on_drank(atom/source, list/reagents, datum/reagents/source_reagents, methods)
+ SIGNAL_HANDLER
+ if (!(methods & INGEST))
+ return
+
+ var/contains_blood = locate(/datum/reagent/blood) in reagents
+ if (!contains_blood)
+ return
+
+ if (!thirst_satiated)
+ to_chat(source, span_cultitalic("The thirst is satisfied... for now."))
+ thirst_satiated = TRUE
+ deltimer(thirst_timer)
+ thirst_timer = addtimer(VARSET_CALLBACK(src, thirst_satiated, FALSE), 3 MINUTES, TIMER_STOPPABLE | TIMER_DELETE_ME)
+
+/obj/item/organ/internal/stomach/corrupt/handle_hunger(mob/living/carbon/human/human, seconds_per_tick, times_fired)
+ if (thirst_satiated || human.has_reagent(/datum/reagent/water/holywater))
+ return ..()
+
+ human.adjust_nutrition(-1 * seconds_per_tick)
+
+ if (!COOLDOWN_FINISHED(src, message_cooldown))
+ return ..()
+ COOLDOWN_START(src, message_cooldown, 30 SECONDS)
+
+ var/static/list/blood_messages = list(
+ "Blood...",
+ "Everyone suddenly looks so tasty.",
+ "The blood...",
+ "There's an emptiness in you that only blood can fill.",
+ "You could really go for some blood right now.",
+ "You feel the blood rushing through your veins.",
+ "You think about biting someone's throat.",
+ "Your stomach growls and you feel a metallic taste in your mouth.",
+ )
+ to_chat(human, span_cultitalic(pick(blood_messages)))
+
+ return ..()
+
+
+/// Occasionally bombards you with spooky hands and lets everyone hear your pulse.
+/obj/item/organ/internal/heart/corrupt
+ name = "corrupt heart"
+ desc = "What corruption is this spreading along with the blood?"
+ /// How long until the next heart?
+ COOLDOWN_DECLARE(hand_cooldown)
+
+/obj/item/organ/internal/heart/corrupt/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/corrupted_organ)
+
+/obj/item/organ/internal/heart/corrupt/on_life(seconds_per_tick, times_fired)
+ . = ..()
+ var/obj/item/organ/internal/heart/heart = owner.get_organ_slot(ORGAN_SLOT_HEART)
+ if (!COOLDOWN_FINISHED(src, hand_cooldown) || IS_IN_MANSUS(owner) || !owner.needs_heart() || !heart.beating || owner.has_reagent(/datum/reagent/water/holywater))
+ return
+ fire_curse_hand(owner)
+ COOLDOWN_START(src, hand_cooldown, rand(6 SECONDS, 45 SECONDS)) // Wide variance to put you off guard
+
+
+/// Sometimes cough out some kind of dangerous gas
+/obj/item/organ/internal/lungs/corrupt
+ name = "corrupt lungs"
+ desc = "Some things SHOULD be drowned in tar."
+ /// How likely are we not to cough every time we take a breath?
+ var/cough_chance = 15
+ /// How much gas to emit?
+ var/gas_amount = 30
+ /// What can we cough up?
+ var/list/gas_types = list(
+ /datum/gas/bz = 30,
+ /datum/gas/miasma = 50,
+ /datum/gas/plasma = 20,
+ )
+
+/obj/item/organ/internal/lungs/corrupt/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/corrupted_organ)
+
+/obj/item/organ/internal/lungs/corrupt/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/breather)
+ . = ..()
+ if (!. || IS_IN_MANSUS(owner) || breather.has_reagent(/datum/reagent/water/holywater) || !prob(cough_chance))
+ return
+ breather.emote("cough");
+ var/chosen_gas = pick_weight(gas_types)
+ var/datum/gas_mixture/mix_to_spawn = new()
+ mix_to_spawn.add_gas(pick(chosen_gas))
+ mix_to_spawn.gases[chosen_gas][MOLES] = gas_amount
+ mix_to_spawn.temperature = breather.bodytemperature
+ log_atmos("[owner] coughed some gas into the air due to their corrupted lungs.", mix_to_spawn)
+ var/turf/open/our_turf = get_turf(breather)
+ our_turf.assume_air(mix_to_spawn)
+
+
+/// It's full of worms
+/obj/item/organ/internal/appendix/corrupt
+ name = "corrupt appendix"
+ desc = "What kind of dark, cosmic force is even going to bother to corrupt an appendix?"
+ /// How likely are we to spawn worms?
+ var/worm_chance = 2
+
+/obj/item/organ/internal/appendix/corrupt/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/corrupted_organ)
+ AddElement(/datum/element/noticable_organ, "abdomen is distended... and wiggling.", BODY_ZONE_PRECISE_GROIN)
+
+/obj/item/organ/internal/appendix/corrupt/on_life(seconds_per_tick, times_fired)
+ . = ..()
+ if (owner.stat != CONSCIOUS || owner.has_reagent(/datum/reagent/water/holywater) || IS_IN_MANSUS(owner) || !SPT_PROB(worm_chance, seconds_per_tick))
+ return
+ owner.vomit(vomit_type = /obj/effect/decal/cleanable/vomit/nebula/worms, distance = 0)
+ owner.Knockdown(0.5 SECONDS)
diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm
index 6faf49021266..1c001c57fcd2 100644
--- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm
+++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm
@@ -86,3 +86,17 @@
return
bloodiest_wound.adjust_blood_flow(-0.5)
+
+/// Torment the target with a frightening hand
+/proc/fire_curse_hand(mob/living/carbon/victim)
+ var/grab_dir = turn(victim.dir, pick(-90, 90, 180, 180)) // Not in front, favour behind
+ var/turf/spawn_turf = get_ranged_target_turf(victim, grab_dir, 8)
+ if (isnull(spawn_turf))
+ return
+ new /obj/effect/temp_visual/dir_setting/curse/grasp_portal(spawn_turf, victim.dir)
+ playsound(spawn_turf, 'sound/effects/curse2.ogg', 80, TRUE, -1)
+ var/obj/projectile/curse_hand/hel/hand = new (spawn_turf)
+ hand.preparePixelProjectile(victim, spawn_turf)
+ if (QDELETED(hand)) // safety check if above fails - above has a stack trace if it does fail
+ return
+ hand.fire()
diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_curse.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_curse.dm
new file mode 100644
index 000000000000..6a12ecc30922
--- /dev/null
+++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_curse.dm
@@ -0,0 +1,93 @@
+/// A curse given to people to disencourage them from retaliating against someone who sacrificed them
+/datum/status_effect/heretic_curse
+ id = "heretic_curse"
+ alert_type = null
+ status_type = STATUS_EFFECT_MULTIPLE // In case several different people sacrifice you, unlucky
+ /// Who cursed us?
+ var/mob/living/the_curser
+ /// Don't experience bad things too often
+ COOLDOWN_DECLARE(consequence_cooldown)
+
+/datum/status_effect/heretic_curse/on_creation(mob/living/new_owner, mob/living/the_curser)
+ src.the_curser = the_curser
+ return ..()
+
+/datum/status_effect/heretic_curse/Destroy()
+ the_curser = null
+ return ..()
+
+/datum/status_effect/heretic_curse/on_apply()
+ if (isnull(the_curser) || !iscarbon(owner))
+ return FALSE
+
+ the_curser.AddElement(/datum/element/relay_attackers)
+ RegisterSignal(the_curser, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_curser_attacked))
+ RegisterSignal(the_curser, COMSIG_QDELETING, PROC_REF(on_curser_destroyed))
+
+ owner.AddElement(/datum/element/relay_attackers)
+ RegisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_owner_attacked))
+
+ return TRUE
+
+/datum/status_effect/heretic_curse/on_remove()
+ UnregisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED)
+ UnregisterSignal(the_curser, COMSIG_ATOM_WAS_ATTACKED)
+ the_curser = null
+
+
+/// If the heretic that cursed us is destroyed this thing is useless now
+/datum/status_effect/heretic_curse/proc/on_curser_destroyed()
+ SIGNAL_HANDLER
+ qdel(src)
+
+/// If we attack the guy who cursed us, that's no good
+/datum/status_effect/heretic_curse/proc/on_curser_attacked(datum/source, mob/attacker)
+ SIGNAL_HANDLER
+ if (attacker != owner || !HAS_TRAIT(source, TRAIT_ALLOW_HERETIC_CASTING))
+ return
+ log_combat(owner, the_curser, "attacked", addition = "and lost some organs because they had previously been sacrificed by them.")
+ experience_the_consequences()
+
+/// If we are attacked by the guy who cursed us, that's also no good
+/datum/status_effect/heretic_curse/proc/on_owner_attacked(datum/source, mob/attacker)
+ SIGNAL_HANDLER
+ if (attacker != the_curser || !HAS_TRAIT(attacker, TRAIT_ALLOW_HERETIC_CASTING))
+ return
+ log_combat(the_curser, owner, "attacked", addition = "and as they had previously sacrificed them, removed some of their organs.")
+ experience_the_consequences()
+
+/// Experience something you may not enjoy which may also significantly shorten your lifespan
+/datum/status_effect/heretic_curse/proc/experience_the_consequences()
+ if (!COOLDOWN_FINISHED(src, consequence_cooldown) || owner.stat != CONSCIOUS)
+ return
+
+ var/mob/living/carbon/carbon_owner = owner
+ var/obj/item/bodypart/chest/organ_storage = owner.get_bodypart(BODY_ZONE_CHEST)
+ if (isnull(organ_storage))
+ carbon_owner.gib() // IDK how you don't have a chest but you're not getting away that easily
+ return
+
+ var/list/removable_organs = list()
+ for(var/obj/item/organ/internal/bodypart_organ in organ_storage.contents)
+ if(bodypart_organ.organ_flags & ORGAN_UNREMOVABLE)
+ continue
+ removable_organs += bodypart_organ
+
+ if (!length(removable_organs))
+ return // This one is a little more possible but they're probably already in pretty bad shape by this point
+
+ var/obj/item/organ/internal/removing_organ = pick(removable_organs)
+
+ if (carbon_owner.vomit(blood = TRUE))
+ carbon_owner.visible_message(span_boldwarning("[carbon_owner] vomits out [carbon_owner.p_their()] [removing_organ]"))
+ else
+ carbon_owner.visible_message(span_boldwarning("[carbon_owner]'s [removing_organ] rips itself out of `[carbon_owner.p_their()] chest!"))
+
+ removing_organ.Remove(carbon_owner)
+
+ var/turf/land_turf = get_step(carbon_owner, carbon_owner.dir)
+ if (land_turf.is_blocked_turf(exclude_mobs = TRUE))
+ land_turf = carbon_owner.drop_location()
+
+ removing_organ.forceMove(land_turf)
+ COOLDOWN_START(src, consequence_cooldown, 10 SECONDS)
diff --git a/code/modules/antagonists/heretic/magic/ash_ascension.dm b/code/modules/antagonists/heretic/magic/ash_ascension.dm
index c9b6b2ce0458..61b8b66dc403 100644
--- a/code/modules/antagonists/heretic/magic/ash_ascension.dm
+++ b/code/modules/antagonists/heretic/magic/ash_ascension.dm
@@ -33,7 +33,7 @@
/// Simple status effect for adding a ring of fire around a mob.
/datum/status_effect/fire_ring
id = "fire_ring"
- tick_interval = 0.1 SECONDS
+ tick_interval = 0.2 SECONDS
status_type = STATUS_EFFECT_REFRESH
alert_type = null
/// The radius of the ring around us.
diff --git a/code/modules/antagonists/heretic/magic/shadow_cloak.dm b/code/modules/antagonists/heretic/magic/shadow_cloak.dm
index ad942c71a328..3aa0b68c7c78 100644
--- a/code/modules/antagonists/heretic/magic/shadow_cloak.dm
+++ b/code/modules/antagonists/heretic/magic/shadow_cloak.dm
@@ -126,7 +126,7 @@
/datum/status_effect/shadow_cloak
id = "shadow_cloak"
alert_type = null
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
/// How much damage we've been hit with
var/damage_sustained = 0
/// How much damage we can be hit with before it starts rolling reveal chances
diff --git a/code/modules/antagonists/heretic/magic/star_touch.dm b/code/modules/antagonists/heretic/magic/star_touch.dm
index bab07f0871bd..6095dcd01a32 100644
--- a/code/modules/antagonists/heretic/magic/star_touch.dm
+++ b/code/modules/antagonists/heretic/magic/star_touch.dm
@@ -116,7 +116,7 @@
/datum/status_effect/cosmic_beam
id = "cosmic_beam"
- tick_interval = 0.1 SECONDS
+ tick_interval = 0.2 SECONDS
duration = 1 MINUTES
status_type = STATUS_EFFECT_REPLACE
alert_type = null
diff --git a/code/modules/antagonists/heretic/status_effects/buffs.dm b/code/modules/antagonists/heretic/status_effects/buffs.dm
index 46f1d65acfd2..667668ae1bc7 100644
--- a/code/modules/antagonists/heretic/status_effects/buffs.dm
+++ b/code/modules/antagonists/heretic/status_effects/buffs.dm
@@ -109,7 +109,7 @@
id = "Silver Knives"
alert_type = null
status_type = STATUS_EFFECT_MULTIPLE
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
/// The number of blades we summon up to.
var/max_num_blades = 4
/// The radius of the blade's orbit.
@@ -242,7 +242,7 @@
/datum/status_effect/caretaker_refuge
id = "Caretaker’s Last Refuge"
status_type = STATUS_EFFECT_REFRESH
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
alert_type = null
var/static/list/caretaking_traits = list(TRAIT_HANDS_BLOCKED, TRAIT_IGNORESLOWDOWN, TRAIT_SECLUDED_LOCATION)
diff --git a/code/modules/antagonists/heretic/status_effects/debuffs.dm b/code/modules/antagonists/heretic/status_effects/debuffs.dm
index 1088f846525f..9050cb97d247 100644
--- a/code/modules/antagonists/heretic/status_effects/debuffs.dm
+++ b/code/modules/antagonists/heretic/status_effects/debuffs.dm
@@ -31,7 +31,7 @@
/datum/status_effect/void_chill/lasting
id = "lasting_void_chill"
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
/datum/movespeed_modifier/void_chill
multiplicative_slowdown = 0.3
@@ -199,7 +199,7 @@
alert_type = /atom/movable/screen/alert/status_effect/heretic_lastresort
duration = 12 SECONDS
status_type = STATUS_EFFECT_REPLACE
- tick_interval = -1
+ tick_interval = STATUS_EFFECT_NO_TICK
/atom/movable/screen/alert/status_effect/heretic_lastresort
name = "Last Resort"
@@ -219,7 +219,7 @@
/datum/status_effect/moon_converted
id = "moon converted"
alert_type = /atom/movable/screen/alert/status_effect/moon_converted
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
status_type = STATUS_EFFECT_REPLACE
///used to track damage
var/damage_sustained = 0
diff --git a/code/modules/antagonists/heretic/status_effects/ghoul.dm b/code/modules/antagonists/heretic/status_effects/ghoul.dm
index ff730573da59..4f0d89ee815c 100644
--- a/code/modules/antagonists/heretic/status_effects/ghoul.dm
+++ b/code/modules/antagonists/heretic/status_effects/ghoul.dm
@@ -1,7 +1,7 @@
/datum/status_effect/ghoul
id = "ghoul"
status_type = STATUS_EFFECT_UNIQUE
- duration = -1
+ duration = STATUS_EFFECT_PERMANENT
alert_type = /atom/movable/screen/alert/status_effect/ghoul
/// The new max health value set for the ghoul, if supplied
var/new_max_health
diff --git a/code/modules/asset_cache/asset_cache_client.dm b/code/modules/asset_cache/asset_cache_client.dm
index 3cff8cb41f3e..cf786de09e8b 100644
--- a/code/modules/asset_cache/asset_cache_client.dm
+++ b/code/modules/asset_cache/asset_cache_client.dm
@@ -36,7 +36,10 @@
var/job = ++last_asset_job
var/t = 0
var/timeout_time = timeout
- src << browse({""}, "window=asset_cache_browser&file=asset_cache_send_verify.htm")
+ if(byond_version < 516)
+ src << browse({""}, "window=asset_cache_browser&file=asset_cache_send_verify.htm")
+ else
+ src << browse({""}, "window=asset_cache_browser&file=asset_cache_send_verify.htm")
while(!completed_asset_jobs["[job]"] && t < timeout_time) // Reception is handled in Topic()
stoplag(1) // Lock up the caller until this is received.
diff --git a/code/modules/asset_cache/asset_list.dm b/code/modules/asset_cache/asset_list.dm
index b99dec3a9744..ff8f58be33a2 100644
--- a/code/modules/asset_cache/asset_list.dm
+++ b/code/modules/asset_cache/asset_list.dm
@@ -8,10 +8,12 @@ GLOBAL_LIST_EMPTY(asset_datums)
//get an assetdatum or make a new one
//does NOT ensure it's filled, if you want that use get_asset_datum()
-/proc/load_asset_datum(type)
+/proc/load_asset_datum(type) as /datum/asset
+ RETURN_TYPE(/datum/asset)
return GLOB.asset_datums[type] || new type()
-/proc/get_asset_datum(type)
+/proc/get_asset_datum(type) as /datum/asset
+ RETURN_TYPE(/datum/asset)
var/datum/asset/loaded_asset = GLOB.asset_datums[type] || new type()
return loaded_asset.ensure_ready()
diff --git a/code/modules/asset_cache/validate_assets.html b/code/modules/asset_cache/validate_assets.html
index 78bcbb92a1ab..70fdca8a9d77 100644
--- a/code/modules/asset_cache/validate_assets.html
+++ b/code/modules/asset_cache/validate_assets.html
@@ -8,7 +8,7 @@
//this is used over window.location because window.location has a character limit in IE.
function sendbyond(text) {
var xhr = new XMLHttpRequest();
- xhr.open('GET', '?'+text, true);
+ xhr.open('GET', 'byond://?' + text, true);
xhr.send(null);
}
var xhr = new XMLHttpRequest();
@@ -24,6 +24,6 @@
};
xhr.send(null);
-
+