diff --git a/.vscode/launch.json b/.vscode/launch.json
index bf3a209531db0..ddaeb44aefc0b 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -54,6 +54,13 @@
"-trusted"
],
"preLaunchTask": "Build All (low memory mode)"
+ },
+ {
+ "type": "opendream",
+ "request": "launch",
+ "name": "Launch OpenDream (requires extension, 64 bit rustg, and an SS14 account)",
+ "preLaunchTask": "OpenDream: compile ${command:CurrentDME}",
+ "json_path": "${workspaceFolder}/${command:CurrentJson}"
}
]
}
diff --git a/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm b/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm
index 58bad24369050..1d5354799e735 100644
--- a/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm
+++ b/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm
@@ -42,7 +42,7 @@
/area/ruin/space/ks13/science/rnd)
"aj" = (
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"ak" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/table,
@@ -60,8 +60,9 @@
/area/ruin/space/ks13/service/kitchen)
"ar" = (
/obj/item/storage/box/lights/mixed,
+/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"as" = (
/obj/item/kirbyplants/random/dead,
/obj/effect/decal/cleanable/dirt,
@@ -117,6 +118,13 @@
/obj/structure/lattice,
/turf/template_noop,
/area/space/nearstation)
+"aV" = (
+/obj/structure/girder/reinforced,
+/obj/machinery/atmospherics/components/unary/portables_connector/visible{
+ dir = 1
+ },
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"aW" = (
/obj/structure/window/spawner/directional/south,
/obj/structure/chair{
@@ -131,13 +139,21 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/engineering/atmos)
"bm" = (
-/obj/item/stack/rods,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/engineering/aux_storage)
+"bn" = (
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/science/genetics)
"bp" = (
/obj/structure/lattice,
/turf/template_noop,
/area/ruin/space/solars/ks13/aft_solars)
+"bC" = (
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"bE" = (
/obj/structure/table_frame,
/obj/item/circuitboard/machine/thermomachine,
@@ -155,6 +171,10 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/hallway/aft)
+"bM" = (
+/obj/item/stack/rods,
+/turf/template_noop,
+/area/ruin/space/ks13/engineering/supermatter)
"bN" = (
/obj/machinery/light/small/directional/north,
/obj/effect/mapping_helpers/broken_floor,
@@ -174,6 +194,12 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/ruin/space/ks13/science/ordnance)
+"bT" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/shard/plasma,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"bY" = (
/obj/effect/mapping_helpers/burnt_floor,
/obj/effect/decal/cleanable/dirt,
@@ -251,6 +277,11 @@
},
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/security/sec)
+"cE" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/grille,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"cI" = (
/obj/structure/table_frame,
/turf/open/floor/plating/airless,
@@ -262,6 +293,12 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/ruin/space/ks13/security/court)
+"cO" = (
+/obj/structure/chair{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/ruin/space/ks13/hallway/starboard_bow)
"cR" = (
/obj/machinery/computer/monitor{
dir = 4
@@ -283,7 +320,7 @@
"dj" = (
/obj/structure/closet/radiation,
/turf/open/floor/iron,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"dn" = (
/obj/structure/table,
/obj/item/paper/crumpled,
@@ -384,6 +421,11 @@
"dT" = (
/turf/closed/wall,
/area/ruin/space/ks13/hallway/starboard_bow)
+"dU" = (
+/obj/structure/door_assembly/door_assembly_eng,
+/obj/structure/cable,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"dY" = (
/obj/machinery/door/window/left/directional/south{
name = "Bridge Access"
@@ -395,6 +437,20 @@
/obj/item/paper/fluff/ruins/thederelict/syndie_mission,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/engineering/aft_solars_control)
+"ej" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/cable,
+/obj/effect/decal/remains/human{
+ desc = "This guy seemed to have died in terrible way! Half his remains are dust.";
+ name = "Syndicate agent remains"
+ },
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
+"ek" = (
+/obj/item/shard/plasma,
+/obj/effect/decal/cleanable/greenglow/radioactive,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"eu" = (
/obj/structure/rack,
/obj/effect/spawner/random/engineering/vending_restock,
@@ -435,12 +491,15 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/engineering/atmos)
"eQ" = (
-/obj/effect/mapping_helpers/broken_floor,
-/obj/structure/chair{
- dir = 1
+/obj/machinery/atmospherics/components/unary/passive_vent{
+ dir = 4
},
-/turf/open/floor/iron,
-/area/ruin/space/ks13/hallway/starboard_bow)
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
+"eU" = (
+/obj/item/stack/sheet/iron,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"eV" = (
/obj/structure/cable,
/obj/effect/mapping_helpers/broken_floor,
@@ -468,7 +527,7 @@
"fg" = (
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"fz" = (
/obj/structure/sign/departments/medbay/alt/directional/west,
/obj/item/kirbyplants/random/dead,
@@ -484,6 +543,10 @@
/obj/structure/chair,
/turf/open/floor/iron/white/airless,
/area/ruin/space/ks13/medical/medbay)
+"fE" = (
+/obj/effect/mapping_helpers/broken_floor,
+/turf/closed/wall/r_wall,
+/area/ruin/space/ks13/engineering/supermatter)
"fH" = (
/obj/machinery/door/morgue{
name = "Chaplains Office";
@@ -522,7 +585,7 @@
"gd" = (
/obj/machinery/portable_atmospherics/canister/plasma,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"ge" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -545,12 +608,17 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/ai/vault)
+"gu" = (
+/obj/structure/table_frame,
+/obj/effect/mapping_helpers/burnt_floor,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/medical/medbay)
"gB" = (
/obj/effect/spawner/structure/window/hollow/reinforced/end{
dir = 4
},
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"gG" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/airless,
@@ -585,10 +653,10 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/hallway/central)
"hD" = (
-/obj/item/screwdriver,
-/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/item/stack/ore/slag,
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/engineering/grav_gen)
"hK" = (
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/engineering/aft_solars_control)
@@ -626,7 +694,7 @@
},
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"ig" = (
/turf/closed/wall/r_wall,
/area/ruin/space/ks13/command/eva)
@@ -657,6 +725,12 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/ai/corridor)
+"iA" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/grille/broken,
+/obj/item/stack/rods,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"iF" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -744,7 +818,7 @@
/obj/item/stack/rods,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"jV" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
/turf/open/floor/plating/airless,
@@ -770,6 +844,10 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/science/ordnance_hall)
+"kw" = (
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/ruin/space/ks13/engineering/grav_gen)
"kx" = (
/obj/machinery/door/window/left/directional/west{
name = "AI Upload Access"
@@ -859,12 +937,31 @@
"lq" = (
/turf/open/floor/circuit/red/off,
/area/ruin/space/ks13/ai/corridor)
-"lw" = (
+"lt" = (
/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/ai/vault)
+"lu" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/reflector/box{
+ dir = 1
+ },
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
+"lv" = (
+/obj/item/stack/rods,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/reflector{
+ dir = 10
+ },
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
+"lw" = (
/obj/item/chair,
/obj/machinery/light/small/broken/directional/east,
-/turf/template_noop,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/effect/mapping_helpers/burnt_floor,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/medical/medbay)
"lz" = (
/obj/machinery/door/airlock/security{
name = "Security"
@@ -907,6 +1004,12 @@
"mb" = (
/turf/open/floor/engine/airless,
/area/ruin/space/ks13/engineering/atmos)
+"mc" = (
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating/airless{
+ luminosity = 2
+ },
+/area/ruin/space/ks13/engineering/supermatter)
"me" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
@@ -946,7 +1049,7 @@
/obj/structure/lattice,
/obj/structure/frame/machine,
/turf/template_noop,
-/area/space/nearstation)
+/area/ruin/space/ks13/service/kitchen)
"mQ" = (
/obj/structure/girder,
/turf/open/floor/plating/airless,
@@ -998,10 +1101,10 @@
/turf/open/floor/plating/airless,
/area/ruin/space/solars/ks13/sb_bow_solars)
"nI" = (
-/obj/structure/table_frame,
/obj/effect/mapping_helpers/burnt_floor,
+/obj/structure/table_frame,
/turf/open/floor/plating/airless,
-/area/space/nearstation)
+/area/ruin/space/ks13/medical/medbay)
"nK" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/effect/mapping_helpers/apc/no_charge,
@@ -1062,7 +1165,7 @@
"ou" = (
/obj/structure/door_assembly/door_assembly_eng,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"ow" = (
/obj/item/stack/cable_coil/cut,
/turf/open/floor/plating/airless,
@@ -1088,6 +1191,14 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"oE" = (
+/obj/machinery/atmospherics/components/unary/portables_connector/visible{
+ dir = 1
+ },
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/structure/fluff/broken_canister_frame,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"oF" = (
/obj/effect/decal/cleanable/glass,
/turf/open/floor/plating/airless,
@@ -1214,7 +1325,7 @@
dir = 8
},
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"pj" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle{
dir = 4
@@ -1280,7 +1391,7 @@
/obj/effect/mapping_helpers/broken_floor,
/obj/structure/cable,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"pz" = (
/obj/effect/spawner/structure/window/hollow/reinforced/end{
dir = 4
@@ -1302,6 +1413,12 @@
/obj/item/shard,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/service/cafe)
+"pD" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/shard/plasma,
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/iron/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"pF" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/burnt_floor,
@@ -1379,11 +1496,16 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/chapel,
/area/ruin/space/ks13/service/chapel)
+"qa" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/shard/plasma,
+/turf/open/floor/iron/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"qd" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/structure/cable,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"qe" = (
/obj/effect/spawner/structure/window/hollow/reinforced/directional{
dir = 1
@@ -1430,12 +1552,11 @@
},
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
/turf/open/floor/iron,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"qv" = (
-/obj/effect/decal/cleanable/glass,
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/service/kitchen)
"qw" = (
/obj/effect/spawner/structure/window/hollow/reinforced/end{
dir = 8
@@ -1447,6 +1568,9 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/white/airless,
/area/ruin/space/ks13/medical/medbay)
+"qB" = (
+/turf/template_noop,
+/area/ruin/space/ks13/hallway/central)
"qC" = (
/obj/machinery/door/window/right/directional/east{
name = "AI Upload"
@@ -1520,8 +1644,9 @@
/area/ruin/space/ks13/security/court_hall)
"qW" = (
/obj/effect/spawner/random/maintenance,
+/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"qX" = (
/obj/structure/cable,
/turf/open/floor/plating/airless,
@@ -1548,11 +1673,9 @@
/turf/open/floor/plating,
/area/ruin/space/ks13/engineering/sb_bow_solars_control)
"rd" = (
-/obj/effect/spawner/structure/window/hollow/reinforced/end{
- dir = 1
- },
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/structure/lattice,
+/turf/template_noop,
+/area/template_noop)
"re" = (
/obj/structure/girder,
/turf/open/floor/plating/airless,
@@ -1764,6 +1887,10 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/iron,
/area/ruin/space/ks13/command/bridge)
+"sf" = (
+/obj/structure/chair,
+/turf/open/floor/plating,
+/area/ruin/space/ks13/hallway/starboard_bow)
"sg" = (
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating/airless,
@@ -1797,6 +1924,12 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"so" = (
+/obj/structure/grille/broken,
+/obj/item/shard/plasma,
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"sp" = (
/obj/structure/grille/broken,
/obj/effect/decal/cleanable/glass,
@@ -1887,11 +2020,13 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/security/sec)
"sJ" = (
-/obj/effect/spawner/structure/window/hollow/reinforced/middle{
- dir = 4
+/obj/machinery/door/airlock/engineering{
+ name = "Engine Room"
},
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"sK" = (
/obj/structure/grille/broken,
/obj/effect/decal/cleanable/glass,
@@ -1953,10 +2088,10 @@
/obj/effect/mapping_helpers/apc/no_charge,
/obj/structure/cable,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"sU" = (
/turf/closed/wall/r_wall,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"sX" = (
/obj/effect/decal/cleanable/blood/footprints{
dir = 1
@@ -1969,10 +2104,13 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/security/sec)
"sZ" = (
-/obj/machinery/light/small/directional/south,
+/turf/template_noop,
+/area/ruin/space/ks13/service/jani)
+"ta" = (
/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/item/stack/cable_coil/cut,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"tb" = (
/turf/closed/wall/r_wall,
/area/ruin/space/ks13/science/ordnance_hall)
@@ -1980,11 +2118,9 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/service/hydro)
"te" = (
-/obj/item/shard,
-/obj/effect/mapping_helpers/broken_floor,
-/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/effect/decal/cleanable/greenglow/radioactive,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"th" = (
/obj/structure/cable,
/turf/open/floor/iron/airless,
@@ -2096,6 +2232,11 @@
/obj/effect/spawner/structure/window/hollow/middle,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/hallway/central)
+"tU" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/stack/sheet/iron,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"tV" = (
/obj/structure/sign/warning/explosives/alt/directional/south,
/turf/open/floor/iron,
@@ -2107,7 +2248,7 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
/obj/structure/cable,
/turf/open/floor/iron,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"tY" = (
/turf/closed/wall/r_wall,
/area/ruin/space/ks13/engineering/atmos)
@@ -2153,10 +2294,8 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/science/genetics)
"ui" = (
-/obj/effect/mapping_helpers/broken_floor,
-/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/turf/template_noop,
+/area/ruin/space/ks13/ai/vault)
"uk" = (
/obj/machinery/sleeper,
/obj/effect/decal/cleanable/dirt,
@@ -2488,6 +2627,11 @@
/obj/structure/cable,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/hallway/aft)
+"wr" = (
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/item/stack/sheet/plasteel,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"wt" = (
/obj/effect/decal/cleanable/dirt,
/obj/item/clothing/head/chaplain/bishopmitre,
@@ -2541,7 +2685,7 @@
dir = 8
},
/turf/open/floor/plating/airless,
-/area/space/nearstation)
+/area/ruin/space/ks13/medical/medbay)
"wF" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/burnt_floor,
@@ -2720,6 +2864,11 @@
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/medical/medbay)
+"xy" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/clothing/head/helmet/space/eva,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"xA" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/effect/mapping_helpers/apc/no_charge,
@@ -2767,7 +2916,7 @@
/area/ruin/space/ks13/engineering/aft_solars_control)
"xJ" = (
/turf/template_noop,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"xL" = (
/obj/structure/rack,
/obj/item/circuitboard/machine/chem_dispenser/drinks{
@@ -2890,7 +3039,7 @@
/obj/effect/mapping_helpers/burnt_floor,
/obj/structure/cable,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"yq" = (
/turf/closed/wall,
/area/ruin/space/ks13/medical/morgue)
@@ -2898,7 +3047,7 @@
/obj/item/storage/toolbox/syndicate,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"yt" = (
/obj/structure/girder/reinforced,
/turf/open/floor/plating/airless,
@@ -3063,7 +3212,12 @@
/obj/item/stack/sheet/glass,
/obj/structure/lattice,
/turf/template_noop,
-/area/space/nearstation)
+/area/ruin/space/ks13/ai/vault)
+"zg" = (
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/item/shard/plasma,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"zi" = (
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
@@ -3123,7 +3277,7 @@
"zv" = (
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"zx" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle{
dir = 4
@@ -3266,6 +3420,11 @@
/obj/machinery/portable_atmospherics/pump,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/hallway/central)
+"Al" = (
+/obj/item/shard/plasma,
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"Am" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/effect/mapping_helpers/apc/no_charge,
@@ -3551,9 +3710,10 @@
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/engineering/atmos)
"BI" = (
-/obj/effect/spawner/structure/window/hollow/reinforced/end,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/grille/broken,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"BJ" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/effect/decal/cleanable/dirt,
@@ -3640,7 +3800,12 @@
pixel_x = -13
},
/turf/template_noop,
-/area/space/nearstation)
+/area/ruin/space/ks13/science/genetics)
+"Ck" = (
+/obj/structure/grille/broken,
+/obj/effect/mapping_helpers/burnt_floor,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Co" = (
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/iron/white/airless,
@@ -3697,7 +3862,7 @@
/obj/effect/mapping_helpers/burnt_floor,
/obj/structure/cable,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"CI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/visible,
/turf/open/floor/plating/airless,
@@ -3715,6 +3880,11 @@
/obj/structure/table,
/turf/open/floor/iron,
/area/ruin/space/ks13/command/bridge)
+"CM" = (
+/obj/machinery/light/small/directional/south,
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"CN" = (
/obj/effect/mapping_helpers/burnt_floor,
/obj/structure/closet/crate/bin,
@@ -3752,11 +3922,15 @@
"CX" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Db" = (
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/wood/airless,
/area/space/nearstation)
+"Dc" = (
+/obj/structure/table,
+/turf/open/floor/plating,
+/area/ruin/space/ks13/hallway/starboard_bow)
"Dd" = (
/obj/structure/table/glass,
/obj/effect/mapping_helpers/broken_floor,
@@ -3813,7 +3987,7 @@
/obj/structure/lattice,
/obj/structure/door_assembly/door_assembly_public,
/turf/template_noop,
-/area/space/nearstation)
+/area/ruin/space/ks13/service/kitchen)
"Dr" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
/turf/open/floor/plating/airless,
@@ -3844,8 +4018,11 @@
/turf/open/floor/iron,
/area/ruin/space/ks13/command/bridge)
"DA" = (
-/turf/closed/wall,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/grille/broken,
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"DB" = (
/obj/structure/table,
/turf/open/floor/plating/airless,
@@ -3868,7 +4045,7 @@
/obj/item/stack/cable_coil,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"DK" = (
/obj/structure/rack,
/obj/item/circuitboard/machine/circuit_imprinter/offstation{
@@ -3948,6 +4125,13 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/service/bar)
+"DX" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/clothing/suit/space/eva,
+/obj/item/stack/sheet/plasteel,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"DY" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
@@ -3984,10 +4168,9 @@
/turf/open/floor/iron/white/airless,
/area/ruin/space/ks13/science/genetics)
"Ed" = (
-/obj/item/stack/ore/slag,
-/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/medical/medbay)
"Ee" = (
/obj/effect/spawner/structure/window/hollow/end{
dir = 8
@@ -4039,7 +4222,7 @@
/obj/effect/mapping_helpers/broken_floor,
/obj/structure/cable,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Ey" = (
/turf/open/floor/iron,
/area/ruin/space/ks13/hallway/starboard_bow)
@@ -4065,6 +4248,10 @@
},
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/science/rnd)
+"EC" = (
+/obj/item/shard/plasma,
+/turf/template_noop,
+/area/ruin/space/ks13/engineering/supermatter)
"ED" = (
/obj/machinery/door/airlock/maintenance{
name = "Atmospherics Access"
@@ -4091,7 +4278,7 @@
"EK" = (
/obj/structure/grille,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"EL" = (
/obj/structure/chair,
/obj/effect/decal/cleanable/dirt,
@@ -4171,9 +4358,15 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/ruin/space/ks13/command/bridge)
+"Fg" = (
+/obj/machinery/power/emitter{
+ dir = 1
+ },
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Fj" = (
/turf/open/floor/iron,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Fk" = (
/obj/effect/turf_decal/plaque{
icon_state = "derelict2"
@@ -4193,10 +4386,9 @@
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/engineering/grav_gen)
"Fp" = (
-/obj/item/clothing/suit/space/eva,
-/obj/effect/decal/cleanable/glass,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"Fq" = (
/obj/structure/frame/computer{
dir = 1
@@ -4240,6 +4432,10 @@
/obj/effect/spawner/random/maintenance/three,
/turf/open/floor/iron,
/area/ruin/space/ks13/command/bridge_hall)
+"FC" = (
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/engineering/grav_gen)
"FF" = (
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
@@ -4252,7 +4448,7 @@
"FI" = (
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"FL" = (
/obj/structure/cable,
/obj/machinery/door/window/right/directional/east{
@@ -4441,12 +4637,14 @@
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/tool_storage)
"GF" = (
-/obj/effect/spawner/structure/window/hollow/reinforced/end,
-/obj/effect/spawner/structure/window/hollow/reinforced/directional{
- dir = 10
- },
+/obj/structure/grille,
+/turf/open/floor/plating,
+/area/ruin/space/ks13/ai/corridor)
+"GG" = (
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/item/stack/cable_coil/cut,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"GH" = (
/obj/structure/table_frame,
/obj/effect/decal/cleanable/dirt,
@@ -4482,8 +4680,8 @@
/obj/item/shard,
/obj/effect/decal/cleanable/glass,
/obj/item/shard,
-/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"GO" = (
/obj/machinery/light/small/directional/west,
/obj/effect/decal/cleanable/dirt,
@@ -4500,7 +4698,7 @@
/obj/structure/sign/warning/radiation/directional/north,
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"GU" = (
/obj/effect/decal/cleanable/blood/drip{
pixel_x = -4;
@@ -4698,9 +4896,17 @@
/obj/structure/girder/reinforced,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/science/ordnance)
+"HL" = (
+/obj/machinery/power/supermatter_crystal/shard,
+/obj/structure/closet/crate/radiation,
+/obj/machinery/door/window/right/directional/west{
+ name = "Spare Crystal"
+ },
+/turf/open/floor/circuit/red/airless,
+/area/ruin/space/ks13/ai/vault)
"HO" = (
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"HP" = (
/obj/effect/spawner/structure/window/hollow/reinforced/end{
dir = 8
@@ -4721,17 +4927,16 @@
/area/ruin/space/ks13/engineering/atmos)
"HV" = (
/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/cable,
/turf/open/floor/plating/airless{
luminosity = 2
},
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"HX" = (
-/obj/item/shard{
- icon_state = "medium"
- },
-/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/effect/decal/cleanable/glass/plasma,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Ia" = (
/obj/item/kirbyplants/random/dead,
/turf/open/floor/iron,
@@ -4743,10 +4948,11 @@
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/security/sec)
"If" = (
-/obj/item/shard,
-/obj/effect/mapping_helpers/burnt_floor,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/decal/cleanable/glass/plasma,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Ig" = (
/obj/machinery/light/small/directional/east,
/obj/structure/cable,
@@ -4806,11 +5012,12 @@
/turf/open/floor/iron/dark,
/area/ruin/space/ks13/medical/morgue)
"ID" = (
-/obj/structure/grille/broken,
-/obj/effect/decal/cleanable/glass,
-/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/machinery/door/airlock/engineering{
+ name = "Engine Room"
+ },
+/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"IF" = (
/turf/open/floor/plating/airless,
/area/space/nearstation)
@@ -4823,6 +5030,11 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/service/cafe)
+"IH" = (
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/item/stack/sheet/iron,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"II" = (
/obj/item/shard,
/obj/structure/grille/broken,
@@ -4846,6 +5058,11 @@
},
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"IS" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/grille,
+/turf/open/floor/iron/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"IT" = (
/obj/machinery/light/small/directional/south,
/turf/open/floor/iron,
@@ -4875,12 +5092,12 @@
/obj/effect/mapping_helpers/burnt_floor,
/obj/structure/cable,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Jc" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Jd" = (
/obj/structure/cable,
/turf/open/floor/iron,
@@ -4918,6 +5135,11 @@
/obj/item/wallframe/firealarm,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/engineering/atmos)
+"Jn" = (
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/effect/decal/cleanable/greenglow/radioactive,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Jp" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle{
dir = 4
@@ -4937,13 +5159,21 @@
},
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Jt" = (
/obj/effect/decal/cleanable/glass,
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/science/genetics)
+"Jv" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/reflector{
+ dir = 6
+ },
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Jw" = (
/turf/closed/wall,
/area/ruin/space/ks13/ai/corridor)
@@ -5116,6 +5346,12 @@
/obj/structure/girder,
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"Km" = (
+/obj/machinery/power/emitter{
+ dir = 8
+ },
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Ko" = (
/obj/machinery/door/window/left/directional/south{
name = "Bridge Access"
@@ -5124,6 +5360,11 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/ruin/space/ks13/command/bridge_hall)
+"Kp" = (
+/obj/effect/spawner/structure/window/reinforced/plasma,
+/obj/effect/mapping_helpers/damaged_window,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Ks" = (
/obj/structure/cable,
/turf/open/floor/plating/airless,
@@ -5148,10 +5389,9 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/engineering/atmos)
"Kw" = (
-/obj/item/stack/rods,
-/obj/effect/mapping_helpers/burnt_floor,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/hallway/central)
"Ky" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/power/apc/auto_name/directional/north,
@@ -5200,6 +5440,7 @@
/obj/effect/decal/cleanable/glass,
/obj/item/stack/rods,
/obj/item/stack/rods,
+/obj/machinery/power/energy_accumulator/grounding_rod/anchored,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/engineering/secure_storage)
"KO" = (
@@ -5210,6 +5451,10 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/engineering/aft_solars_control)
+"KT" = (
+/obj/effect/mapping_helpers/burnt_floor,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/medical/medbay)
"KU" = (
/obj/structure/lattice,
/turf/template_noop,
@@ -5225,9 +5470,9 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/ai/corridor)
"KX" = (
-/obj/machinery/field/generator,
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/burnt_floor,
+/obj/machinery/power/energy_accumulator/tesla_coil/anchored,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/engineering/secure_storage)
"KZ" = (
@@ -5410,9 +5655,10 @@
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/engineering/aft_solars_control)
"LZ" = (
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Mc" = (
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
/turf/closed/wall/r_wall,
@@ -5421,6 +5667,11 @@
/obj/structure/girder,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/service/hydro)
+"Mf" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/iron/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Mg" = (
/obj/machinery/door/airlock/engineering{
name = "Engineering Access"
@@ -5474,13 +5725,18 @@
/obj/effect/mapping_helpers/broken_floor,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Mx" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/service/kitchen)
+"My" = (
+/obj/item/shard/plasma,
+/obj/effect/mapping_helpers/burnt_floor,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Mz" = (
/obj/item/stack/cable_coil/cut,
/obj/effect/mapping_helpers/broken_floor,
@@ -5516,12 +5772,10 @@
/turf/open/floor/iron,
/area/ruin/space/ks13/science/ordnance)
"MG" = (
-/obj/item/stack/ore/iron,
-/obj/item/stack/ore/iron,
-/obj/item/stack/ore/iron,
-/obj/structure/lattice,
-/turf/template_noop,
-/area/space/nearstation)
+/obj/effect/mapping_helpers/broken_floor,
+/obj/machinery/portable_atmospherics/canister/nitrogen,
+/turf/open/floor/iron/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"MJ" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/broken_floor,
@@ -5591,6 +5845,12 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/engineering/aux_storage)
+"MZ" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/stack/sheet/plasteel,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Na" = (
/obj/effect/spawner/structure/window/hollow/reinforced/end{
dir = 8
@@ -5692,13 +5952,21 @@
"NB" = (
/obj/effect/decal/cleanable/glass,
/obj/effect/mapping_helpers/burnt_floor,
+/obj/structure/cable,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"ND" = (
/obj/structure/chair/stool/directional/north,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/service/cafe)
+"NE" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/shard/plasma,
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"NF" = (
/obj/item/language_manual/dronespeak_manual,
/turf/open/floor/iron/airless,
@@ -5748,7 +6016,7 @@
/obj/machinery/light/small/directional/north,
/obj/item/stack/cable_coil/cut,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"NS" = (
/obj/structure/table_frame,
/obj/effect/mapping_helpers/broken_floor,
@@ -5933,7 +6201,7 @@
/obj/machinery/light/small/directional/east,
/obj/structure/sign/warning/secure_area/directional/north,
/turf/open/floor/iron,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"OU" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
@@ -5942,6 +6210,9 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/service/hydro)
+"OY" = (
+/turf/template_noop,
+/area/ruin/space/ks13/engineering/grav_gen)
"OZ" = (
/obj/structure/cable,
/obj/structure/table,
@@ -6019,11 +6290,18 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/hallway/aft)
+"Pm" = (
+/obj/item/stack/ore/iron,
+/obj/item/stack/ore/iron,
+/obj/item/stack/ore/iron,
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/engineering/grav_gen)
"Pn" = (
/obj/effect/mapping_helpers/burnt_floor,
/obj/structure/noticeboard/directional/north,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Po" = (
/obj/structure/rack,
/obj/item/circuitboard/machine/microwave{
@@ -6082,7 +6360,7 @@
/obj/item/stack/cable_coil/cut,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Pz" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle{
dir = 4
@@ -6123,10 +6401,8 @@
/turf/open/floor/iron/dark,
/area/ruin/space/ks13/medical/morgue)
"PG" = (
-/obj/item/clothing/head/helmet/space/eva,
-/obj/effect/decal/cleanable/glass,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/turf/closed/wall/r_wall,
+/area/template_noop)
"PH" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/machinery/power/apc/auto_name/directional/north,
@@ -6137,7 +6413,7 @@
"PI" = (
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"PJ" = (
/obj/effect/decal/cleanable/blood/footprints{
dir = 4
@@ -6163,7 +6439,7 @@
/obj/effect/mapping_helpers/broken_floor,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"PU" = (
/obj/structure/cable,
/turf/open/floor/iron,
@@ -6445,14 +6721,16 @@
/turf/open/floor/iron/white/airless,
/area/ruin/space/ks13/science/genetics)
"RE" = (
-/obj/structure/grille/broken,
-/obj/effect/decal/remains/human{
- desc = "This guy seemed to have died in terrible way! Half his remains are dust.";
- name = "Syndicate agent remains"
- },
-/obj/effect/decal/cleanable/glass,
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/engineering/supermatter)
+"RF" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/cable,
+/obj/item/stack/rods,
+/obj/effect/decal/cleanable/glass/plasma,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"RG" = (
/obj/structure/chair{
dir = 8
@@ -6470,9 +6748,8 @@
/turf/open/floor/iron/dark,
/area/ruin/space/ks13/medical/morgue)
"RI" = (
-/obj/effect/spawner/structure/window/hollow/reinforced/directional,
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"RJ" = (
/obj/structure/reagent_dispensers/watertank,
/obj/effect/decal/cleanable/dirt,
@@ -6596,20 +6873,17 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/science/rnd)
"Sn" = (
-/obj/item/shard{
- icon_state = "small"
- },
-/obj/item/shard{
- icon_state = "medium"
- },
-/obj/effect/decal/cleanable/glass,
+/obj/structure/grille/broken,
+/obj/effect/mapping_helpers/burnt_floor,
+/obj/effect/decal/cleanable/glass/plasma,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"So" = (
-/obj/item/stack/ore/slag,
-/obj/structure/lattice,
-/turf/template_noop,
-/area/space/nearstation)
+/obj/effect/mapping_helpers/broken_floor,
+/obj/structure/table_frame,
+/obj/item/stack/sheet/iron,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Sp" = (
/obj/structure/table_frame,
/turf/open/floor/plating/airless,
@@ -6843,10 +7117,9 @@
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/science/genetics)
"Tg" = (
-/obj/machinery/light/small/directional/east,
-/obj/effect/mapping_helpers/broken_floor,
-/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/item/shard/plasma,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"Th" = (
/obj/structure/cable,
/obj/effect/mapping_helpers/broken_floor,
@@ -6898,7 +7171,7 @@
/obj/item/pushbroom,
/obj/item/reagent_containers/spray/cleaner,
/turf/template_noop,
-/area/space/nearstation)
+/area/ruin/space/ks13/service/jani)
"Tr" = (
/obj/structure/cable,
/obj/effect/mapping_helpers/broken_floor,
@@ -6977,11 +7250,9 @@
/turf/template_noop,
/area/space/nearstation)
"TM" = (
-/obj/item/shard{
- icon_state = "small"
- },
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/structure/lattice,
+/turf/template_noop,
+/area/ruin/space/ks13/service/bar)
"TN" = (
/obj/structure/cable,
/obj/effect/mapping_helpers/broken_floor,
@@ -6997,7 +7268,7 @@
},
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"TR" = (
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron,
@@ -7210,12 +7481,17 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/security/court_hall)
+"UY" = (
+/obj/structure/grille/broken,
+/obj/effect/mapping_helpers/broken_floor,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"UZ" = (
/obj/effect/spawner/random/maintenance,
/obj/structure/sign/warning/electric_shock/directional/north,
/obj/effect/spawner/random/maintenance,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Va" = (
/obj/effect/turf_decal/plaque{
icon_state = "derelict6"
@@ -7236,11 +7512,9 @@
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/engineering/atmos)
"Vh" = (
-/obj/effect/spawner/structure/window/hollow/reinforced/middle{
- dir = 8
- },
-/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/obj/structure/door_assembly/door_assembly_eng,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"Vj" = (
/obj/machinery/door/poddoor/preopen{
id = "toxin_vent"
@@ -7265,6 +7539,13 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/security/sec)
+"Vp" = (
+/obj/machinery/power/emitter{
+ dir = 8
+ },
+/obj/structure/cable,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Vr" = (
/obj/structure/table,
/obj/effect/spawner/random/maintenance,
@@ -7293,6 +7574,11 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/hallway/central)
+"Vx" = (
+/obj/effect/decal/cleanable/greenglow/radioactive,
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/engine,
+/area/ruin/space/ks13/engineering/supermatter)
"VB" = (
/obj/structure/cable,
/turf/open/floor/iron,
@@ -7405,7 +7691,7 @@
"Wk" = (
/obj/structure/girder/reinforced,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Wl" = (
/obj/machinery/door/airlock/research/glass{
name = "Toxins Mix Internal Airlock"
@@ -7496,11 +7782,12 @@
/turf/open/floor/iron,
/area/ruin/space/ks13/science/ordnance)
"WH" = (
-/obj/effect/spawner/structure/window/hollow/reinforced/directional{
- dir = 8
- },
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/shard/plasma,
+/obj/item/stack/rods,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"WI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible,
/turf/open/floor/plating/airless,
@@ -7530,7 +7817,7 @@
/obj/effect/spawner/random/maintenance,
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"WP" = (
/obj/effect/spawner/structure/window/hollow/end,
/turf/open/floor/plating/airless,
@@ -7572,6 +7859,12 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/ai/vault)
+"WZ" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/shard/plasma,
+/obj/effect/decal/cleanable/glass/plasma,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Xa" = (
/turf/open/floor/plating/airless,
/area/ruin/space/ks13/ai/corridor)
@@ -7628,6 +7921,11 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/airless,
/area/ruin/space/ks13/science/rnd)
+"Xp" = (
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/stack/sheet/plasteel,
+/turf/open/floor/plating/airless,
+/area/ruin/space/ks13/engineering/supermatter)
"Xr" = (
/turf/closed/wall,
/area/ruin/space/ks13/science/genetics)
@@ -7860,7 +8158,10 @@
/obj/machinery/light/small/directional/west,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
+"YH" = (
+/turf/template_noop,
+/area/ruin/space/ks13/science/genetics)
"YK" = (
/obj/effect/spawner/structure/window/hollow/reinforced/directional{
dir = 10
@@ -7874,7 +8175,7 @@
"YM" = (
/obj/item/stack/cable_coil/cut,
/turf/open/floor/plating/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"YP" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating/airless,
@@ -7891,7 +8192,7 @@
/obj/effect/decal/cleanable/glass,
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"YW" = (
/obj/structure/table,
/obj/item/paper_bin{
@@ -8028,7 +8329,7 @@
/obj/item/stack/cable_coil/cut,
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/iron/airless,
-/area/ruin/space/ks13/engineering/singulo)
+/area/ruin/space/ks13/engineering/supermatter)
"Zy" = (
/obj/structure/closet/crate/bin,
/obj/effect/decal/cleanable/dirt,
@@ -10162,11 +10463,11 @@ Jr
MW
Jr
ZO
-rk
+qv
Kh
-rk
-rk
-rk
+qv
+qv
+qv
Ii
Ii
Me
@@ -10278,13 +10579,13 @@ Sp
ZO
rh
Kh
-rk
+qv
mK
td
-rk
+qv
cI
qJ
-rk
+qv
aa
rk
rk
@@ -10394,7 +10695,7 @@ WC
oF
mE
hm
-rk
+qv
OX
kG
Me
@@ -10693,11 +10994,11 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
+rk
+rk
+rk
+rk
+rk
rk
rk
QG
@@ -10730,9 +11031,9 @@ LJ
UT
ak
Vk
-rk
+qv
He
-rk
+qv
vZ
VE
rR
@@ -10805,11 +11106,11 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
+rk
+rk
+rk
+rk
+rk
rk
QG
QG
@@ -10843,10 +11144,10 @@ Cs
pK
an
UF
-rk
+qv
Me
Dg
-rk
+qv
vZ
zr
Iy
@@ -10917,10 +11218,10 @@ aa
aa
aa
aa
-aa
rk
rk
-aa
+rk
+rk
rk
rk
rk
@@ -10959,9 +11260,9 @@ oL
CW
Iy
sB
-rk
+qv
Zj
-rk
+qv
Me
rk
rk
@@ -11027,12 +11328,12 @@ aa
aa
aa
aa
-aa
rk
rk
rk
rk
-aa
+rk
+rk
rk
rk
rk
@@ -11072,13 +11373,13 @@ JD
Zk
Ii
pS
-rk
+qv
Ii
zx
Me
-aa
-aa
-aa
+bm
+bm
+bm
ZK
ke
Ez
@@ -11139,16 +11440,16 @@ aa
aa
aa
aa
-aa
rk
-aa
+nQ
rk
+Kb
sU
sU
-sU
-sU
-Wk
-sU
+rk
+rk
+rk
+rk
sU
Dy
Us
@@ -11159,7 +11460,7 @@ zP
QG
sU
sU
-aa
+eQ
aa
pL
rK
@@ -11188,10 +11489,10 @@ jl
jl
jl
dH
-rk
+TM
Uz
-aa
-aa
+bm
+bm
XO
TK
Fv
@@ -11250,18 +11551,18 @@ aa
aa
aa
aa
-aa
rk
rk
rk
rk
+Kb
sU
sU
sU
sU
sU
Wk
-Wk
+aV
sU
Dy
VN
@@ -11272,8 +11573,8 @@ tt
Dy
sU
sU
-DA
-PI
+EK
+fE
LN
Gh
Se
@@ -11303,7 +11604,7 @@ wN
dH
Fa
KV
-rk
+bm
lW
ZK
TK
@@ -11362,12 +11663,11 @@ aa
aa
aa
aa
-aa
rk
rk
rk
rk
-sU
+Kb
sU
gd
CX
@@ -11376,6 +11676,7 @@ PI
PI
PI
PI
+PI
Jc
YM
px
@@ -11476,30 +11777,30 @@ aa
aa
aa
aa
-aa
rk
Kb
rk
-sU
+Kb
sU
aj
CX
Jc
Ex
+tU
+Xp
PI
-Jc
Ex
PI
Jc
-Jc
+WH
Jc
Jc
PI
ou
Js
-fg
-DA
-EK
+qa
+HO
+PI
pL
Lz
Wj
@@ -11582,8 +11883,7 @@ rk
rk
rk
rk
-rk
-aa
+nQ
aa
aa
aa
@@ -11592,32 +11892,33 @@ aa
aa
Kb
sg
-sU
+Kb
Wk
-fg
+MG
WO
CX
PI
-px
-Jc
-rd
-Vh
+ej
+Xp
+Wk
+sU
Vh
-GF
-fg
-fg
-Kw
-rd
-WH
-ID
+Wk
+EK
+UY
+BI
+sU
+wr
+Wk
+PI
Sn
-rk
-rk
-Bw
-rk
-rk
-qG
-nI
+Wk
+IS
+HO
+KT
+Ed
+Ed
+gu
DS
Hb
Ts
@@ -11695,8 +11996,7 @@ Jw
Jw
Jw
Jw
-rk
-aa
+nQ
aa
aa
aa
@@ -11705,31 +12005,32 @@ aa
aa
aa
rk
-sU
+Kb
Wk
-fg
+MG
FI
CX
-PI
+xy
Ex
-pi
-FI
-FI
-FI
-FI
+Wk
zv
-fg
-Ed
-PI
-PI
-qv
+IH
+te
+RI
+Tg
+Fp
+Fp
zv
-rk
-rk
-rk
-rk
-rk
-rk
+zv
+zv
+GG
+bC
+Ck
+PI
+eU
+sU
+Ed
+Ed
nI
DV
Se
@@ -11816,34 +12117,34 @@ aa
aa
aa
aa
-aa
rk
-sU
+Kb
sU
UZ
FI
gB
ys
PS
-RE
-PG
-fg
-fg
-PI
+ID
+Fp
zv
-PI
-PI
-PI
zv
-Jc
+RI
+zv
+RI
zv
+zv
+Wk
+Fp
+zv
+RI
ID
NB
-fg
-Wk
+px
+sU
sU
lw
-rk
+Ed
Xr
BB
yQ
@@ -11922,38 +12223,38 @@ Jw
rk
aa
aa
-aa
-aa
-aa
-rk
-rk
+OY
+OY
+FC
+FC
+yf
yf
yf
yf
yf
yf
-sU
NR
fg
px
fg
-Jc
+DX
+Wk
Fp
-TM
zv
+Fp
+RI
zv
-bm
-PI
+te
zv
+RI
+Wk
+RI
zv
-PI
-Jc
-Jc
-fg
zv
+EK
GN
-fg
-Wk
+Ex
+CM
sU
sU
wE
@@ -12035,9 +12336,8 @@ Yc
rk
rk
aa
-aa
uu
-MG
+Pm
wQ
wQ
wQ
@@ -12045,29 +12345,30 @@ Fo
HP
Ug
Hc
-sU
+yf
IY
FI
pi
Jc
fg
-bm
-PI
+EK
+HX
+RI
zv
-PI
-Jc
-xJ
-xJ
-xJ
-Jc
zv
+Wk
+RE
+zv
+RE
PI
+te
+RI
zv
-gB
-Jc
-Jc
-fg
sU
+Jc
+Jv
+ta
+tU
sU
sU
Xr
@@ -12148,7 +12449,6 @@ Yc
aa
rk
aa
-aa
uu
NJ
QJ
@@ -12158,29 +12458,30 @@ Fo
pH
tu
lg
-sU
+yf
tX
qt
sU
Mw
Jc
-zv
-ui
-PI
-zv
-xJ
-xJ
-xJ
+DA
+RI
+RI
+Wk
+RE
+bM
xJ
xJ
-PI
-PI
+EC
+bM
+ek
+te
+zv
+Kp
+If
Jc
PI
-Jc
-Jc
-sZ
-sU
+PI
ar
sU
Vu
@@ -12261,7 +12562,6 @@ Yc
aa
aa
aa
-aa
yf
bN
wQ
@@ -12272,29 +12572,30 @@ Mg
tu
tu
qY
-LZ
+kw
Fj
sU
sS
-zv
+zg
+so
te
zv
-PI
-zv
-xJ
+Vh
+RE
xJ
xJ
xJ
xJ
+RE
+RI
+RI
+HX
+Sn
+bT
PI
-zv
-Jc
-Jc
-Jc
PI
-fg
-HO
-HO
+lu
+Fg
sU
Dd
sc
@@ -12374,7 +12675,6 @@ Yc
aa
aa
aa
-aa
yf
wQ
wQ
@@ -12384,29 +12684,30 @@ Fo
HP
Gc
lg
-sU
+yf
OS
dj
sU
Pn
+HX
+iA
+RI
zv
zv
-PI
-zv
-PI
-xJ
-xJ
-xJ
-xJ
+RI
+RE
+EC
xJ
-PI
-fg
-Jc
-Jc
-jq
+EC
+RE
+RI
+My
+RI
+EK
+lv
Jc
-fg
-sU
+Vp
+PI
qW
sU
ug
@@ -12487,42 +12788,42 @@ Yc
aa
aa
aa
-aa
yf
WF
wQ
-So
+hD
wQ
wQ
pH
Ct
UE
-sU
+yf
sU
sU
sU
GS
Jc
-PI
+cE
+Al
zv
-PI
zv
-Jc
-xJ
-xJ
-xJ
-PI
-PI
-fg
-FI
-pi
+Wk
+RE
+RI
+bC
+Vx
+sU
+RI
+zv
+te
+sU
Jc
Jc
-fg
-Wk
+px
+Km
sU
sU
-rk
+bn
SD
aD
LA
@@ -12599,42 +12900,42 @@ Yc
Yc
Yc
Bw
-Jw
aa
yf
yf
uu
uu
-aa
-rk
+OY
+FC
+yf
yf
yf
yf
-sU
HO
YF
HO
Jc
Jc
+sU
RI
zv
+Fp
zv
-PI
-zv
-PI
-PI
+Wk
+RI
+RI
+RI
+Wk
+RI
zv
+RI
+Ck
+If
+ta
PI
-zv
-zv
-FI
-CX
-Jc
-fg
sU
sU
-sU
-rk
+bn
yF
Za
SX
@@ -12712,7 +13013,6 @@ Yc
Yc
Yc
rk
-rk
aa
aa
aa
@@ -12720,35 +13020,36 @@ aa
aa
aa
aa
+rd
rk
-rk
-sU
+Kb
sU
fg
PI
Jc
Jc
Jc
-CX
+Vh
+Fp
+Jn
zv
-PI
-PI
-PI
+oE
zv
-PI
-PI
zv
-PI
-PI
-FI
-CX
-HV
-Jc
-sU
+zv
+zv
+zv
+RI
+zv
+te
+dU
+mc
+Ex
+CM
sU
EY
-rk
-rk
+bn
+bn
Cj
Tc
AU
@@ -12833,36 +13134,36 @@ aa
aa
aa
aa
-aa
-rk
-Wk
+rd
+BK
Wk
fg
Jc
PI
fg
Jc
-gB
-PI
-zv
+sU
+Fp
+RI
zv
+Fp
zv
HX
-hD
-zv
+RI
zv
zv
+RI
Tg
-PI
-gB
-Jc
-HV
-Wk
+RI
+Kp
+mc
+mc
+So
sU
wy
-aa
-aa
-rk
+YH
+YH
+bn
XG
ub
GU
@@ -12945,32 +13246,32 @@ aa
aa
aa
aa
-aa
-Kb
+PG
IF
-sU
+Kb
Wk
PI
Jc
Mw
DJ
Jc
-fg
-rd
-sJ
-sJ
-BI
PI
-zv
-If
-rd
-sJ
+Wk
+Xp
sJ
+Wk
BI
-Jc
-Jc
-fg
+BI
+cE
+Wk
+BI
+Ck
+cE
+IH
+Wk
Wk
+zv
+sU
sU
HH
ib
@@ -13058,27 +13359,27 @@ aa
aa
aa
aa
-aa
-rk
+rd
Kb
rk
-Wk
+BK
Wk
HO
fg
PI
+Xp
PI
-Jc
+MZ
PI
PI
PI
-px
-Jc
-PI
+RF
+NE
+WZ
Py
-fg
-fg
-Jc
+pD
+Mf
+LZ
Jc
HV
HV
@@ -13088,7 +13389,7 @@ KU
NS
RJ
ib
-rk
+bn
Tp
Jt
OE
@@ -13171,16 +13472,16 @@ aa
aa
aa
aa
-aa
-rk
+rd
rk
rk
-sU
+Kb
sU
HO
HO
fg
PI
+PI
Jc
Jc
Zw
@@ -13195,10 +13496,10 @@ fg
fg
Jc
fg
-Wk
+sU
sU
sD
-aa
+sZ
rF
ib
yQ
@@ -13285,10 +13586,10 @@ aa
aa
aa
aa
-aa
-rk
+rd
rk
rk
+Kb
sU
sU
sU
@@ -13304,11 +13605,11 @@ ky
ky
UB
rr
-Wk
-Wk
-Wk
-Wk
-Wk
+sU
+sU
+sU
+sU
+sU
Tq
AR
rF
@@ -13398,11 +13699,11 @@ aa
aa
aa
aa
-aa
-rk
+rd
rk
rk
rk
+Kb
sU
sU
sU
@@ -13422,7 +13723,7 @@ sU
sU
sU
sU
-rk
+KU
OQ
Rc
OQ
@@ -13512,8 +13813,8 @@ aa
aa
aa
aa
-aa
-rk
+rd
+nQ
aa
aa
aa
@@ -13531,10 +13832,10 @@ sr
EH
rr
sU
-aa
-aa
-aa
-aa
+qB
+qB
+Kw
+Kw
AX
Hy
Hk
@@ -13643,8 +13944,8 @@ GW
DL
rr
rr
-rk
-aa
+Kw
+Kw
AX
xd
QR
@@ -13756,7 +14057,7 @@ rr
rr
rr
rr
-rk
+Kw
qX
zi
BJ
@@ -14289,8 +14590,8 @@ yz
yz
xf
Ym
-aa
-rk
+ui
+lt
BX
BD
xf
@@ -14403,7 +14704,7 @@ yz
xf
Ym
zf
-aa
+ui
BX
Ym
xf
@@ -15307,7 +15608,7 @@ yz
oP
wX
At
-dK
+At
At
oZ
oP
@@ -15420,7 +15721,7 @@ yz
oP
Zp
At
-yw
+At
NF
WN
oP
@@ -15532,9 +15833,9 @@ yz
yz
oP
oP
-oP
-oP
-oP
+dK
+At
+yw
oP
oP
yz
@@ -15644,11 +15945,11 @@ yz
yz
yz
yz
-yz
-yz
-yz
-yz
-yz
+oP
+oP
+HL
+oP
+oP
yz
yz
yz
@@ -15758,9 +16059,9 @@ yz
yz
yz
yz
-yz
-yz
-yz
+oP
+oP
+oP
yz
yz
yz
@@ -15867,14 +16168,14 @@ HC
DU
yz
yz
-dT
-dT
-dT
-dT
-dT
-dT
-dT
-dT
+GF
+GF
+GF
+GF
+GF
+GF
+GF
+GF
dT
dT
dT
@@ -15981,14 +16282,14 @@ DU
dT
dT
dT
-Er
-zR
-eQ
-Ey
-uY
-Ey
-Ey
-Ey
+dT
+dT
+dT
+dT
+dT
+dT
+dT
+dT
Er
zR
Vs
@@ -16094,9 +16395,9 @@ DU
Ly
dT
Mm
-DN
-DN
-DN
+sf
+Dc
+cO
Ey
DN
Ey
diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm
index 427310fd0a7b6..402b8f827c67c 100644
--- a/_maps/map_files/Birdshot/birdshot.dmm
+++ b/_maps/map_files/Birdshot/birdshot.dmm
@@ -2454,6 +2454,12 @@
/obj/machinery/power/apc/auto_name/directional/south,
/turf/open/floor/plating,
/area/station/maintenance/department/science/xenobiology)
+"aVK" = (
+/obj/structure/rack,
+/obj/item/stack/sheet/iron/fifty,
+/obj/item/stack/sheet/glass/fifty,
+/turf/open/floor/plating,
+/area/station/maintenance/department/science/xenobiology)
"aVT" = (
/obj/machinery/door/airlock/research/glass/incinerator/ordmix_interior,
/obj/effect/mapping_helpers/airlock/locked,
@@ -26322,8 +26328,8 @@
/area/station/maintenance/port/greater)
"jar" = (
/obj/machinery/drone_dispenser,
-/turf/open/misc/asteroid,
-/area/station/maintenance/starboard/greater)
+/turf/open/floor/plating,
+/area/station/maintenance/department/science/xenobiology)
"jat" = (
/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on{
dir = 4
@@ -34190,6 +34196,7 @@
/obj/item/clothing/glasses/welding,
/obj/item/radio/intercom/directional/north,
/obj/item/clothing/head/utility/welding,
+/obj/item/toy/crayon/spraycan/roboticist,
/turf/open/floor/iron,
/area/station/science/robotics/lab)
"lEa" = (
@@ -112833,7 +112840,7 @@ tjj
tjj
blb
ssz
-xQI
+jar
qRO
ssz
vLv
@@ -113090,7 +113097,7 @@ tjj
blb
blb
ssz
-roz
+aVK
sPO
ssz
aSy
@@ -113347,9 +113354,9 @@ blb
blb
ssz
ssz
+xQI
roz
ssz
-ssz
pus
cYG
srb
@@ -113604,7 +113611,7 @@ ssz
ssz
ssz
xQI
-roz
+xQI
roz
ssz
iWZ
@@ -131093,7 +131100,7 @@ tiN
aCM
bDq
eUF
-jar
+fcq
mMr
fPR
ylD
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 4200fe13d159d..92854ca2a6215 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -69865,6 +69865,7 @@
dir = 8
},
/obj/machinery/light/small/directional/south,
+/obj/item/toy/crayon/spraycan/roboticist,
/turf/open/floor/iron,
/area/station/science/robotics/lab)
"ryt" = (
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index 6cbcb15e08eed..141895206a53a 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -70674,6 +70674,7 @@
/obj/item/multitool{
pixel_x = 3
},
+/obj/item/toy/crayon/spraycan/roboticist,
/turf/open/floor/iron,
/area/station/science/robotics/lab)
"utA" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 865e1ea3444b7..3c4c6f608263c 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -15685,6 +15685,7 @@
/obj/machinery/door/airlock/security/glass{
name = "Security Post - Cargo"
},
+/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/iron/dark,
/area/station/security/checkpoint/supply)
"fEW" = (
@@ -23637,6 +23638,7 @@
/obj/item/multitool,
/obj/item/clothing/head/utility/welding,
/obj/item/clothing/glasses/welding,
+/obj/item/toy/crayon/spraycan/roboticist,
/turf/open/floor/iron,
/area/station/science/robotics/lab)
"iwL" = (
@@ -63491,7 +63493,9 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
-/turf/open/floor/plating,
+/obj/effect/turf_decal/tile/brown/fourcorners,
+/obj/effect/mapping_helpers/airlock/access/all/security/general,
+/turf/open/floor/iron/dark,
/area/station/security/checkpoint/supply)
"wmf" = (
/obj/effect/spawner/random/trash/garbage{
diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm
index 2fc187c626d6d..0fa17fa43bfbe 100644
--- a/_maps/map_files/NorthStar/north_star.dmm
+++ b/_maps/map_files/NorthStar/north_star.dmm
@@ -6123,6 +6123,7 @@
/area/station/maintenance/floor1/starboard/fore)
"bxk" = (
/obj/structure/rack,
+/obj/item/toy/crayon/spraycan/roboticist,
/turf/open/floor/iron/dark/smooth_large,
/area/station/science/robotics/lab)
"bxl" = (
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index 9c97fd61253f4..a0c0bc0964b08 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -5979,6 +5979,7 @@
/obj/item/clothing/glasses/welding,
/obj/item/radio/intercom/directional/north,
/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/toy/crayon/spraycan/roboticist,
/turf/open/floor/iron/dark,
/area/station/science/robotics/lab)
"aUc" = (
diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm
index f71639d998658..af9811526292f 100644
--- a/_maps/map_files/wawastation/wawastation.dmm
+++ b/_maps/map_files/wawastation/wawastation.dmm
@@ -12657,6 +12657,7 @@
/obj/item/clothing/head/utility/welding,
/obj/item/clothing/glasses/welding,
/obj/machinery/airalarm/directional/south,
+/obj/item/toy/crayon/spraycan/roboticist,
/turf/open/floor/iron/dark/textured,
/area/station/science/robotics/lab)
"exR" = (
diff --git a/code/__DEFINES/ai/ai.dm b/code/__DEFINES/ai/ai.dm
index 73a8f2d1900bd..c91f7eb06597f 100644
--- a/code/__DEFINES/ai/ai.dm
+++ b/code/__DEFINES/ai/ai.dm
@@ -11,6 +11,12 @@
///The AI is currently in idle mode.
#define AI_STATUS_IDLE "ai_idle"
+//Flags returned by get_able_to_run()
+///pauses AI processing
+#define AI_UNABLE_TO_RUN (1<<1)
+///bypass canceling our actions on set_ai_status()
+#define AI_PREVENT_CANCEL_ACTIONS (1<<2)
+
///For JPS pathing, the maximum length of a path we'll try to generate. Should be modularized depending on what we're doing later on
#define AI_MAX_PATH_LENGTH 30 // 30 is possibly overkill since by default we lose interest after 14 tiles of distance, but this gives wiggle room for weaving around obstacles
#define AI_BOT_PATH_LENGTH 75
diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm
index 2b25d0cfb31e1..24461464c3e03 100644
--- a/code/__DEFINES/ai/ai_blackboard.dm
+++ b/code/__DEFINES/ai/ai_blackboard.dm
@@ -172,8 +172,26 @@
///Text we display when we befriend someone
#define BB_FRIENDLY_MESSAGE "friendly_message"
+//fishing!
+
///our fishing target
-#define BB_FISHING_TARGET "fishing_target"
+#define BB_FISHING_TARGET "BB_fishing_target"
+
+///key holding the list of things we are able to fish from
+#define BB_FISHABLE_LIST "BB_fishable_list"
+
+///key holding our cooldown between fishing attempts
+#define BB_FISHING_COOLDOWN "BB_fishing_cooldown"
+
+///key that holds the next time we will start fishing
+#define BB_FISHING_TIMER "BB_fishing_timer"
+
+///are we ONLY allowed to fish when we're hungry?
+#define BB_ONLY_FISH_WHILE_HUNGRY "BB_only_fish_while_hungry"
+
+///drillable ice we can make holes in
+#define BB_DRILLABLE_ICE "BB_drillable_ice"
+
// Keys used by one and only one behavior
// Used to hold state without making bigass lists
diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm
index 46e179ee567ba..3d28fdd81162c 100644
--- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm
@@ -40,7 +40,7 @@
#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act"
///from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode)
#define COMSIG_ATOM_RCD_ACT "atom_rcd_act"
-///from base of atom/singularity_pull(): (/datum/component/singularity, current_size)
+///from base of atom/singularity_pull(): (/atom, current_size)
#define COMSIG_ATOM_SING_PULL "atom_sing_pull"
///from obj/machinery/bsa/full/proc/fire(): ()
#define COMSIG_ATOM_BSA_BEAM "atom_bsa_beam_pass"
diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
index 633282001f67a..ef47b6f4b8243 100644
--- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
+++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
@@ -297,3 +297,5 @@
#define COMSIG_MOB_ENSLAVED_TO "mob_enslaved_to"
/// From /obj/item/proc/attack_atom: (mob/living/attacker, atom/attacked)
#define COMSIG_LIVING_ATTACK_ATOM "living_attack_atom"
+/// From /mob/living/proc/stop_leaning()
+#define COMSIG_LIVING_STOPPED_LEANING "living_stopped_leaning"
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index df9b7cc22960e..d1862f787d65c 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -297,12 +297,12 @@
//Charge levels for Ethereals, in joules.
#define ETHEREAL_CHARGE_NONE 0
-#define ETHEREAL_CHARGE_LOWPOWER (0.4 * STANDARD_CELL_CHARGE)
-#define ETHEREAL_CHARGE_NORMAL (1 * STANDARD_CELL_CHARGE)
-#define ETHEREAL_CHARGE_ALMOSTFULL (1.5 * STANDARD_CELL_CHARGE)
-#define ETHEREAL_CHARGE_FULL (2 * STANDARD_CELL_CHARGE)
-#define ETHEREAL_CHARGE_OVERLOAD (2.5 * STANDARD_CELL_CHARGE)
-#define ETHEREAL_CHARGE_DANGEROUS (3 * STANDARD_CELL_CHARGE)
+#define ETHEREAL_CHARGE_LOWPOWER (0.4 * STANDARD_BATTERY_CHARGE)
+#define ETHEREAL_CHARGE_NORMAL (1 * STANDARD_BATTERY_CHARGE)
+#define ETHEREAL_CHARGE_ALMOSTFULL (1.5 * STANDARD_BATTERY_CHARGE)
+#define ETHEREAL_CHARGE_FULL (2 * STANDARD_BATTERY_CHARGE)
+#define ETHEREAL_CHARGE_OVERLOAD (2.5 * STANDARD_BATTERY_CHARGE)
+#define ETHEREAL_CHARGE_DANGEROUS (3 * STANDARD_BATTERY_CHARGE)
#define CRYSTALIZE_COOLDOWN_LENGTH (120 SECONDS)
@@ -647,6 +647,9 @@
#define GRADIENT_APPLIES_TO_HAIR (1<<0)
#define GRADIENT_APPLIES_TO_FACIAL_HAIR (1<<1)
+// Hair masks
+#define HAIR_MASK_HIDE_ABOVE_45_DEG_MEDIUM "hide_above_45deg"
+
// Height defines
// - They are numbers so you can compare height values (x height < y height)
// - They do not start at 0 for futureproofing
@@ -833,6 +836,9 @@ GLOBAL_LIST_INIT(layers_to_offset, list(
/// The layer above mutant body parts
#define ABOVE_BODY_FRONT_LAYER (BODY_FRONT_LAYER-1)
+/// We need gloves to layer on top of modsuit chestplates because we need the hole in the suit filled in if the user lacks a limb
+#define MOD_CHESTPLATE_LAYER (GLOVES_LAYER+0.5)
+
/// If gravity must be present to perform action (can't use pens without gravity)
#define NEED_GRAVITY (1<<0)
/// If reading is required to perform action (can't read a book if you are illiterate)
diff --git a/code/__DEFINES/nuclear_bomb.dm b/code/__DEFINES/nuclear_bomb.dm
index fecd9ef06118b..7e1707ea78003 100644
--- a/code/__DEFINES/nuclear_bomb.dm
+++ b/code/__DEFINES/nuclear_bomb.dm
@@ -1,23 +1,39 @@
// Nuclear bomb de/construction status
+///Pristine condition, no tampering has occurred yet
#define NUKESTATE_INTACT 5
+///Front panel has been unscrewed
#define NUKESTATE_UNSCREWED 4
+///Front panel has been removed with a crowbar, exposing the reinforced cover
#define NUKESTATE_PANEL_REMOVED 3
+///Reinforced cover has been welded, preparing it for removal
#define NUKESTATE_WELDED 2
+///Reinforced cover has been removed with a crowbar, revealing the core
#define NUKESTATE_CORE_EXPOSED 1
+///Nuke core removed with the special kit
#define NUKESTATE_CORE_REMOVED 0
// Nuclear bomb UI modes
+///Device is locked and is awaiting the disk for further operations (additionally shows time left if armed)
#define NUKEUI_AWAIT_DISK 0
+///Device is awaiting activation codes input
#define NUKEUI_AWAIT_CODE 1
+///Device is awaiting timer input
#define NUKEUI_AWAIT_TIMER 2
+///Device is awaiting confirmation of arming process and shows the time set
#define NUKEUI_AWAIT_ARM 3
+///Device is counting down to setting off the charge
#define NUKEUI_TIMING 4
+///Device is setting off the charge, aka `proc/actually_explode()`
#define NUKEUI_EXPLODED 5
// Nuclear bomb states
+///Device has not received activation codes and no timer have been set, all lights are off
#define NUKE_OFF_LOCKED 0
+///Device has received activation codes and the timer is set; awaiting arming and the safety warning lights are on
#define NUKE_OFF_UNLOCKED 1
+///Device is counting down to setting off the charge, red lights are on
#define NUKE_ON_TIMING 2
+///Device is setting off the charge, aka `proc/actually_explode()`, red lights are blinking fast
#define NUKE_ON_EXPLODING 3
// Nuclear bomb detonation statuses
diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm
index db01267936345..de93661e16920 100644
--- a/code/__DEFINES/traits/declarations.dm
+++ b/code/__DEFINES/traits/declarations.dm
@@ -1334,6 +1334,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
///Trait which silences all chemical reactions in its container
#define TRAIT_SILENT_REACTIONS "silent_reactions"
+///Trait given to mobs that can dig
+#define TRAIT_MOB_CAN_DIG "mob_can_dig"
+
/**
*
* This trait is used in some interactions very high in the interaction chain to allow
diff --git a/code/__HELPERS/dynamic_human_icon_gen.dm b/code/__HELPERS/dynamic_human_icon_gen.dm
index f1f3be038a86b..d709b38207a59 100644
--- a/code/__HELPERS/dynamic_human_icon_gen.dm
+++ b/code/__HELPERS/dynamic_human_icon_gen.dm
@@ -23,7 +23,7 @@ GLOBAL_LIST_EMPTY(dynamic_human_appearances)
outfit.r_hand = r_hand
if(l_hand != NO_REPLACE)
outfit.l_hand = l_hand
- dummy.equipOutfit(outfit, visualsOnly = TRUE)
+ dummy.equipOutfit(outfit, visuals_only = TRUE)
else if(mob_spawn_path)
var/obj/effect/mob_spawn/spawner = new mob_spawn_path(null, TRUE)
spawner.outfit_override = list()
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index d337f3026656f..a6cc058fd6f49 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -270,7 +270,7 @@
if(!filter_name_ic(trimmed)) // Contains IC chat prohibited words
return
- return trim_reduced(trimmed)
+ return trimtext(trimmed)
/// Helper proc to check if a name is valid for the IC filter
@@ -337,24 +337,6 @@
return copytext(text, 1, i + 1)
return ""
-//Returns a string with reserved characters and spaces after the first and last letters removed
-//Like trim(), but very slightly faster. worth it for niche usecases
-/proc/trim_reduced(text)
- var/starting_coord = 1
- var/text_len = length(text)
- for (var/i in 1 to text_len)
- if (text2ascii(text, i) > 32)
- starting_coord = i
- break
-
- for (var/i = text_len, i >= starting_coord, i--)
- if (text2ascii(text, i) > 32)
- return copytext(text, starting_coord, i + 1)
-
- if(starting_coord > 1)
- return copytext(text, starting_coord)
- return ""
-
/**
* Truncate a string to the given length
*
@@ -375,7 +357,7 @@
/proc/trim(text, max_length)
if(max_length)
text = copytext_char(text, 1, max_length)
- return trim_reduced(text)
+ return trimtext(text)
//Returns a string with the first element of the string capitalized.
/proc/capitalize(t)
@@ -1210,6 +1192,16 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
else
. = ""
+/proc/weight_class_to_tooltip(w_class)
+ switch(w_class)
+ if(WEIGHT_CLASS_TINY to WEIGHT_CLASS_SMALL)
+ return "This item can fit into pockets, boxes and backpacks."
+ if(WEIGHT_CLASS_NORMAL)
+ return "This item can fit into backpacks."
+ if(WEIGHT_CLASS_BULKY to WEIGHT_CLASS_GIGANTIC)
+ return "This item is too large to fit into any standard storage."
+ return ""
+
/// Removes all non-alphanumerics from the text, keep in mind this can lead to id conflicts
/proc/sanitize_css_class_name(name)
var/static/regex/regex = new(@"[^a-zA-Z0-9а-яА-ЯёЁ]","g") // BANDASTATION EDIT: Add Cyrillic support for this proc
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index 13cb39b7e7806..9eef84860b510 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -335,6 +335,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_MINDSHIELD" = TRAIT_MINDSHIELD,
"TRAIT_MIND_TEMPORARILY_GONE" = TRAIT_MIND_TEMPORARILY_GONE,
"TRAIT_MOB_BREEDER" = TRAIT_MOB_BREEDER,
+ "TRAIT_MOB_CAN_DIG" = TRAIT_MOB_CAN_DIG,
"TRAIT_MOB_EATER" = TRAIT_MOB_EATER,
"TRAIT_MOB_HATCHED" = TRAIT_MOB_HATCHED,
"TRAIT_MOB_HIDE_HAPPINESS" = TRAIT_MOB_HIDE_HAPPINESS,
diff --git a/code/controllers/subsystem/ambience.dm b/code/controllers/subsystem/ambience.dm
index 87f088a41ea13..2d8286a737ad5 100644
--- a/code/controllers/subsystem/ambience.dm
+++ b/code/controllers/subsystem/ambience.dm
@@ -108,7 +108,7 @@ SUBSYSTEM_DEF(ambience)
/mob/proc/refresh_looping_ambience()
SIGNAL_HANDLER
- if(!client) // If a tree falls in the woods.
+ if(!client || isobserver(client.mob)) // If a tree falls in the woods. sadboysuss: Don't refresh for ghosts, it sounds bad
return
var/area/my_area = get_area(src)
diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm
index d6230ec8d3534..07e3851a1aeab 100644
--- a/code/datums/ai/_ai_controller.dm
+++ b/code/datums/ai/_ai_controller.dm
@@ -268,11 +268,6 @@ multiple modular subtrees with behaviors
return AI_STATUS_IDLE
return AI_STATUS_ON
-/datum/ai_controller/proc/get_current_turf()
- var/mob/living/mob_pawn = pawn
- var/turf/pawn_turf = get_turf(mob_pawn)
- to_chat(world, "[pawn_turf]")
-
///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
@@ -322,18 +317,21 @@ multiple modular subtrees with behaviors
/datum/ai_controller/proc/update_able_to_run()
SIGNAL_HANDLER
- able_to_run = get_able_to_run()
- if(!able_to_run)
+ var/run_flags = get_able_to_run()
+ if(run_flags & AI_UNABLE_TO_RUN)
+ able_to_run = FALSE
GLOB.move_manager.stop_looping(pawn) //stop moving
- set_ai_status(get_expected_ai_status())
+ else
+ able_to_run = TRUE
+ set_ai_status(get_expected_ai_status(), run_flags)
///Returns TRUE if the ai controller can actually run at the moment, FALSE otherwise
/datum/ai_controller/proc/get_able_to_run()
if(HAS_TRAIT(pawn, TRAIT_AI_PAUSED))
- return FALSE
+ return AI_UNABLE_TO_RUN
if(world.time < paused_until)
- return FALSE
- return TRUE
+ return AI_UNABLE_TO_RUN
+ return NONE
///Can this pawn interact with objects?
/datum/ai_controller/proc/ai_can_interact()
@@ -380,6 +378,7 @@ multiple modular subtrees with behaviors
if(isnull(current_movement_target))
fail_behavior(current_behavior)
return
+
///Stops pawns from performing such actions that should require the target to be adjacent.
var/atom/movable/moving_pawn = pawn
var/can_reach = !(current_behavior.behavior_flags & AI_BEHAVIOR_REQUIRE_REACH) || moving_pawn.CanReach(current_movement_target)
@@ -419,7 +418,7 @@ multiple modular subtrees with behaviors
forgotten_behavior.finish_action(arglist(arguments))
///This proc handles changing ai status, and starts/stops processing if required.
-/datum/ai_controller/proc/set_ai_status(new_ai_status)
+/datum/ai_controller/proc/set_ai_status(new_ai_status, additional_flags = NONE)
if(ai_status == new_ai_status)
return FALSE //no change
@@ -431,7 +430,8 @@ multiple modular subtrees with behaviors
ai_status = new_ai_status
GLOB.ai_controllers_by_status[new_ai_status] += src
if(ai_status == AI_STATUS_OFF)
- CancelActions()
+ if(!(additional_flags & AI_PREVENT_CANCEL_ACTIONS))
+ CancelActions()
return
if(!length(current_behaviors))
add_to_unplanned_controllers()
diff --git a/code/datums/ai/bane/bane_controller.dm b/code/datums/ai/bane/bane_controller.dm
index 64e1dcf31af3a..580e80440a419 100644
--- a/code/datums/ai/bane/bane_controller.dm
+++ b/code/datums/ai/bane/bane_controller.dm
@@ -27,5 +27,5 @@ And the only victory you achieved was a lie. Now you understand Gotham is beyond
/datum/ai_controller/bane/get_able_to_run()
var/mob/living/living_pawn = pawn
if(IS_DEAD_OR_INCAP(living_pawn))
- return FALSE
+ return AI_UNABLE_TO_RUN
return ..()
diff --git a/code/datums/ai/basic_mobs/base_basic_controller.dm b/code/datums/ai/basic_mobs/base_basic_controller.dm
index 7ab15437f7d35..eb1c38437e3be 100644
--- a/code/datums/ai/basic_mobs/base_basic_controller.dm
+++ b/code/datums/ai/basic_mobs/base_basic_controller.dm
@@ -30,17 +30,17 @@
/datum/ai_controller/basic_controller/get_able_to_run()
. = ..()
- if(!.)
- return FALSE
+ if(. & AI_UNABLE_TO_RUN)
+ return .
var/mob/living/living_pawn = pawn
if(!(ai_traits & CAN_ACT_WHILE_DEAD))
// Unroll for flags here
if (ai_traits & CAN_ACT_IN_STASIS && (living_pawn.stat || INCAPACITATED_IGNORING(living_pawn, INCAPABLE_STASIS)))
- return FALSE
- else if(IS_DEAD_OR_INCAP(living_pawn))
- return FALSE
+ return AI_UNABLE_TO_RUN
+ if(IS_DEAD_OR_INCAP(living_pawn))
+ return AI_UNABLE_TO_RUN
if(ai_traits & PAUSE_DURING_DO_AFTER && LAZYLEN(living_pawn.do_afters))
- return FALSE
+ return AI_UNABLE_TO_RUN | AI_PREVENT_CANCEL_ACTIONS //dont erase targets post a do_after
/datum/ai_controller/basic_controller/proc/update_speed(mob/living/basic/basic_mob)
SIGNAL_HANDLER
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/interact_with_target.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/interact_with_target.dm
index 3b0c4245656e5..e3b202c5e164f 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/interact_with_target.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/interact_with_target.dm
@@ -3,6 +3,8 @@
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH
///should we be clearing the target after the fact?
var/clear_target = TRUE
+ ///should our combat mode be off during interaction?
+ var/combat_mode = TRUE
/datum/ai_behavior/interact_with_target/setup(datum/ai_controller/controller, target_key)
. = ..()
@@ -15,7 +17,7 @@
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target) || !pre_interact(controller, target))
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
- controller.ai_interact(target)
+ controller.ai_interact(target, combat_mode)
return AI_BEHAVIOR_SUCCEEDED | AI_BEHAVIOR_DELAY
/datum/ai_behavior/interact_with_target/finish_action(datum/ai_controller/controller, succeeded, target_key)
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/fishing.dm b/code/datums/ai/basic_mobs/basic_subtrees/fishing.dm
new file mode 100644
index 0000000000000..e17f50740fa64
--- /dev/null
+++ b/code/datums/ai/basic_mobs/basic_subtrees/fishing.dm
@@ -0,0 +1,44 @@
+#define FISHING_COOLDOWN 45 SECONDS
+
+///subtree for fishing and eating food!
+/datum/ai_planning_subtree/fish
+ ///behavior we use to find fishable objects
+ var/datum/ai_behavior/find_fishable_behavior = /datum/ai_behavior/find_and_set/in_list
+ ///behavior we use to fish!
+ var/datum/ai_behavior/fishing_behavior = /datum/ai_behavior/interact_with_target/fishing
+ ///blackboard key storing things we can fish from
+ var/fishable_list_key = BB_FISHABLE_LIST
+ ///key where we store found fishable items
+ var/fishing_target_key = BB_FISHING_TARGET
+ ///key where we store our fishing cooldown
+ var/fishing_cooldown_key = BB_FISHING_COOLDOWN
+ ///our fishing range
+ var/fishing_range = 5
+
+/datum/ai_planning_subtree/fish/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ if(controller.blackboard[BB_ONLY_FISH_WHILE_HUNGRY] && controller.blackboard[BB_NEXT_FOOD_EAT] > world.time)
+ return
+ if(controller.blackboard[BB_FISHING_TIMER] > world.time)
+ return
+ if(!controller.blackboard_key_exists(fishing_target_key))
+ controller.queue_behavior(find_fishable_behavior, fishing_target_key, controller.blackboard[fishable_list_key], fishing_range)
+ return
+ controller.queue_behavior(/datum/ai_behavior/interact_with_target/fishing, fishing_target_key, fishing_cooldown_key)
+ return SUBTREE_RETURN_FINISH_PLANNING
+
+///less expensive fishing behavior!
+/datum/ai_planning_subtree/fish/fish_from_turfs
+ find_fishable_behavior = /datum/ai_behavior/find_and_set/in_list/closest_turf
+
+/datum/ai_behavior/interact_with_target/fishing
+ clear_target = FALSE
+ combat_mode = FALSE
+
+/datum/ai_behavior/interact_with_target/fishing/finish_action(datum/ai_controller/controller, succeeded, fishing_target_key, fishing_cooldown_key)
+ . = ..()
+ if(!succeeded)
+ return
+ var/cooldown = controller.blackboard[fishing_cooldown_key] || FISHING_COOLDOWN
+ controller.set_blackboard_key(BB_FISHING_TIMER, world.time + cooldown)
+
+#undef FISHING_COOLDOWN
diff --git a/code/datums/ai/generic/find_and_set.dm b/code/datums/ai/generic/find_and_set.dm
index 5a424f304f28f..0096ff0f2eb5c 100644
--- a/code/datums/ai/generic/find_and_set.dm
+++ b/code/datums/ai/generic/find_and_set.dm
@@ -181,7 +181,6 @@
/datum/ai_behavior/find_and_set/in_list/turf_types
-
/datum/ai_behavior/find_and_set/in_list/turf_types/search_tactic(datum/ai_controller/controller, locate_paths, search_range)
var/list/found = RANGE_TURFS(search_range, controller.pawn)
shuffle_inplace(found)
@@ -191,3 +190,12 @@
if(can_see(controller.pawn, possible_turf, search_range))
return possible_turf
return null
+
+/datum/ai_behavior/find_and_set/in_list/closest_turf
+
+/datum/ai_behavior/find_and_set/in_list/closest_turf/search_tactic(datum/ai_controller/controller, locate_paths, search_range)
+ var/list/found = RANGE_TURFS(search_range, controller.pawn)
+ for(var/turf/possible_turf as anything in found)
+ if(!is_type_in_typecache(possible_turf, locate_paths) || !can_see(controller.pawn, possible_turf, search_range))
+ found -= possible_turf
+ return (length(found)) ? get_closest_atom(/turf, found, controller.pawn) : null
diff --git a/code/datums/ai/generic/generic_behaviors.dm b/code/datums/ai/generic/generic_behaviors.dm
index c6fcbcfb57265..901a9eeef7f6c 100644
--- a/code/datums/ai/generic/generic_behaviors.dm
+++ b/code/datums/ai/generic/generic_behaviors.dm
@@ -275,7 +275,7 @@
return AI_BEHAVIOR_INSTANT
living_pawn.manual_emote(emote)
if(speech_sound) // Only audible emotes will pass in a sound
- playsound(living_pawn, speech_sound, 80, vary = TRUE)
+ playsound(living_pawn, speech_sound, 80, vary = TRUE, pressure_affected =TRUE, ignore_walls = FALSE)
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/perform_speech
diff --git a/code/datums/ai/hunting_behavior/hunting_behaviors.dm b/code/datums/ai/hunting_behavior/hunting_behaviors.dm
index c202c4be6a7d8..0ab14ff0d3209 100644
--- a/code/datums/ai/hunting_behavior/hunting_behaviors.dm
+++ b/code/datums/ai/hunting_behavior/hunting_behaviors.dm
@@ -50,11 +50,13 @@
/// Finds a specific atom type to hunt.
/datum/ai_behavior/find_hunt_target
+ ///is this only meant to search for turf types?
+ var/search_turf_types = FALSE
/datum/ai_behavior/find_hunt_target/perform(seconds_per_tick, datum/ai_controller/controller, hunting_target_key, types_to_hunt, hunt_range)
var/mob/living/living_mob = controller.pawn
-
- for(var/atom/possible_dinner as anything in typecache_filter_list(range(hunt_range, living_mob), types_to_hunt))
+ var/list/interesting_objects = search_turf_types ? RANGE_TURFS(hunt_range, living_mob) : oview(hunt_range, living_mob)
+ for(var/atom/possible_dinner as anything in typecache_filter_list(interesting_objects, types_to_hunt))
if(!valid_dinner(living_mob, possible_dinner, hunt_range, controller, seconds_per_tick))
continue
controller.set_blackboard_key(hunting_target_key, possible_dinner)
@@ -69,6 +71,9 @@
return can_see(source, dinner, radius)
+/datum/ai_behavior/find_hunt_target/search_turf_types
+ search_turf_types = TRUE
+
/// Hunts down a specific atom type.
/datum/ai_behavior/hunt_target
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH
diff --git a/code/datums/ai/monkey/monkey_controller.dm b/code/datums/ai/monkey/monkey_controller.dm
index e92ec519b209a..71e3d5f398114 100644
--- a/code/datums/ai/monkey/monkey_controller.dm
+++ b/code/datums/ai/monkey/monkey_controller.dm
@@ -120,7 +120,7 @@ have ways of interacting with a specific mob and control it.
var/mob/living/living_pawn = pawn
if(INCAPACITATED_IGNORING(living_pawn, INCAPABLE_RESTRAINTS|INCAPABLE_STASIS|INCAPABLE_GRAB) || living_pawn.stat > CONSCIOUS)
- return FALSE
+ return AI_UNABLE_TO_RUN
return ..()
/datum/ai_controller/monkey/proc/set_trip_mode(mode = TRUE)
diff --git a/code/datums/ai/oldhostile/hostile_tameable.dm b/code/datums/ai/oldhostile/hostile_tameable.dm
index 907ab955a8d53..92e300d939b7b 100644
--- a/code/datums/ai/oldhostile/hostile_tameable.dm
+++ b/code/datums/ai/oldhostile/hostile_tameable.dm
@@ -66,7 +66,7 @@
var/mob/living/living_pawn = pawn
if(IS_DEAD_OR_INCAP(living_pawn))
- return FALSE
+ return AI_UNABLE_TO_RUN
return ..()
/datum/ai_controller/hostile_friend/get_access()
diff --git a/code/datums/beam.dm b/code/datums/beam.dm
index ad27ee5ee3edf..69da1c9142db6 100644
--- a/code/datums/beam.dm
+++ b/code/datums/beam.dm
@@ -206,7 +206,7 @@
owner = null
return ..()
-/obj/effect/ebeam/singularity_pull()
+/obj/effect/ebeam/singularity_pull(atom/singularity, current_size)
return
/obj/effect/ebeam/singularity_act()
diff --git a/code/datums/components/crafting/melee_weapon.dm b/code/datums/components/crafting/melee_weapon.dm
index 018d99d870352..b8771257cfa15 100644
--- a/code/datums/components/crafting/melee_weapon.dm
+++ b/code/datums/components/crafting/melee_weapon.dm
@@ -201,3 +201,15 @@
)
time = 8 SECONDS
category = CAT_WEAPON_MELEE
+
+/datum/crafting_recipe/sm_sword
+ name = "Supermatter Sword"
+ result = /obj/item/melee/supermatter_sword
+ reqs = list(
+ /obj/item/assembly/signaler/anomaly/vortex = (MAX_CORES_VORTEX - 1),
+ )
+ machinery = list(
+ /obj/machinery/power/supermatter_crystal/small = CRAFTING_MACHINERY_CONSUME,
+ )
+ time = 120 SECONDS
+ category = CAT_WEAPON_MELEE
diff --git a/code/datums/components/crafting/structures.dm b/code/datums/components/crafting/structures.dm
index 090ec31ce226f..10fe81efe96d9 100644
--- a/code/datums/components/crafting/structures.dm
+++ b/code/datums/components/crafting/structures.dm
@@ -85,3 +85,26 @@
)
category = CAT_STRUCTURE
crafting_flags = CRAFT_CHECK_DENSITY
+
+/datum/crafting_recipe/adam_pedestal
+ name = "Adamantine Pedestal"
+ result = /obj/item/adamantine_pedestal
+ reqs = list(
+ /obj/item/stack/sheet/mineral/adamantine = 20,
+ )
+ time = 120 SECONDS
+ category = CAT_STRUCTURE
+
+
+/datum/crafting_recipe/sm_small
+ name = "Small Supermatter Crystal"
+ result = /obj/machinery/power/supermatter_crystal/small
+ reqs = list(
+ /obj/item/gun/magic/wand/shrink = 1,
+ /obj/item/adamantine_pedestal = 1,
+ )
+ machinery = list(
+ /obj/machinery/power/supermatter_crystal = CRAFTING_MACHINERY_CONSUME,
+ )
+ time = 120 SECONDS
+ category = CAT_STRUCTURE
diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm
index cc04d6ef5f6cc..430ae7eeccdb3 100644
--- a/code/datums/components/food/edible.dm
+++ b/code/datums/components/food/edible.dm
@@ -566,10 +566,7 @@ Behavior that's still missing from this component that original food items had t
last_check_time = world.time
var/food_quality = get_perceived_food_quality(gourmand)
- if(food_quality <= FOOD_QUALITY_DANGEROUS && (foodtypes & gourmand.get_allergic_foodtypes())) // Only cause anaphylaxis if we're ACTUALLY allergic, otherwise it just tastes horrible
- if(gourmand.ForceContractDisease(new /datum/disease/anaphylaxis(), make_copy = FALSE, del_on_fail = TRUE))
- to_chat(gourmand, span_warning("You feel your throat start to itch."))
- gourmand.add_mood_event("allergic_food", /datum/mood_event/allergic_food)
+ if(food_quality <= FOOD_QUALITY_DANGEROUS && gourmand.check_allergic_reaction(foodtypes, chance = 100, histamine_add = 10))
return
if(food_quality <= TOXIC_FOOD_QUALITY_THRESHOLD)
diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm
index a3f2009b3b506..e93e0f54129bd 100644
--- a/code/datums/components/fullauto.dm
+++ b/code/datums/components/fullauto.dm
@@ -309,8 +309,11 @@
var/bonus_spread = 0
if(istype(akimbo_gun) && weapon_weight < WEAPON_MEDIUM && allow_akimbo)
if(akimbo_gun.weapon_weight < WEAPON_MEDIUM && akimbo_gun.can_trigger_gun(shooter))
- bonus_spread = dual_wield_spread
- addtimer(CALLBACK(akimbo_gun, TYPE_PROC_REF(/obj/item/gun, process_fire), target, shooter, TRUE, params, null, bonus_spread), 0.1 SECONDS)
+ if(!akimbo_gun.can_shoot())
+ addtimer(CALLBACK(akimbo_gun, TYPE_PROC_REF(/obj/item/gun, shoot_with_empty_chamber), shooter), 0.1 SECONDS)
+ else
+ bonus_spread = dual_wield_spread
+ addtimer(CALLBACK(akimbo_gun, TYPE_PROC_REF(/obj/item/gun, process_fire), target, shooter, TRUE, params, null, bonus_spread), 0.1 SECONDS)
process_fire(target, shooter, TRUE, params, null, bonus_spread)
#undef AUTOFIRE_MOUSEUP
diff --git a/code/datums/components/holderloving.dm b/code/datums/components/holderloving.dm
index e41d986600df6..ba457b816b320 100644
--- a/code/datums/components/holderloving.dm
+++ b/code/datums/components/holderloving.dm
@@ -1,92 +1,56 @@
/** Holder Loving Component
*
- * This component is assigned to an [/obj/item], and also keeps track of a [holder].
- * The [parent] is 'bound' to [holder]. [parent] will be kept either directly
- * inside [holder], or in the inventory of a [/mob] that is itself holding [holder].
- *
- * If [parent] is placed in a [loc] that is not [holder] or [holder].[loc]
- * (if it's a mob), it is placed back inside [holder].
- *
- * This is intended for items that are a 'part' of another item.
- *
- * It can also delete [parent] when [holder] is deleted.
+ * When you drop an object onto a turf it gets moved back into its parent holder
*
+ * Prevents you from force moving the object into any other location that isn't its parent holder
*/
/datum/component/holderloving
- can_transfer = TRUE
/** Item that parent is bound to.
* We try to keep parent either directly in holder, or in holder's loc if loc is a mob,
* and warp parent into holder if they go anywhere else.
*/
var/atom/holder
- /// If parent is deleted when the holder gets deleted
- var/del_parent_with_holder = FALSE
-/datum/component/holderloving/Initialize(holder, del_parent_with_holder)
+/datum/component/holderloving/Initialize(holder)
if(!isitem(parent) || !holder)
return COMPONENT_INCOMPATIBLE
src.holder = holder
- if(del_parent_with_holder)
- src.del_parent_with_holder = del_parent_with_holder
/datum/component/holderloving/RegisterWithParent()
- RegisterSignal(holder, COMSIG_MOVABLE_MOVED, PROC_REF(check_my_loc))
RegisterSignal(holder, COMSIG_QDELETING, PROC_REF(holder_deleting))
- RegisterSignals(parent, list(
- COMSIG_ITEM_DROPPED,
- COMSIG_ITEM_EQUIPPED,
- COMSIG_ATOM_ENTERED,
- COMSIG_ATOM_EXITED,
- COMSIG_ITEM_STORED,
- ), PROC_REF(check_my_loc))
- RegisterSignal(parent, COMSIG_ITEM_PRE_UNEQUIP, PROC_REF(no_unequip))
+ RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(check_my_loc))
+ RegisterSignal(parent, COMSIG_ITEM_PRE_UNEQUIP, PROC_REF(can_be_moved))
/datum/component/holderloving/UnregisterFromParent()
- UnregisterSignal(holder, list(COMSIG_MOVABLE_MOVED, COMSIG_QDELETING))
- UnregisterSignal(parent, list(
- COMSIG_ITEM_DROPPED,
- COMSIG_ITEM_EQUIPPED,
- COMSIG_ATOM_ENTERED,
- COMSIG_ATOM_EXITED,
- COMSIG_ITEM_STORED,
- COMSIG_ITEM_PRE_UNEQUIP,
- ))
+ UnregisterSignal(holder, list(COMSIG_QDELETING))
+ UnregisterSignal(parent, list(COMSIG_ITEM_DROPPED, COMSIG_ITEM_PRE_UNEQUIP))
-/datum/component/holderloving/PostTransfer()
- if(!isitem(parent))
- return COMPONENT_INCOMPATIBLE
+/datum/component/holderloving/proc/holder_deleting(datum/source, force)
+ SIGNAL_HANDLER
-/datum/component/holderloving/InheritComponent(datum/component/holderloving/friend, i_am_original, list/arguments)
- if(i_am_original)
- holder = friend.holder
+ qdel(parent)
-/datum/component/holderloving/proc/check_valid_loc(atom/location)
- return (location == holder || ( location == holder.loc && ismob(holder.loc) ))
+/datum/component/holderloving/proc/is_valid_location(atom/location)
+ SHOULD_BE_PURE(TRUE)
-/datum/component/holderloving/proc/holder_deleting(datum/source, force)
- SIGNAL_HANDLER
+ if(location == holder || ( location == holder.loc && ismob(holder.loc)))
+ return TRUE
- if(del_parent_with_holder)
- qdel(parent)
- else
- qdel(src)
+ return FALSE
/datum/component/holderloving/proc/check_my_loc(datum/source)
SIGNAL_HANDLER
var/obj/item/item_parent = parent
- if(!check_valid_loc(item_parent.loc))
+ if(!is_valid_location(item_parent.loc))
item_parent.forceMove(holder)
-/datum/component/holderloving/proc/no_unequip(obj/item/I, force, atom/newloc, no_move, invdrop, silent)
+/datum/component/holderloving/proc/can_be_moved(obj/item/I, force, atom/newloc, no_move, invdrop, silent)
SIGNAL_HANDLER
- // just allow it
- if(force)
+ //allow the item to be dropped on the turf so it can be later moved back into the holder as a convinience tool
+ if(isturf(newloc) || is_valid_location(newloc))
return NONE
- // dropping onto a turf just forcemoves it back to the holder. let it happen, it's intuitive
- // no_move says it's just going to be moved a second time. so let it happen, it'll just be moved back if it's invalid anyway
- if(isturf(newloc) || no_move)
- return NONE
- // the item is being unequipped to somewhere invalid. stop it
+
+ //prevent this item from being moved anywhere else
return COMPONENT_ITEM_BLOCK_UNEQUIP
diff --git a/code/datums/components/item_equipped_movement_rustle.dm b/code/datums/components/item_equipped_movement_rustle.dm
index 435914dada785..115ad9120b495 100644
--- a/code/datums/components/item_equipped_movement_rustle.dm
+++ b/code/datums/components/item_equipped_movement_rustle.dm
@@ -2,8 +2,6 @@
///sound that plays, use an SFX define if there is multiple.
var/rustle_sounds = SFX_SUIT_STEP
- ///human that has the item equipped.
- var/mob/holder
///what move are we on.
var/move_counter = 0
@@ -42,26 +40,25 @@
sound_falloff_distance = falloff_distance
/datum/component/item_equipped_movement_rustle/proc/on_equip(datum/source, mob/equipper, slot)
+ SIGNAL_HANDLER
var/obj/item/our_item = parent
if(!(slot & our_item.slot_flags))
return
- SIGNAL_HANDLER
- holder = equipper
- RegisterSignal(holder, COMSIG_MOVABLE_MOVED, PROC_REF(try_step), override = TRUE)
+ RegisterSignal(equipper, COMSIG_MOVABLE_MOVED, PROC_REF(try_step))
-/datum/component/item_equipped_movement_rustle/proc/on_unequip(datum/source, mob/equipper, slot)
+/datum/component/item_equipped_movement_rustle/proc/on_unequip(datum/source, mob/dropped)
SIGNAL_HANDLER
move_counter = 0
- UnregisterSignal(equipper, COMSIG_MOVABLE_MOVED)
- holder = null
+ UnregisterSignal(dropped, COMSIG_MOVABLE_MOVED)
-/datum/component/item_equipped_movement_rustle/proc/try_step(obj/item/clothing/source)
+/datum/component/item_equipped_movement_rustle/proc/try_step(mob/source)
SIGNAL_HANDLER
-
+ if (source.moving_diagonally == FIRST_DIAG_STEP)
+ return
move_counter++
if(move_counter >= move_delay)
- play_rustle_sound()
+ play_rustle_sound(source)
move_counter = 0
-/datum/component/item_equipped_movement_rustle/proc/play_rustle_sound()
- playsound(parent, rustle_sounds, volume, sound_vary, sound_extra_range, sound_falloff_exponent, falloff_distance = sound_falloff_distance)
+/datum/component/item_equipped_movement_rustle/proc/play_rustle_sound(mob/source)
+ playsound(source, rustle_sounds, volume, sound_vary, sound_extra_range, sound_falloff_exponent, falloff_distance = sound_falloff_distance)
diff --git a/code/datums/components/leanable.dm b/code/datums/components/leanable.dm
new file mode 100644
index 0000000000000..3d2a4e0b73e5b
--- /dev/null
+++ b/code/datums/components/leanable.dm
@@ -0,0 +1,111 @@
+/// Things with this component can be leaned onto, optionally exclusive to RMB dragging
+/datum/component/leanable
+ /// How much will mobs that lean onto this object be offset
+ var/leaning_offset = 11
+ /// List of click modifiers that are required to be present for leaning to trigger
+ var/list/click_mods = null
+ /// Callback called for additional checks if a lean is valid
+ var/datum/callback/lean_check = null
+ /// Whenever this object can be leaned on from the same turf as its' own. Do not use without a custom lean_check!
+ var/same_turf = FALSE
+ /// List of mobs currently leaning on our parent
+ var/list/leaning_mobs = list()
+
+/datum/component/leanable/Initialize(leaning_offset = 11, list/click_mods = null, datum/callback/lean_check = null, same_turf = FALSE)
+ . = ..()
+ src.leaning_offset = leaning_offset
+ src.click_mods = click_mods
+ src.lean_check = lean_check
+ src.same_turf = same_turf
+
+/datum/component/leanable/RegisterWithParent()
+ RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, PROC_REF(mousedrop_receive))
+ RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
+
+/datum/component/leanable/Destroy(force)
+ for (var/mob/living/leaner as anything in leaning_mobs)
+ leaner.stop_leaning()
+ leaning_mobs = null
+ return ..()
+
+/datum/component/leanable/proc/on_moved(datum/source)
+ SIGNAL_HANDLER
+ for (var/mob/living/leaner as anything in leaning_mobs)
+ leaner.stop_leaning()
+
+/datum/component/leanable/proc/mousedrop_receive(atom/source, atom/movable/dropped, mob/user, params)
+ if (dropped != user)
+ return
+ if (islist(click_mods))
+ var/list/modifiers = params2list(params)
+ for (var/modifier in click_mods)
+ if (!LAZYACCESS(modifiers, modifier))
+ return
+ if (!iscarbon(dropped) && !iscyborg(dropped))
+ return
+ var/mob/living/leaner = dropped
+ if (INCAPACITATED_IGNORING(leaner, INCAPABLE_RESTRAINTS) || leaner.stat != CONSCIOUS || HAS_TRAIT(leaner, TRAIT_NO_TRANSFORM))
+ return
+ if (HAS_TRAIT_FROM(leaner, TRAIT_UNDENSE, LEANING_TRAIT))
+ return
+ var/turf/checked_turf = get_step(leaner, REVERSE_DIR(leaner.dir))
+ if (checked_turf != get_turf(source) && (!same_turf || get_turf(source) != get_turf(leaner)))
+ return
+ if (!isnull(lean_check) && !lean_check.Invoke(dropped, params))
+ return
+ leaner.start_leaning(source, leaning_offset)
+ leaning_mobs += leaner
+ RegisterSignals(leaner, list(COMSIG_LIVING_STOPPED_LEANING, COMSIG_QDELETING), PROC_REF(stopped_leaning))
+ return COMPONENT_CANCEL_MOUSEDROPPED_ONTO
+
+/datum/component/leanable/proc/stopped_leaning(datum/source)
+ SIGNAL_HANDLER
+ leaning_mobs -= source
+ UnregisterSignal(source, list(COMSIG_LIVING_STOPPED_LEANING, COMSIG_QDELETING))
+
+/mob/living/proc/start_leaning(atom/lean_target, leaning_offset)
+ var/new_x = lean_target.pixel_x + base_pixel_x + body_position_pixel_x_offset
+ var/new_y = lean_target.pixel_y + base_pixel_y + body_position_pixel_y_offset
+ switch(dir)
+ if(SOUTH)
+ new_y += leaning_offset
+ if(NORTH)
+ new_y -= leaning_offset
+ if(WEST)
+ new_x += leaning_offset
+ if(EAST)
+ new_x -= leaning_offset
+
+ animate(src, 0.2 SECONDS, pixel_x = new_x, pixel_y = new_y)
+ add_traits(list(TRAIT_UNDENSE, TRAIT_EXPANDED_FOV), LEANING_TRAIT)
+ visible_message(
+ span_notice("[src] leans against [lean_target]."),
+ span_notice("You lean against [lean_target]."),
+ )
+ RegisterSignals(src, list(
+ COMSIG_MOB_CLIENT_PRE_MOVE,
+ COMSIG_LIVING_DISARM_HIT,
+ COMSIG_LIVING_GET_PULLED,
+ COMSIG_MOVABLE_TELEPORTING,
+ ), PROC_REF(stop_leaning))
+ RegisterSignal(src, COMSIG_ATOM_POST_DIR_CHANGE, PROC_REF(lean_dir_changed))
+ update_fov()
+
+/mob/living/proc/stop_leaning()
+ SIGNAL_HANDLER
+ UnregisterSignal(src, list(
+ COMSIG_MOB_CLIENT_PRE_MOVE,
+ COMSIG_LIVING_DISARM_HIT,
+ COMSIG_LIVING_GET_PULLED,
+ COMSIG_MOVABLE_TELEPORTING,
+ COMSIG_ATOM_POST_DIR_CHANGE,
+ ))
+ animate(src, 0.2 SECONDS, pixel_x = base_pixel_x + body_position_pixel_x_offset, pixel_y = base_pixel_y + body_position_pixel_y_offset)
+ remove_traits(list(TRAIT_UNDENSE, TRAIT_EXPANDED_FOV), LEANING_TRAIT)
+ SEND_SIGNAL(src, COMSIG_LIVING_STOPPED_LEANING)
+ update_fov()
+
+/mob/living/proc/lean_dir_changed(atom/source, old_dir, new_dir)
+ SIGNAL_HANDLER
+ if (old_dir != new_dir)
+ INVOKE_ASYNC(src, PROC_REF(stop_leaning))
diff --git a/code/datums/elements/basic_allergenic_attack.dm b/code/datums/elements/basic_allergenic_attack.dm
new file mode 100644
index 0000000000000..29bcbf9d79884
--- /dev/null
+++ b/code/datums/elements/basic_allergenic_attack.dm
@@ -0,0 +1,34 @@
+/// Attach to basic mobs, when they attack, they may trigger a food-based allergic reaction in the target.
+/datum/element/basic_allergenic_attack
+ element_flags = ELEMENT_BESPOKE
+ argument_hash_start_idx = 2
+ /// What allergen is being used. Corresponds to a FOODTYPE
+ var/allergen = NONE
+ /// Chance of the reaction happening
+ var/allergen_chance = 100
+ /// How much histamine to add to the target on reaction
+ var/histamine_add = 0
+
+/datum/element/basic_allergenic_attack/Attach(datum/target, allergen = NONE, allergen_chance = 100, histamine_add = 0)
+ . = ..()
+ if(!isbasicmob(target))
+ return ELEMENT_INCOMPATIBLE
+
+ src.allergen = allergen
+ src.allergen_chance = allergen_chance
+ src.histamine_add = histamine_add
+ RegisterSignal(target, COMSIG_HOSTILE_POST_ATTACKINGTARGET, PROC_REF(trigger_allergy))
+
+/datum/element/basic_allergenic_attack/Detach(datum/source, ...)
+ . = ..()
+ UnregisterSignal(source, COMSIG_HOSTILE_POST_ATTACKINGTARGET)
+
+/datum/element/basic_allergenic_attack/proc/trigger_allergy(mob/living/source, mob/living/target, result)
+ SIGNAL_HANDLER
+
+ if(result <= 0 || !istype(target))
+ return
+ if(!target.can_inject(source))
+ return
+
+ target.check_allergic_reaction(allergen, allergen_chance, histamine_add)
diff --git a/code/datums/mutations/touch.dm b/code/datums/mutations/touch.dm
index 251ab1d8ddcc9..4cfb605ba3d5f 100644
--- a/code/datums/mutations/touch.dm
+++ b/code/datums/mutations/touch.dm
@@ -1,6 +1,6 @@
/datum/mutation/human/shock
name = "Shock Touch"
- desc = "The affected can channel excess electricity through their hands without shocking themselves, allowing them to shock others."
+ desc = "The affected can channel excess electricity through their hands without shocking themselves, allowing them to shock others. Mostly harmless! Mostly... "
quality = POSITIVE
locked = TRUE
difficulty = 16
@@ -19,30 +19,23 @@
return
if(GET_MUTATION_POWER(src) <= 1)
- to_modify.chain = initial(to_modify.chain)
+ to_modify.stagger = initial(to_modify.stagger)
return
- to_modify.chain = TRUE
+ to_modify.stagger = TRUE
/datum/action/cooldown/spell/touch/shock
name = "Shock Touch"
- desc = "Channel electricity to your hand to shock people with."
+ desc = "Channel electricity to your hand to shock people with. Mostly harmless! Mostly... "
button_icon_state = "zap"
sound = 'sound/items/weapons/zapbang.ogg'
- cooldown_time = 12 SECONDS
+ cooldown_time = 7 SECONDS
invocation_type = INVOCATION_NONE
spell_requirements = NONE
antimagic_flags = NONE
- //Vars for zaps made when power chromosome is applied, ripped and toned down from reactive tesla armor code.
- ///This var decides if the spell should chain, dictated by presence of power chromosome
- var/chain = FALSE
- ///Affects damage, should do about 1 per limb
- var/zap_power = 7.5 KILO JOULES
- ///Range of tesla shock bounces
- var/zap_range = 7
- ///flags that dictate what the tesla shock can interact with, Can only damage mobs, Cannot damage machines or generate energy
- var/zap_flags = ZAP_MOB_DAMAGE
+ ///This var decides if the spell should stagger, dictated by presence of power chromosome
+ var/stagger = FALSE
hand_path = /obj/item/melee/touch_attack/shock
draw_message = span_notice("You channel electricity into your hand.")
@@ -51,7 +44,12 @@
/datum/action/cooldown/spell/touch/shock/cast_on_hand_hit(obj/item/melee/touch_attack/hand, atom/victim, mob/living/carbon/caster)
if(iscarbon(victim))
var/mob/living/carbon/carbon_victim = victim
- if(carbon_victim.electrocute_act(15, caster, 1, SHOCK_NOGLOVES | SHOCK_NOSTUN))//doesn't stun. never let this stun
+ if(carbon_victim.electrocute_act(5, caster, 1, SHOCK_NOGLOVES | SHOCK_NOSTUN))//doesn't stun. never let this stun
+
+ var/obj/item/bodypart/affecting = carbon_victim.get_bodypart(carbon_victim.get_random_valid_zone(caster.zone_selected))
+ var/armor_block = carbon_victim.run_armor_check(affecting, ENERGY)
+ carbon_victim.apply_damage(20, STAMINA, def_zone = affecting, blocked = armor_block)
+
carbon_victim.dropItemToGround(carbon_victim.get_active_held_item())
carbon_victim.dropItemToGround(carbon_victim.get_inactive_held_item())
carbon_victim.adjust_confusion(15 SECONDS)
@@ -59,21 +57,19 @@
span_danger("[caster] electrocutes [victim]!"),
span_userdanger("[caster] electrocutes you!"),
)
- if(chain)
- tesla_zap(source = victim, zap_range = zap_range, power = zap_power, cutoff = 1 KILO JOULES, zap_flags = zap_flags)
- carbon_victim.visible_message(span_danger("An arc of electricity explodes out of [victim]!"))
+ if(stagger)
+ carbon_victim.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS)
return TRUE
else if(isliving(victim))
var/mob/living/living_victim = victim
- if(living_victim.electrocute_act(15, caster, 1, SHOCK_NOSTUN))
+ if(living_victim.electrocute_act(15, caster, 1, SHOCK_NOSTUN)) //We do damage here because non-carbon mobs typically ignore stamina damage.
living_victim.visible_message(
span_danger("[caster] electrocutes [victim]!"),
span_userdanger("[caster] electrocutes you!"),
)
- if(chain)
- tesla_zap(source = victim, zap_range = zap_range, power = zap_power, cutoff = 1 KILO JOULES, zap_flags = zap_flags)
- living_victim.visible_message(span_danger("An arc of electricity explodes out of [victim]!"))
+ if(stagger)
+ living_victim.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS)
return TRUE
to_chat(caster, span_warning("The electricity doesn't seem to affect [victim]..."))
diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm
index 542d0d6504672..20660ede6f527 100644
--- a/code/datums/outfit.dm
+++ b/code/datums/outfit.dm
@@ -136,11 +136,11 @@
* other such sources of change
*
* Extra Arguments
- * * visualsOnly true if this is only for display (in the character setup screen)
+ * * visuals_only true if this is only for display (in the character setup screen)
*
- * If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
+ * If visuals_only is true, you can omit any work that doesn't visually appear on the character sprite
*/
-/datum/outfit/proc/pre_equip(mob/living/carbon/human/user, visualsOnly = FALSE)
+/datum/outfit/proc/pre_equip(mob/living/carbon/human/user, visuals_only = FALSE)
//to be overridden for customization depending on client prefs,species etc
return
@@ -151,11 +151,11 @@
* fiddle with id bindings and accesses etc
*
* Extra Arguments
- * * visualsOnly true if this is only for display (in the character setup screen)
+ * * visuals_only true if this is only for display (in the character setup screen)
*
- * If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
+ * If visuals_only is true, you can omit any work that doesn't visually appear on the character sprite
*/
-/datum/outfit/proc/post_equip(mob/living/carbon/human/user, visualsOnly = FALSE)
+/datum/outfit/proc/post_equip(mob/living/carbon/human/user, visuals_only = FALSE)
//to be overridden for toggling internals, id binding, access etc
return
@@ -163,7 +163,7 @@
user.equip_to_slot_or_del(SSwardrobe.provide_type(##item_path, user), ##slot_name, TRUE, indirect_action = TRUE); \
var/obj/item/outfit_item = user.get_item_by_slot(##slot_name); \
if (outfit_item && outfit_item.type == ##item_path) { \
- outfit_item.on_outfit_equip(user, visualsOnly, ##slot_name); \
+ outfit_item.on_outfit_equip(user, visuals_only, ##slot_name); \
} \
}
@@ -171,12 +171,12 @@
* Equips all defined types and paths to the mob passed in
*
* Extra Arguments
- * * visualsOnly true if this is only for display (in the character setup screen)
+ * * visuals_only true if this is only for display (in the character setup screen)
*
- * If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
+ * If visuals_only is true, you can omit any work that doesn't visually appear on the character sprite
*/
-/datum/outfit/proc/equip(mob/living/carbon/human/user, visualsOnly = FALSE)
- pre_equip(user, visualsOnly)
+/datum/outfit/proc/equip(mob/living/carbon/human/user, visuals_only = FALSE)
+ pre_equip(user, visuals_only)
//Start with uniform,suit,backpack for additional slots
if(uniform)
@@ -203,7 +203,7 @@
EQUIP_OUTFIT_ITEM(back, ITEM_SLOT_BACK)
if(id)
EQUIP_OUTFIT_ITEM(id, ITEM_SLOT_ID)
- if(!visualsOnly && id_trim && user.wear_id)
+ if(!visuals_only && id_trim && user.wear_id)
var/obj/item/card/id/id_card = user.wear_id
if(!istype(id_card)) //If an ID wasn't found in their ID slot, it's probably something holding their ID like a wallet or PDA
id_card = locate() in user.wear_id
@@ -235,11 +235,11 @@
WARNING("Unable to equip accessory [accessory] in outfit [name]. No uniform present!")
if(l_hand)
- user.put_in_l_hand(SSwardrobe.provide_type(l_hand, user))
+ user.put_in_l_hand(SSwardrobe.provide_type(l_hand, user), visuals_only = visuals_only)
if(r_hand)
- user.put_in_r_hand(SSwardrobe.provide_type(r_hand, user))
+ user.put_in_r_hand(SSwardrobe.provide_type(r_hand, user), visuals_only = visuals_only)
- if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
+ if(!visuals_only) // Items in pockets or backpack don't show up on mob's icon.
if(l_pocket)
EQUIP_OUTFIT_ITEM(l_pocket, ITEM_SLOT_LPOCKET)
if(r_pocket)
@@ -267,9 +267,9 @@
for(var/i in 1 to number)
EQUIP_OUTFIT_ITEM(path, ITEM_SLOT_BELTPACK)
- post_equip(user, visualsOnly)
+ post_equip(user, visuals_only)
- if(!visualsOnly)
+ if(!visuals_only)
apply_fingerprints(user)
if(internals_slot)
if(internals_slot & ITEM_SLOT_HANDS)
diff --git a/code/game/area/areas/ruins/space.dm b/code/game/area/areas/ruins/space.dm
index ac687d6024a88..2e25aeb2d6fd4 100644
--- a/code/game/area/areas/ruins/space.dm
+++ b/code/game/area/areas/ruins/space.dm
@@ -369,9 +369,9 @@
// Area define for organization
/area/ruin/space/ks13/engineering
-/area/ruin/space/ks13/engineering/singulo
- name = "\improper Derelict Singulairty Engine"
- icon_state = "ks13_singulo"
+/area/ruin/space/ks13/engineering/supermatter
+ name = "\improper Derelict Supermatter Engine"
+ icon_state = "ks13_supermatter"
/area/ruin/space/ks13/engineering/atmos
name = "\improper Derelict Atmospherics"
diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm
index 7f43cc2c6ee8c..473336b1ccc4d 100644
--- a/code/game/atom/_atom.dm
+++ b/code/game/atom/_atom.dm
@@ -700,6 +700,9 @@
/atom/proc/OnCreatedFromProcessing(mob/living/user, obj/item/work_tool, list/chosen_option, atom/original_atom)
SHOULD_CALL_PARENT(TRUE)
+ if(HAS_TRAIT(original_atom, TRAIT_FOOD_SILVER))
+ ADD_TRAIT(src, TRAIT_FOOD_SILVER, INNATE_TRAIT) // stinky food always stinky
+
SEND_SIGNAL(src, COMSIG_ATOM_CREATEDBY_PROCESSING, original_atom, chosen_option)
if(user.mind)
ADD_TRAIT(src, TRAIT_FOOD_CHEF_MADE, REF(user.mind))
diff --git a/code/game/atom/atom_act.dm b/code/game/atom/atom_act.dm
index 7b69f02340c87..8565d790612c2 100644
--- a/code/game/atom/atom_act.dm
+++ b/code/game/atom/atom_act.dm
@@ -151,7 +151,7 @@
*
* Default behaviour is to send [COMSIG_ATOM_SING_PULL] and return
*/
-/atom/proc/singularity_pull(obj/singularity/singularity, current_size)
+/atom/proc/singularity_pull(atom/singularity, current_size)
SEND_SIGNAL(src, COMSIG_ATOM_SING_PULL, singularity, current_size)
/**
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index b3e04fdc80769..bd6e6ad483299 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -270,7 +270,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
return
user.electrocute_act(10, src)
-/obj/machinery/camera/singularity_pull(S, current_size)
+/obj/machinery/camera/singularity_pull(atom/singularity, current_size)
if (camera_enabled && current_size >= STAGE_FIVE) // If the singulo is strong enough to pull anchored objects and the camera is still active, turn off the camera as it gets ripped off the wall.
toggle_cam(null, 0)
return ..()
diff --git a/code/game/machinery/camera/camera_construction.dm b/code/game/machinery/camera/camera_construction.dm
index d6988617e1f25..b3593aad6e7e2 100644
--- a/code/game/machinery/camera/camera_construction.dm
+++ b/code/game/machinery/camera/camera_construction.dm
@@ -123,7 +123,7 @@
if(camera_construction_state != CAMERA_STATE_FINISHED || panel_open)
if(attacking_item.tool_behaviour == TOOL_ANALYZER)
if(!isXRay(TRUE)) //don't reveal it was already upgraded if was done via MALF AI Upgrade Camera Network ability
- if(!user.temporarilyRemoveItemFromInventory(attacking_item))
+ if(!user.temporarilyRemoveItemFromInventory(attacking_item, newloc = src))
return
upgradeXRay(FALSE, TRUE)
to_chat(user, span_notice("You attach [attacking_item] into [name]'s inner circuits."))
@@ -141,7 +141,7 @@
return
else if(isprox(attacking_item))
if(!isMotion())
- if(!user.temporarilyRemoveItemFromInventory(attacking_item))
+ if(!user.temporarilyRemoveItemFromInventory(attacking_item, newloc = src))
return
upgradeMotion()
to_chat(user, span_notice("You attach [attacking_item] into [name]'s inner circuits."))
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 8385a639b7f4a..2b473c3dbe6c1 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1825,7 +1825,7 @@
/obj/structure/fluff/airlock_filler/singularity_act()
return
-/obj/structure/fluff/airlock_filler/singularity_pull(S, current_size)
+/obj/structure/fluff/airlock_filler/singularity_pull(atom/singularity, current_size)
return
/obj/machinery/door/airlock/proc/set_cycle_pump(obj/machinery/atmospherics/components/unary/airlock_pump/pump)
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index 3fc4dcf219adb..b22959ce461be 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -425,7 +425,7 @@
if(prob(33) && buildstage == FIRE_ALARM_BUILD_SECURED) //require fully wired electronics to set of the alarms
alarm()
-/obj/machinery/firealarm/singularity_pull(S, current_size)
+/obj/machinery/firealarm/singularity_pull(atom/singularity, current_size)
if (current_size >= STAGE_FIVE) // If the singulo is strong enough to pull anchored objects, the fire alarm experiences integrity failure
deconstruct()
return ..()
diff --git a/code/game/machinery/scanner_gate.dm b/code/game/machinery/scanner_gate.dm
index 41b84a26ddfb0..5f9918c32da7e 100644
--- a/code/game/machinery/scanner_gate.dm
+++ b/code/game/machinery/scanner_gate.dm
@@ -52,7 +52,8 @@
var/base_false_beep = 5
///Is an n-spect scanner attached to the gate? Enables contraband scanning.
var/obj/item/inspector/n_spect = null
-
+ /// Overlay object we're using for scanlines
+ var/obj/effect/overlay/scanline = null
/obj/machinery/scanner_gate/Initialize(mapload)
. = ..()
@@ -64,6 +65,10 @@
AddElement(/datum/element/connect_loc, loc_connections)
register_context()
+/obj/machinery/scanner_gate/Destroy(force)
+ QDEL_NULL(scanline)
+ return ..()
+
/obj/machinery/scanner_gate/RefreshParts()
. = ..()
for(var/datum/stock_part/scanning_module/scanning_module in component_parts)
@@ -104,13 +109,31 @@
if(!(machine_stat & (BROKEN|NOPOWER)) && anchored && !panel_open)
perform_scan(thing)
-/obj/machinery/scanner_gate/proc/set_scanline(type, duration)
- cut_overlays()
+/obj/machinery/scanner_gate/proc/set_scanline(scanline_type, duration)
+ if (!isnull(scanline))
+ vis_contents -= scanline
+ else
+ scanline = new(src)
+ scanline.icon = icon
+ scanline.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ scanline.layer = layer
deltimer(scanline_timer)
- add_overlay(type)
+ if (isnull(scanline_type))
+ if(duration)
+ scanline_timer = addtimer(CALLBACK(src, PROC_REF(set_scanline), "passive"), duration, TIMER_STOPPABLE)
+ return
+ scanline.icon_state = scanline_type
+ vis_contents += scanline
if(duration)
scanline_timer = addtimer(CALLBACK(src, PROC_REF(set_scanline), "passive"), duration, TIMER_STOPPABLE)
+/obj/machinery/scanner_gate/power_change()
+ . = ..()
+ if (machine_stat & (NOPOWER | BROKEN))
+ set_scanline(null)
+ return
+ set_scanline("passive")
+
/obj/machinery/scanner_gate/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(istype(tool, /obj/item/inspector))
if(n_spect)
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 1eff3f6587080..44d441b93dbcd 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -2,7 +2,7 @@
// SUIT STORAGE UNIT /////////////////
/obj/machinery/suit_storage_unit
name = "suit storage unit"
- desc = "An industrial unit made to hold and decontaminate irradiated equipment. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit."
+ desc = "An industrial unit made to hold, charge, and decontaminate equipment. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit."
icon = 'icons/obj/machines/suit_storage.dmi'
icon_state = "classic"
base_icon_state = "classic"
@@ -401,7 +401,7 @@
if (occupant && safeties)
say("Alert: safeties triggered, occupant detected!")
return
- else if (!helmet && !mask && !suit && !storage && !occupant)
+ else if (!helmet && !mask && !suit && !mod && !storage && !occupant)
to_chat(user, "There's nothing inside [src] to disinfect!")
return
else
@@ -751,9 +751,9 @@
if(!user.transferItemToLoc(weapon, src))
return
mask = weapon
- else if(istype(weapon, /obj/item/mod/control))
+ else if(istype(weapon, /obj/item/storage/backpack) || istype(weapon, /obj/item/mod/control))
if(mod)
- to_chat(user, span_warning("The unit already contains a MOD!"))
+ to_chat(user, span_warning("The unit already contains a backpack or MOD!"))
return
if(!user.transferItemToLoc(weapon, src))
return
diff --git a/code/game/objects/effects/bump_teleporter.dm b/code/game/objects/effects/bump_teleporter.dm
index 04dd7e4809a6d..ede5302d512b5 100644
--- a/code/game/objects/effects/bump_teleporter.dm
+++ b/code/game/objects/effects/bump_teleporter.dm
@@ -26,7 +26,7 @@
/obj/effect/bump_teleporter/singularity_act()
return
-/obj/effect/bump_teleporter/singularity_pull()
+/obj/effect/bump_teleporter/singularity_pull(atom/singularity, current_size)
return
/obj/effect/bump_teleporter/Bumped(atom/movable/bumper)
diff --git a/code/game/objects/effects/countdown.dm b/code/game/objects/effects/countdown.dm
index d83440ee9bd36..11364a047b774 100644
--- a/code/game/objects/effects/countdown.dm
+++ b/code/game/objects/effects/countdown.dm
@@ -73,7 +73,7 @@
STOP_PROCESSING(SSfastprocess, src)
. = ..()
-/obj/effect/countdown/singularity_pull()
+/obj/effect/countdown/singularity_pull(atom/singularity, current_size)
return
/obj/effect/countdown/singularity_act()
diff --git a/code/game/objects/effects/effect_system/effect_shield.dm b/code/game/objects/effects/effect_system/effect_shield.dm
index 9b1cc2c1bf202..d76712626b8e3 100644
--- a/code/game/objects/effects/effect_system/effect_shield.dm
+++ b/code/game/objects/effects/effect_system/effect_shield.dm
@@ -21,6 +21,6 @@
/obj/effect/shield/singularity_act()
return
-/obj/effect/shield/singularity_pull(S, current_size)
+/obj/effect/shield/singularity_pull(atom/singularity, current_size)
return
diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm
index 0c050579de45b..495c61510a601 100644
--- a/code/game/objects/effects/effects.dm
+++ b/code/game/objects/effects/effects.dm
@@ -50,7 +50,7 @@
/obj/effect/abstract
resistance_flags = parent_type::resistance_flags | SHUTTLE_CRUSH_PROOF
-/obj/effect/abstract/singularity_pull()
+/obj/effect/abstract/singularity_pull(atom/singularity, current_size)
return
/obj/effect/abstract/singularity_act()
@@ -59,7 +59,7 @@
/obj/effect/abstract/has_gravity(turf/gravity_turf)
return FALSE
-/obj/effect/dummy/singularity_pull()
+/obj/effect/dummy/singularity_pull(atom/singularity, current_size)
return
/obj/effect/dummy/singularity_act()
diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm
index 60ce9d7662b81..dc51e5079f4c8 100644
--- a/code/game/objects/effects/forcefields.dm
+++ b/code/game/objects/effects/forcefields.dm
@@ -14,7 +14,7 @@
if(initial_duration > 0 SECONDS)
QDEL_IN(src, initial_duration)
-/obj/effect/forcefield/singularity_pull()
+/obj/effect/forcefield/singularity_pull(atom/singularity, current_size)
return
/// The wizard's forcefield, summoned by forcewall
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index b1a4a75c945d7..5efb41e602916 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -11,7 +11,7 @@
/obj/effect/landmark/singularity_act()
return
-/obj/effect/landmark/singularity_pull()
+/obj/effect/landmark/singularity_pull(atom/singularity, current_size)
return
INITIALIZE_IMMEDIATE(/obj/effect/landmark)
diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm
index 075e927d65328..f502138552493 100644
--- a/code/game/objects/effects/misc.dm
+++ b/code/game/objects/effects/misc.dm
@@ -15,7 +15,7 @@
/obj/effect/beam/singularity_act()
return
-/obj/effect/beam/singularity_pull()
+/obj/effect/beam/singularity_pull(atom/singularity, current_size)
return
/obj/effect/spawner
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index 24fae3f613917..b90ebe54ffaf2 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -4,7 +4,7 @@
/obj/effect/overlay/singularity_act()
return
-/obj/effect/overlay/singularity_pull()
+/obj/effect/overlay/singularity_pull(atom/singularity, current_size)
return
/obj/effect/overlay/beam//Not actually a projectile, just an effect.
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index a43fee5608de3..18f633504264f 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -113,7 +113,7 @@
playsound(loc, SFX_PORTAL_CLOSE, 50, FALSE, SHORT_RANGE_SOUND_EXTRARANGE)
qdel(src)
-/obj/effect/portal/singularity_pull()
+/obj/effect/portal/singularity_pull(atom/singularity, current_size)
return
/obj/effect/portal/singularity_act()
diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm
index 68a49b8a3031b..31ca55a54fb7b 100644
--- a/code/game/objects/effects/step_triggers.dm
+++ b/code/game/objects/effects/step_triggers.dm
@@ -31,7 +31,7 @@
/obj/effect/step_trigger/singularity_act()
return
-/obj/effect/step_trigger/singularity_pull()
+/obj/effect/step_trigger/singularity_pull(atom/singularity, current_size)
return
/* Sends a message to mob when triggered*/
diff --git a/code/game/objects/effects/temporary_visuals/projectiles/projectile_effects.dm b/code/game/objects/effects/temporary_visuals/projectiles/projectile_effects.dm
index 81c854f2c3e17..2d112aa205909 100644
--- a/code/game/objects/effects/temporary_visuals/projectiles/projectile_effects.dm
+++ b/code/game/objects/effects/temporary_visuals/projectiles/projectile_effects.dm
@@ -7,7 +7,7 @@
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
appearance_flags = LONG_GLIDE
-/obj/effect/projectile/singularity_pull()
+/obj/effect/projectile/singularity_pull(atom/singularity, current_size)
return
/obj/effect/projectile/singularity_act()
diff --git a/code/game/objects/effects/temporary_visuals/temporary_visual.dm b/code/game/objects/effects/temporary_visuals/temporary_visual.dm
index 9669b4ed290ec..a4c94104e1e75 100644
--- a/code/game/objects/effects/temporary_visuals/temporary_visual.dm
+++ b/code/game/objects/effects/temporary_visuals/temporary_visual.dm
@@ -25,7 +25,7 @@
/obj/effect/temp_visual/singularity_act()
return
-/obj/effect/temp_visual/singularity_pull()
+/obj/effect/temp_visual/singularity_pull(atom/singularity, current_size)
return
/obj/effect/temp_visual/dir_setting
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index d957cfe54310e..eb1f54feb25f5 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -130,6 +130,9 @@
var/flags_inv
///you can see someone's mask through their transparent visor, but you can't reach it
var/transparent_protection = NONE
+ ///Name of a mask in icons\mob\human\hair_masks.dmi to apply to hair when this item is worn
+ ///Used by certain hats to give the appearance of squishing down tall hairstyles without hiding the hair completely
+ var/hair_mask = ""
///flags for what should be done when you click on the item, default is picking it up
var/interaction_flags_item = INTERACT_ITEM_ATTACK_HAND_PICKUP
@@ -443,7 +446,7 @@
var/list/parent_tags = ..()
parent_tags.Insert(1, weight_class_to_text(w_class)) // To make size display first, otherwise it looks goofy
. = parent_tags
- .[weight_class_to_text(w_class)] = "[gender == PLURAL ? "They are" : "It is"] a [weight_class_to_text(w_class)] item."
+ .[weight_class_to_text(w_class)] = weight_class_to_tooltip(w_class)
if(item_flags & CRUEL_IMPLEMENT)
.[span_red("morbid")] = "It seems quite practical for particularly morbid procedures and experiments."
@@ -831,10 +834,10 @@
/obj/item/proc/IsReflect(def_zone)
return FALSE
-/obj/item/singularity_pull(S, current_size)
+/obj/item/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FOUR)
- throw_at(S,14,3, spin=0)
+ throw_at(singularity, 14, 3, spin=0)
else
return
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 31c2f66dac0bb..5b402e3402bca 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -819,7 +819,13 @@
return .
context[SCREENTIP_CONTEXT_LMB] = "Paint"
- context[SCREENTIP_CONTEXT_RMB] = "Copy color"
+
+ if(isbodypart(target))
+ var/obj/item/bodypart/limb = target
+ if(IS_ROBOTIC_LIMB(limb))
+ context[SCREENTIP_CONTEXT_RMB] = "Restyle robotic limb"
+ else
+ context[SCREENTIP_CONTEXT_RMB] = "Copy color"
return CONTEXTUAL_SCREENTIP_SET
@@ -981,7 +987,7 @@
if(isbodypart(interacting_with) && actually_paints)
var/obj/item/bodypart/limb = interacting_with
- if(!IS_ORGANIC_LIMB(limb))
+ if(IS_ROBOTIC_LIMB(limb))
var/list/skins = list()
var/static/list/style_list_icons = list("standard" = 'icons/mob/augmentation/augments.dmi', "engineer" = 'icons/mob/augmentation/augments_engineer.dmi', "security" = 'icons/mob/augmentation/augments_security.dmi', "mining" = 'icons/mob/augmentation/augments_mining.dmi')
for(var/skin_option in style_list_icons)
@@ -1093,6 +1099,13 @@
charges = INFINITE_CHARGES
desc = "Now with 30% more bluespace technology."
+/obj/item/toy/crayon/spraycan/roboticist
+ name = "roboticist spraycan"
+ desc = "Paint for restyling unattached robotic limbs. Sadly doesn't shine like chrome."
+ icon_state = "robocan"
+ icon_capped = "robocan_cap"
+ icon_uncapped = "robocan"
+
#undef RANDOM_GRAFFITI
#undef RANDOM_LETTER
#undef RANDOM_PUNCTUATION
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 93a131a9b468b..fcb5318d63bf8 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -351,7 +351,7 @@
if(isliving(talking_movable))
var/mob/living/talking_living = talking_movable
- if(radio_noise && !HAS_TRAIT(talking_living, TRAIT_DEAF) && talking_living.client?.prefs.read_preference(/datum/preference/toggle/radio_noise))
+ if(radio_noise && talking_living.can_hear() && talking_living.client?.prefs.read_preference(/datum/preference/toggle/radio_noise) && signal.frequency != FREQ_COMMON)
SEND_SOUND(talking_living, 'sound/items/radio/radio_talk.ogg')
// All radios make an attempt to use the subspace system first
diff --git a/code/game/objects/items/food/donkpocket.dm b/code/game/objects/items/food/donkpocket.dm
index a5da7a6de2340..4cbf83ce631bc 100644
--- a/code/game/objects/items/food/donkpocket.dm
+++ b/code/game/objects/items/food/donkpocket.dm
@@ -310,7 +310,6 @@
tastes = list("raw meat" = 2, "more meat" = 2, "no carbs" = 1)
foodtypes = MEAT | RAW
crafting_complexity = FOOD_COMPLEXITY_4
-
warm_type = /obj/item/food/donkpocket/warm/deluxe/nocarb
/obj/item/food/donkpocket/deluxe/meat/make_bakeable()
@@ -343,6 +342,7 @@
tastes = list("rice patty" = 2, "dough" = 2, "peppery kick" = 1)
foodtypes = GRAIN | VEGETABLES
crafting_complexity = FOOD_COMPLEXITY_4
+ warm_type = /obj/item/food/donkpocket/warm/deluxe/vegan
/obj/item/food/donkpocket/deluxe/vegan/make_bakeable()
AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, deluxe_added_reagents)
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index c51adf91b3b10..7c8173fae3653 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -121,12 +121,12 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag)
SEND_SIGNAL(src, COMSIG_ATOM_UI_INTERACT, user)
ui_interact(user)
-/obj/singularity_pull(S, current_size)
+/obj/singularity_pull(atom/singularity, current_size)
..()
if(move_resist == INFINITY)
return
if(!anchored || current_size >= STAGE_FIVE)
- step_towards(src,S)
+ step_towards(src, singularity)
/obj/get_dumping_location()
return get_turf(src)
diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm
index ffe4ea44a00cb..17f81eb242820 100644
--- a/code/game/objects/structures/ladders.dm
+++ b/code/game/objects/structures/ladders.dm
@@ -79,7 +79,7 @@
icon_state = "ladder[up ? 1 : 0][down ? 1 : 0]"
return ..()
-/obj/structure/ladder/singularity_pull()
+/obj/structure/ladder/singularity_pull(atom/singularity, current_size)
if (!(resistance_flags & INDESTRUCTIBLE))
visible_message(span_danger("[src] is torn to pieces by the gravitational pull!"))
qdel(src)
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index 0b55326130022..a0cf53487cf34 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -82,7 +82,7 @@
return TRUE
return FALSE
-/obj/structure/lattice/singularity_pull(S, current_size)
+/obj/structure/lattice/singularity_pull(atom/singularity, current_size)
if(current_size >= STAGE_FOUR)
deconstruct()
diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm
index e0852b0fd39c2..5518375de6801 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube.dm
@@ -27,7 +27,7 @@
P.deconstruct(FALSE)
return ..()
-/obj/structure/transit_tube/singularity_pull(S, current_size)
+/obj/structure/transit_tube/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index 6522a2125fea3..a35915d6f007b 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -63,7 +63,7 @@
if(EXPLODE_LIGHT)
SSexplosions.low_mov_atom += contents
-/obj/structure/transit_tube_pod/singularity_pull(S, current_size)
+/obj/structure/transit_tube_pod/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 032b86721b0bb..b3a3ea310386a 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -37,6 +37,8 @@
var/datum/material/glass_material_datum = /datum/material/glass
/// Whether or not we're disappearing but dramatically
var/dramatically_disappearing = FALSE
+ /// If we added a leaning component to ourselves
+ var/added_leaning = FALSE
/datum/armor/structure_window
melee = 50
@@ -78,6 +80,15 @@
if (flags_1 & ON_BORDER_1)
AddElement(/datum/element/connect_loc, loc_connections)
+/obj/structure/window/mouse_drop_receive(atom/dropping, mob/user, params)
+ . = ..()
+ if (added_leaning || (flags_1 & ON_BORDER_1))
+ return
+ /// For performance reasons and to cut down on init times we are "lazy-loading" the leaning component when someone drags their sprite onto us, and then calling dragging code again to trigger the component
+ AddComponent(/datum/component/leanable, 11)
+ added_leaning = TRUE
+ dropping.base_mouse_drop_handler(src, null, null, params)
+
/obj/structure/window/examine(mob/user)
. = ..()
@@ -106,7 +117,7 @@
/obj/structure/window/narsie_act()
add_atom_colour(NARSIE_WINDOW_COLOUR, FIXED_COLOUR_PRIORITY)
-/obj/structure/window/singularity_pull(S, current_size)
+/obj/structure/window/singularity_pull(atom/singularity, current_size)
..()
if(anchored && current_size >= STAGE_TWO)
set_anchored(FALSE)
diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm
index 6ac5dc1649600..133f52f569f93 100644
--- a/code/game/turfs/closed/walls.dm
+++ b/code/game/turfs/closed/walls.dm
@@ -1,5 +1,3 @@
-#define LEANING_OFFSET 11
-
/turf/closed/wall
name = "wall"
RU_NAMES_LIST_INIT("wall", "стена", "стены", "стене", "стену", "стеной", "стене")
@@ -32,67 +30,11 @@
var/girder_type = /obj/structure/girder
/// A turf that will replace this turf when this turf is destroyed
var/decon_type
+ /// If we added a leaning component to ourselves
+ var/added_leaning = FALSE
var/list/dent_decals
-/turf/closed/wall/mouse_drop_receive(atom/dropping, mob/user, params)
- if(dropping != user)
- return
- if(!iscarbon(dropping) && !iscyborg(dropping))
- return
- var/mob/living/leaner = dropping
- if(INCAPACITATED_IGNORING(leaner, INCAPABLE_RESTRAINTS) || leaner.stat != CONSCIOUS || HAS_TRAIT(leaner, TRAIT_NO_TRANSFORM))
- return
- if(!leaner.density || leaner.pulledby || leaner.buckled || !(leaner.mobility_flags & MOBILITY_STAND))
- return
- if(HAS_TRAIT_FROM(leaner, TRAIT_UNDENSE, LEANING_TRAIT))
- return
- var/turf/checked_turf = get_step(leaner, REVERSE_DIR(leaner.dir))
- if(checked_turf != src)
- return
- leaner.start_leaning(src)
-
-/mob/living/proc/start_leaning(turf/closed/wall/wall)
- var/new_y = base_pixel_y + pixel_y
- var/new_x = base_pixel_x + pixel_x
- switch(dir)
- if(SOUTH)
- new_y += LEANING_OFFSET
- if(NORTH)
- new_y -= LEANING_OFFSET
- if(WEST)
- new_x += LEANING_OFFSET
- if(EAST)
- new_x -= LEANING_OFFSET
-
- animate(src, 0.2 SECONDS, pixel_x = new_x, pixel_y = new_y)
- add_traits(list(TRAIT_UNDENSE, TRAIT_EXPANDED_FOV), LEANING_TRAIT)
- visible_message(
- span_notice("[src] leans against [wall]."),
- span_notice("You lean against [wall]."),
- )
- RegisterSignals(src, list(
- COMSIG_MOB_CLIENT_PRE_MOVE,
- COMSIG_LIVING_DISARM_HIT,
- COMSIG_LIVING_GET_PULLED,
- COMSIG_MOVABLE_TELEPORTING,
- COMSIG_ATOM_DIR_CHANGE,
- ), PROC_REF(stop_leaning))
- update_fov()
-
-/mob/living/proc/stop_leaning()
- SIGNAL_HANDLER
- UnregisterSignal(src, list(
- COMSIG_MOB_CLIENT_PRE_MOVE,
- COMSIG_LIVING_DISARM_HIT,
- COMSIG_LIVING_GET_PULLED,
- COMSIG_MOVABLE_TELEPORTING,
- COMSIG_ATOM_DIR_CHANGE,
- ))
- animate(src, 0.2 SECONDS, pixel_x = base_pixel_x, pixel_y = base_pixel_y)
- remove_traits(list(TRAIT_UNDENSE, TRAIT_EXPANDED_FOV), LEANING_TRAIT)
- update_fov()
-
/turf/closed/wall/Initialize(mapload)
. = ..()
if(!can_engrave)
@@ -109,6 +51,15 @@
fixed_underlay = string_assoc_list(fixed_underlay)
underlays += underlay_appearance
+/turf/closed/wall/mouse_drop_receive(atom/dropping, mob/user, params)
+ . = ..()
+ if (added_leaning)
+ return
+ /// For performance reasons and to cut down on init times we are "lazy-loading" the leaning component when someone drags their sprite onto us, and then calling dragging code again to trigger the component
+ AddComponent(/datum/component/leanable, 11)
+ added_leaning = TRUE
+ dropping.base_mouse_drop_handler(src, null, null, params)
+
/turf/closed/wall/atom_destruction(damage_flag)
. = ..()
dismantle_wall(TRUE, FALSE)
@@ -297,7 +248,7 @@
return FALSE
-/turf/closed/wall/singularity_pull(S, current_size)
+/turf/closed/wall/singularity_pull(atom/singularity, current_size)
..()
wall_singularity_pull(current_size)
@@ -379,5 +330,3 @@
/turf/closed/wall/Exited(atom/movable/gone, direction)
. = ..()
SEND_SIGNAL(gone, COMSIG_LIVING_WALL_EXITED, src)
-
-#undef LEANING_OFFSET
diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm
index c3ea369404331..cad574eb4ec8d 100644
--- a/code/game/turfs/open/floor.dm
+++ b/code/game/turfs/open/floor.dm
@@ -175,7 +175,7 @@
return null
return new floor_tile(src)
-/turf/open/floor/singularity_pull(S, current_size)
+/turf/open/floor/singularity_pull(atom/singularity, current_size)
..()
var/sheer = FALSE
switch(current_size)
diff --git a/code/game/turfs/open/floor/reinforced_floor.dm b/code/game/turfs/open/floor/reinforced_floor.dm
index dcba9ed36673a..78b6e5a803e5a 100644
--- a/code/game/turfs/open/floor/reinforced_floor.dm
+++ b/code/game/turfs/open/floor/reinforced_floor.dm
@@ -75,7 +75,7 @@
return TRUE
-/turf/open/floor/engine/singularity_pull(S, current_size)
+/turf/open/floor/engine/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FIVE)
if(floor_tile)
diff --git a/code/game/turfs/open/ice.dm b/code/game/turfs/open/ice.dm
index f28bc8dd4b052..39abe6ebfeef7 100644
--- a/code/game/turfs/open/ice.dm
+++ b/code/game/turfs/open/ice.dm
@@ -42,15 +42,23 @@
if(can_make_hole)
. += span_info("You could use a [EXAMINE_HINT("shovel")] or a [EXAMINE_HINT("pick")] to dig a fishing hole here.")
+/turf/open/misc/ice/attack_animal(mob/living/animal, list/modifiers)
+ . = ..()
+ if(HAS_TRAIT(animal, TRAIT_MOB_CAN_DIG))
+ dig_hole(animal)
+
/turf/open/misc/ice/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
- if(!can_make_hole)
- return NONE
if(tool.tool_behaviour != TOOL_SHOVEL && tool.tool_behaviour != TOOL_MINING)
return NONE
+ return dig_hole(user) ? ITEM_INTERACT_SUCCESS : NONE
+
+/turf/open/misc/ice/proc/dig_hole(mob/living/user)
+ if(!can_make_hole)
+ return FALSE
balloon_alert(user, "digging...")
playsound(src, 'sound/effects/shovel_dig.ogg', 50, TRUE)
if(!do_after(user, 5 SECONDS, src))
- return NONE
+ return FALSE
balloon_alert(user, "dug hole")
AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/ice_fishing])
ADD_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT)
@@ -58,7 +66,7 @@
can_make_hole = FALSE
RemoveElement(/datum/element/contextual_screentip_tools, tool_screentips)
flags_1 &= ~HAS_CONTEXTUAL_SCREENTIPS_1
- return ITEM_INTERACT_SUCCESS
+ return TRUE
/turf/open/misc/ice/smooth
icon_state = "ice_turf-255"
diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm
index 1a9f24ce50ebd..fa0b0c4b12872 100644
--- a/code/game/turfs/open/lava.dm
+++ b/code/game/turfs/open/lava.dm
@@ -175,7 +175,7 @@
/turf/open/lava/singularity_act()
return
-/turf/open/lava/singularity_pull(S, current_size)
+/turf/open/lava/singularity_pull(atom/singularity, current_size)
return
/turf/open/lava/GetHeatCapacity()
diff --git a/code/modules/admin/sound_emitter.dm b/code/modules/admin/sound_emitter.dm
index c68baa32e4ea1..9f1d430a46c03 100644
--- a/code/modules/admin/sound_emitter.dm
+++ b/code/modules/admin/sound_emitter.dm
@@ -30,7 +30,7 @@
/obj/effect/sound_emitter/singularity_act()
return
-/obj/effect/sound_emitter/singularity_pull()
+/obj/effect/sound_emitter/singularity_pull(atom/singularity, current_size)
return
/obj/effect/sound_emitter/examine(mob/user)
diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm
index 1305e5a660d6e..4da97d2c447bf 100644
--- a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm
+++ b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm
@@ -117,6 +117,9 @@
/proc/_text2num(T)
return text2num(T)
+/proc/_trimtext(Text)
+ return trimtext(Text)
+
/proc/_ohearers(Dist, Center = usr)
return ohearers(Dist, Center)
diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm
index f490095a019d9..78d5a988f0849 100644
--- a/code/modules/antagonists/_common/antag_datum.dm
+++ b/code/modules/antagonists/_common/antag_datum.dm
@@ -468,7 +468,7 @@ GLOBAL_LIST_EMPTY(antagonists)
/// result of `get_preview_icon` is expected to be the completed version.
/datum/antagonist/proc/render_preview_outfit(datum/outfit/outfit, mob/living/carbon/human/dummy)
dummy = dummy || new /mob/living/carbon/human/dummy/consistent
- dummy.equipOutfit(outfit, visualsOnly = TRUE)
+ dummy.equipOutfit(outfit, visuals_only = TRUE)
dummy.wear_suit?.update_greyscale()
var/icon = getFlatIcon(dummy)
diff --git a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm
index 8739a9de74950..e598742f1b167 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm
@@ -24,9 +24,9 @@
for(var/obj/item/abductor/gizmo/G in B.contents)
console.AddGizmo(G)
-/datum/outfit/abductor/post_equip(mob/living/carbon/human/user, visualsOnly = FALSE)
+/datum/outfit/abductor/post_equip(mob/living/carbon/human/user, visuals_only = FALSE)
. = ..()
- if(visualsOnly)
+ if(visuals_only)
return
if(!isnull(user.mind))
@@ -64,9 +64,9 @@
/obj/item/abductor/gizmo = 1
)
-/datum/outfit/abductor/scientist/post_equip(mob/living/carbon/human/user, visualsOnly = FALSE)
+/datum/outfit/abductor/scientist/post_equip(mob/living/carbon/human/user, visuals_only = FALSE)
. = ..()
- if(!visualsOnly && !isnull(user.mind))
+ if(!visuals_only && !isnull(user.mind))
var/obj/item/implant/abductor/beamplant = new /obj/item/implant/abductor(user)
beamplant.implant(user)
diff --git a/code/modules/antagonists/clown_ops/clownop.dm b/code/modules/antagonists/clown_ops/clownop.dm
index 9866ee30ccf13..8dbcb3c232d96 100644
--- a/code/modules/antagonists/clown_ops/clownop.dm
+++ b/code/modules/antagonists/clown_ops/clownop.dm
@@ -76,7 +76,7 @@
back = /obj/item/mod/control/pre_equipped/empty/syndicate/honkerative
uniform = /obj/item/clothing/under/syndicate
-/datum/outfit/clown_operative/post_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/clown_operative/post_equip(mob/living/carbon/human/H, visuals_only)
var/obj/item/mod/module/armor_booster/booster = locate() in H.back
booster.active = TRUE
H.update_worn_back()
@@ -87,7 +87,7 @@
back = /obj/item/mod/control/pre_equipped/empty/syndicate/honkerative
uniform = /obj/item/clothing/under/syndicate
-/datum/outfit/clown_operative_elite/post_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/clown_operative_elite/post_equip(mob/living/carbon/human/H, visuals_only)
var/obj/item/mod/module/armor_booster/booster = locate() in H.back
booster.active = TRUE
H.update_worn_back()
diff --git a/code/modules/antagonists/cult/cult_other.dm b/code/modules/antagonists/cult/cult_other.dm
index f9e1462a30efe..bbeec10ce17c0 100644
--- a/code/modules/antagonists/cult/cult_other.dm
+++ b/code/modules/antagonists/cult/cult_other.dm
@@ -7,7 +7,7 @@
shoes = /obj/item/clothing/shoes/cult/alt
r_hand = /obj/item/melee/blood_magic/stun
-/datum/outfit/cultist/post_equip(mob/living/carbon/human/equipped, visualsOnly)
+/datum/outfit/cultist/post_equip(mob/living/carbon/human/equipped, visuals_only)
equipped.eye_color_left = BLOODCULT_EYE
equipped.eye_color_right = BLOODCULT_EYE
equipped.update_body()
diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm
index 5aae2a6ccbc22..d2269c19dff0a 100644
--- a/code/modules/antagonists/cult/cult_structures.dm
+++ b/code/modules/antagonists/cult/cult_structures.dm
@@ -215,5 +215,5 @@
/obj/effect/gateway/singularity_act()
return
-/obj/effect/gateway/singularity_pull()
+/obj/effect/gateway/singularity_pull(atom/singularity, current_size)
return
diff --git a/code/modules/antagonists/cult/cult_turf_overlay.dm b/code/modules/antagonists/cult/cult_turf_overlay.dm
index e2324b5f933e0..df92d7aec90f0 100644
--- a/code/modules/antagonists/cult/cult_turf_overlay.dm
+++ b/code/modules/antagonists/cult/cult_turf_overlay.dm
@@ -15,7 +15,7 @@
/obj/effect/cult_turf/singularity_act()
return
-/obj/effect/cult_turf/singularity_pull()
+/obj/effect/cult_turf/singularity_pull(atom/singularity, current_size)
return
/obj/effect/cult_turf/Destroy()
diff --git a/code/modules/antagonists/fugitive/fugitive_outfits.dm b/code/modules/antagonists/fugitive/fugitive_outfits.dm
index e1530ba16eddd..bbd1fc9ee03a5 100644
--- a/code/modules/antagonists/fugitive/fugitive_outfits.dm
+++ b/code/modules/antagonists/fugitive/fugitive_outfits.dm
@@ -4,12 +4,12 @@
shoes = /obj/item/clothing/shoes/sneakers/orange
r_pocket = /obj/item/knife/shiv
-/datum/outfit/prisoner/post_equip(mob/living/carbon/human/prisoner, visualsOnly=FALSE)
+/datum/outfit/prisoner/post_equip(mob/living/carbon/human/prisoner, visuals_only=FALSE)
// This outfit is used by the assets SS, which is ran before the atoms SS
if(SSatoms.initialized == INITIALIZATION_INSSATOMS)
prisoner.w_uniform?.update_greyscale()
prisoner.update_worn_undersuit()
- if(visualsOnly)
+ if(visuals_only)
return
prisoner.fully_replace_character_name(null,"NTP #CC-0[rand(111,999)]") //same as the lavaland prisoner transport, but this time they are from CC, or CentCom
@@ -30,10 +30,10 @@
ears = /obj/item/radio/headset
glasses = /obj/item/clothing/glasses/regular/circle
-/datum/outfit/waldo/post_equip(mob/living/carbon/human/equipped_on, visualsOnly=FALSE)
+/datum/outfit/waldo/post_equip(mob/living/carbon/human/equipped_on, visuals_only=FALSE)
equipped_on.w_uniform?.update_greyscale()
equipped_on.update_worn_undersuit()
- if(visualsOnly)
+ if(visuals_only)
return
equipped_on.fully_replace_character_name(null, "Waldo")
equipped_on.eye_color_left = COLOR_BLACK
@@ -63,8 +63,8 @@
uniform = /obj/item/clothing/under/color/white
ears = /obj/item/radio/headset
-/datum/outfit/synthetic/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/synthetic/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/organ/internal/eyes/robotic/glow/eyes = new()
eyes.Insert(H, movement_flags = DELETE_IF_REPLACED)
@@ -82,7 +82,7 @@
/obj/item/reagent_containers/hypospray/medipen/invisibility = 3,
)
-/datum/outfit/invisible_man/post_equip(mob/living/carbon/human/equipee, visualsOnly)
+/datum/outfit/invisible_man/post_equip(mob/living/carbon/human/equipee, visuals_only)
. = ..()
var/obj/item/implant/camouflage/invisibility_implant = new(equipee)
diff --git a/code/modules/antagonists/fugitive/hunters/hunter_gear.dm b/code/modules/antagonists/fugitive/hunters/hunter_gear.dm
index 8e2b62c8187a4..523db5a321410 100644
--- a/code/modules/antagonists/fugitive/hunters/hunter_gear.dm
+++ b/code/modules/antagonists/fugitive/hunters/hunter_gear.dm
@@ -134,6 +134,7 @@
icon_state = "bouncy_castle"
anchored = TRUE
density = TRUE
+ layer = OBJ_LAYER
/obj/structure/bouncy_castle/Initialize(mapload, mob/gored)
. = ..()
diff --git a/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm b/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm
index 20eccc6977900..422c576ed9e31 100644
--- a/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm
+++ b/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm
@@ -14,8 +14,8 @@
id = /obj/item/card/id/advanced/bountyhunter
id_trim = /datum/id_trim/bounty_hunter/police
-/datum/outfit/spacepol/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/spacepol/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/W = H.wear_id
W.registered_name = H.real_name
@@ -72,8 +72,8 @@
if(prob(50))
head = pick(alt_helmets)
-/datum/outfit/russian_hunter/post_equip(mob/living/carbon/human/equip_to, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/russian_hunter/post_equip(mob/living/carbon/human/equip_to, visuals_only = FALSE)
+ if(visuals_only)
return
if(istype(equip_to.wear_id, /obj/item/card/id))
@@ -118,8 +118,8 @@
/obj/item/ammo_casing/shotgun/incendiary/no_trail = 4,
)
-/datum/outfit/bountyarmor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/bountyarmor/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/W = H.wear_id
W.registered_name = H.real_name
@@ -143,8 +143,8 @@
/obj/item/ammo_casing/shotgun/incapacitate = 6
)
-/datum/outfit/bountyhook/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/bountyhook/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/W = H.wear_id
W.registered_name = H.real_name
@@ -231,7 +231,7 @@
box = /obj/item/storage/box/survival/syndie
implants = list(/obj/item/implant/explosive)
-/datum/outfit/mi13_hunter/pre_equip(mob/living/carbon/human/agent, visualsOnly = FALSE)
+/datum/outfit/mi13_hunter/pre_equip(mob/living/carbon/human/agent, visuals_only = FALSE)
backpack_contents = list()
backpack_contents += pick_weight(list(/obj/item/ammo_box/magazine/m9mm = 80,
/obj/item/ammo_box/magazine/m9mm/hp = 10,
@@ -253,8 +253,8 @@
/obj/item/gun/ballistic/automatic/pistol/clandestine/fisher = 10,
))
-/datum/outfit/mi13_hunter/post_equip(mob/living/carbon/human/agent, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/mi13_hunter/post_equip(mob/living/carbon/human/agent, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/wearing = agent.wear_id
wearing.registered_name = agent.real_name
diff --git a/code/modules/antagonists/nightmare/nightmare.dm b/code/modules/antagonists/nightmare/nightmare.dm
index 10dfd662dab7e..f5e795fa3d60b 100644
--- a/code/modules/antagonists/nightmare/nightmare.dm
+++ b/code/modules/antagonists/nightmare/nightmare.dm
@@ -20,7 +20,7 @@
/datum/outfit/nightmare
name = "Nightmare (Preview only)"
-/datum/outfit/nightmare/post_equip(mob/living/carbon/human/human, visualsOnly)
+/datum/outfit/nightmare/post_equip(mob/living/carbon/human/human, visuals_only)
human.set_species(/datum/species/shadow/nightmare)
/datum/objective/nightmare_fluff
diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm
index 3214232648b2a..7445b20cb902a 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm
@@ -74,10 +74,31 @@ GLOBAL_VAR(station_nuke_source)
/obj/machinery/nuclearbomb/examine(mob/user)
. = ..()
- if(exploding)
- . += span_bolddanger("It is in the process of exploding. Perhaps reviewing your affairs is in order.")
- if(timing)
- . += span_danger("There are [get_time_left()] seconds until detonation.")
+ switch(deconstruction_state)
+ if(NUKESTATE_UNSCREWED)
+ . += span_notice("The front panel has been unscrewed and can be pried open.")
+ if(NUKESTATE_PANEL_REMOVED)
+ . += span_notice("The inner plate is exposed and can be cut with a welding tool.")
+ if(NUKESTATE_WELDED)
+ . += span_notice("The inner plate has been cut through and can be pried off.")
+ if(NUKESTATE_CORE_EXPOSED)
+ . += span_danger("The inner chamber is exposed, revealing [core] to the outside!")
+ . += span_notice("The damaged inner plate covering the inner chamber can be replaced with some iron.")
+ if(NUKESTATE_CORE_REMOVED)
+ . += span_notice("The inner chamber is exposed, but is empty.")
+ if(NUKESTATE_INTACT)
+ . += span_notice("The front panel is secured.")
+
+ switch(get_nuke_state())
+ if(NUKE_OFF_LOCKED)
+ . += span_notice("The device is awaiting activation codes.")
+ if(NUKE_OFF_UNLOCKED)
+ . += span_notice("The device is set and is ready for arming the detonation countdown.")
+ if(NUKE_ON_TIMING)
+ . += span_danger("There are [get_time_left()] seconds until detonation.")
+ if(NUKE_ON_EXPLODING)
+ . += span_bolddanger("It is in the process of exploding. Perhaps reviewing your affairs is in order.")
+
/// Checks if the disk inserted is a real nuke disk or not.
/obj/machinery/nuclearbomb/proc/disk_check(obj/item/disk/nuclear/inserted_disk)
@@ -225,12 +246,11 @@ GLOBAL_VAR(station_nuke_source)
if(NUKESTATE_CORE_REMOVED)
interior = "core-removed"
if(NUKESTATE_INTACT)
- return
+ interior = null
switch(get_nuke_state())
if(NUKE_OFF_LOCKED)
- lights = ""
- return
+ lights = null
if(NUKE_OFF_UNLOCKED)
lights = "lights-safety"
if(NUKE_ON_TIMING)
@@ -425,11 +445,12 @@ GLOBAL_VAR(station_nuke_source)
// We're safe now, so stop any ongoing timers
if(safety)
if(timing)
+ timing = FALSE
disarm_nuke()
- timing = FALSE
detonation_timer = null
countdown.stop()
+ update_appearance(UPDATE_OVERLAYS) //only the lights overlay are affected by safety
/// Arms the nuke, or disarms it if it's already active.
/obj/machinery/nuclearbomb/proc/toggle_nuke_armed()
diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm
index bd6dbfacf457a..32fe7dfd5c0a6 100644
--- a/code/modules/antagonists/nukeop/outfits.dm
+++ b/code/modules/antagonists/nukeop/outfits.dm
@@ -40,8 +40,8 @@
uniform = /obj/item/clothing/under/plasmaman/syndicate
r_hand = /obj/item/tank/internals/plasmaman/belt/full
-/datum/outfit/syndicate/post_equip(mob/living/carbon/human/nukie, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/syndicate/post_equip(mob/living/carbon/human/nukie, visuals_only = FALSE)
+ if(visuals_only)
return
// We don't require the nukiebase be loaded to function, but lets go ahead and kick off loading just in case
@@ -107,9 +107,9 @@
)
var/faction = "The Syndicate"
-/datum/outfit/syndicate/reinforcement/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/syndicate/reinforcement/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
. = ..()
- if(visualsOnly)
+ if(visuals_only)
return
to_chat(H, span_notice("You're an agent of [faction], sent to accompany the nuclear squad on their mission. \
Support your allies, and remember: Down with Nanotrasen."))
@@ -186,7 +186,7 @@
back = /obj/item/mod/control/pre_equipped/empty/syndicate
uniform = /obj/item/clothing/under/syndicate
-/datum/outfit/nuclear_operative/post_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/nuclear_operative/post_equip(mob/living/carbon/human/H, visuals_only)
var/obj/item/mod/module/armor_booster/booster = locate() in H.back
booster.active = TRUE
H.update_worn_back()
@@ -199,7 +199,7 @@
l_hand = /obj/item/modular_computer/pda/nukeops
r_hand = /obj/item/shield/energy
-/datum/outfit/nuclear_operative_elite/post_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/nuclear_operative_elite/post_equip(mob/living/carbon/human/H, visuals_only)
var/obj/item/mod/module/armor_booster/booster = locate() in H.back
booster.active = TRUE
H.update_worn_back()
diff --git a/code/modules/antagonists/traitor/contractor/contract_teammate.dm b/code/modules/antagonists/traitor/contractor/contract_teammate.dm
index 965d99e89ac6a..484d8196ddfff 100644
--- a/code/modules/antagonists/traitor/contractor/contract_teammate.dm
+++ b/code/modules/antagonists/traitor/contractor/contract_teammate.dm
@@ -39,7 +39,7 @@
/obj/item/lighter,
)
-/datum/outfit/contractor_partner/post_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/contractor_partner/post_equip(mob/living/carbon/human/H, visuals_only)
. = ..()
var/obj/item/cigarette/syndicate/cig = H.get_item_by_slot(ITEM_SLOT_MASK)
cig.light()
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index f739245314fc2..57ca4540612e4 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -408,7 +408,7 @@
r_hand = /obj/item/gun/energy/recharge/ebow
shoes = /obj/item/clothing/shoes/magboots/advance
-/datum/outfit/traitor/post_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/traitor/post_equip(mob/living/carbon/human/H, visuals_only)
var/obj/item/melee/energy/sword/sword = locate() in H.held_items
if(sword.flags_1 & INITIALIZED_1)
sword.attack_self()
diff --git a/code/modules/antagonists/voidwalker/voidwalker.dm b/code/modules/antagonists/voidwalker/voidwalker.dm
index 6222dc0c35fbe..3d9b0012555dc 100644
--- a/code/modules/antagonists/voidwalker/voidwalker.dm
+++ b/code/modules/antagonists/voidwalker/voidwalker.dm
@@ -39,7 +39,7 @@
/datum/outfit/voidwalker
name = "Voidwalker (Preview only)"
-/datum/outfit/voidwalker/post_equip(mob/living/carbon/human/human, visualsOnly)
+/datum/outfit/voidwalker/post_equip(mob/living/carbon/human/human, visuals_only)
human.set_species(/datum/species/voidwalker)
/datum/objective/voidwalker_objective
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 446825779e299..ef2a40636d0fc 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -73,7 +73,7 @@
/obj/effect/rend/singularity_act()
return
-/obj/effect/rend/singularity_pull()
+/obj/effect/rend/singularity_pull(atom/singularity, current_size)
return
/obj/item/veilrender/vealrender
@@ -306,7 +306,7 @@
r_hand = /obj/item/claymore
l_hand = /obj/item/shield/roman
-/datum/outfit/roman/pre_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/roman/pre_equip(mob/living/carbon/human/H, visuals_only)
. = ..()
head = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionnaire)
diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm
index 00bb94d6bc31f..47a2af4651cbc 100644
--- a/code/modules/atmospherics/environmental/LINDA_fire.dm
+++ b/code/modules/atmospherics/environmental/LINDA_fire.dm
@@ -302,7 +302,7 @@
var/mob/living/immolated = arrived
immolated.fire_act(temperature, volume)
-/obj/effect/hotspot/singularity_pull()
+/obj/effect/hotspot/singularity_pull(atom/singularity, current_size)
return
#undef INSUFFICIENT
diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm
index 186ef8ea9aace..9d46a73e16c27 100644
--- a/code/modules/atmospherics/machinery/atmosmachinery.dm
+++ b/code/modules/atmospherics/machinery/atmosmachinery.dm
@@ -560,7 +560,7 @@
L.ventcrawl_layer = piping_layer
return ..()
-/obj/machinery/atmospherics/singularity_pull(S, current_size)
+/obj/machinery/atmospherics/singularity_pull(atom/singularity, current_size)
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
return ..()
diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm
index 97bff1ddaeacb..cee96ae0ee772 100644
--- a/code/modules/atmospherics/machinery/other/meter.dm
+++ b/code/modules/atmospherics/machinery/other/meter.dm
@@ -152,7 +152,7 @@
else
to_chat(user, status())
-/obj/machinery/meter/singularity_pull(S, current_size)
+/obj/machinery/meter/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct()
diff --git a/code/modules/basketball/basketball_teams.dm b/code/modules/basketball/basketball_teams.dm
index 4f5d2b22f1839..9169fa4fcc43f 100644
--- a/code/modules/basketball/basketball_teams.dm
+++ b/code/modules/basketball/basketball_teams.dm
@@ -16,8 +16,8 @@
//Chance for the wearer to have their height increased. This is repeated three times for maximum height.
var/taller_chance = 50
-/datum/outfit/basketball/post_equip(mob/living/carbon/human/human_to_equip, visualsOnly=FALSE)
- if(visualsOnly)
+/datum/outfit/basketball/post_equip(mob/living/carbon/human/human_to_equip, visuals_only=FALSE)
+ if(visuals_only)
return
var/list/no_drops = list()
@@ -98,7 +98,7 @@
head = /obj/item/clothing/head/costume/xenos
mask = /obj/item/clothing/mask/chameleon
-/datum/outfit/basketball/lusty_xenomorphs/post_equip(mob/living/carbon/human/human_to_equip, visualsOnly=FALSE)
+/datum/outfit/basketball/lusty_xenomorphs/post_equip(mob/living/carbon/human/human_to_equip, visuals_only=FALSE)
. = ..()
var/obj/item/card/id/idcard = human_to_equip.wear_id
diff --git a/code/modules/bitrunning/antagonists/cyber_police.dm b/code/modules/bitrunning/antagonists/cyber_police.dm
index bb137607ec423..2ec8e042572bf 100644
--- a/code/modules/bitrunning/antagonists/cyber_police.dm
+++ b/code/modules/bitrunning/antagonists/cyber_police.dm
@@ -23,15 +23,15 @@
shoes = /obj/item/clothing/shoes/laceup
uniform = /obj/item/clothing/under/suit/black_really
-/datum/outfit/cyber_police/pre_equip(mob/living/carbon/human/user, visualsOnly)
- if(!visualsOnly)
+/datum/outfit/cyber_police/pre_equip(mob/living/carbon/human/user, visuals_only)
+ if(!visuals_only)
return
user.set_facial_hairstyle("Shaved", update = FALSE)
user.set_haircolor("#4B3D28", update = FALSE)
user.set_hairstyle("Business Hair")
-/datum/outfit/cyber_police/post_equip(mob/living/carbon/human/user, visualsOnly)
+/datum/outfit/cyber_police/post_equip(mob/living/carbon/human/user, visuals_only)
var/obj/item/clothing/under/officer_uniform = user.w_uniform
if(officer_uniform)
officer_uniform.has_sensor = NO_SENSORS
diff --git a/code/modules/bitrunning/antagonists/cyber_tac.dm b/code/modules/bitrunning/antagonists/cyber_tac.dm
index a45fdb345d304..e9a36a65ee59f 100644
--- a/code/modules/bitrunning/antagonists/cyber_tac.dm
+++ b/code/modules/bitrunning/antagonists/cyber_tac.dm
@@ -24,7 +24,7 @@
/obj/item/ammo_box/magazine/m223,
)
-/datum/outfit/cyber_police/tactical/post_equip(mob/living/carbon/human/user, visualsOnly)
+/datum/outfit/cyber_police/tactical/post_equip(mob/living/carbon/human/user, visuals_only)
. = ..()
var/obj/item/implant/weapons_auth/auth = new(user)
diff --git a/code/modules/bitrunning/outfits.dm b/code/modules/bitrunning/outfits.dm
index c0bb01ebc06e5..afad097773cc0 100644
--- a/code/modules/bitrunning/outfits.dm
+++ b/code/modules/bitrunning/outfits.dm
@@ -11,7 +11,7 @@
id = /obj/item/card/id/advanced
-/datum/outfit/echolocator/post_equip(mob/living/carbon/human/user, visualsOnly)
+/datum/outfit/echolocator/post_equip(mob/living/carbon/human/user, visuals_only)
. = ..()
user.psykerize()
@@ -51,7 +51,7 @@
)
-/datum/outfit/beachbum_combat/post_equip(mob/living/carbon/human/bum, visualsOnly)
+/datum/outfit/beachbum_combat/post_equip(mob/living/carbon/human/bum, visuals_only)
. = ..()
var/choice = rand(1, length(ranged_weaps))
diff --git a/code/modules/bitrunning/server/obj_generation.dm b/code/modules/bitrunning/server/obj_generation.dm
index baf427855a236..ae15ddbd623e7 100644
--- a/code/modules/bitrunning/server/obj_generation.dm
+++ b/code/modules/bitrunning/server/obj_generation.dm
@@ -53,7 +53,7 @@
to_wear.suit = null
to_wear.suit_store = null
- avatar.equipOutfit(to_wear, visualsOnly = TRUE)
+ avatar.equipOutfit(to_wear, visuals_only = TRUE)
var/obj/item/clothing/under/jumpsuit = avatar.w_uniform
if(istype(jumpsuit))
diff --git a/code/modules/bitrunning/spawners.dm b/code/modules/bitrunning/spawners.dm
index 26288d54a1555..07e97837f522d 100644
--- a/code/modules/bitrunning/spawners.dm
+++ b/code/modules/bitrunning/spawners.dm
@@ -70,5 +70,5 @@
implants = list(/obj/item/implant/weapons_auth)
-/datum/outfit/virtual_syndicate/post_equip(mob/living/carbon/human/user, visualsOnly)
+/datum/outfit/virtual_syndicate/post_equip(mob/living/carbon/human/user, visuals_only)
user.faction |= ROLE_SYNDICATE
diff --git a/code/modules/capture_the_flag/ctf_classes.dm b/code/modules/capture_the_flag/ctf_classes.dm
index 8f6a03ba7dfc4..2b9f022d80145 100644
--- a/code/modules/capture_the_flag/ctf_classes.dm
+++ b/code/modules/capture_the_flag/ctf_classes.dm
@@ -28,8 +28,8 @@
///Which slots to apply TRAIT_NODROP to the items in
var/list/nodrop_slots = list(ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_EARS)
-/datum/outfit/ctf/post_equip(mob/living/carbon/human/human_to_equip, visualsOnly=FALSE)
- if(visualsOnly)
+/datum/outfit/ctf/post_equip(mob/living/carbon/human/human_to_equip, visuals_only=FALSE)
+ if(visuals_only)
return
var/list/no_drops = list()
diff --git a/code/modules/client/preferences/middleware/species.dm b/code/modules/client/preferences/middleware/species.dm
index 80c78d2564063..9f1e4cf6c155f 100644
--- a/code/modules/client/preferences/middleware/species.dm
+++ b/code/modules/client/preferences/middleware/species.dm
@@ -18,7 +18,7 @@
var/mob/living/carbon/human/dummy/consistent/dummy = new
dummy.set_species(species_type)
- dummy.equipOutfit(/datum/outfit/job/assistant/consistent, visualsOnly = TRUE)
+ dummy.equipOutfit(/datum/outfit/job/assistant/consistent, visuals_only = TRUE)
dummy.dna.species.prepare_human_for_preview(dummy)
var/icon/dummy_icon = getFlatIcon(dummy)
diff --git a/code/modules/clothing/chameleon/_chameleon_action.dm b/code/modules/clothing/chameleon/_chameleon_action.dm
index b9a1697976bd8..fbbe480e59a02 100644
--- a/code/modules/clothing/chameleon/_chameleon_action.dm
+++ b/code/modules/clothing/chameleon/_chameleon_action.dm
@@ -156,6 +156,7 @@
)
item_target.flags_inv = initial(picked_item.flags_inv)
+ item_target.hair_mask = initial(picked_item.hair_mask)
item_target.transparent_protection = initial(picked_item.transparent_protection)
if(isclothing(item_target) && ispath(picked_item, /obj/item/clothing))
var/obj/item/clothing/clothing_target = item_target
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index 6cd88c1746c7f..56a8661a4127a 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -9,6 +9,7 @@
inhand_icon_state = null
armor_type = /datum/armor/utility_hardhat
flags_inv = 0
+ hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_MEDIUM
actions_types = list(/datum/action/item_action/toggle_helmet_light)
clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT
resistance_flags = FIRE_PROOF
@@ -211,6 +212,7 @@
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
visor_flags_cover = NONE
flags_inv = HIDEEARS|HIDEHAIR|HIDEFACE|HIDEFACIALHAIR|HIDESNOUT
+ hair_mask = ""
transparent_protection = HIDEMASK|HIDEEYES
visor_flags_inv = NONE
visor_state = "weldvisor_atmos"
@@ -230,6 +232,8 @@
hat_type = "pumpkin"
clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
+ hair_mask = ""
+
armor_type = /datum/armor/none
light_range = 2 //luminosity when on
flags_cover = HEADCOVERSEYES
@@ -296,6 +300,7 @@
inhand_icon_state = null
hat_type = "reindeer"
flags_inv = 0
+ hair_mask = ""
armor_type = /datum/armor/none
light_range = 1 //luminosity when on
clothing_traits = list()
diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm
index b14573a087cf1..62893c78344df 100644
--- a/code/modules/clothing/outfits/ert.dm
+++ b/code/modules/clothing/outfits/ert.dm
@@ -1,8 +1,8 @@
/datum/outfit/centcom
name = "CentCom Base"
-/datum/outfit/centcom/post_equip(mob/living/carbon/human/centcom_member, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/centcom/post_equip(mob/living/carbon/human/centcom_member, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/implant/mindshield/mindshield = new /obj/item/implant/mindshield(centcom_member)//hmm lets have centcom officials become revs
mindshield.implant(centcom_member, null, silent = TRUE)
@@ -17,8 +17,8 @@
shoes = /obj/item/clothing/shoes/combat/swat
var/additional_radio
-/datum/outfit/centcom/ert/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/centcom/ert/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/radio/headset/R = H.ears
@@ -168,8 +168,8 @@
r_pocket = /obj/item/modular_computer/pda/heads
l_hand = /obj/item/clipboard
-/datum/outfit/centcom/centcom_official/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/centcom/centcom_official/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/modular_computer/pda/heads/pda = H.r_store
@@ -282,9 +282,9 @@
r_pocket = /obj/item/bikehorn/golden
additional_radio = /obj/item/encryptionkey/heads/hop
-/datum/outfit/centcom/ert/clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/centcom/ert/clown/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
..()
- if(visualsOnly)
+ if(visuals_only)
return
ADD_TRAIT(H.mind, TRAIT_NAIVE, INNATE_TRAIT)
H.dna.add_mutation(/datum/mutation/human/clumsy)
@@ -308,8 +308,8 @@
r_pocket = /obj/item/ammo_box/strilka310
l_hand = /obj/item/gun/ballistic/rifle/boltaction
-/datum/outfit/centcom/centcom_intern/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/centcom/centcom_intern/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/W = H.wear_id
@@ -454,8 +454,8 @@
/obj/item/skillchip/disk_verifier,
)
-/datum/outfit/centcom/death_commando/post_equip(mob/living/carbon/human/squaddie, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/centcom/death_commando/post_equip(mob/living/carbon/human/squaddie, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/radio/radio = squaddie.ears
@@ -472,7 +472,7 @@
back = /obj/item/mod/control/pre_equipped/apocryphal/officer
-/datum/outfit/centcom/death_commando/officer/post_equip(mob/living/carbon/human/squaddie, visualsOnly = FALSE)
+/datum/outfit/centcom/death_commando/officer/post_equip(mob/living/carbon/human/squaddie, visuals_only = FALSE)
. = ..()
var/obj/item/mod/control/mod = squaddie.back
if(!istype(mod))
diff --git a/code/modules/clothing/outfits/event.dm b/code/modules/clothing/outfits/event.dm
index b99ea6f526202..25b7f5665b594 100644
--- a/code/modules/clothing/outfits/event.dm
+++ b/code/modules/clothing/outfits/event.dm
@@ -14,8 +14,8 @@
box = /obj/item/storage/box/survival/engineer
-/datum/outfit/santa/post_equip(mob/living/carbon/human/user, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/santa/post_equip(mob/living/carbon/human/user, visuals_only = FALSE)
+ if(visuals_only)
return
user.fully_replace_character_name(user.real_name, "Santa Claus")
user.mind.set_assigned_role(SSjob.get_job_type(/datum/job/santa))
diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm
index 46bdd0742bb5b..3f10afb3158e3 100644
--- a/code/modules/clothing/outfits/standard.dm
+++ b/code/modules/clothing/outfits/standard.dm
@@ -15,8 +15,8 @@
shoes = /obj/item/clothing/shoes/combat/swat
r_pocket = /obj/item/lighter
-/datum/outfit/centcom/spec_ops/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/centcom/spec_ops/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/W = H.wear_id
@@ -81,8 +81,8 @@
r_hand = /obj/item/mop
l_hand = /obj/item/reagent_containers/cup/bucket
-/datum/outfit/tournament/janitor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/tournament/janitor/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/reagent_containers/cup/bucket/bucket = H.get_item_for_held_index(1)
@@ -160,8 +160,8 @@
r_pocket = /obj/item/bikehorn
l_hand = /obj/item/fireaxe
-/datum/outfit/tunnel_clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/tunnel_clown/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/W = H.wear_id
@@ -206,11 +206,11 @@
l_pocket = /obj/item/melee/energy/sword/saber
l_hand = /obj/item/storage/briefcase/secure
-/datum/outfit/assassin/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/assassin/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
var/obj/item/clothing/under/U = H.w_uniform
U.attach_accessory(new /obj/item/clothing/accessory/waistcoat(H))
- if(visualsOnly)
+ if(visuals_only)
return
//Could use a type
@@ -250,8 +250,8 @@
l_pocket = /obj/item/ammo_box/a357
r_pocket = /obj/item/lighter
-/datum/outfit/centcom/commander/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/centcom/commander/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/W = H.wear_id
@@ -303,8 +303,8 @@
r_pocket = /obj/item/teleportation_scroll
l_hand = /obj/item/staff
-/datum/outfit/wizard/post_equip(mob/living/carbon/human/wizard, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/wizard/post_equip(mob/living/carbon/human/wizard, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/spellbook/new_spellbook = locate() in wizard.back
@@ -315,7 +315,7 @@
name = "Wizard - Bookless"
backpack_contents = list()
-/datum/outfit/wizard/bookless/post_equip(mob/living/carbon/human/wizard, visualsOnly)
+/datum/outfit/wizard/bookless/post_equip(mob/living/carbon/human/wizard, visuals_only)
return
/datum/outfit/wizard/apprentice
@@ -362,8 +362,8 @@
head = /obj/item/clothing/head/costume/pirate/captain
shoes = /obj/item/clothing/shoes/combat
-/datum/outfit/centcom/soviet/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/centcom/soviet/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/W = H.wear_id
@@ -387,8 +387,8 @@
shoes = /obj/item/clothing/shoes/laceup
l_hand = /obj/item/gun/ballistic/automatic/tommygun
-/datum/outfit/mobster/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/mobster/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return
var/obj/item/card/id/W = H.wear_id
@@ -404,7 +404,7 @@
mask = /obj/item/clothing/mask/breath
back = /obj/item/mod/control/pre_equipped/chrono
-/datum/outfit/chrono_agent/post_equip(mob/living/carbon/human/agent, visualsOnly)
+/datum/outfit/chrono_agent/post_equip(mob/living/carbon/human/agent, visuals_only)
. = ..()
var/obj/item/mod/control/mod = agent.back
if(!istype(mod))
@@ -437,7 +437,7 @@
box = /obj/item/storage/box/debugtools
internals_slot = ITEM_SLOT_SUITSTORE
-/datum/outfit/debug/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/debug/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
var/obj/item/card/id/W = H.wear_id
W.registered_name = H.real_name
W.update_label()
@@ -469,7 +469,7 @@
box = /obj/item/storage/box/debugtools
internals_slot = ITEM_SLOT_SUITSTORE
-/datum/outfit/admin/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/admin/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
var/obj/item/card/id/W = H.wear_id
W.registered_name = H.real_name
W.update_label()
diff --git a/code/modules/clothing/outfits/vv_outfit.dm b/code/modules/clothing/outfits/vv_outfit.dm
index 6277b5c1dd8c0..eba12d3976b75 100644
--- a/code/modules/clothing/outfits/vv_outfit.dm
+++ b/code/modules/clothing/outfits/vv_outfit.dm
@@ -6,7 +6,7 @@
var/list/stored_access
var/update_id_name = FALSE //If the name of the human is same as the name on the id they're wearing we'll update provided id when equipping
-/datum/outfit/varedit/pre_equip(mob/living/carbon/human/equipping_mob, visualsOnly)
+/datum/outfit/varedit/pre_equip(mob/living/carbon/human/equipping_mob, visuals_only)
equipping_mob.delete_equipment() //Applying VV to wrong objects is not reccomended.
return ..()
@@ -139,7 +139,7 @@
GLOB.custom_outfits += outfit
to_chat(usr,"Outfit registered, use select equipment to equip it.")
-/datum/outfit/varedit/post_equip(mob/living/carbon/human/human, visualsOnly)
+/datum/outfit/varedit/post_equip(mob/living/carbon/human/human, visuals_only)
. = ..()
//Apply VV
for(var/slot in vv_values)
diff --git a/code/modules/deathmatch/deathmatch_loadouts.dm b/code/modules/deathmatch/deathmatch_loadouts.dm
index 5670995512001..b80ec573419fe 100644
--- a/code/modules/deathmatch/deathmatch_loadouts.dm
+++ b/code/modules/deathmatch/deathmatch_loadouts.dm
@@ -12,7 +12,7 @@
/// This outfit will grant these mutations if applied
var/list/mutations_to_add = list()
-/datum/outfit/deathmatch_loadout/pre_equip(mob/living/carbon/human/user, visualsOnly = FALSE)
+/datum/outfit/deathmatch_loadout/pre_equip(mob/living/carbon/human/user, visuals_only = FALSE)
. = ..()
if(isdummy(user))
return
@@ -914,13 +914,13 @@
// We don't want them to just punch each other to death
-/datum/outfit/deathmatch_loadout/lattice_battles/pre_equip(mob/living/carbon/human/user, visualsOnly)
+/datum/outfit/deathmatch_loadout/lattice_battles/pre_equip(mob/living/carbon/human/user, visuals_only)
. = ..()
ADD_TRAIT(user, TRAIT_PACIFISM, REF(src))
// Ragnarok: Fight between religions!
-/datum/outfit/deathmatch_loadout/cultish/pre_equip(mob/living/carbon/human/user, visualsOnly)
+/datum/outfit/deathmatch_loadout/cultish/pre_equip(mob/living/carbon/human/user, visuals_only)
. = ..()
ADD_TRAIT(user, TRAIT_ACT_AS_CULTIST, REF(src))
user.AddElement(/datum/element/cult_halo, initial_delay = 0 SECONDS)
@@ -990,7 +990,7 @@
/datum/action/innate/cult/blood_spell/manipulation,
)
-/datum/outfit/deathmatch_loadout/cultish/artificer/post_equip(mob/living/carbon/human/user, visualsOnly)
+/datum/outfit/deathmatch_loadout/cultish/artificer/post_equip(mob/living/carbon/human/user, visuals_only)
. = ..()
var/datum/action/innate/cult/blood_spell/manipulation/magick = locate() in user.get_all_contents()
magick.charges = 300
@@ -999,7 +999,7 @@
/// Grants the effects of these knowledges to the DMer
var/list/knowledge_to_grant
-/datum/outfit/deathmatch_loadout/heresy/pre_equip(mob/living/carbon/human/user, visualsOnly)
+/datum/outfit/deathmatch_loadout/heresy/pre_equip(mob/living/carbon/human/user, visuals_only)
. = ..()
ADD_TRAIT(user, TRAIT_ACT_AS_HERETIC, REF(src))
user.AddElement(/datum/element/leeching_walk)
diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm
index 7110e368dce68..29a64c2b98a7a 100644
--- a/code/modules/detectivework/evidence.dm
+++ b/code/modules/detectivework/evidence.dm
@@ -9,95 +9,72 @@
w_class = WEIGHT_CLASS_TINY
item_flags = NOBLUDGEON
+/obj/item/evidencebag/Initialize(mapload)
+ . = ..()
+ create_storage(
+ max_slots = 1,
+ max_specific_storage = WEIGHT_CLASS_NORMAL,
+ )
+ RegisterSignal(atom_storage, COMSIG_STORAGE_STORED_ITEM, PROC_REF(on_insert))
+ RegisterSignal(atom_storage, COMSIG_STORAGE_REMOVED_ITEM, PROC_REF(on_remove))
+
/obj/item/evidencebag/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(interacting_with == loc || !isitem(interacting_with) || HAS_TRAIT(interacting_with, TRAIT_COMBAT_MODE_SKIP_INTERACTION))
return NONE
- if(evidencebagEquip(interacting_with, user))
+ if(atom_storage.attempt_insert(interacting_with, user))
return ITEM_INTERACT_SUCCESS
return NONE
/obj/item/evidencebag/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
- if(evidencebagEquip(tool, user))
+ if(atom_storage.attempt_insert(tool, user))
return ITEM_INTERACT_SUCCESS
return NONE
-/obj/item/evidencebag/Exited(atom/movable/gone, direction)
+/obj/item/evidencebag/update_desc(updates)
. = ..()
- cut_overlays()
- update_weight_class(initial(w_class))
- icon_state = initial(icon_state)
- desc = initial(desc)
-
-/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
- if(!istype(I) || I.anchored)
- return FALSE
-
- if(loc.atom_storage && I.atom_storage)
- to_chat(user, span_warning("No matter what way you try, you can't get [I] to fit inside [src]."))
- return TRUE //begone infinite storage ghosts, begone from me
-
- if(HAS_TRAIT(I, TRAIT_NO_STORAGE_INSERT))
- to_chat(user, span_warning("No matter what way you try, you can't get [I] to fit inside [src]."))
- return TRUE
-
- if(istype(I, /obj/item/evidencebag))
- to_chat(user, span_warning("You find putting an evidence bag in another evidence bag to be slightly absurd."))
- return TRUE //now this is podracing
-
- if(loc in I.get_all_contents()) // fixes tg #39452, evidence bags could store their own location, causing I to be stored in the bag while being present inworld still, and able to be teleported when removed.
- to_chat(user, span_warning("You find putting [I] in [src] while it's still inside it quite difficult!"))
- return TRUE
-
- if(I.w_class > WEIGHT_CLASS_NORMAL)
- to_chat(user, span_warning("[I] won't fit in [src]!"))
- return TRUE
-
- if(contents.len)
- to_chat(user, span_warning("[src] already has something inside it!"))
- return TRUE
-
- if(!isturf(I.loc)) //If it isn't on the floor. Do some checks to see if it's in our hands or a box. Otherwise give up.
- if(I.loc.atom_storage) //in a container.
- I.loc.atom_storage.remove_single(user, I, src)
- if(!user.is_holding(I) || HAS_TRAIT(I, TRAIT_NODROP))
- return TRUE
-
- if(QDELETED(I))
- return TRUE
-
- user.visible_message(span_notice("[user] puts [I] into [src]."), span_notice("You put [I] inside [src]."),\
- span_hear("You hear a rustle as someone puts something into a plastic bag."))
+ if(!atom_storage.get_total_weight())
+ desc = src::desc
+ return
+ var/obj/item/inserted = locate(/obj/item) in atom_storage.real_location
+ desc = "An evidence bag containing [inserted]. [inserted.desc]"
+/obj/item/evidencebag/update_icon_state()
+ . = ..()
+ if(!atom_storage.get_total_weight())
+ icon_state = "evidenceobj"
+ return
icon_state = "evidence"
- var/mutable_appearance/in_evidence = new(I)
+/obj/item/evidencebag/update_overlays()
+ . = ..()
+ if(!atom_storage.get_total_weight())
+ return
+ var/obj/item/inserted = locate(/obj/item) in atom_storage.real_location
+ var/mutable_appearance/in_evidence = new(inserted)
in_evidence.plane = FLOAT_PLANE
in_evidence.layer = FLOAT_LAYER
in_evidence.pixel_x = 0
in_evidence.pixel_y = 0
- add_overlay(in_evidence)
- add_overlay("evidence") //should look nicer for transparent stuff. not really that important, but hey.
+ . += in_evidence
+ . += "evidence"
- desc = "An evidence bag containing [I]. [I.desc]"
- I.forceMove(src)
- update_weight_class(I.w_class)
- return TRUE
+/obj/item/evidencebag/proc/on_insert(datum/storage/storage, obj/item/to_insert, mob/user, force)
+ SIGNAL_HANDLER
+ update_weight_class(to_insert.w_class)
-/obj/item/evidencebag/attack_self(mob/user)
- if(contents.len)
- var/obj/item/I = contents[1]
- user.visible_message(span_notice("[user] takes [I] out of [src]."), span_notice("You take [I] out of [src]."),\
- span_hear("You hear someone rustle around in a plastic bag, and remove something."))
- cut_overlays() //remove the overlays
- user.put_in_hands(I)
- update_weight_class(WEIGHT_CLASS_TINY)
- icon_state = "evidenceobj"
- desc = "An empty evidence bag."
+/obj/item/evidencebag/proc/on_remove(datum/storage/storage, obj/item/to_remove, atom/remove_to_loc, silent)
+ SIGNAL_HANDLER
+ if(!atom_storage.get_total_weight())
+ return
+ update_weight_class(WEIGHT_CLASS_TINY)
- else
+/obj/item/evidencebag/attack_self(mob/user)
+ if(!atom_storage.get_total_weight())
to_chat(user, span_notice("[src] is empty."))
- icon_state = "evidenceobj"
- return
+ return
+ user.visible_message(span_notice("[user] empties [src]."), span_notice("You empty [src]."),\
+ span_hear("You hear someone rustle around in a plastic bag, and remove something."))
+ atom_storage.remove_all()
/obj/item/storage/box/evidence
name = "evidence bag box"
diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm
index 7f3b732caf4de..eed92903f3cef 100644
--- a/code/modules/detectivework/scanner.dm
+++ b/code/modules/detectivework/scanner.dm
@@ -103,9 +103,13 @@
* This should always return TRUE barring a runtime
*/
/obj/item/detective_scanner/proc/scan(mob/user, atom/scanned_atom)
- // Can remotely scan objects and mobs.
- if((get_dist(scanned_atom, user) > range) || (!(scanned_atom in view(range, user)) && view_check) || (loc != user))
+ if(loc != user)
return TRUE
+ // Can scan items we hold and store
+ if(!(scanned_atom in user.get_all_contents()))
+ // Can remotely scan objects and mobs.
+ if((get_dist(scanned_atom, user) > range) || (!(scanned_atom in view(range, user)) && view_check))
+ return TRUE
playsound(src, SFX_INDUSTRIAL_SCAN, 20, TRUE, -2, TRUE, FALSE)
scanner_busy = TRUE
diff --git a/code/modules/events/immovable_rod/immovable_rod.dm b/code/modules/events/immovable_rod/immovable_rod.dm
index e1f0ada0e600c..d73adf8ed756b 100644
--- a/code/modules/events/immovable_rod/immovable_rod.dm
+++ b/code/modules/events/immovable_rod/immovable_rod.dm
@@ -145,7 +145,7 @@
/obj/effect/immovablerod/singularity_act()
return
-/obj/effect/immovablerod/singularity_pull()
+/obj/effect/immovablerod/singularity_pull(atom/singularity, current_size)
return
/obj/effect/immovablerod/Process_Spacemove(movement_dir = 0, continuous_move = FALSE)
diff --git a/code/modules/hallucination/_hallucination.dm b/code/modules/hallucination/_hallucination.dm
index 9e23a65680290..b3f33fc3191b7 100644
--- a/code/modules/hallucination/_hallucination.dm
+++ b/code/modules/hallucination/_hallucination.dm
@@ -197,7 +197,7 @@
return
regenerate_image()
-/obj/effect/client_image_holder/singularity_pull()
+/obj/effect/client_image_holder/singularity_pull(atom/singularity, current_size)
return
/obj/effect/client_image_holder/singularity_act()
diff --git a/code/modules/hallucination/mother.dm b/code/modules/hallucination/mother.dm
index 7d407e43d8eb1..12b31b04f05c1 100644
--- a/code/modules/hallucination/mother.dm
+++ b/code/modules/hallucination/mother.dm
@@ -63,7 +63,7 @@
neck = /obj/item/clothing/neck/beads
shoes = /obj/item/clothing/shoes/sandal
-/datum/outfit/yourmother/post_equip(mob/living/carbon/human/user, visualsOnly = FALSE)
+/datum/outfit/yourmother/post_equip(mob/living/carbon/human/user, visuals_only = FALSE)
. = ..()
user.set_hairstyle("Braided", update = TRUE) //get_dynamic_human_appearance uses bald dummies
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index c086dce7c8156..3b2bac8b4b289 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -349,7 +349,7 @@
var/pda_slot = ITEM_SLOT_BELT
-/datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/job/pre_equip(mob/living/carbon/human/H, visuals_only = FALSE)
if(ispath(back, /obj/item/storage/backpack))
switch(H.backpack)
if(GBACKPACK)
@@ -386,8 +386,8 @@
if(client?.is_veteran() && client?.prefs.read_preference(/datum/preference/toggle/playtime_reward_cloak))
neck = /obj/item/clothing/neck/cloak/skill_reward/playing
-/datum/outfit/job/post_equip(mob/living/carbon/human/equipped, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/job/post_equip(mob/living/carbon/human/equipped, visuals_only = FALSE)
+ if(visuals_only)
return
var/datum/job/equipped_job = SSjob.get_job_type(jobtype)
diff --git a/code/modules/jobs/job_types/assistant/assistant.dm b/code/modules/jobs/job_types/assistant/assistant.dm
index 57691a5b29cdb..a0cb2699d82da 100644
--- a/code/modules/jobs/job_types/assistant/assistant.dm
+++ b/code/modules/jobs/job_types/assistant/assistant.dm
@@ -94,7 +94,7 @@ Assistant
/datum/outfit/job/assistant/consistent/give_jumpsuit(mob/living/carbon/human/target)
uniform = /obj/item/clothing/under/color/grey
-/datum/outfit/job/assistant/consistent/post_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/job/assistant/consistent/post_equip(mob/living/carbon/human/H, visuals_only)
..()
// This outfit is used by the assets SS, which is ran before the atoms SS
diff --git a/code/modules/jobs/job_types/assistant/gimmick_assistants.dm b/code/modules/jobs/job_types/assistant/gimmick_assistants.dm
index e86698c8720f3..d5eb15d0c4733 100644
--- a/code/modules/jobs/job_types/assistant/gimmick_assistants.dm
+++ b/code/modules/jobs/job_types/assistant/gimmick_assistants.dm
@@ -47,7 +47,7 @@
outfit_weight = 2
-/datum/outfit/job/assistant/gimmick/cyborg/post_equip(mob/living/carbon/human/equipped, visualsOnly)
+/datum/outfit/job/assistant/gimmick/cyborg/post_equip(mob/living/carbon/human/equipped, visuals_only)
. = ..()
var/obj/item/organ/internal/tongue/robot/robotongue = new ()
robotongue.Insert(equipped, movement_flags = DELETE_IF_REPLACED)
@@ -103,7 +103,7 @@
outfit_weight = 5
-/datum/outfit/job/assistant/gimmick/mopper/post_equip(mob/living/carbon/human/equipped, visualsOnly)
+/datum/outfit/job/assistant/gimmick/mopper/post_equip(mob/living/carbon/human/equipped, visuals_only)
. = ..()
for(var/turf/turf in range(1, equipped))
diff --git a/code/modules/jobs/job_types/bartender.dm b/code/modules/jobs/job_types/bartender.dm
index c0f200c82f7b6..d0e813bf46eef 100644
--- a/code/modules/jobs/job_types/bartender.dm
+++ b/code/modules/jobs/job_types/bartender.dm
@@ -61,7 +61,7 @@
skillchips = list(/obj/item/skillchip/drunken_brawler)
-/datum/outfit/job/bartender/post_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/job/bartender/post_equip(mob/living/carbon/human/H, visuals_only)
. = ..()
var/obj/item/card/id/W = H.wear_id
diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm
index 99bc35bb60320..35155a7c7b70d 100644
--- a/code/modules/jobs/job_types/captain.dm
+++ b/code/modules/jobs/job_types/captain.dm
@@ -93,7 +93,7 @@
var/special_charter
-/datum/outfit/job/captain/pre_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/job/captain/pre_equip(mob/living/carbon/human/H, visuals_only)
. = ..()
special_charter = CHECK_MAP_JOB_CHANGE(JOB_CAPTAIN, "special_charter")
if(!special_charter)
@@ -106,9 +106,9 @@
else if(!r_hand)
r_hand = /obj/item/station_charter/banner
-/datum/outfit/job/captain/post_equip(mob/living/carbon/human/equipped, visualsOnly)
+/datum/outfit/job/captain/post_equip(mob/living/carbon/human/equipped, visuals_only)
. = ..()
- if(visualsOnly || !special_charter)
+ if(visuals_only || !special_charter)
return
var/obj/item/station_charter/banner/celestial_charter = locate() in equipped.held_items
diff --git a/code/modules/jobs/job_types/clown.dm b/code/modules/jobs/job_types/clown.dm
index 12f30a9de1b88..5b20496072d44 100644
--- a/code/modules/jobs/job_types/clown.dm
+++ b/code/modules/jobs/job_types/clown.dm
@@ -83,7 +83,7 @@
back = /obj/item/mod/control/pre_equipped/cosmohonk
internals_slot = ITEM_SLOT_SUITSTORE
-/datum/outfit/job/clown/pre_equip(mob/living/carbon/human/H, visualsOnly)
+/datum/outfit/job/clown/pre_equip(mob/living/carbon/human/H, visuals_only)
. = ..()
if(HAS_TRAIT(SSstation, STATION_TRAIT_BANANIUM_SHIPMENTS))
backpack_contents[/obj/item/stack/sheet/mineral/bananium/five] = 1
@@ -93,9 +93,9 @@
if(HAS_TRAIT(SSstation, STATION_TRAIT_BANANIUM_SHIPMENTS))
. += /obj/item/stack/sheet/mineral/bananium/five
-/datum/outfit/job/clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/job/clown/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
..()
- if(visualsOnly)
+ if(visuals_only)
return
H.fully_replace_character_name(H.real_name, pick(GLOB.clown_names)) //rename the mob AFTER they're equipped so their ID gets updated properly.
diff --git a/code/modules/jobs/job_types/cook.dm b/code/modules/jobs/job_types/cook.dm
index dc36796c4d1cf..3498bffedcbbb 100644
--- a/code/modules/jobs/job_types/cook.dm
+++ b/code/modules/jobs/job_types/cook.dm
@@ -80,7 +80,7 @@
skillchips = list(/obj/item/skillchip/job/chef)
-/datum/outfit/job/cook/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/job/cook/pre_equip(mob/living/carbon/human/H, visuals_only = FALSE)
..()
var/datum/job/cook/other_chefs = SSjob.get_job_type(jobtype)
if(other_chefs) // If there's other Chefs, you're a Cook
@@ -88,10 +88,10 @@
id_trim = /datum/id_trim/job/cook
suit = /obj/item/clothing/suit/apron/chef
head = /obj/item/clothing/head/soft/mime
- if(!visualsOnly)
+ if(!visuals_only)
other_chefs.cooks++
-/datum/outfit/job/cook/post_equip(mob/living/carbon/human/user, visualsOnly = FALSE)
+/datum/outfit/job/cook/post_equip(mob/living/carbon/human/user, visuals_only = FALSE)
. = ..()
// Update PDA to match possible new trim.
var/obj/item/card/id/worn_id = user.wear_id
diff --git a/code/modules/jobs/job_types/curator.dm b/code/modules/jobs/job_types/curator.dm
index 93475fdc79e23..1ab089b42b799 100644
--- a/code/modules/jobs/job_types/curator.dm
+++ b/code/modules/jobs/job_types/curator.dm
@@ -55,8 +55,8 @@
accessory = /obj/item/clothing/accessory/pocketprotector/full
-/datum/outfit/job/curator/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/job/curator/pre_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return ..()
/// There can be only one cameraman on this station, and no, not that kind
@@ -67,10 +67,10 @@
return ..()
-/datum/outfit/job/curator/post_equip(mob/living/carbon/human/translator, visualsOnly = FALSE)
+/datum/outfit/job/curator/post_equip(mob/living/carbon/human/translator, visuals_only = FALSE)
..()
- if(visualsOnly)
+ if(visuals_only)
return
translator.grant_all_languages(source = LANGUAGE_CURATOR)
diff --git a/code/modules/jobs/job_types/detective.dm b/code/modules/jobs/job_types/detective.dm
index 258b2b322f1b9..2c8f7c6174884 100644
--- a/code/modules/jobs/job_types/detective.dm
+++ b/code/modules/jobs/job_types/detective.dm
@@ -78,17 +78,17 @@
skillchips = list(/obj/item/skillchip/job/detectives_taste)
-/datum/outfit/job/detective/pre_equip(mob/living/carbon/human/human, visualsOnly = FALSE)
+/datum/outfit/job/detective/pre_equip(mob/living/carbon/human/human, visuals_only = FALSE)
. = ..()
if (human.age < AGE_MINOR)
mask = /obj/item/cigarette/candy
head = /obj/item/clothing/head/fedora/det_hat/minor
-/datum/outfit/job/detective/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/job/detective/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
..()
var/obj/item/cigarette/cig = H.wear_mask
if(istype(cig)) //Some species specfic changes can mess this up (plasmamen)
cig.light("")
- if(visualsOnly)
+ if(visuals_only)
return
diff --git a/code/modules/jobs/job_types/lawyer.dm b/code/modules/jobs/job_types/lawyer.dm
index a25a1d86d3ade..c1cdafab00b18 100644
--- a/code/modules/jobs/job_types/lawyer.dm
+++ b/code/modules/jobs/job_types/lawyer.dm
@@ -47,8 +47,8 @@
chameleon_extras = /obj/item/stamp/law
-/datum/outfit/job/lawyer/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/job/lawyer/pre_equip(mob/living/carbon/human/H, visuals_only = FALSE)
+ if(visuals_only)
return ..()
var/static/use_purple_suit = FALSE //If there is one lawyer, they get the default blue suit. If another lawyer joins the round, they start with a purple suit.
diff --git a/code/modules/jobs/job_types/mime.dm b/code/modules/jobs/job_types/mime.dm
index 46090cdbe30ac..1a19365a83e1f 100644
--- a/code/modules/jobs/job_types/mime.dm
+++ b/code/modules/jobs/job_types/mime.dm
@@ -69,10 +69,10 @@
box = /obj/item/storage/box/survival/hug/black
chameleon_extras = /obj/item/stamp/mime
-/datum/outfit/job/mime/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+/datum/outfit/job/mime/post_equip(mob/living/carbon/human/H, visuals_only = FALSE)
..()
- if(visualsOnly)
+ if(visuals_only)
return
// Start our mime out with a vow of silence and the ability to break (or make) it
diff --git a/code/modules/jobs/job_types/prisoner.dm b/code/modules/jobs/job_types/prisoner.dm
index 1d4be888e9678..59f15b3b3836a 100644
--- a/code/modules/jobs/job_types/prisoner.dm
+++ b/code/modules/jobs/job_types/prisoner.dm
@@ -65,7 +65,7 @@
if(prob(1)) // D BOYYYYSSSSS
head = /obj/item/clothing/head/beanie/black/dboy
-/datum/outfit/job/prisoner/post_equip(mob/living/carbon/human/new_prisoner, visualsOnly)
+/datum/outfit/job/prisoner/post_equip(mob/living/carbon/human/new_prisoner, visuals_only)
. = ..()
var/crime_name = new_prisoner.client?.prefs?.read_preference(/datum/preference/choiced/prisoner_crime)
@@ -74,7 +74,7 @@
return
var/list/limbs_to_tat = new_prisoner.bodyparts.Copy()
for(var/i in 1 to crime.tattoos)
- if(!length(SSpersistence.prison_tattoos_to_use) || visualsOnly)
+ if(!length(SSpersistence.prison_tattoos_to_use) || visuals_only)
return
var/obj/item/bodypart/tatted_limb = pick_n_take(limbs_to_tat)
var/list/tattoo = pick_n_take(SSpersistence.prison_tattoos_to_use)
diff --git a/code/modules/jobs/job_types/shaft_miner.dm b/code/modules/jobs/job_types/shaft_miner.dm
index 64d1a3b0bff19..d5d31743ada6c 100644
--- a/code/modules/jobs/job_types/shaft_miner.dm
+++ b/code/modules/jobs/job_types/shaft_miner.dm
@@ -98,9 +98,9 @@
r_pocket = /obj/item/extinguisher/mini
belt = /obj/item/storage/belt/mining/healing
-/datum/outfit/job/miner/equipped/combat/post_equip(mob/living/carbon/human/miner, visualsOnly = FALSE)
+/datum/outfit/job/miner/equipped/combat/post_equip(mob/living/carbon/human/miner, visuals_only = FALSE)
. = ..()
- if(visualsOnly)
+ if(visuals_only)
return
var/list/miner_contents = miner.get_all_contents()
var/obj/item/clothing/suit/hooded/explorer/explorer_suit = locate() in miner_contents
diff --git a/code/modules/jobs/job_types/station_trait/human_ai.dm b/code/modules/jobs/job_types/station_trait/human_ai.dm
index d6f89357b4489..b328679795a2c 100644
--- a/code/modules/jobs/job_types/station_trait/human_ai.dm
+++ b/code/modules/jobs/job_types/station_trait/human_ai.dm
@@ -111,9 +111,9 @@
l_hand = /obj/item/paper/default_lawset_list
-/datum/outfit/job/human_ai/pre_equip(mob/living/carbon/human/equipped, visualsOnly)
+/datum/outfit/job/human_ai/pre_equip(mob/living/carbon/human/equipped, visuals_only)
. = ..()
- if(visualsOnly)
+ if(visuals_only)
return
if(is_safe_turf(equipped.loc, dense_atoms = TRUE)) //skip this if it's safe. We allow dense atoms because we spawn out of the inactive core.
return
@@ -123,9 +123,9 @@
suit = /obj/item/clothing/suit/space/nasavoid
head = /obj/item/clothing/head/helmet/space/nasavoid
-/datum/outfit/job/human_ai/post_equip(mob/living/carbon/human/equipped, visualsOnly)
+/datum/outfit/job/human_ai/post_equip(mob/living/carbon/human/equipped, visuals_only)
. = ..()
- if(visualsOnly)
+ if(visuals_only)
return
if(!equipped.get_quirk(/datum/quirk/body_purist))
var/obj/item/organ/internal/tongue/robot/cybernetic = new()
diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm
index 7fda1df5951f0..6baaf8e566070 100644
--- a/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm
+++ b/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm
@@ -57,7 +57,7 @@
qdel(sight_blocker)
return ..()
-/obj/structure/necropolis_gate/singularity_pull()
+/obj/structure/necropolis_gate/singularity_pull(atom/singularity, current_size)
return 0
/obj/structure/necropolis_gate/CanAllowThrough(atom/movable/mover, border_dir)
@@ -88,7 +88,7 @@
opacity = TRUE
anchored = TRUE
-/obj/structure/opacity_blocker/singularity_pull()
+/obj/structure/opacity_blocker/singularity_pull(atom/singularity, current_size)
return FALSE
//ATTACK HAND IGNORING PARENT RETURN VALUE
@@ -242,7 +242,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate)
AddComponent(/datum/component/seethrough, SEE_THROUGH_MAP_DEFAULT_TWO_TALL)
-/obj/structure/necropolis_arch/singularity_pull()
+/obj/structure/necropolis_arch/singularity_pull(atom/singularity, current_size)
return 0
//stone tiles for boss arenas
@@ -266,7 +266,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate)
give_turf_traits = string_list(list(TRAIT_LAVA_STOPPED, TRAIT_CHASM_STOPPED, TRAIT_IMMERSE_STOPPED))
AddElement(/datum/element/give_turf_traits, give_turf_traits)
-/obj/structure/stone_tile/singularity_pull()
+/obj/structure/stone_tile/singularity_pull(atom/singularity, current_size)
return
/obj/structure/stone_tile/block
diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm
index 0e77140422525..157cfbb9e16b6 100644
--- a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm
+++ b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm
@@ -589,9 +589,9 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
suit = /obj/item/clothing/suit/toggle/labcoat
id_trim = /datum/id_trim/away/hilbert
-/datum/outfit/doctorhilbert/pre_equip(mob/living/carbon/human/hilbert, visualsOnly)
+/datum/outfit/doctorhilbert/pre_equip(mob/living/carbon/human/hilbert, visuals_only)
. = ..()
- if(!visualsOnly)
+ if(!visuals_only)
hilbert.gender = MALE
hilbert.update_body()
@@ -708,6 +708,9 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
/obj/machinery/porta_turret/syndicate/teleport
name = "displacement turret"
desc = "A ballistic machine gun auto-turret that fires bluespace bullets."
- lethal_projectile = /obj/projectile/magic/teleport
- stun_projectile = /obj/projectile/magic/teleport
+ lethal_projectile = /obj/projectile/magic/teleport/bluespace
+ stun_projectile = /obj/projectile/magic/teleport/bluespace
faction = list(FACTION_TURRET)
+
+/obj/projectile/magic/teleport/bluespace
+ antimagic_flags = NONE
diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm
index 4328ff3411008..bca2ace626062 100644
--- a/code/modules/mapping/reader.dm
+++ b/code/modules/mapping/reader.dm
@@ -130,9 +130,6 @@
newfriend.turf_blacklist = turf_blacklist?.Copy()
return newfriend
-//text trimming (both directions) helper macro
-#define TRIM_TEXT(text) (trim_reduced(text))
-
/**
* Helper and recommened way to load a map file
* - dmm_file: The path to the map file
@@ -842,7 +839,7 @@ GLOBAL_LIST_EMPTY(map_model_default)
if(member_string[length(member_string)] == "}")
variables_start = findtext(member_string, "{")
- var/path_text = TRIM_TEXT(copytext(member_string, 1, variables_start))
+ var/path_text = trimtext(copytext(member_string, 1, variables_start))
var/atom_def = text2path(path_text) //path definition, e.g /obj/foo/bar
if(!ispath(atom_def, /atom)) // Skip the item if the path does not exist. Fix your crap, mappers!
@@ -1014,7 +1011,7 @@ GLOBAL_LIST_EMPTY(map_model_default)
// check if this is a simple variable (as in list(var1, var2)) or an associative one (as in list(var1="foo",var2=7))
var/equal_position = findtext(text,"=",old_position, position)
- var/trim_left = TRIM_TEXT(copytext(text,old_position,(equal_position ? equal_position : position)))
+ var/trim_left = trimtext(copytext(text,old_position,(equal_position ? equal_position : position)))
var/left_constant = parse_constant(trim_left)
if(position)
old_position = position + length(text[position])
@@ -1024,7 +1021,7 @@ GLOBAL_LIST_EMPTY(map_model_default)
if(equal_position && !isnum(left_constant))
// Associative var, so do the association.
// Note that numbers cannot be keys - the RHS is dropped if so.
- var/trim_right = TRIM_TEXT(copytext(text, equal_position + length(text[equal_position]), position))
+ var/trim_right = trimtext(copytext(text, equal_position + length(text[equal_position]), position))
var/right_constant = parse_constant(trim_right)
.[left_constant] = right_constant
else // simple var
@@ -1081,5 +1078,4 @@ GLOBAL_LIST_EMPTY(map_model_default)
#undef MAP_DMM
#undef MAP_TGM
#undef MAP_UNKNOWN
-#undef TRIM_TEXT
#undef MAPLOADING_CHECK_TICK
diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm
index 1ef2f778bc54b..7092c8c0f7616 100644
--- a/code/modules/mining/fulton.dm
+++ b/code/modules/mining/fulton.dm
@@ -243,7 +243,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
/obj/effect/extraction_holder/singularity_act()
return
-/obj/effect/extraction_holder/singularity_pull()
+/obj/effect/extraction_holder/singularity_pull(atom/singularity, current_size)
return
/obj/item/extraction_pack/syndicate
diff --git a/code/modules/mining/lavaland/tendril_loot.dm b/code/modules/mining/lavaland/tendril_loot.dm
index 7acc0299f1018..02156684afac4 100644
--- a/code/modules/mining/lavaland/tendril_loot.dm
+++ b/code/modules/mining/lavaland/tendril_loot.dm
@@ -453,7 +453,7 @@
// but regardless block all relayed moves, because no, you cannot move in the void.
return
-/obj/effect/immortality_talisman/singularity_pull()
+/obj/effect/immortality_talisman/singularity_pull(atom/singularity, current_size)
return
/obj/effect/immortality_talisman/void
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index aaf127bf8b594..798ec58cd1e73 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -13,7 +13,7 @@
. = ..()
set_light(set_luminosity, set_cap)
-/obj/effect/light_emitter/singularity_pull()
+/obj/effect/light_emitter/singularity_pull(atom/singularity, current_size)
return
/obj/effect/light_emitter/singularity_act()
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index b19718b498201..ee173795c1321 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -159,7 +159,7 @@
return FALSE
return !held_items[hand_index]
-/mob/proc/put_in_hand(obj/item/I, hand_index, forced = FALSE, ignore_anim = TRUE)
+/mob/proc/put_in_hand(obj/item/I, hand_index, forced = FALSE, ignore_anim = TRUE, visuals_only = FALSE)
if(hand_index == null || !held_items.len || (!forced && !can_put_in_hand(I, hand_index)))
return FALSE
@@ -172,7 +172,7 @@
SET_PLANE_EXPLICIT(I, ABOVE_HUD_PLANE, src)
if(I.pulledby)
I.pulledby.stop_pulling()
- if(!I.on_equipped(src, ITEM_SLOT_HANDS))
+ if(!I.on_equipped(src, ITEM_SLOT_HANDS, initial = visuals_only))
return FALSE
update_held_items()
I.pixel_x = I.base_pixel_x
@@ -183,12 +183,12 @@
return hand_index
//Puts the item into the first available left hand if possible and calls all necessary triggers/updates. returns 1 on success.
-/mob/proc/put_in_l_hand(obj/item/I)
- return put_in_hand(I, get_empty_held_index_for_side(LEFT_HANDS))
+/mob/proc/put_in_l_hand(obj/item/I, visuals_only = FALSE)
+ return put_in_hand(I, get_empty_held_index_for_side(LEFT_HANDS), visuals_only = visuals_only)
//Puts the item into the first available right hand if possible and calls all necessary triggers/updates. returns 1 on success.
-/mob/proc/put_in_r_hand(obj/item/I)
- return put_in_hand(I, get_empty_held_index_for_side(RIGHT_HANDS))
+/mob/proc/put_in_r_hand(obj/item/I, visuals_only = FALSE)
+ return put_in_hand(I, get_empty_held_index_for_side(RIGHT_HANDS), visuals_only = visuals_only)
/mob/proc/put_in_hand_check(obj/item/I)
return FALSE //nonliving mobs don't have hands
@@ -200,19 +200,19 @@
return FALSE
//Puts the item into our active hand if possible. returns TRUE on success.
-/mob/proc/put_in_active_hand(obj/item/I, forced = FALSE, ignore_animation = TRUE)
- return put_in_hand(I, active_hand_index, forced, ignore_animation)
+/mob/proc/put_in_active_hand(obj/item/I, forced = FALSE, ignore_animation = TRUE, visuals_only = FALSE)
+ return put_in_hand(I, active_hand_index, forced, ignore_animation, visuals_only)
//Puts the item into our inactive hand if possible, returns TRUE on success
-/mob/proc/put_in_inactive_hand(obj/item/I, forced = FALSE)
- return put_in_hand(I, get_inactive_hand_index(), forced)
+/mob/proc/put_in_inactive_hand(obj/item/I, forced = FALSE, visuals_only = FALSE)
+ return put_in_hand(I, get_inactive_hand_index(), forced, visuals_only = visuals_only)
//Puts the item our active hand if possible. Failing that it tries other hands. Returns TRUE on success.
//If both fail it drops it on the floor (or nearby tables if germ sensitive) and returns FALSE.
//This is probably the main one you need to know :)
-/mob/proc/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, forced = FALSE, ignore_animation = TRUE)
+/mob/proc/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, forced = FALSE, ignore_animation = TRUE, visuals_only = FALSE)
if(QDELETED(I))
return FALSE
@@ -236,14 +236,14 @@
to_chat(usr, span_notice("Your [inactive_stack.name] stack now contains [inactive_stack.get_amount()] [inactive_stack.singular_name]\s."))
return TRUE
- if(put_in_active_hand(I, forced, ignore_animation))
+ if(put_in_active_hand(I, forced, ignore_animation, visuals_only))
return TRUE
var/hand = get_empty_held_index_for_side(LEFT_HANDS)
if(!hand)
hand = get_empty_held_index_for_side(RIGHT_HANDS)
if(hand)
- if(put_in_hand(I, hand, forced, ignore_animation))
+ if(put_in_hand(I, hand, forced, ignore_animation, visuals_only))
return TRUE
if(del_on_fail)
qdel(I)
@@ -355,10 +355,10 @@
. = doUnEquip(I, force, newloc, FALSE, silent = silent)
I.do_drop_animation(src)
-//visibly unequips I but it is NOT MOVED AND REMAINS IN SRC
+//visibly unequips I but it is NOT MOVED AND REMAINS IN SRC, newloc is for signal handling checks only which hints where you want to move the object after removal
//item MUST BE FORCEMOVE'D OR QDEL'D
-/mob/proc/temporarilyRemoveItemFromInventory(obj/item/I, force = FALSE, idrop = TRUE)
- return doUnEquip(I, force, null, TRUE, idrop, silent = TRUE)
+/mob/proc/temporarilyRemoveItemFromInventory(obj/item/I, force = FALSE, idrop = TRUE, atom/newloc = src)
+ return doUnEquip(I, force, newloc, TRUE, idrop, silent = TRUE)
//DO NOT CALL THIS PROC
//use one of the above 3 helper procs
diff --git a/code/modules/mob/living/basic/bots/bot_ai.dm b/code/modules/mob/living/basic/bots/bot_ai.dm
index fd89168ddf4f1..d777614d7433e 100644
--- a/code/modules/mob/living/basic/bots/bot_ai.dm
+++ b/code/modules/mob/living/basic/bots/bot_ai.dm
@@ -72,7 +72,7 @@
/datum/ai_controller/basic_controller/bot/get_able_to_run()
var/mob/living/basic/bot/bot_pawn = pawn
if(!(bot_pawn.bot_mode_flags & BOT_MODE_ON))
- return FALSE
+ return AI_UNABLE_TO_RUN
return ..()
/datum/ai_controller/basic_controller/bot/get_access()
diff --git a/code/modules/mob/living/basic/bots/medbot/medbot_ai.dm b/code/modules/mob/living/basic/bots/medbot/medbot_ai.dm
index f0b2f089cb6e7..2fe705433a162 100644
--- a/code/modules/mob/living/basic/bots/medbot/medbot_ai.dm
+++ b/code/modules/mob/living/basic/bots/medbot/medbot_ai.dm
@@ -218,6 +218,13 @@
///travel towards beacon behavior
travel_behavior = /datum/ai_behavior/travel_towards/beacon/medbot
+/datum/ai_planning_subtree/find_patrol_beacon/medbot/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ var/mob/living/basic/bot/medbot/bot_pawn = controller.pawn
+ if(bot_pawn.medical_mode_flags & MEDBOT_STATIONARY_MODE)
+ return
+ return ..()
+
+
/datum/ai_behavior/travel_towards/beacon/medbot
new_movement_type = /datum/ai_movement/jps/bot/medbot/travel_to_beacon
diff --git a/code/modules/mob/living/basic/drone/drone_tools.dm b/code/modules/mob/living/basic/drone/drone_tools.dm
index b55b438362a9d..8408738bf6a3d 100644
--- a/code/modules/mob/living/basic/drone/drone_tools.dm
+++ b/code/modules/mob/living/basic/drone/drone_tools.dm
@@ -26,7 +26,7 @@
builtintools += new /obj/item/soap/drone(src)
for(var/obj/item/tool as anything in builtintools)
- tool.AddComponent(/datum/component/holderloving, src, TRUE)
+ tool.AddComponent(/datum/component/holderloving, src)
/obj/item/crowbar/drone
name = "built-in crowbar"
diff --git a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm
index 2eae87310591e..e9dd79fd5ef06 100644
--- a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm
+++ b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm
@@ -70,6 +70,7 @@
AddComponent(/datum/component/swarming)
AddComponent(/datum/component/obeys_commands, pet_commands)
AddElement(/datum/element/swabable, CELL_LINE_TABLE_QUEEN_BEE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
+ AddElement(/datum/element/basic_allergenic_attack, allergen = BUGS, allergen_chance = 33, histamine_add = 5)
/mob/living/basic/bee/mob_pickup(mob/living/picker)
if(flags_1 & HOLOGRAM_1)
diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
index 625dc4af90726..d7f5a024aceb1 100644
--- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
+++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
@@ -55,6 +55,8 @@
charge = new charge_type(src)
charge.Grant(src)
ai_controller.set_blackboard_key(BB_TARGETED_ACTION, charge)
+ var/static/list/fishable_turfs = typecacheof(list(/turf/open/lava))
+ ai_controller.set_blackboard_key(BB_FISHABLE_LIST, fishable_turfs)
/mob/living/basic/mining/lobstrosity/Destroy()
QDEL_NULL(charge)
diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm
index de6ca4a0cc1b4..647aeac9474ec 100644
--- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm
@@ -14,6 +14,8 @@
BB_LOBSTROSITY_FINGER_LUST = 0,
BB_LOBSTROSITY_NAIVE_HUNTER = FALSE,
BB_BASIC_MOB_FLEE_DISTANCE = 8,
+ BB_EAT_FOOD_COOLDOWN = 3 MINUTES,
+ BB_ONLY_FISH_WHILE_HUNGRY = TRUE,
BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN,
BB_OWNER_SELF_HARM_RESPONSES = SHRIMP_HARM_RESPONSES,
)
@@ -31,7 +33,7 @@
/datum/ai_planning_subtree/attack_obstacle_in_path,
/datum/ai_planning_subtree/basic_melee_attack_subtree/lobster,
/datum/ai_planning_subtree/find_food,
- /datum/ai_planning_subtree/find_and_hunt_target/lobster_fishing,
+ /datum/ai_planning_subtree/fish/fish_from_turfs,
/datum/ai_planning_subtree/find_fingers,
)
@@ -65,7 +67,7 @@
/datum/ai_planning_subtree/attack_obstacle_in_path,
/datum/ai_planning_subtree/basic_melee_attack_subtree/lobster,
/datum/ai_planning_subtree/find_food,
- /datum/ai_planning_subtree/find_and_hunt_target/lobster_fishing,
+ /datum/ai_planning_subtree/fish/fish_from_turfs,
/datum/ai_planning_subtree/find_fingers,
)
@@ -81,7 +83,7 @@
/datum/ai_planning_subtree/attack_obstacle_in_path,
/datum/ai_planning_subtree/basic_melee_attack_subtree/lobster,
/datum/ai_planning_subtree/find_food,
- /datum/ai_planning_subtree/find_and_hunt_target/lobster_fishing,
+ /datum/ai_planning_subtree/fish/fish_from_turfs,
/datum/ai_planning_subtree/find_fingers,
)
@@ -97,15 +99,10 @@
/datum/ai_planning_subtree/attack_obstacle_in_path,
/datum/ai_planning_subtree/basic_melee_attack_subtree/lobster,
/datum/ai_planning_subtree/find_food,
- /datum/ai_planning_subtree/find_and_hunt_target/lobster_fishing,
+ /datum/ai_planning_subtree/fish/fish_from_turfs,
/datum/ai_planning_subtree/find_fingers,
)
-/datum/ai_planning_subtree/find_and_hunt_target/lobster_fishing
- target_key = BB_FISHING_TARGET
- hunt_targets = list(/turf/open/lava)
- hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off
-
/datum/ai_planning_subtree/basic_melee_attack_subtree/lobster
melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/lobster
diff --git a/code/modules/mob/living/basic/pets/penguin.dm b/code/modules/mob/living/basic/pets/penguin/penguin.dm
similarity index 72%
rename from code/modules/mob/living/basic/pets/penguin.dm
rename to code/modules/mob/living/basic/pets/penguin/penguin.dm
index c1afe10187c75..5a4732039987d 100644
--- a/code/modules/mob/living/basic/pets/penguin.dm
+++ b/code/modules/mob/living/basic/pets/penguin/penguin.dm
@@ -35,6 +35,7 @@
AddElement(/datum/element/ai_flee_while_injured)
AddElement(/datum/element/pet_bonus, "honk")
AddElementTrait(TRAIT_WADDLING, INNATE_TRAIT, /datum/element/waddling)
+ ADD_TRAIT(src, TRAIT_MOB_CAN_DIG, INNATE_TRAIT)
if(!can_lay_eggs)
return
AddComponent(\
@@ -47,6 +48,11 @@
max_eggs_held = 1,\
egg_laid_callback = CALLBACK(src, PROC_REF(lay_penguin_egg)),\
)
+ var/static/list/fishable_objects = typecacheof(list(/turf/open/misc/ice))
+ ai_controller.set_blackboard_key(BB_FISHABLE_LIST, fishable_objects)
+ var/static/list/delicious_food = list(/obj/item/fish)
+ AddElement(/datum/element/basic_eating, heal_amt = 10, food_types = delicious_food)
+ ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(delicious_food))
/mob/living/basic/pet/penguin/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
. = ..()
@@ -93,38 +99,6 @@
carried_egg = null
cut_overlay("penguin_egg_overlay")
-/datum/ai_controller/basic_controller/penguin
- blackboard = list(
- BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
- )
-
- ai_traits = STOP_MOVING_WHEN_PULLED
- ai_movement = /datum/ai_movement/basic_avoidance
- idle_behavior = /datum/idle_behavior/idle_random_walk
-
- planning_subtrees = list(
- /datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
- /datum/ai_planning_subtree/flee_target,
- /datum/ai_planning_subtree/find_and_hunt_target/penguin_egg,
- /datum/ai_planning_subtree/random_speech/penguin,
- )
-
-/datum/ai_planning_subtree/find_and_hunt_target/penguin_egg
- target_key = BB_LOW_PRIORITY_HUNTING_TARGET
- hunting_behavior = /datum/ai_behavior/hunt_target/penguin_egg
- finding_behavior = /datum/ai_behavior/find_hunt_target/penguin_egg
- hunt_targets = list(/obj/item/food/egg/penguin_egg)
- hunt_range = 7
-
-/datum/ai_behavior/find_hunt_target/penguin_egg/valid_dinner(mob/living/source, atom/dinner, radius)
- return can_see(source, dinner, radius) && !(dinner in source.contents)
-/datum/ai_behavior/hunt_target/penguin_egg
- hunt_cooldown = 15 SECONDS
- always_reset_target = TRUE
-
-/datum/ai_behavior/hunt_target/penguin_egg/target_caught(mob/living/basic/hunter, obj/item/food/egg/target)
- hunter.UnarmedAttack(target, TRUE)
-
/mob/living/basic/pet/penguin/emperor
name = "emperor penguin"
real_name = "penguin"
@@ -163,7 +137,6 @@
///will it grow up?
var/can_grow_up = TRUE
-
/mob/living/basic/pet/penguin/baby/Initialize(mapload)
. = ..()
if(!can_grow_up)
@@ -187,23 +160,6 @@
/mob/living/basic/pet/penguin/baby/proc/ready_to_grow()
return (stat == CONSCIOUS)
-/datum/ai_controller/basic_controller/penguin/baby
- blackboard = list(
- BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
- BB_FIND_MOM_TYPES = list(/mob/living/basic/pet/penguin),
- BB_IGNORE_MOM_TYPES = list(/mob/living/basic/pet/penguin/baby),
- )
-
- ai_traits = STOP_MOVING_WHEN_PULLED
- ai_movement = /datum/ai_movement/basic_avoidance
- idle_behavior = /datum/idle_behavior/idle_random_walk
-
- planning_subtrees = list(
- /datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
- /datum/ai_planning_subtree/flee_target,
- /datum/ai_planning_subtree/look_for_adult,
- )
-
/mob/living/basic/pet/penguin/baby/permanent
can_grow_up = FALSE
diff --git a/code/modules/mob/living/basic/pets/penguin/penguin_ai.dm b/code/modules/mob/living/basic/pets/penguin/penguin_ai.dm
new file mode 100644
index 0000000000000..90d12e8794179
--- /dev/null
+++ b/code/modules/mob/living/basic/pets/penguin/penguin_ai.dm
@@ -0,0 +1,79 @@
+
+/datum/ai_controller/basic_controller/penguin
+ blackboard = list(
+ BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
+ BB_ONLY_FISH_WHILE_HUNGRY = TRUE,
+ )
+
+ ai_traits = STOP_MOVING_WHEN_PULLED
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
+ /datum/ai_planning_subtree/flee_target,
+ /datum/ai_planning_subtree/find_food,
+ /datum/ai_planning_subtree/fish/drilled_ice,
+ /datum/ai_planning_subtree/find_and_hunt_target/drill_ice,
+ /datum/ai_planning_subtree/find_and_hunt_target/penguin_egg,
+ /datum/ai_planning_subtree/random_speech/penguin,
+ )
+
+///subtree to find baby eggs!
+/datum/ai_planning_subtree/find_and_hunt_target/penguin_egg
+ target_key = BB_LOW_PRIORITY_HUNTING_TARGET
+ hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/reset_target
+ finding_behavior = /datum/ai_behavior/find_hunt_target/penguin_egg
+ hunt_targets = list(/obj/item/food/egg/penguin_egg)
+ hunt_range = 7
+
+/datum/ai_behavior/find_hunt_target/penguin_egg/valid_dinner(mob/living/source, atom/dinner, radius)
+ return can_see(source, dinner, radius) && !(dinner in source.contents)
+
+///subtree to find diggable ice we can fish from!
+/datum/ai_planning_subtree/find_and_hunt_target/drill_ice
+ target_key = BB_DRILLABLE_ICE
+ hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/reset_target
+ finding_behavior = /datum/ai_behavior/find_hunt_target/search_turf_types/drillable_ice
+ hunt_targets = list(/turf/open/misc/ice)
+ hunt_range = 7
+
+/datum/ai_behavior/find_hunt_target/search_turf_types/drillable_ice
+
+/datum/ai_behavior/find_hunt_target/search_turf_types/drillable_ice/valid_dinner(mob/living/source, turf/open/misc/ice/ice, radius)
+ return ice.can_make_hole && can_see(source, ice, radius)
+
+/datum/ai_planning_subtree/find_and_hunt_target/drill_ice/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
+ if(controller.blackboard_key_exists(BB_FISHING_TARGET))
+ return
+ return ..()
+
+/datum/ai_planning_subtree/fish/drilled_ice
+ find_fishable_behavior = /datum/ai_behavior/find_and_set/in_list/drilled_ice
+
+/datum/ai_behavior/find_and_set/in_list/drilled_ice/search_tactic(datum/ai_controller/controller, locate_paths, search_range)
+ for(var/atom/possible_ice as anything in RANGE_TURFS(search_range, controller.pawn))
+ if(!istype(possible_ice, /turf/open/misc/ice))
+ continue
+ if(HAS_TRAIT(possible_ice, TRAIT_FISHING_SPOT))
+ return possible_ice
+ return null
+
+///ai controller for the baby penguin
+/datum/ai_controller/basic_controller/penguin/baby
+ blackboard = list(
+ BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
+ BB_FIND_MOM_TYPES = list(/mob/living/basic/pet/penguin),
+ BB_IGNORE_MOM_TYPES = list(/mob/living/basic/pet/penguin/baby),
+ )
+
+ ai_traits = STOP_MOVING_WHEN_PULLED
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
+ /datum/ai_planning_subtree/flee_target,
+ /datum/ai_planning_subtree/find_food,
+ /datum/ai_planning_subtree/look_for_adult,
+ )
diff --git a/code/modules/mob/living/basic/space_fauna/ant.dm b/code/modules/mob/living/basic/space_fauna/ant.dm
index 3ae46b7f53947..60b91c5dcc215 100644
--- a/code/modules/mob/living/basic/space_fauna/ant.dm
+++ b/code/modules/mob/living/basic/space_fauna/ant.dm
@@ -52,6 +52,7 @@
AddElement(/datum/element/pet_bonus, "clack")
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
+ AddElement(/datum/element/basic_allergenic_attack, allergen = BUGS, allergen_chance = 20, histamine_add = 5)
/datum/ai_controller/basic_controller/ant
blackboard = list(
diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider.dm b/code/modules/mob/living/basic/space_fauna/spider/spider.dm
index 195b814983301..d71f6791a9c9a 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/spider.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/spider.dm
@@ -69,6 +69,7 @@
AddElement(/datum/element/prevent_attacking_of_types, GLOB.typecache_general_bad_hostile_attack_targets, "this tastes awful!")
AddElement(/datum/element/cliff_walking)
AddComponent(/datum/component/health_scaling_effects, min_health_slowdown = 1.5)
+ AddElement(/datum/element/basic_allergenic_attack, allergen = BUGS, allergen_chance = 20, histamine_add = 5)
if(poison_per_bite)
AddElement(/datum/element/venomous, poison_type, poison_per_bite, injection_flags = bite_injection_flags)
diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/wrap.dm b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/wrap.dm
index 088905a5ae2f3..5ea10c5532d02 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/wrap.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/spider_abilities/wrap.dm
@@ -74,6 +74,8 @@
return TRUE
/datum/action/cooldown/mob_cooldown/wrap/proc/cocoon(atom/movable/to_wrap)
+ if(isliving(to_wrap))
+ to_chat(to_wrap, span_userdanger("[owner] begins to secrete a sticky substance around you."))
owner.visible_message(
span_notice("[owner] begins to secrete a sticky substance around [to_wrap]."),
span_notice("You begin wrapping [to_wrap] into a cocoon."),
diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm
index 8863dedd43e61..aebba0ae2a9ff 100644
--- a/code/modules/mob/living/carbon/carbon_update_icons.dm
+++ b/code/modules/mob/living/carbon/carbon_update_icons.dm
@@ -580,6 +580,8 @@
if(gradient_styles?[GRADIENT_HAIR_KEY])
. += "-[gradient_styles[GRADIENT_HAIR_KEY]]"
. += "-[gradient_colors[GRADIENT_HAIR_KEY]]"
+ if(LAZYLEN(hair_masks))
+ . += "-[jointext(hair_masks, "-")]"
return .
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 9fcb4083f30f6..462b9b8e33124 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -488,13 +488,13 @@
underwear = "Nude"
update_body(is_creating = TRUE)
-/mob/living/carbon/human/singularity_pull(S, current_size)
+/mob/living/carbon/human/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_THREE)
for(var/obj/item/hand in held_items)
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && dropItemToGround(hand))
step_towards(hand, src)
- to_chat(src, span_warning("\The [S] pulls \the [hand] from your grip!"))
+ to_chat(src, span_warning("\The [singularity] pulls \the [hand] from your grip!"))
#define CPR_PANIC_SPEED (0.8 SECONDS)
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index eef20329ef890..02f627459cb93 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -335,7 +335,7 @@
/mob/living/carbon/human/toggle_externals(obj/item/tank)
return toggle_internals(tank, TRUE)
-/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE)
+/mob/living/carbon/human/proc/equipOutfit(outfit, visuals_only = FALSE)
var/datum/outfit/O = null
if(ispath(outfit))
@@ -347,11 +347,11 @@
if(!O)
return 0
- return O.equip(src, visualsOnly)
+ return O.equip(src, visuals_only)
///A version of equipOutfit that overrides passed in outfits with their entry on the species' outfit override registry
-/mob/living/carbon/human/proc/equip_species_outfit(outfit, visualsOnly = FALSE)
+/mob/living/carbon/human/proc/equip_species_outfit(outfit, visuals_only = FALSE)
var/datum/outfit/outfit_to_equip
var/override_outfit_path = dna?.species.outfit_override_registry[outfit]
@@ -363,7 +363,7 @@
if(isnull(outfit_to_equip))
return FALSE
- return outfit_to_equip.equip(src, visualsOnly)
+ return outfit_to_equip.equip(src, visuals_only)
//delete all equipment without dropping anything
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index e50f35b8f02d3..db1cf6fb9d821 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1282,14 +1282,14 @@
animate(src, transform = flipped_matrix, pixel_y = pixel_y-4, time = 0.5 SECONDS, easing = EASE_OUT)
base_pixel_y -= 4
-/mob/living/singularity_pull(S, current_size)
+/mob/living/singularity_pull(atom/singularity, current_size)
..()
if(move_resist == INFINITY)
return
if(current_size >= STAGE_SIX) //your puny magboots/wings/whatever will not save you against supermatter singularity
- throw_at(S, 14, 3, src, TRUE)
+ throw_at(singularity, 14, 3, src, TRUE)
else if(!src.mob_negates_gravity())
- step_towards(src,S)
+ step_towards(src, singularity)
/mob/living/proc/get_temperature(datum/gas_mixture/environment)
var/loc_temp = environment ? environment.temperature : T0C
diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm
index 28dbbc078c5af..2b88984bf41fc 100644
--- a/code/modules/mob/living/taste.dm
+++ b/code/modules/mob/living/taste.dm
@@ -101,6 +101,28 @@
var/datum/quirk/item_quirk/food_allergic/allergy = get_quirk(/datum/quirk/item_quirk/food_allergic)
return allergy?.target_foodtypes || NONE
+/**
+ * Checks if the mob has an allergic reaction to the given food type.
+ * If so, the mob will contract anaphylaxis.
+ *
+ * * to_foodtype: The food type to check for an allergic reaction to.
+ * * chance: The chance of an allergic reaction occurring. Default is 100 (guaranteed).
+ * * histamine_add: The amount of histamine to add to the mob if they are already experiencing an allergic reaction.
+ *
+ * Returns TRUE if the mob had an allergic reaction, FALSE otherwise.
+ */
+/mob/living/proc/check_allergic_reaction(to_foodtype = NONE, chance = 100, histamine_add = 0)
+ if(!(get_allergic_foodtypes() & to_foodtype))
+ return FALSE
+ if(!prob(chance))
+ return FALSE
+ if(ForceContractDisease(new /datum/disease/anaphylaxis(), make_copy = FALSE, del_on_fail = TRUE))
+ to_chat(src, span_warning("You feel your throat start to itch."))
+ add_mood_event("allergic_food", /datum/mood_event/allergic_food)
+ else if(histamine_add)
+ reagents.add_reagent(/datum/reagent/toxin/histamine, histamine_add)
+ return TRUE
+
/**
* Gets the food reaction a mob would normally have from the given food item,
* assuming that no check_liked callback was used in the edible component.
diff --git a/code/modules/mob_spawn/corpses/mining_corpses.dm b/code/modules/mob_spawn/corpses/mining_corpses.dm
index 972bb5c3fa589..3963cefcb4931 100644
--- a/code/modules/mob_spawn/corpses/mining_corpses.dm
+++ b/code/modules/mob_spawn/corpses/mining_corpses.dm
@@ -135,9 +135,9 @@
mask = /obj/item/clothing/mask/gas/explorer
shoes = /obj/item/clothing/shoes/workboots/mining
-/datum/outfit/consumed_miner/pre_equip(mob/living/carbon/human/miner, visualsOnly = FALSE)
+/datum/outfit/consumed_miner/pre_equip(mob/living/carbon/human/miner, visuals_only = FALSE)
var/regular_uniform = FALSE
- if(visualsOnly)
+ if(visuals_only)
regular_uniform = TRUE //assume human
else
var/new_species_type = pick_weight(list(
@@ -195,8 +195,8 @@
name = "Legion-Consumed Ashwalker"
uniform = /obj/item/clothing/under/costume/gladiator/ash_walker
-/datum/outfit/consumed_ashwalker/pre_equip(mob/living/carbon/human/ashwalker, visualsOnly = FALSE)
- if(!visualsOnly)
+/datum/outfit/consumed_ashwalker/pre_equip(mob/living/carbon/human/ashwalker, visuals_only = FALSE)
+ if(!visuals_only)
ashwalker.set_species(/datum/species/lizard/ashwalker)
if(prob(95))
head = /obj/item/clothing/head/helmet/gladiator
@@ -234,8 +234,8 @@
///drops a pie cannon on post_equip. i'm so done with this stupid outfit trying to put shit that doesn't fit in the backpack!
var/drop_a_pie_cannon = FALSE
-/datum/outfit/consumed_clown/pre_equip(mob/living/carbon/human/clown, visualsOnly = FALSE)
- if(!visualsOnly)
+/datum/outfit/consumed_clown/pre_equip(mob/living/carbon/human/clown, visuals_only = FALSE)
+ if(!visuals_only)
clown.fully_replace_character_name(clown.name, pick(GLOB.clown_names))
if(prob(70))
var/backpack_loot = pick(list(
@@ -260,7 +260,7 @@
if(prob(10))
r_pocket = /obj/item/implanter/sad_trombone
-/datum/outfit/consumed_clown/post_equip(mob/living/carbon/human/clown, visualsOnly)
+/datum/outfit/consumed_clown/post_equip(mob/living/carbon/human/clown, visuals_only)
. = ..()
if(drop_a_pie_cannon)
new /obj/item/pneumatic_cannon/pie(get_turf(clown))
@@ -269,8 +269,8 @@
name = "Legion-Consumed Golem"
//Oops! All randomized!
-/datum/outfit/consumed_golem/pre_equip(mob/living/carbon/human/golem, visualsOnly = FALSE)
- if(!visualsOnly)
+/datum/outfit/consumed_golem/pre_equip(mob/living/carbon/human/golem, visuals_only = FALSE)
+ if(!visuals_only)
golem.set_species(/datum/species/golem)
if(prob(30))
glasses = pick_weight(list(
@@ -281,7 +281,7 @@
/obj/item/clothing/glasses/welding = 2,
/obj/item/clothing/glasses/night = 1,
))
- if(prob(10) && !visualsOnly) //visualsonly = not a golem = can't put things in the belt slot without a jumpsuit
+ if(prob(10) && !visuals_only) //visuals_only = not a golem = can't put things in the belt slot without a jumpsuit
belt = pick(list(
/obj/item/crowbar/power,
/obj/item/screwdriver/power,
@@ -299,7 +299,7 @@
shoes = /obj/item/clothing/shoes/winterboots
mask = /obj/item/clothing/mask/breath
-/datum/outfit/consumed_ice_settler/pre_equip(mob/living/carbon/human/ice_settler, visualsOnly = FALSE)
+/datum/outfit/consumed_ice_settler/pre_equip(mob/living/carbon/human/ice_settler, visuals_only = FALSE)
if(prob(40))
r_pocket = pick_weight(list(
/obj/item/coin/silver = 5,
@@ -333,8 +333,8 @@
shoes = /obj/item/clothing/shoes/laceup
r_pocket = /obj/item/tank/internals/emergency_oxygen
-/datum/outfit/consumed_dame/pre_equip(mob/living/carbon/human/dame, visualsOnly = FALSE)
- if(!visualsOnly)
+/datum/outfit/consumed_dame/pre_equip(mob/living/carbon/human/dame, visuals_only = FALSE)
+ if(!visuals_only)
dame.gender = FEMALE
dame.physique = FEMALE
dame.update_body()
@@ -356,8 +356,8 @@
accessory = /obj/item/clothing/accessory/medal/plasma/nobel_science
-/datum/outfit/consumed_shadowperson/pre_equip(mob/living/carbon/human/shadowperson, visualsOnly = FALSE)
- if(visualsOnly)
+/datum/outfit/consumed_shadowperson/pre_equip(mob/living/carbon/human/shadowperson, visuals_only = FALSE)
+ if(visuals_only)
return
shadowperson.set_species(/datum/species/shadow)
@@ -381,8 +381,8 @@
suit = /obj/item/clothing/suit/hooded/cultrobes/eldritch
head = /obj/item/clothing/head/hooded/cult_hoodie/eldritch
-/datum/outfit/consumed_heremoth/pre_equip(mob/living/carbon/human/moth, visualsOnly = FALSE)
- if(!visualsOnly)
+/datum/outfit/consumed_heremoth/pre_equip(mob/living/carbon/human/moth, visuals_only = FALSE)
+ if(!visuals_only)
moth.set_species(/datum/species/moth)
if(prob(70))
glasses = /obj/item/clothing/glasses/blindfold
diff --git a/code/modules/mob_spawn/ghost_roles/mining_roles.dm b/code/modules/mob_spawn/ghost_roles/mining_roles.dm
index 12b5c6deb2f2f..3edfbb3416ac7 100644
--- a/code/modules/mob_spawn/ghost_roles/mining_roles.dm
+++ b/code/modules/mob_spawn/ghost_roles/mining_roles.dm
@@ -99,9 +99,9 @@
l_pocket = /obj/item/food/pizzaslice/dank
r_pocket = /obj/item/storage/wallet/random
-/datum/outfit/beachbum/post_equip(mob/living/carbon/human/bum, visualsOnly = FALSE)
+/datum/outfit/beachbum/post_equip(mob/living/carbon/human/bum, visuals_only = FALSE)
. = ..()
- if(visualsOnly)
+ if(visuals_only)
return
bum.dna.add_mutation(/datum/mutation/human/stoner)
@@ -131,7 +131,7 @@
glasses = /obj/item/clothing/glasses/sunglasses/reagent
shoes = /obj/item/clothing/shoes/sneakers/black
-/datum/outfit/spacebartender/post_equip(mob/living/carbon/human/bartender, visualsOnly = FALSE)
+/datum/outfit/spacebartender/post_equip(mob/living/carbon/human/bartender, visuals_only = FALSE)
. = ..()
var/obj/item/card/id/id_card = bartender.wear_id
if(bartender.age < AGE_MINOR)
@@ -312,7 +312,7 @@
implants = list(/obj/item/implant/weapons_auth)
-/datum/outfit/lavaland_syndicate/post_equip(mob/living/carbon/human/syndicate, visualsOnly = FALSE)
+/datum/outfit/lavaland_syndicate/post_equip(mob/living/carbon/human/syndicate, visuals_only = FALSE)
syndicate.faction |= ROLE_SYNDICATE
/datum/outfit/lavaland_syndicate/comms
diff --git a/code/modules/mod/mod_activation.dm b/code/modules/mod/mod_activation.dm
index 7da28c17a3a46..a9a793d8a2fd5 100644
--- a/code/modules/mod/mod_activation.dm
+++ b/code/modules/mod/mod_activation.dm
@@ -20,13 +20,15 @@
var/obj/item/part = locate(part_reference) in get_parts()
if(!istype(part) || user.incapacitated)
return
- if(active || activating)
- balloon_alert(user, "deactivate the suit first!")
+ if(activating)
+ balloon_alert(user, "currently [active ? "unsealing" : "sealing"]!")
playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
return
var/parts_to_check = parts - part
if(part.loc == src)
deploy(user, part)
+ if(active && !delayed_seal_part(part))
+ return
SEND_SIGNAL(src, COMSIG_MOD_DEPLOYED, user)
for(var/obj/item/checking_part as anything in parts_to_check)
if(checking_part.loc != src)
@@ -34,6 +36,8 @@
choose_deploy(user)
break
else
+ if(active && !delayed_seal_part(part))
+ return
retract(user, part)
SEND_SIGNAL(src, COMSIG_MOD_RETRACTED, user)
for(var/obj/item/checking_part as anything in parts_to_check)
@@ -44,8 +48,8 @@
/// Quickly deploys all parts (or retracts if all are on the wearer)
/obj/item/mod/control/proc/quick_deploy(mob/user)
- if(active || activating)
- balloon_alert(user, "deactivate the suit first!")
+ if(activating)
+ balloon_alert(user, "currently sealing/unsealing!")
playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
return FALSE
var/deploy = TRUE
@@ -57,7 +61,11 @@
for(var/obj/item/part as anything in get_parts())
if(deploy && part.loc == src)
deploy(null, part)
+ if(active && !delayed_seal_part(part))
+ return
else if(!deploy && part.loc != src)
+ if(active && !delayed_seal_part(part))
+ return
retract(null, part)
wearer.visible_message(span_notice("[wearer]'s [src] [deploy ? "deploys" : "retracts"] its parts with a mechanical hiss."),
span_notice("[src] [deploy ? "deploys" : "retracts"] its parts with a mechanical hiss."),
@@ -137,11 +145,6 @@
if(!force_deactivate && (SEND_SIGNAL(src, COMSIG_MOD_ACTIVATE, user) & MOD_CANCEL_ACTIVATE))
playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
return FALSE
- for(var/obj/item/part as anything in get_parts())
- if(!force_deactivate && part.loc == src)
- balloon_alert(user, "deploy all parts first!")
- playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
- return FALSE
if(locked && !active && !allowed(user) && !force_deactivate)
balloon_alert(user, "access insufficient!")
playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
@@ -166,29 +169,45 @@
activating = TRUE
mod_link.end_call()
to_chat(wearer, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
- for(var/obj/item/part as anything in get_parts())
- var/datum/mod_part/part_datum = get_part_datum(part)
- if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(get_wearer)), hidden = TRUE))
- to_chat(wearer, span_notice("[part] [active ? part_datum.unsealed_message : part_datum.sealed_message]."))
- playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- seal_part(part, is_sealed = !active)
+ //deploy the control unit
if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(get_wearer)), hidden = TRUE))
- to_chat(wearer, span_notice("Systems [active ? "shut down. Parts unsealed. Goodbye" : "started up. Parts sealed. Welcome"], [wearer]."))
- if(ai_assistant)
- to_chat(ai_assistant, span_notice("SYSTEMS [active ? "DEACTIVATED. GOODBYE" : "ACTIVATED. WELCOME"]: \"[ai_assistant]\""))
- finish_activation(is_on = !active)
- if(active)
- playsound(src, 'sound/machines/synth/synth_yes.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000)
- if(!malfunctioning)
- wearer.playsound_local(get_turf(src), 'sound/vehicles/mecha/nominal.ogg', 50)
- else
- playsound(src, 'sound/machines/synth/synth_no.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000)
+ playsound(src, active ? 'sound/machines/synth/synth_no.ogg' : 'sound/machines/synth/synth_yes.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 8000)
+ else
+ activating = FALSE
+ return
+
+ for(var/obj/item/part as anything in get_parts()) //seals/unseals all deployed parts
+ if(part.loc == src)
+ continue
+ delayed_seal_part(part, no_activation = TRUE)
+
+ //finish activation
+ to_chat(wearer, span_notice("Systems [active ? "shut down. Parts unsealed. Goodbye" : "started up. Parts sealed. Welcome"], [wearer]."))
+ if(ai_assistant)
+ to_chat(ai_assistant, span_notice("SYSTEMS [active ? "DEACTIVATED. GOODBYE" : "ACTIVATED. WELCOME"]: \"[ai_assistant]\""))
+ finish_activation(is_on = !active)
+ if(active)
+ playsound(src, 'sound/machines/synth/synth_yes.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000)
+ if(!malfunctioning)
+ wearer.playsound_local(get_turf(src), 'sound/vehicles/mecha/nominal.ogg', 50)
+ else
+ playsound(src, 'sound/machines/synth/synth_no.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000)
+
activating = FALSE
SEND_SIGNAL(src, COMSIG_MOD_TOGGLED, user)
return TRUE
+/obj/item/mod/control/proc/delayed_seal_part(obj/item/clothing/part, no_activation = FALSE)
+ . = FALSE
+ var/datum/mod_part/part_datum = get_part_datum(part)
+ if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(get_wearer)), hidden = TRUE))
+ to_chat(wearer, span_notice("[part] [!part_datum.sealed ? part_datum.sealed_message : part_datum.unsealed_message]."))
+ playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
+ seal_part(part, is_sealed = !part_datum.sealed, no_activation = no_activation)
+ return TRUE
+
///Seals or unseals the given part.
-/obj/item/mod/control/proc/seal_part(obj/item/clothing/part, is_sealed)
+/obj/item/mod/control/proc/seal_part(obj/item/clothing/part, is_sealed, no_activation = FALSE)
var/datum/mod_part/part_datum = get_part_datum(part)
part_datum.sealed = is_sealed
if(part_datum.sealed)
@@ -211,6 +230,22 @@
wearer.update_obscured_slots(part.visor_flags_inv)
if((part.clothing_flags & (MASKINTERNALS|HEADINTERNALS)) && wearer.invalid_internals())
wearer.cutoff_internals()
+ if(!active || no_activation)
+ return
+ // these only matter during sealing and unsealing while active via deployment
+ if(is_sealed)
+ for(var/obj/item/mod/module/module as anything in modules)
+ if(!module.has_required_parts(list("[part.slot_flags]" = part_datum), need_extended = TRUE))
+ continue
+ module.on_suit_activation()
+ else
+ for(var/obj/item/mod/module/module as anything in modules)
+ if(!module.has_required_parts(list("[part.slot_flags]" = part_datum), need_extended = TRUE))
+ continue
+ module.on_suit_deactivation()
+ if(!module.active || (module.allow_flags & MODULE_ALLOW_INACTIVE))
+ continue
+ module.deactivate(display_message = FALSE)
/// Finishes the suit's activation
/obj/item/mod/control/proc/finish_activation(is_on)
@@ -219,9 +254,13 @@
active = is_on
if(active)
for(var/obj/item/mod/module/module as anything in modules)
+ if(!module.has_required_parts(mod_parts, need_extended = TRUE))
+ continue
module.on_suit_activation()
else
for(var/obj/item/mod/module/module as anything in modules)
+ if(!module.has_required_parts(mod_parts, need_extended = TRUE)) //it probably will runtime if we dont do this
+ continue
module.on_suit_deactivation()
update_speed()
update_appearance(UPDATE_ICON_STATE)
diff --git a/code/modules/mod/mod_clothes.dm b/code/modules/mod/mod_clothes.dm
index 1c8ca8e5416c7..2eac9105c0a46 100644
--- a/code/modules/mod/mod_clothes.dm
+++ b/code/modules/mod/mod_clothes.dm
@@ -29,6 +29,7 @@
heat_protection = CHEST|GROIN
cold_protection = CHEST|GROIN
item_flags = IMMUTABLE_SLOW
+ drop_sound = null
/obj/item/clothing/gloves/mod
name = "MOD gauntlets"
@@ -42,6 +43,8 @@
heat_protection = HANDS|ARMS
cold_protection = HANDS|ARMS
item_flags = IMMUTABLE_SLOW
+ equip_sound = null
+ drop_sound = null
/obj/item/clothing/shoes/mod
name = "MOD boots"
diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm
index df2096ae367a4..21bf8509d6b99 100644
--- a/code/modules/mod/mod_control.dm
+++ b/code/modules/mod/mod_control.dm
@@ -219,6 +219,10 @@
/obj/item/mod/control/allow_attack_hand_drop(mob/user)
if(user != wearer)
return ..()
+ if(active)
+ balloon_alert(wearer, "deactivate the suit first!")
+ playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE)
+ return
for(var/obj/item/part as anything in get_parts())
if(part.loc != src)
balloon_alert(user, "retract parts first!")
@@ -228,6 +232,10 @@
/obj/item/mod/control/mouse_drop_dragged(atom/over_object, mob/user)
if(user != wearer || !istype(over_object, /atom/movable/screen/inventory/hand))
return
+ if(active)
+ balloon_alert(wearer, "deactivate the suit first!")
+ playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE)
+ return
for(var/obj/item/part as anything in get_parts())
if(part.loc != src)
balloon_alert(wearer, "retract parts first!")
@@ -575,7 +583,7 @@
new_module.on_install()
if(wearer)
new_module.on_equip()
- if(active)
+ if(active && new_module.has_required_parts(mod_parts, need_extended = TRUE))
new_module.on_suit_activation()
if(user)
balloon_alert(user, "[new_module] added")
@@ -679,8 +687,6 @@
part.forceMove(src)
return
retract(wearer, part)
- if(active)
- INVOKE_ASYNC(src, PROC_REF(toggle_activate), wearer, TRUE)
/obj/item/mod/control/proc/on_part_destruction(obj/item/part, damage_flag)
SIGNAL_HANDLER
diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm
index 76f9063df0b9c..664f9118b83a7 100644
--- a/code/modules/mod/mod_theme.dm
+++ b/code/modules/mod/mod_theme.dm
@@ -62,6 +62,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -203,6 +205,8 @@
SEALED_COVER = HEADCOVERSEYES,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
UNSEALED_MESSAGE = CHESTPLATE_UNSEAL_MESSAGE,
@@ -266,6 +270,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -334,6 +340,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -406,6 +414,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -480,6 +490,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT|HIDEBELT,
@@ -512,6 +524,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT|HIDEBELT,
@@ -588,6 +602,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
UNSEALED_MESSAGE = CHESTPLATE_UNSEAL_MESSAGE,
SEALED_MESSAGE = CHESTPLATE_SEAL_MESSAGE,
@@ -660,6 +676,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -693,6 +711,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -773,6 +793,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -845,6 +867,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -912,6 +936,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -979,6 +1005,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1052,6 +1080,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1120,6 +1150,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1195,6 +1227,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1228,6 +1262,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1301,6 +1337,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1376,6 +1414,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_INVISIBILITY = HIDEJUMPSUIT|HIDEMUTWINGS,
CAN_OVERSLOT = TRUE,
@@ -1461,6 +1501,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1531,6 +1573,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL|CASTING_CLOTHES,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1600,6 +1644,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1671,6 +1717,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1739,6 +1787,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1806,6 +1856,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1837,6 +1889,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1919,6 +1973,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -1988,6 +2044,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -2052,6 +2110,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -2118,6 +2178,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL,
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
@@ -2183,6 +2245,8 @@
SEALED_MESSAGE = HELMET_SEAL_MESSAGE,
),
/obj/item/clothing/suit/mod = list(
+ UNSEALED_LAYER = MOD_CHESTPLATE_LAYER,
+ SEALED_LAYER = MOD_CHESTPLATE_LAYER,
UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
SEALED_INVISIBILITY = HIDEJUMPSUIT,
UNSEALED_MESSAGE = CHESTPLATE_UNSEAL_MESSAGE,
diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm
index 6065a486d0c14..3055d0616f983 100644
--- a/code/modules/mod/modules/_module.dm
+++ b/code/modules/mod/modules/_module.dm
@@ -108,6 +108,16 @@
if(mod.wearer)
balloon_alert(mod.wearer, "not active!")
return
+ if(!has_required_parts(mod.mod_parts, need_extended = TRUE))
+ if(mod.wearer)
+ balloon_alert(mod.wearer, "required parts inactive!")
+ var/list/slot_strings = list()
+ for(var/slot in required_slots)
+ var/list/slot_list = parse_slot_flags(slot)
+ slot_strings += (length(slot_list) == 1 ? "" : "one of ") + english_list(slot_list, and_text = " or ")
+ to_chat(mod.wearer, span_warning("[src] requires these slots to be deployed: [english_list(slot_strings)]"))
+ playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
+ return
if(module_type != MODULE_USABLE)
if(active)
deactivate()
diff --git a/code/modules/mod/modules/modules_timeline.dm b/code/modules/mod/modules/modules_timeline.dm
index 522ddf57501d1..c14825bf3c70d 100644
--- a/code/modules/mod/modules/modules_timeline.dm
+++ b/code/modules/mod/modules/modules_timeline.dm
@@ -421,7 +421,7 @@
/obj/structure/chrono_field/singularity_act()
return
-/obj/structure/chrono_field/singularity_pull()
+/obj/structure/chrono_field/singularity_pull(atom/singularity, current_size)
return
/obj/structure/chrono_field/ex_act()
diff --git a/code/modules/modular_computers/file_system/programs/borg_monitor.dm b/code/modules/modular_computers/file_system/programs/borg_monitor.dm
index 90213963e3e64..0f9197272059f 100644
--- a/code/modules/modular_computers/file_system/programs/borg_monitor.dm
+++ b/code/modules/modular_computers/file_system/programs/borg_monitor.dm
@@ -161,7 +161,9 @@
if(computer.obj_flags & EMAGGED)
return "STDERR:UNDF"
return FALSE
- return ID.registered_name
+ . = "[ID.registered_name]"
+ if(ID.assignment)
+ . = "[.], [ID.assignment]"
/datum/computer_file/program/borg_monitor/syndicate
filename = "roboverlord"
diff --git a/code/modules/power/apc/apc_attack.dm b/code/modules/power/apc/apc_attack.dm
index a40af34fc2a85..3b786cfd199c9 100644
--- a/code/modules/power/apc/apc_attack.dm
+++ b/code/modules/power/apc/apc_attack.dm
@@ -1,8 +1,8 @@
// Ethereals:
/// How long it takes an ethereal to drain or charge APCs. Also used as a spam limiter.
-#define ETHEREAL_APC_DRAIN_TIME (7.5 SECONDS)
+#define ETHEREAL_APC_DRAIN_TIME (3 SECONDS)
/// How much power ethereals gain/drain from APCs.
-#define ETHEREAL_APC_POWER_GAIN (0.2 * STANDARD_BATTERY_CHARGE)
+#define ETHEREAL_APC_POWER_GAIN (10 * STANDARD_CELL_CHARGE)
/obj/machinery/power/apc/attack_hand_secondary(mob/user, list/modifiers)
. = ..()
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index fdfab1fed8462..a4cab5f991055 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -221,7 +221,7 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(
else
return FALSE
-/obj/structure/cable/singularity_pull(S, current_size)
+/obj/structure/cable/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct()
diff --git a/code/modules/power/pipecleaners.dm b/code/modules/power/pipecleaners.dm
index 4700004904796..a042c3c8cd657 100644
--- a/code/modules/power/pipecleaners.dm
+++ b/code/modules/power/pipecleaners.dm
@@ -154,7 +154,7 @@ By design, d1 is the smallest direction and d2 is the highest
/obj/structure/pipe_cleaner/attackby(obj/item/W, mob/user, params)
handlecable(W, user, params)
-/obj/structure/pipe_cleaner/singularity_pull(S, current_size)
+/obj/structure/pipe_cleaner/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct()
diff --git a/code/modules/power/supermatter/supermatter_variants.dm b/code/modules/power/supermatter/supermatter_variants.dm
index ebc21b2b5b09f..df01fe483f9b6 100644
--- a/code/modules/power/supermatter/supermatter_variants.dm
+++ b/code/modules/power/supermatter/supermatter_variants.dm
@@ -60,3 +60,27 @@
icon_state = "light"
pixel_x = -176
pixel_y = -176
+
+/// Normal sm but small (sm sword recipe element) (wiz only) and adamantine pedestal for it
+/obj/machinery/power/supermatter_crystal/small
+ name = "strangely small supermatter crystal"
+ desc = "A strangely translucent and iridescent crystal on an adamantine pedestal. It looks like it should be a bit bigger..."
+ base_icon_state = "sm_small"
+ icon_state = "sm_small"
+ moveable = TRUE
+ anchored = FALSE
+
+/obj/machinery/power/supermatter_crystal/small/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/gps, "Adamantium Signal")
+ priority_announce("Anomalous crystal detected onboard. Location is marked on every GPS device.", "Nanotrasen Anomaly Department Announcement")
+
+/obj/item/adamantine_pedestal
+ name = "adamantine pedestal"
+ desc = "An adamantine pedestal. It looks like it should have something small but massive on top."
+ icon = 'icons/obj/machines/engine/supermatter.dmi'
+ icon_state = "pedestal"
+ w_class = WEIGHT_CLASS_HUGE
+ throw_speed = 1
+ throw_range = 1
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index d36b66eac7ffe..355221eab8620 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -197,7 +197,7 @@
wound_bonus = -40
bare_wound_bonus = 70
-/obj/projectile/beam/emitter/singularity_pull()
+/obj/projectile/beam/emitter/singularity_pull(atom/singularity, current_size)
return //don't want the emitters to miss
/obj/projectile/beam/emitter/hitscan
diff --git a/code/modules/projectiles/projectile/energy/net_snare.dm b/code/modules/projectiles/projectile/energy/net_snare.dm
index ae05a9eb85d7e..db3805c6ba87e 100644
--- a/code/modules/projectiles/projectile/energy/net_snare.dm
+++ b/code/modules/projectiles/projectile/energy/net_snare.dm
@@ -52,7 +52,7 @@
/obj/effect/nettingportal/singularity_act()
return
-/obj/effect/nettingportal/singularity_pull()
+/obj/effect/nettingportal/singularity_pull(atom/singularity, current_size)
return
/obj/item/dragnet_beacon
diff --git a/code/modules/projectiles/projectile/energy/thermal.dm b/code/modules/projectiles/projectile/energy/thermal.dm
index 7b1319e117a9e..dbe78c70f5a2b 100644
--- a/code/modules/projectiles/projectile/energy/thermal.dm
+++ b/code/modules/projectiles/projectile/energy/thermal.dm
@@ -15,6 +15,9 @@
if(!ishuman(target))
return
+ if(HAS_TRAIT(target, TRAIT_RESISTCOLD))
+ return
+
var/mob/living/carbon/cold_target = target
var/how_cold_is_target = cold_target.bodytemperature
var/danger_zone = cold_target.dna.species.bodytemp_cold_damage_limit - 150
@@ -40,6 +43,9 @@
if(!ishuman(target))
return
+ if(HAS_TRAIT(target, TRAIT_RESISTHEAT))
+ return
+
var/mob/living/carbon/hot_target = target
var/how_hot_is_target = hot_target.bodytemperature
var/danger_zone = hot_target.dna.species.bodytemp_heat_damage_limit + 300
diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
index fa869cb267a57..fcc428df9b629 100644
--- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
@@ -97,19 +97,14 @@
/datum/reagent/consumable/ethanol/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)//Splashing people with ethanol isn't quite as good as fuel.
. = ..()
- if(!(methods & (TOUCH|VAPOR|PATCH)))
- return
-
- exposed_mob.adjust_fire_stacks(reac_volume / 15)
-
- if(!iscarbon(exposed_mob))
- return
-
- var/mob/living/carbon/exposed_carbon = exposed_mob
- var/power_multiplier = boozepwr / 65 // Weak alcohol has less sterilizing power
+ if(methods & INGEST)
+ exposed_mob.check_allergic_reaction(ALCOHOL, chance = reac_volume * 5, histamine_add = min(10, reac_volume))
- for(var/datum/surgery/surgery as anything in exposed_carbon.surgeries)
- surgery.speed_modifier = max(0.1 * power_multiplier, surgery.speed_modifier)
+ if(methods & (TOUCH|VAPOR|PATCH))
+ exposed_mob.adjust_fire_stacks(reac_volume / 15)
+ var/power_multiplier = boozepwr / 65 // Weak alcohol has less sterilizing power
+ for(var/datum/surgery/surgery as anything in exposed_mob.surgeries)
+ surgery.speed_modifier = max(0.1 * power_multiplier, surgery.speed_modifier)
/datum/reagent/consumable/ethanol/beer
name = "Beer"
@@ -2660,7 +2655,7 @@
var/mob/living/carbon/exposed_carbon = exposed_mob
var/obj/item/organ/internal/stomach/ethereal/stomach = exposed_carbon.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
- stomach.adjust_charge(reac_volume * 0.003 * ETHEREAL_CHARGE_NORMAL)
+ stomach.adjust_charge(reac_volume * 0.02 * ETHEREAL_CHARGE_NORMAL)
/datum/reagent/consumable/ethanol/telepole
name = "Telepole"
@@ -2680,7 +2675,7 @@
var/mob/living/carbon/exposed_carbon = exposed_mob
var/obj/item/organ/internal/stomach/ethereal/stomach = exposed_carbon.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
- stomach.adjust_charge(reac_volume * 0.002 * ETHEREAL_CHARGE_NORMAL)
+ stomach.adjust_charge(reac_volume * 0.05 * ETHEREAL_CHARGE_NORMAL)
/datum/reagent/consumable/ethanol/pod_tesla
name = "Pod Tesla"
@@ -2707,7 +2702,7 @@
var/mob/living/carbon/exposed_carbon = exposed_mob
var/obj/item/organ/internal/stomach/ethereal/stomach = exposed_carbon.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
- stomach.adjust_charge(reac_volume * 0.005 * ETHEREAL_CHARGE_NORMAL)
+ stomach.adjust_charge(reac_volume * 0.1 * ETHEREAL_CHARGE_NORMAL)
// Welcome to the Blue Room Bar and Grill, home to Mars' finest cocktails
/datum/reagent/consumable/ethanol/rice_beer
diff --git a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm
index 2aa0fd3ace550..cb400e9ac7dae 100644
--- a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm
@@ -1291,4 +1291,4 @@
var/mob/living/carbon/exposed_carbon = exposed_mob
var/obj/item/organ/internal/stomach/ethereal/stomach = exposed_carbon.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
- stomach.adjust_charge(reac_volume * 0.003 * ETHEREAL_CHARGE_NORMAL)
+ stomach.adjust_charge(reac_volume * 0.02 * ETHEREAL_CHARGE_NORMAL)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index c41ab8ffca521..5bb978e628192 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -302,6 +302,11 @@
. = ..()
affected_mob.adjust_drowsiness_up_to((5 SECONDS * REM * seconds_per_tick), 60 SECONDS)
+/datum/reagent/consumable/sugar/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(methods & INGEST)
+ exposed_mob.check_allergic_reaction(SUGAR, chance = reac_volume * 10, histamine_add = min(10, reac_volume * 2))
+
/datum/reagent/consumable/virus_food
name = "Virus Food"
description = "A mixture of water and milk. Virus cells can use this mixture to reproduce."
@@ -1008,6 +1013,11 @@
reagent_state = SOLID
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+/datum/reagent/consumable/caramel/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(methods & INGEST)
+ exposed_mob.check_allergic_reaction(SUGAR, chance = reac_volume * 10, histamine_add = min(10, reac_volume * 2))
+
/datum/reagent/consumable/char
name = "Char"
description = "Essence of the grill. Has strange properties when overdosed."
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 14a592aa685f4..b0e35f9f23aa6 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -2931,8 +2931,10 @@
/datum/reagent/ants/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
- if(!iscarbon(exposed_mob) || (methods & (INGEST|INJECT)))
+ if(!iscarbon(exposed_mob))
return
+ if(methods & INGEST)
+ exposed_mob.check_allergic_reaction(BUGS, chance = reac_volume * 10, histamine_add = min(10, reac_volume))
if(methods & (PATCH|TOUCH|VAPOR))
amount_left = round(reac_volume,0.1)
exposed_mob.apply_status_effect(status_effect, amount_left)
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 77e1ef3903992..36c17e6f04ac7 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -301,5 +301,5 @@
/obj/item/reagent_containers/equipped(mob/user, slot, initial = FALSE)
. = ..()
- if((slot & ITEM_SLOT_HANDS) && reagent_container_liquid_sound && reagents.total_volume > 0)
+ if(!initial && (slot & ITEM_SLOT_HANDS) && reagent_container_liquid_sound && reagents.total_volume > 0)
playsound(src, reagent_container_liquid_sound, LIQUID_SLOSHING_SOUND_VOLUME, vary = TRUE, ignore_walls = FALSE)
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 1d1354e865dbc..e23bfc8d0a330 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -96,7 +96,7 @@
stored = null
deconstruct(FALSE)
-/obj/machinery/disposal/singularity_pull(S, current_size)
+/obj/machinery/disposal/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct()
diff --git a/code/modules/recycling/disposal/pipe.dm b/code/modules/recycling/disposal/pipe.dm
index b08323e66e4aa..ace39e55c8a53 100644
--- a/code/modules/recycling/disposal/pipe.dm
+++ b/code/modules/recycling/disposal/pipe.dm
@@ -189,7 +189,7 @@
pipe.setDir(dir)
spew_forth()
-/obj/structure/disposalpipe/singularity_pull(S, current_size)
+/obj/structure/disposalpipe/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct()
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index bf6e81a955760..b853d949d464c 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -73,7 +73,7 @@
/obj/docking_port/take_damage(damage_amount, damage_type = BRUTE, damage_flag = "", sound_effect = TRUE, attack_dir, armour_penetration = 0)
return
-/obj/docking_port/singularity_pull()
+/obj/docking_port/singularity_pull(atom/singularity, current_size)
return
/obj/docking_port/singularity_act()
diff --git a/code/modules/spells/spell_types/self/spacetime_distortion.dm b/code/modules/spells/spell_types/self/spacetime_distortion.dm
index 976d83e8a30a8..80cb605cb472f 100644
--- a/code/modules/spells/spell_types/self/spacetime_distortion.dm
+++ b/code/modules/spells/spell_types/self/spacetime_distortion.dm
@@ -115,7 +115,7 @@
/obj/effect/cross_action/singularity_act()
return
-/obj/effect/cross_action/singularity_pull()
+/obj/effect/cross_action/singularity_pull(atom/singularity, current_size)
return
/obj/effect/cross_action/spacetime_dist/Initialize(mapload, flags = MAGIC_RESISTANCE)
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index cce8935f80349..30c841147a708 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -43,6 +43,8 @@
var/hair_alpha = 255
/// Is the hair currently hidden by something?
var/hair_hidden = FALSE
+ /// Lazy initialized hashset of all hair masks that should be applied
+ var/list/hair_masks
///Facial hair style
var/facial_hairstyle = "Shaved"
diff --git a/code/modules/surgery/bodyparts/head_hair_and_lips.dm b/code/modules/surgery/bodyparts/head_hair_and_lips.dm
index 7f81a615f3555..861076e184b7c 100644
--- a/code/modules/surgery/bodyparts/head_hair_and_lips.dm
+++ b/code/modules/surgery/bodyparts/head_hair_and_lips.dm
@@ -8,12 +8,15 @@
//HIDDEN CHECKS START
hair_hidden = FALSE
facial_hair_hidden = FALSE
+ LAZYNULL(hair_masks)
if(human_head_owner)
for(var/obj/item/worn_item in human_head_owner.get_equipped_items())
if(worn_item.flags_inv & HIDEHAIR)
hair_hidden = TRUE
if(worn_item.flags_inv & HIDEFACIALHAIR)
facial_hair_hidden = TRUE
+ if(worn_item.hair_mask)
+ LAZYSET(hair_masks, worn_item.hair_mask, TRUE)
//invisibility and husk stuff
if(HAS_TRAIT(human_head_owner, TRAIT_INVISIBLE_MAN) || HAS_TRAIT(human_head_owner, TRAIT_HUSK))
hair_hidden = TRUE
@@ -99,15 +102,24 @@
var/facial_hair_gradient_style = gradient_styles[GRADIENT_FACIAL_HAIR_KEY]
if(facial_hair_gradient_style != "None")
var/facial_hair_gradient_color = gradient_colors[GRADIENT_FACIAL_HAIR_KEY]
- var/image/facial_hair_gradient_overlay = get_gradient_overlay(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER, SSaccessories.facial_hair_gradients_list[facial_hair_gradient_style], facial_hair_gradient_color, image_dir)
+ var/image/facial_hair_gradient_overlay = get_gradient_overlay(icon(sprite_accessory.icon, sprite_accessory.icon_state), -HAIR_LAYER, SSaccessories.facial_hair_gradients_list[facial_hair_gradient_style], facial_hair_gradient_color, image_dir)
. += facial_hair_gradient_overlay
var/image/hair_overlay
if(!(show_debrained && (head_flags & HEAD_DEBRAIN)) && !hair_hidden && hairstyle && (head_flags & HEAD_HAIR))
var/datum/sprite_accessory/hair/hair_sprite_accessory = SSaccessories.hairstyles_list[hairstyle]
if(hair_sprite_accessory)
+ var/icon/base_icon
+ if(LAZYLEN(hair_masks))
+ base_icon = icon(hair_sprite_accessory.icon, hair_sprite_accessory.icon_state)
+ for(var/mask in hair_masks)
+ var/icon/blend_with = icon('icons/mob/human/hair_masks.dmi', mask)
+ blend_with.Shift(SOUTH, hair_sprite_accessory.y_offset)
+ base_icon.Blend(blend_with, ICON_ADD)
+ else
+ base_icon = icon(hair_sprite_accessory.icon, hair_sprite_accessory.icon_state)
//Overlay
- hair_overlay = image(hair_sprite_accessory.icon, hair_sprite_accessory.icon_state, -HAIR_LAYER, image_dir)
+ hair_overlay = image(base_icon, layer=-HAIR_LAYER, dir=image_dir)
hair_overlay.alpha = hair_alpha
hair_overlay.pixel_y = hair_sprite_accessory.y_offset
//Emissive blocker
@@ -120,7 +132,7 @@
var/hair_gradient_style = gradient_styles[GRADIENT_HAIR_KEY]
if(hair_gradient_style != "None")
var/hair_gradient_color = gradient_colors[GRADIENT_HAIR_KEY]
- var/image/hair_gradient_overlay = get_gradient_overlay(hair_sprite_accessory.icon, hair_sprite_accessory.icon_state, -HAIR_LAYER, SSaccessories.hair_gradients_list[hair_gradient_style], hair_gradient_color, image_dir)
+ var/image/hair_gradient_overlay = get_gradient_overlay(base_icon, -HAIR_LAYER, SSaccessories.hair_gradients_list[hair_gradient_style], hair_gradient_color, image_dir)
hair_gradient_overlay.pixel_y = hair_sprite_accessory.y_offset
. += hair_gradient_overlay
@@ -184,12 +196,12 @@
return eyeless_overlay
/// Returns an appropriate hair/facial hair gradient overlay
-/obj/item/bodypart/head/proc/get_gradient_overlay(file, icon, layer, datum/sprite_accessory/gradient, grad_color, image_dir)
+/obj/item/bodypart/head/proc/get_gradient_overlay(icon/base_icon, layer, datum/sprite_accessory/gradient, grad_color, image_dir)
RETURN_TYPE(/mutable_appearance)
var/mutable_appearance/gradient_overlay = mutable_appearance(layer = layer)
var/icon/temp = icon(gradient.icon, gradient.icon_state, image_dir)
- var/icon/temp_hair = icon(file, icon, image_dir)
+ var/icon/temp_hair = icon(base_icon, dir=image_dir)
temp.Blend(temp_hair, ICON_ADD)
gradient_overlay.icon = temp
gradient_overlay.color = grad_color
diff --git a/code/modules/transport/tram/tram_structures.dm b/code/modules/transport/tram/tram_structures.dm
index bdea433a9c925..346cb5e680283 100644
--- a/code/modules/transport/tram/tram_structures.dm
+++ b/code/modules/transport/tram/tram_structures.dm
@@ -145,7 +145,7 @@
/obj/structure/tram/narsie_act()
add_atom_colour(NARSIE_WINDOW_COLOUR, FIXED_COLOUR_PRIORITY)
-/obj/structure/tram/singularity_pull(singulo, current_size)
+/obj/structure/tram/singularity_pull(atom/singularity, current_size)
..()
if(current_size >= STAGE_FIVE)
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index 46461a23a3d6a..0b268b4416648 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -160,6 +160,7 @@
#include "heretic_knowledge.dm"
#include "heretic_rituals.dm"
#include "high_five.dm"
+#include "holder_loving.dm"
#include "holidays.dm"
#include "hulk.dm"
#include "human_through_recycler.dm"
diff --git a/code/modules/unit_tests/holder_loving.dm b/code/modules/unit_tests/holder_loving.dm
new file mode 100644
index 0000000000000..6799cb228daa6
--- /dev/null
+++ b/code/modules/unit_tests/holder_loving.dm
@@ -0,0 +1,31 @@
+/datum/unit_test/holder_loving
+
+/datum/unit_test/holder_loving/Run()
+ var/mob/living/carbon/human/consistent/person = allocate(/mob/living/carbon/human/consistent)
+ var/obj/item/storage/backpack/duffelbag/bag = allocate(/obj/item/storage/backpack/duffelbag)
+ var/obj/item/storage/backpack/duffelbag/testbag = allocate(/obj/item/storage/backpack/duffelbag)
+ var/obj/item/wrench/tool = allocate(/obj/item/wrench)
+
+ //put wrench in bag & equip bag on human
+ tool.AddComponent(/datum/component/holderloving, bag)
+ bag.atom_storage.attempt_insert(tool, person, messages = FALSE)
+ person.equip_to_slot_if_possible(bag, ITEM_SLOT_BACK)
+
+ //Test 1: Should be able to move wrench from bag to hand
+ person.putItemFromInventoryInHandIfPossible(tool, 1)
+ TEST_ASSERT_EQUAL(person.get_item_for_held_index(1), tool, "Holder loving component blocked equiping wrench from storage into hand!")
+
+ //Test 2: Should be able to swap the item between hands
+ person.swap_hand(2, silent = TRUE)
+ tool.attempt_pickup(person)
+ TEST_ASSERT_EQUAL(person.get_item_for_held_index(2), tool, "Holder loving component blocked swapping the wrench into the other hand!")
+
+ //Test 3: Upon dropping the item onto the ground it should move back into the bag
+ person.dropItemToGround(tool, silent = TRUE)
+ TEST_ASSERT_NOTNULL(locate(/obj/item/wrench) in bag, "Holder loving component did not move the wrench back into storage upon dropping!")
+
+ //Test 4: Should not be able to move the wrench into any other atom besides its holder
+ TEST_ASSERT(!person.transferItemToLoc(tool, testbag), "Holder loving component failed to block moving the wrench into another atom that isn't the holder!")
+
+ //Test 5: Should fail at the signal checks
+ TEST_ASSERT(!person.temporarilyRemoveItemFromInventory(tool, newloc = testbag), "Holder loving component failed to block temporarily removing wrench and moving it into another atom that isn't the holder!")
diff --git a/code/modules/unit_tests/screenshot_humanoids.dm b/code/modules/unit_tests/screenshot_humanoids.dm
index 1b7e39f03bb14..6edaadb0e714d 100644
--- a/code/modules/unit_tests/screenshot_humanoids.dm
+++ b/code/modules/unit_tests/screenshot_humanoids.dm
@@ -23,7 +23,7 @@
moth.dna.features["moth_markings"] = "None"
moth.dna.features["moth_wings"] = "Firewatch"
moth.set_species(/datum/species/moth)
- moth.equipOutfit(/datum/outfit/job/cmo, visualsOnly = TRUE)
+ moth.equipOutfit(/datum/outfit/job/cmo, visuals_only = TRUE)
test_screenshot("[/datum/species/moth]", get_flat_icon_for_all_directions(moth))
testable_species -= /datum/species/moth
@@ -45,5 +45,5 @@
/datum/unit_test/screenshot_humanoids/proc/make_dummy(species, job_outfit)
var/mob/living/carbon/human/dummy/consistent/dummy = allocate(/mob/living/carbon/human/dummy/consistent)
dummy.set_species(species)
- dummy.equipOutfit(job_outfit, visualsOnly = TRUE)
+ dummy.equipOutfit(job_outfit, visuals_only = TRUE)
return dummy
diff --git a/code/modules/unit_tests/screenshot_saturnx.dm b/code/modules/unit_tests/screenshot_saturnx.dm
index 771ea278e3247..2183f0e66eadc 100644
--- a/code/modules/unit_tests/screenshot_saturnx.dm
+++ b/code/modules/unit_tests/screenshot_saturnx.dm
@@ -3,7 +3,7 @@
/datum/unit_test/screenshot_saturnx/Run()
var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human/dummy/consistent) //we don't use a dummy as they have no organs
- human.equipOutfit(/datum/outfit/job/assistant/consistent, visualsOnly = TRUE)
+ human.equipOutfit(/datum/outfit/job/assistant/consistent, visuals_only = TRUE)
var/datum/reagent/drug/saturnx/saturnx_reagent = new()
diff --git a/code/modules/visuals/render_steps.dm b/code/modules/visuals/render_steps.dm
index e29436596c6e5..e9cfbf3b5562c 100644
--- a/code/modules/visuals/render_steps.dm
+++ b/code/modules/visuals/render_steps.dm
@@ -29,7 +29,7 @@
/atom/movable/render_step/singularity_act()
return
-/atom/movable/render_step/singularity_pull()
+/atom/movable/render_step/singularity_pull(atom/singularity, current_size)
return
/atom/movable/render_step/blob_act()
diff --git a/html/changelogs/AutoChangeLog-pr-87097.yml b/html/changelogs/AutoChangeLog-pr-87097.yml
deleted file mode 100644
index 4cbd5f905cfa1..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-87097.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Absolucy"
-delete-after: True
-changes:
- - rscadd: "Added a separate preference for hearing vocal AI announcements (also known as VOX), as opposed to lumping it into the \"Enable announcement sounds\" preference."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87231.yml b/html/changelogs/AutoChangeLog-pr-87231.yml
new file mode 100644
index 0000000000000..3b5a7657054db
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87231.yml
@@ -0,0 +1,4 @@
+author: "WebcomicArtist"
+delete-after: True
+changes:
+ - bugfix: "Un-breaks etherial apc charging and charge from ethereal wine."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87232.yml b/html/changelogs/AutoChangeLog-pr-87232.yml
new file mode 100644
index 0000000000000..941d66ddf52eb
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87232.yml
@@ -0,0 +1,4 @@
+author: "MelokGleb and KREKS"
+delete-after: True
+changes:
+ - rscadd: "very hard wiz-only sm sword craft"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87289.yml b/html/changelogs/AutoChangeLog-pr-87289.yml
new file mode 100644
index 0000000000000..46b0cab527be4
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87289.yml
@@ -0,0 +1,4 @@
+author: "necromanceranne"
+delete-after: True
+changes:
+ - balance: "Shock touch is now less-than-lethal, dealing a decent amount of stamina damage at the cost of lethal damage. Lower cooldown. Power chromosome makes it force a stagger rather than cause a chain lightning effect (this used to do like only 5 damage so...)"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87392.yml b/html/changelogs/AutoChangeLog-pr-87392.yml
new file mode 100644
index 0000000000000..b72a4ef3eb4e6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87392.yml
@@ -0,0 +1,8 @@
+author: "Melbert"
+delete-after: True
+changes:
+ - rscadd: "Drinking any ethanol (beer, wine, etc) will trigger alcohol allergies"
+ - rscadd: "Drinking ants will trigger Bug allergies"
+ - rscadd: "Getting stung by a bee, or bitten by a (giant) ant or (giant) spider, will trigger bug allergies"
+ - rscadd: "Drinking plain sugar or caramel will trigger sugar allergies"
+ - qol: "Ethanol can speed up the surgeries of any mob type applied to, rather than solely humans."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87424.yml b/html/changelogs/AutoChangeLog-pr-87424.yml
new file mode 100644
index 0000000000000..4974aa7d4d64d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87424.yml
@@ -0,0 +1,4 @@
+author: "grungussuss"
+delete-after: True
+changes:
+ - sound: "radio noise will no longer play on the common channel"
\ No newline at end of file
diff --git a/html/changelogs/archive/2024-10.yml b/html/changelogs/archive/2024-10.yml
index e44c215bd1042..317e679e0b44d 100644
--- a/html/changelogs/archive/2024-10.yml
+++ b/html/changelogs/archive/2024-10.yml
@@ -705,3 +705,79 @@
zxaber:
- balance: Borgs and AIs can now access dropped PDAs. The Messenger app does not
work over a remote connection, however.
+2024-10-25:
+ Absolucy:
+ - rscadd: Added a separate preference for hearing vocal AI announcements (also known
+ as VOX), as opposed to lumping it into the "Enable announcement sounds" preference.
+ - refactor: Refactored some text helper procs to use BYOND's native text trimming
+ proc.
+ - admin: Added a _trimtext proc, for use with SDQL2 or Lua scripting.
+ Ben10Omintrix:
+ - rscadd: penguins will now fish from water holes
+ - bugfix: fixes ai controllers resetting their targets post do_afters
+ - bugfix: stationary medbots no longer search for patrol beacons
+ Cruix:
+ - rscadd: Hardhats now squish down excessively tall hairstyles while being worn.
+ DaCoolBoss:
+ - bugfix: Donk-Rolls no longer turn into Deluxe Donk Pockets when microwaved.
+ DaydreamIQ:
+ - map: Moved Birdshot's drone dispenser closer to robotics
+ Fikou:
+ - bugfix: bouncy castles no longer render under the gibs they spawn
+ - qol: suit storage units can hold backpacks in the modsuit slot
+ - bugfix: teleport turrets are no longer magical and will not be stopped by antimagic
+ JackEnoff:
+ - bugfix: MetaStation's Cargo Security Outpost is no longer free to access by anyone.
+ Profakos:
+ - rscadd: Adds a roboticist spraycan, and adds one of them to robotics on every
+ map
+ - qol: adds a screentip to spraycans that tells you that it can restyle robotic
+ limbs
+ - bugfix: fixes peg legs bringing up the augment restyle menu
+ - bugfix: if an outfit puts a reagent container in the preview dummy's hand, it
+ will not try to slosh
+ - code_imp: outfits putting items in your hand will respect the visual_only argument
+ Sealed101:
+ - bugfix: fixed akimbo firing automatic guns runtiming on the offhand gun when it's
+ empty, possibly causing dry fire clicks to not play
+ - bugfix: fixed nuclear devices not showing the overlays for deconstruction states
+ and lights for arming state properly
+ - qol: more examine feedback for nuclear devices (deconstruction/arming state)
+ SmArtKar:
+ - rscadd: You can now lean on windows the same way you can lean on walls
+ - bugfix: You no longer stop leaning on walls after clicking on anything
+ - bugfix: Rustle component no longer counts diagonal steps as two moves
+ - qol: Improved descriptions on size tooltips to explain where the item can be stored
+ - qol: Made scanner gate scanlines mouse transparent
+ - bugfix: Scanner gate scanlines no longer appear only after someone walks through
+ them and are disabled when the gate is unpowered
+ - sound: Removed MOD chestplate and glove equip/drop sounds
+ SyncIt21:
+ - refactor: cleaned up how drone holds their tools from the toolbox. report bugs
+ on github
+ carlarctg:
+ - bugfix: Silver extract food now transfers its slime trait to any processed slices
+ grungussuss:
+ - sound: 'reduced volume of: lightningbolt, lightningshock, lightning_chargeup sounds'
+ - qol: getting cocooned gives a better warning
+ - sound: ambience no longer gets cut off for ghosts
+ - sound: radio noise will no longer be heard in hard crit
+ - sound: AI controlled mobs will no longer make sounds that ignore walls
+ larentoun:
+ - rscadd: Evidence Bag is now considered a storage container with 1 slot. Allows
+ to use all features storage has, such as drag-and-drop the bag onto a table.
+ - rscadd: Using Evidence Bag in hand now drops the item on the ground instead of
+ putting it in your hands. Don't mess with the evidence!
+ - qol: Detective's scanner can now scan items on your person. You can now pick up
+ an evidence bag, open it like any other container, and scan the item inside
+ without removing it
+ mc-oofert:
+ - balance: you no longer need all parts deployed to activate a modsuit, you can
+ use them limbless
+ necromanceranne:
+ - bugfix: Nanite projectiles respect a targets immunity to any temperature effects
+ that the bullet might look for (cold immune targets against inferno bullets/heat
+ immune targets against cold bullets)
+ zxaber:
+ - rscadd: Borgs now get the job title of someone sending them a message through
+ SiliConnect.
diff --git a/icons/area/areas_ruins.dmi b/icons/area/areas_ruins.dmi
index 2b25401250b20..7a559ee6cf6c5 100644
Binary files a/icons/area/areas_ruins.dmi and b/icons/area/areas_ruins.dmi differ
diff --git a/icons/mob/clothing/modsuit/mod_clothing.dmi b/icons/mob/clothing/modsuit/mod_clothing.dmi
index aa9b6feca11af..071db6ba93ca8 100644
Binary files a/icons/mob/clothing/modsuit/mod_clothing.dmi and b/icons/mob/clothing/modsuit/mod_clothing.dmi differ
diff --git a/icons/mob/human/hair_masks.dmi b/icons/mob/human/hair_masks.dmi
new file mode 100644
index 0000000000000..45ecb761d9a54
Binary files /dev/null and b/icons/mob/human/hair_masks.dmi differ
diff --git a/icons/obj/art/crayons.dmi b/icons/obj/art/crayons.dmi
index dd686329a1471..26f601f454a50 100644
Binary files a/icons/obj/art/crayons.dmi and b/icons/obj/art/crayons.dmi differ
diff --git a/icons/obj/machines/engine/supermatter.dmi b/icons/obj/machines/engine/supermatter.dmi
index 12b6aff39f638..0a68846715e4c 100644
Binary files a/icons/obj/machines/engine/supermatter.dmi and b/icons/obj/machines/engine/supermatter.dmi differ
diff --git a/icons/obj/weapons/sword.dmi b/icons/obj/weapons/sword.dmi
index 9464c7b474585..d6a1309731372 100644
Binary files a/icons/obj/weapons/sword.dmi and b/icons/obj/weapons/sword.dmi differ
diff --git a/sound/effects/magic/lightning_chargeup.ogg b/sound/effects/magic/lightning_chargeup.ogg
index 4a825b086cc1f..b273cc42c49aa 100644
Binary files a/sound/effects/magic/lightning_chargeup.ogg and b/sound/effects/magic/lightning_chargeup.ogg differ
diff --git a/sound/effects/magic/lightningbolt.ogg b/sound/effects/magic/lightningbolt.ogg
index 8f1746cc46103..87d275ab9fecf 100644
Binary files a/sound/effects/magic/lightningbolt.ogg and b/sound/effects/magic/lightningbolt.ogg differ
diff --git a/sound/effects/magic/lightningshock.ogg b/sound/effects/magic/lightningshock.ogg
index 568dc256f25af..a28b843185316 100644
Binary files a/sound/effects/magic/lightningshock.ogg and b/sound/effects/magic/lightningshock.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index f0cbf0c404703..ef121e8707149 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -929,6 +929,7 @@
#include "code\datums\ai\basic_mobs\basic_subtrees\find_paper_and_write.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\find_parent.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\find_targets_prioritize_traits.dm"
+#include "code\datums\ai\basic_mobs\basic_subtrees\fishing.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\flee_target.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\go_for_swim.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\maintain_distance.dm"
@@ -1158,6 +1159,7 @@
#include "code\datums\components\jukebox.dm"
#include "code\datums\components\keep_me_secure.dm"
#include "code\datums\components\knockoff.dm"
+#include "code\datums\components\leanable.dm"
#include "code\datums\components\leash.dm"
#include "code\datums\components\life_link.dm"
#include "code\datums\components\light_eater.dm"
@@ -1427,6 +1429,7 @@
#include "code\datums\elements\attack_zone_randomiser.dm"
#include "code\datums\elements\backblast.dm"
#include "code\datums\elements\bane.dm"
+#include "code\datums\elements\basic_allergenic_attack.dm"
#include "code\datums\elements\basic_eating.dm"
#include "code\datums\elements\basic_health_examine.dm"
#include "code\datums\elements\beauty.dm"
@@ -4972,7 +4975,6 @@
#include "code\modules\mob\living\basic\minebots\minebot_remote_control.dm"
#include "code\modules\mob\living\basic\minebots\minebot_upgrades.dm"
#include "code\modules\mob\living\basic\pets\fox.dm"
-#include "code\modules\mob\living\basic\pets\penguin.dm"
#include "code\modules\mob\living\basic\pets\pet.dm"
#include "code\modules\mob\living\basic\pets\pet_designer.dm"
#include "code\modules\mob\living\basic\pets\sloth.dm"
@@ -5001,6 +5003,8 @@
#include "code\modules\mob\living\basic\pets\parrot\parrot_ai\parrot_hoarding.dm"
#include "code\modules\mob\living\basic\pets\parrot\parrot_ai\parrot_perching.dm"
#include "code\modules\mob\living\basic\pets\parrot\parrot_ai\parroting_action.dm"
+#include "code\modules\mob\living\basic\pets\penguin\penguin.dm"
+#include "code\modules\mob\living\basic\pets\penguin\penguin_ai.dm"
#include "code\modules\mob\living\basic\pets\pet_cult\pet_cult_abilities.dm"
#include "code\modules\mob\living\basic\pets\pet_cult\pet_cult_ai.dm"
#include "code\modules\mob\living\basic\ruin_defender\cybersun_aicore.dm"