diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 6c1642ca8b..452a080be0 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -57072,7 +57072,7 @@
/turf/open/floor/plating,
/area/space)
"sRH" = (
-/obj/machinery/autolathe{
+/obj/machinery/autolathe/secure{
name = "public autolathe"
},
/turf/open/floor/plasteel,
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 1abdd85019..13597584ae 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -34904,7 +34904,7 @@
/obj/effect/turf_decal/tile/brown{
dir = 8
},
-/obj/machinery/autolathe{
+/obj/machinery/autolathe/secure{
name = "public autolathe"
},
/turf/open/floor/plasteel,
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 1be18fdfeb..3c8e251bb1 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -31856,7 +31856,7 @@
/obj/effect/turf_decal/tile/brown{
dir = 8
},
-/obj/machinery/autolathe{
+/obj/machinery/autolathe/secure{
name = "public autolathe"
},
/turf/open/floor/plasteel,
diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm
index 72f68910f7..13dd939ad7 100644
--- a/_maps/map_files/Mining/Lavaland.dmm
+++ b/_maps/map_files/Mining/Lavaland.dmm
@@ -77,6 +77,27 @@
"aA" = (
/turf/open/lava/smooth/lava_land_surface,
/area/template_noop)
+"aQ" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"aU" = (
+/obj/structure/stone_tile/block/cracked,
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/item/t_scanner/adv_mining_scanner/lesser,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"cp" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"cu" = (
/obj/item/pickaxe,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
@@ -85,6 +106,106 @@
/obj/structure/ore_box,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"cw" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/blood,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"dA" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"dD" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"dF" = (
+/obj/structure/stone_tile/block/cracked,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"dM" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eb" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/machinery/iv_drip,
+/obj/item/reagent_containers/glass/beaker/waterbottle/large,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eh" = (
+/obj/structure/stone_tile/slab/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eo" = (
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eq" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eP" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eQ" = (
+/obj/structure/closet/crate/radiation,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/flare,
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"ft" = (
+/obj/structure/stone_tile/block,
+/obj/item/twohanded/bonespear,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"fN" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/item/twohanded/bonespear,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"fQ" = (
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors/unexplored/danger)
@@ -165,6 +286,17 @@
/obj/structure/stone_tile,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"gt" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/center/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"gy" = (
/obj/structure/stone_tile/cracked,
/obj/structure/stone_tile{
@@ -203,6 +335,12 @@
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"gF" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"gG" = (
/obj/structure/stone_tile{
dir = 1
@@ -239,18 +377,47 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"hd" = (
+/obj/structure/mineral_door/sandstone,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"hg" = (
/obj/structure/stone_tile/surrounding,
/obj/structure/stone_tile/center/cracked,
/mob/living/simple_animal/hostile/megafauna/legion,
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"hr" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/obj/item/hatchet,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"hs" = (
/obj/structure/stone_tile/block{
dir = 1
},
/turf/open/lava/smooth/lava_land_surface,
/area/lavaland/surface/outdoors)
+"hy" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"hD" = (
+/obj/effect/mob_spawn/human/corpse/damaged,
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"hH" = (
/obj/structure/stone_tile/block{
dir = 1
@@ -271,6 +438,13 @@
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"ia" = (
+/obj/item/reagent_containers/glass/bucket,
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"id" = (
/obj/structure/stone_tile{
dir = 4
@@ -284,6 +458,10 @@
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"io" = (
+/obj/structure/stone_tile/slab/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"ir" = (
/obj/structure/stone_tile/slab/cracked{
dir = 5
@@ -327,6 +505,38 @@
/obj/structure/stone_tile/block/cracked,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"iG" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/seeds/tower,
+/obj/item/seeds/tower,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"iJ" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/table/wood,
+/obj/item/clothing/head/helmet/roman/legionnaire,
+/obj/item/twohanded/bonespear,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
"iK" = (
/obj/structure/stone_tile/block,
/obj/structure/stone_tile/cracked{
@@ -376,6 +586,16 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"jj" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
"jk" = (
/obj/structure/stone_tile/center,
/obj/structure/stone_tile/surrounding_tile,
@@ -491,6 +711,12 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"ke" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"kg" = (
/obj/structure/fluff/drake_statue,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
@@ -504,6 +730,12 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"kk" = (
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"kl" = (
/obj/structure/fluff/drake_statue/falling,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
@@ -551,6 +783,13 @@
/obj/structure/stone_tile/center,
/turf/open/lava/smooth/lava_land_surface,
/area/lavaland/surface/outdoors)
+"kG" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
"kH" = (
/obj/structure/stone_tile/surrounding_tile{
dir = 1
@@ -562,6 +801,9 @@
/obj/structure/stone_tile/center/cracked,
/turf/open/lava/smooth/lava_land_surface,
/area/lavaland/surface/outdoors)
+"kI" = (
+/turf/closed/mineral/random/volcanic,
+/area/ruin/unpowered/ash_walkers)
"kJ" = (
/obj/structure/stone_tile/surrounding_tile{
dir = 4
@@ -587,10 +829,30 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"kP" = (
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"kR" = (
/obj/structure/stone_tile/slab/cracked,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"lb" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
"le" = (
/obj/structure/stone_tile,
/obj/structure/stone_tile{
@@ -1179,10 +1441,989 @@
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"nt" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/blood,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"nB" = (
+/obj/item/shovel,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"nI" = (
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"nJ" = (
+/turf/closed/wall/mineral/wood,
+/area/ruin/unpowered/ash_walkers)
+"nU" = (
+/obj/structure/stone_tile,
+/obj/item/shard,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"nW" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
"ol" = (
/obj/effect/landmark/stationroom/lavaland/station,
/turf/open/lava/smooth/lava_land_surface,
/area/template_noop)
+"ot" = (
+/obj/structure/stone_tile/surrounding_tile,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"oB" = (
+/obj/item/stack/sheet/mineral/wood,
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"oS" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/malf_upgrade,
+/obj/item/disk/tech_disk/illegal,
+/obj/structure/safe,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pc" = (
+/obj/effect/decal/cleanable/blood,
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pq" = (
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pt" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"pD" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pF" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pG" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pH" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"qh" = (
+/obj/structure/stone_tile/surrounding/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"qi" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"qA" = (
+/obj/item/flashlight/lantern,
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"qN" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"qS" = (
+/obj/structure/stone_tile/slab,
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"rz" = (
+/obj/item/storage/box/rxglasses,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"rO" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/ore_box,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"rQ" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"sa" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"se" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"sk" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"sl" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"sq" = (
+/obj/structure/stone_tile,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"sx" = (
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"sR" = (
+/obj/structure/stone_tile/block/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"ty" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"tz" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/toy/cards/deck/syndicate,
+/obj/item/construction/rcd/loaded/upgraded,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"ub" = (
+/obj/structure/stone_tile/slab,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"ui" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"uk" = (
+/obj/structure/lavaland/ash_walker,
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"uz" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"vi" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"vu" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/center,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"vR" = (
+/obj/machinery/hydroponics/soil,
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"wm" = (
+/obj/item/seeds/glowshroom,
+/obj/item/seeds/glowshroom,
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"ww" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/center/cracked,
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"wF" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"xr" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/closet/crate/internals,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"xs" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"xJ" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/block,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"xX" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/item/pickaxe,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"yf" = (
+/obj/machinery/hydroponics/soil,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"yv" = (
+/obj/structure/stone_tile/block,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"zf" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"zv" = (
+/obj/machinery/hydroponics/soil,
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Ad" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Ag" = (
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"An" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/twohanded/bonespear,
+/obj/item/twohanded/bonespear,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"AH" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/twohanded/bonespear,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"AU" = (
+/obj/structure/stone_tile,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"AY" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Bf" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Bj" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/blood,
+/obj/structure/necropolis_gate/ashwalker,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Br" = (
+/obj/structure/stone_tile/slab,
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Bs" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/closet/crate,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"BF" = (
+/obj/structure/flora/rock/jungle,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"BG" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"BH" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/center/cracked,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"BP" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"BU" = (
+/turf/closed/indestructible/riveted/boss/see_through,
+/area/ruin/unpowered/ash_walkers)
+"Ch" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/center/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"CG" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"CL" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/clothing/head/helmet/skull,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Dn" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
+"Do" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Ds" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Dx" = (
+/obj/structure/bonfire/dense,
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Dz" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Ef" = (
+/obj/structure/stone_tile/block/cracked,
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"Ez" = (
+/obj/machinery/grill{
+ name = "old rusty grill"
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"EQ" = (
+/obj/structure/stone_tile/surrounding/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"EV" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Fn" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Fz" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"FD" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"Gc" = (
+/obj/structure/flora/junglebush/b,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Gw" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Gx" = (
+/obj/item/pickaxe,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"GC" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/center,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"Hq" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/table/wood,
+/obj/item/scythe,
+/obj/item/twohanded/bonespear,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"HX" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"It" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Jq" = (
+/obj/structure/stone_tile/slab/cracked,
+/obj/effect/decal/cleanable/blood,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"JP" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"JR" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"JZ" = (
+/obj/structure/stone_tile/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"KA" = (
+/obj/structure/stone_tile/slab,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"KJ" = (
+/obj/structure/stone_tile/block/cracked,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"KV" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/effect/mob_spawn/human/corpse/damaged,
+/obj/effect/decal/cleanable/blood,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"LJ" = (
+/turf/open/water,
+/area/ruin/unpowered/ash_walkers)
+"Mh" = (
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Mx" = (
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"MQ" = (
+/obj/structure/table/optable,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/item/surgical_drapes,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"MS" = (
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"MX" = (
+/obj/structure/stone_tile/slab/cracked,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"NN" = (
+/obj/structure/stone_tile/block/cracked,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Ou" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/storage/toolbox/syndicate,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Oy" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"OR" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile/block/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Pj" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Qd" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/table/wood,
+/obj/item/storage/belt,
+/obj/item/twohanded/bonespear,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Qk" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/stack/marker_beacon/ten,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"QC" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"QG" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"QM" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Rb" = (
+/obj/structure/closet/crate,
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Rk" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Rr" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
+"RF" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"RX" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile,
+/obj/effect/decal/cleanable/blood,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Sh" = (
+/obj/structure/stone_tile/block,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Si" = (
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
+"Sr" = (
+/turf/closed/mineral/random/high_chance/volcanic,
+/area/ruin/unpowered/ash_walkers)
+"SG" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Tn" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/table/wood,
+/obj/item/kitchen/knife/combat/bone,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"TN" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"Uh" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/weldingtool/experimental,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
"Uq" = (
/obj/docking_port/stationary{
area_type = /area/lavaland/surface/outdoors;
@@ -1195,6 +2436,221 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"UG" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"UV" = (
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked,
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Vb" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/item/storage/bag/plants/portaseeder,
+/obj/item/seeds/cotton,
+/obj/item/seeds/cotton,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Vj" = (
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"VI" = (
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/reagent_dispensers/watertank,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"VP" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Wb" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
+"Wh" = (
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Wj" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"WL" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/closet/crate/medical,
+/obj/item/storage/firstaid/regular,
+/obj/item/storage/firstaid/ancient,
+/obj/item/reagent_containers/blood/random,
+/obj/item/reagent_containers/blood/lizard,
+/obj/item/reagent_containers/blood/lizard,
+/obj/item/stack/sheet/cloth/ten,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"WN" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/item/twohanded/bonespear,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"WT" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"WU" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Xe" = (
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/center/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Xf" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Xo" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Xw" = (
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Xz" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"XG" = (
+/obj/effect/decal/cleanable/blood,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Yg" = (
+/obj/structure/flora/rock/pile/largejungle{
+ light_range = null
+ },
+/turf/open/water,
+/area/ruin/unpowered/ash_walkers)
+"Yy" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/item/flashlight/lantern,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"YH" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Zc" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/machinery/the_singularitygen,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Zs" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
(1,1,1) = {"
aa
@@ -52358,9 +53814,9 @@ aa
aa
aa
ad
-ab
-ab
-ab
+Mx
+Mx
+Mx
aj
aj
aj
@@ -52615,11 +54071,11 @@ aa
aa
aa
ad
-ab
-ab
-ab
-aj
-aj
+Mx
+Mx
+Mx
+Mx
+Mx
aj
aj
aj
@@ -52864,20 +54320,20 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ab
-ab
-ab
-ab
-aj
-aj
-aj
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+Ag
+Ag
+Ag
+Mx
+Mx
+Mx
+Mx
aj
aj
aj
@@ -53121,20 +54577,20 @@ aa
aa
aa
aa
-aa
-ad
-ad
-ad
-iy
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
+Si
+Sr
+Sr
+Sr
+JZ
+nI
+nI
+nI
+nI
+CG
+Ag
+Ag
+Ag
+Mx
aj
aj
aj
@@ -53378,20 +54834,20 @@ aa
aa
aa
aa
-aa
-ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
+Si
+Sr
+nI
+nI
+nI
+nI
+pq
+nI
+LJ
+nI
+nI
+nI
+Ag
+Mx
aj
aj
aj
@@ -53635,20 +55091,20 @@ aa
aa
aa
aa
-aa
-it
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
+Si
+yv
+nI
+nI
+nI
+nI
+BF
+LJ
+LJ
+LJ
+nI
+JZ
+nI
+Mx
aj
aj
aj
@@ -53892,20 +55348,20 @@ aa
aa
aa
aa
-aa
-it
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ai
-ai
-ab
-ab
-ab
+Si
+yv
+nI
+nI
+Ad
+nI
+LJ
+LJ
+LJ
+LJ
+kI
+nI
+JZ
+Mx
aj
aj
aj
@@ -54149,20 +55605,20 @@ aa
aa
aa
aa
-aa
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ad
-ai
-ai
-ab
-ab
-ab
+Si
+nI
+nI
+Ez
+nI
+LJ
+LJ
+Yg
+LJ
+kI
+kI
+nI
+nI
+Mx
aj
ab
aj
@@ -54406,21 +55862,21 @@ aa
aa
aa
aa
-aa
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ai
-ai
-ad
-ab
-aj
-aj
+Si
+nI
+nI
+sx
+nI
+LJ
+LJ
+LJ
+LJ
+kI
+kI
+Sr
+Ag
+Mx
+Mx
aj
aj
aj
@@ -54663,21 +56119,21 @@ aa
aa
aa
aa
-aa
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ad
-ab
-ab
-aj
-aj
+Si
+nI
+nI
+nI
+Wh
+nI
+LJ
+LJ
+Gc
+nI
+Sr
+nI
+Ag
+Mx
+Mx
aj
aj
aj
@@ -54920,21 +56376,21 @@ aa
aa
aa
aa
-aa
-ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
+Si
+Sr
+nI
+nI
+nI
+Wh
+nI
+nI
+nI
+nI
+nI
+nI
+Ag
+Mx
+Mx
aj
aj
aj
@@ -55177,21 +56633,21 @@ aa
aa
aa
aa
-aa
-aa
-aa
-it
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
+Si
+Ag
+Ag
+nI
+nI
+nI
+nI
+Ds
+nI
+Ds
+nI
+nI
+Ag
+Mx
+Mx
aj
aj
aj
@@ -55429,25 +56885,25 @@ aa
aa
aa
aa
+wF
+Do
+Mh
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
+Rr
+Ag
+xs
+eq
+nI
+nI
+nI
+nI
+nI
+nI
+nI
+nI
+Ag
+Mx
aj
aj
aj
@@ -55457,14 +56913,14 @@ aj
ab
ab
ab
+ab
ak
ak
ak
ak
ak
-ak
-ak
-ak
+ab
+ab
ak
ak
ak
@@ -55687,42 +57143,42 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+yv
+nI
+nI
+sq
+kk
+Gx
+nI
+nI
+nI
+Si
+Mx
+aj
+aj
ab
aj
aj
aj
-aj
-aj
-aj
-aj
+aa
+ab
ab
ab
ab
ak
ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
+ab
+ab
+ab
+ab
+ab
ak
ak
ak
@@ -55944,13 +57400,32 @@ aa
aa
aa
aa
+Si
+oS
+CG
+wm
+Vb
+Bs
+Si
+yv
+sq
+CG
+AH
+Ds
+Ds
+KV
+nI
+Ad
+Si
+aa
+ab
+aj
+aj
+ab
+aj
aa
aa
-aa
-aa
-aa
-aa
-ad
+kG
ab
ab
ab
@@ -55960,14 +57435,6 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
ab
ab
@@ -56171,17 +57638,6 @@ ak
ak
ak
ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
al
fQ
aj
@@ -56200,13 +57656,33 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+Gw
+Si
+aU
+Wh
+zf
+Qk
+iG
+Si
+Wh
+EV
+Xe
+ke
+Ch
+kk
+Ad
+Wh
+nI
+Ad
+lp
+lz
+lp
+lF
+lp
+lP
+lS
+iy
+iu
ab
ab
ab
@@ -56217,14 +57693,6 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
ab
ab
@@ -56429,18 +57897,6 @@ ak
ak
ak
ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
aj
aj
aj
@@ -56457,13 +57913,33 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+Rk
+Si
+sR
+rz
+qh
+pq
+Jq
+ke
+ub
+YH
+sR
+Dx
+Bf
+UV
+kk
+Ds
+nI
+yv
+lu
+lq
+lD
+lG
+lu
+lQ
+lu
+kR
+kM
ab
ab
ab
@@ -56474,14 +57950,6 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
ab
ab
@@ -56686,18 +58154,6 @@ ak
ak
ak
ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
aj
aj
aj
@@ -56714,13 +58170,33 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+uz
+Si
+MQ
+nU
+ui
+Xw
+Rb
+Si
+sR
+Wh
+gt
+gF
+pF
+sq
+Ad
+VP
+Ad
+pq
+lv
+lv
+lE
+lv
+lE
+lR
+lv
+ab
+jS
ab
ab
ab
@@ -56731,27 +58207,7 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
-ab
-ab
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
ak
ak
ak
@@ -56971,14 +58427,33 @@ aa
aa
aa
aa
+uz
+Si
+WL
+eb
+dM
+eQ
+Zc
+Si
+Wh
+XG
+pq
+NN
+JZ
+oB
+EV
+nB
+nI
+Si
+aa
+aj
+aj
+aj
+aj
+aj
aa
aa
-aa
-aa
-aa
-aa
-ad
-js
+FD
ab
ab
ab
@@ -56988,26 +58463,7 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
-ab
-ab
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
ak
ak
ak
@@ -57229,41 +58685,41 @@ aa
aa
aa
aa
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+CG
+Wh
+CG
+JR
+Ad
+Pj
+ia
+yf
+Ds
+Si
+aj
+aj
+ab
+ab
+aj
+aj
+aj
aa
-aa
-aa
-aa
-aa
-ad
-ad
-ad
ab
ab
ab
ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-ab
-ab
-ab
-ak
-ak
-ak
-ak
-ak
-ak
ak
ak
+ab
+ab
+ab
+ab
ak
ak
ak
@@ -57484,42 +58940,42 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
+dD
+pt
+Wb
+Dn
+Zs
+Zs
+xX
+gF
+Fz
+QM
+CG
+Wh
+pc
+dA
+yv
+qA
+vR
+WU
+Ag
+aj
+aj
+aj
+aj
+aj
+aj
+aj
ab
ab
ab
ab
-ab
-ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-ab
-ab
-ab
-ak
-ak
-ak
ak
ak
ak
ak
+ab
+ab
ak
ak
ak
@@ -57740,27 +59196,27 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
-ad
+wF
+qS
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+Br
+pD
+Wh
+Ad
+NN
+Wh
+hr
+zv
+BH
+sq
+Ag
ab
-ab
-ab
-ab
-ab
-aj
-aj
aj
aj
aj
@@ -57997,27 +59453,27 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
-ad
+Gw
+Si
+KA
+KA
+KA
+KA
+KA
+Si
+Si
+Si
+ft
+Ad
+pq
+NN
+VI
+Vj
+MS
+AU
+Ag
+Ag
ab
-ab
-ab
-ab
-ab
-aj
-aj
aj
aj
aj
@@ -58254,28 +59710,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
-ad
+lb
+tz
+KA
+AY
+BP
+cw
+WT
+ty
+Si
+Si
+qN
+nI
+hD
+UG
+Ag
+Ag
+Ag
+Ag
+Ag
+Ag
+Mx
ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -58511,28 +59967,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
-ad
+uz
+Ou
+KA
+QC
+GC
+hy
+ww
+vi
+Si
+BU
+kP
+cp
+CG
+xJ
+RF
+Ag
+xs
+xs
+xs
+Xz
+Mx
ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -58768,28 +60224,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-gP
-ai
-ai
-ai
-ai
-ad
+Gw
+An
+KA
+nt
+Ef
+uk
+rQ
+MX
+sa
+Bj
+ub
+It
+dA
+sk
+Si
+Si
+nJ
+Si
+Si
+Ag
+Mx
ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -59025,29 +60481,29 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ab
-ai
-ai
-ai
-ai
+Gw
+Uh
+KA
+jj
+vu
+qi
+TN
+RX
+Si
+BU
+Oy
+cp
+pq
+UG
+nJ
+WN
+Yy
+Hq
+nJ
+Ag
+Mx
ab
ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -59282,27 +60738,27 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ab
-ai
-ai
-ai
-ai
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
+sl
+CL
+KA
+nW
+Dz
+Xf
+QG
+se
+Si
+Si
+KJ
+CG
+fN
+ub
+RF
+eh
+EQ
+Tn
+nJ
+Ag
+Mx
aj
aj
ab
@@ -59539,28 +60995,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+Gw
+Si
+KA
+KA
+KA
+KA
+KA
+Si
+Si
+Si
+sR
+pq
+sq
+nI
+nJ
+JP
+Qd
+iJ
+Si
+Sh
+Mx
ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -59796,28 +61252,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+pH
+qS
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+io
+rO
+xr
+nI
+eo
+nJ
+nJ
+nJ
+Si
+Si
+dF
+Mx
ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -60054,27 +61510,27 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+aQ
+Fn
+SG
+SG
+SG
+BG
+SG
+Xo
+ot
+nI
+nI
+nI
+pG
+Ag
+Ag
+eP
+Ag
+Ag
+Wj
+Mx
ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -60318,19 +61774,19 @@ aa
aa
aa
aa
+Mx
+Mx
+nI
+nI
+nI
+HX
+Ag
+Mx
+Mx
+Mx
ab
+Mx
ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
aj
aj
aj
@@ -60575,15 +62031,15 @@ aa
aa
aa
aa
-it
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
+Mx
+Mx
+Ag
+nI
+nI
+OR
+Ag
+Mx
+Mx
ab
ab
aj
@@ -60833,13 +62289,13 @@ aa
aa
aa
ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
+Mx
+Ag
+Ag
+nI
+gF
+Ag
+Mx
ab
ab
ab
@@ -61091,12 +62547,12 @@ aa
aa
ad
ad
-ab
-ab
-ab
-ab
-ab
-ab
+Mx
+Mx
+Ag
+hd
+Ag
+Mx
ab
ab
ab
@@ -61350,7 +62806,7 @@ ad
ad
ad
ad
-ab
+Mx
ab
ab
ab
@@ -61607,7 +63063,7 @@ ad
ad
ad
ad
-ab
+Mx
ab
ab
ab
@@ -61860,12 +63316,12 @@ aa
aa
aa
aa
-gP
-js
-ab
+Mx
+Mx
+Mx
ad
ad
-ab
+Mx
ab
ab
ab
@@ -62122,7 +63578,7 @@ aa
aa
aa
aa
-ab
+Mx
ab
ab
ab
@@ -62385,10 +63841,10 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
+ab
+ab
+ab
+ab
ab
ab
aj
@@ -62643,9 +64099,9 @@ ab
ab
ab
ab
-aj
ab
-aj
+ab
+ab
ab
ab
ab
@@ -62902,8 +64358,8 @@ ab
aj
aj
aj
-aj
-aj
+ab
+ab
ab
ab
ab
diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index 6913473e88..0a64f01a43 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -138,8 +138,8 @@
////organ defines
#define STANDARD_ORGAN_THRESHOLD 100
-#define STANDARD_ORGAN_HEALING 0.001
-#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
+#define STANDARD_ORGAN_HEALING (1/(15 MINUTES / (2 SECONDS)))
+#define STANDARD_ORGAN_DECAY (1/(15 MINUTES / (2 SECONDS))) //designed to fail organs when left to decay for ~15 minutes. 2 SECOND is SSmobs tickrate.
#define G_MALE 1
#define G_FEMALE 2
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 317066f673..957f6edae4 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -54,7 +54,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define PASSCLOSEDTURF (1<<5)
#define LETPASSTHROW (1<<6)
-
//Movement Types
#define GROUND (1<<0)
#define FLYING (1<<1)
diff --git a/code/__DEFINES/interaction_flags.dm b/code/__DEFINES/interaction_flags.dm
index 6df5bf77fb..dc3242c910 100644
--- a/code/__DEFINES/interaction_flags.dm
+++ b/code/__DEFINES/interaction_flags.dm
@@ -20,5 +20,3 @@
#define INTERACT_MACHINE_SET_MACHINE (1<<6) //MACHINES HAVE THIS BY DEFAULT, SOMEONE SHOULD RUN THROUGH MACHINES AND REMOVE IT FROM THINGS LIKE LIGHT SWITCHES WHEN POSSIBLE!!--------------------------
//This flag determines if a machine set_machine's the user when the user uses it, making updateUsrDialog make the user re-call interact() on it.
//THIS FLAG IS ON ALL MACHINES BY DEFAULT, NEEDS TO BE RE-EVALUATED LATER!!
-
-#define INTERACT_GHOST_READ (1<<0)
\ No newline at end of file
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index e2d93aebf5..ac8681ead7 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -406,6 +406,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define DUMMY_HUMAN_SLOT_HOLOFORM "dummy_holoform_generation"
#define DUMMY_HUMAN_SLOT_ADMIN "admintools"
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
+#define DUMMY_HUMAN_SLOT_HALLUCINATION "dummy_hallucination"
#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index f89c11d91b..dc67de3150 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -35,17 +35,17 @@
#define BLOODCRAWL 1
#define BLOODCRAWL_EAT 2
-//Mob bio-types
-#define MOB_ORGANIC "organic"
-#define MOB_INORGANIC "inorganic"
-#define MOB_ROBOTIC "robotic"
-#define MOB_UNDEAD "undead"
-#define MOB_HUMANOID "humanoid"
-#define MOB_BUG "bug"
-#define MOB_BEAST "beast"
-#define MOB_EPIC "epic" //megafauna
-#define MOB_REPTILE "reptile"
-#define MOB_SPIRIT "spirit"
+//Mob bio-types flags
+#define MOB_ORGANIC 1 << 0
+#define MOB_MINERAL 1 << 1
+#define MOB_ROBOTIC 1 << 2
+#define MOB_UNDEAD 1 << 3
+#define MOB_HUMANOID 1 << 4
+#define MOB_BUG 1 << 5
+#define MOB_BEAST 1 << 6
+#define MOB_EPIC 1 << 7 //megafauna
+#define MOB_REPTILE 1 << 8
+#define MOB_SPIRIT 1 << 9
//Organ defines for carbon mobs
#define ORGAN_ORGANIC 1
diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm
index 831f73ac74..d78de86d25 100644
--- a/code/__DEFINES/obj_flags.dm
+++ b/code/__DEFINES/obj_flags.dm
@@ -17,18 +17,19 @@
// Flags for the item_flags var on /obj/item
-#define BEING_REMOVED (1<<0)
-#define IN_INVENTORY (1<<1) //is this item equipped into an inventory slot or hand of a mob? used for tooltips
-#define FORCE_STRING_OVERRIDE (1<<2) //used for tooltips
-#define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use.
-#define SLOWS_WHILE_IN_HAND (1<<4)
-#define NO_MAT_REDEMPTION (1<<5) //Stops you from putting things like an RCD or other items into an ORM or protolathe for materials.
-#define DROPDEL (1<<6) //When dropped, it calls qdel on itself
-#define NOBLUDGEON (1<<7) //when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
-#define ABSTRACT (1<<8) //for all things that are technically items but used for various different stuff
-#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect)
-#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
-#define NO_UNIFORM_REQUIRED (1<<11) //Can be worn on certain slots (currently belt and id) that would otherwise require an uniform.
+#define BEING_REMOVED (1<<0)
+#define IN_INVENTORY (1<<1) //is this item equipped into an inventory slot or hand of a mob? used for tooltips
+#define FORCE_STRING_OVERRIDE (1<<2) //used for tooltips
+#define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use.
+#define SLOWS_WHILE_IN_HAND (1<<4)
+#define NO_MAT_REDEMPTION (1<<5) //Stops you from putting things like an RCD or other items into an ORM or protolathe for materials.
+#define DROPDEL (1<<6) //When dropped, it calls qdel on itself
+#define NOBLUDGEON (1<<7) //when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
+#define ABSTRACT (1<<8) //for all things that are technically items but used for various different stuff
+#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect)
+#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
+#define NO_UNIFORM_REQUIRED (1<<11) //Can be worn on certain slots (currently belt and id) that would otherwise require an uniform.
+#define NO_ATTACK_CHAIN_SOFT_STAMCRIT (1<<12) //Entirely blocks melee_attack_chain() if user is soft stamcritted. Uses getStaminaLoss() to check at this point in time. THIS DOES NOT BLOCK RANGED AFTERATTACK()S, ONLY MELEE RANGE AFTERATTACK()S.
// Flags for the clothing_flags var on /obj/item/clothing
diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm
index d08344cc96..97ae7b8e95 100644
--- a/code/__DEFINES/reagents.dm
+++ b/code/__DEFINES/reagents.dm
@@ -22,6 +22,11 @@
// Is an open container for all intents and purposes.
#define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT)
+//reagents_value defines, for cargo stuff.
+#define DEFAULT_REAGENTS_VALUE 1
+#define NO_REAGENTS_VALUE 0
+#define HARVEST_REAGENTS_VALUE 0.3
+
#define TOUCH 1 // splashing
#define INGEST 2 // ingestion
diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm
index beeee22df9..49cfba8cd2 100644
--- a/code/__DEFINES/say.dm
+++ b/code/__DEFINES/say.dm
@@ -81,6 +81,7 @@
//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam
#define MAX_MESSAGE_LEN 2048 //Citadel edit: What's the WORST that could happen?
+#define MAX_FAVOR_LEN 4096 //double the maximum message length.
#define MAX_NAME_LEN 42
#define MAX_BROADCAST_LEN 512
#define MAX_CHARTER_LEN 80
diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm
index 1bde770045..26910a916b 100644
--- a/code/__HELPERS/_cit_helpers.dm
+++ b/code/__HELPERS/_cit_helpers.dm
@@ -108,27 +108,37 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
message_admins("[key_name_admin(usr)] manually reloaded mentors")
//Flavor Text
-/mob/living/carbon/human/verb/set_flavor()
+/mob/proc/set_flavor()
set name = "Set Flavor Text"
set desc = "Sets an extended description of your character's features."
set category = "IC"
- var/new_flavor = input(src, "Enter your new flavor text:", "Flavor text", null) as message|null
+ var/new_flavor = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", flavor_text, MAX_FAVOR_LEN, TRUE)
if(!isnull(new_flavor))
- flavor_text = sanitize(new_flavor)
+ flavor_text = new_flavor
to_chat(src, "Your flavor text has been updated.")
//Flavor Text
-/mob/living/carbon/human/verb/set_flavor_2()
+/mob/proc/set_flavor_2()
set name = "Set Temporary Flavor Text"
set desc = "Sets a description of your character's current appearance. Use this for emotions, poses etc."
set category = "IC"
- var/new_flavor = input(src, "Enter your new temporary flavor text:", "Temporary flavor text", null) as message|null
+ var/new_flavor = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", flavor_text_2, MAX_FAVOR_LEN, TRUE)
if(!isnull(new_flavor))
- flavor_text_2 = sanitize(new_flavor)
+ flavor_text_2 = new_flavor
to_chat(src, "Your temporary flavor text has been updated.")
+/mob/proc/print_flavor_text(flavor)
+ if(!flavor)
+ return
+ // We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
+ var/msg = html_decode(replacetext(flavor, "\n", " "))
+ if(length_char(msg) <= 40)
+ return "[html_encode(msg)]"
+ else
+ return "[html_encode(copytext_char(msg, 1, 37))]... More..."
+
//LOOC toggles
/client/verb/listen_looc()
set name = "Show/Hide LOOC"
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 605f7f8ae7..60d7fa42b9 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -436,7 +436,7 @@
var/list/result = list()
for(var/m in group)
var/mob/M = m
- if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && M.ckey in GLOB.poll_ignore[ignore_category]))
+ if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && (M.ckey in GLOB.poll_ignore[ignore_category])))
continue
if(be_special_flag)
if(!(M.client.prefs) || !(be_special_flag in M.client.prefs.be_special))
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 1669c941c2..a5924994e7 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -529,7 +529,7 @@ GLOBAL_LIST_EMPTY(species_list)
continue
if(M.stat != DEAD && !override)
continue
- if(speaker_key && speaker_key in prefs.ignoring)
+ if(speaker_key && (speaker_key in prefs.ignoring))
continue
switch(message_type)
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 04e7ffd721..0f1e75ff73 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -146,19 +146,19 @@
var/list/file_data = list()
var/pos = 1
for(var/V in GLOB.news_network.network_channels)
- var/datum/newscaster/feed_channel/channel = V
+ var/datum/news/feed_channel/channel = V
if(!istype(channel))
stack_trace("Non-channel in newscaster channel list")
continue
file_data["[pos]"] = list("channel name" = "[channel.channel_name]", "author" = "[channel.author]", "censored" = channel.censored ? 1 : 0, "author censored" = channel.authorCensor ? 1 : 0, "messages" = list())
for(var/M in channel.messages)
- var/datum/newscaster/feed_message/message = M
+ var/datum/news/feed_message/message = M
if(!istype(message))
stack_trace("Non-message in newscaster channel messages list")
continue
var/list/comment_data = list()
for(var/C in message.comments)
- var/datum/newscaster/feed_comment/comment = C
+ var/datum/news/feed_comment/comment = C
if(!istype(comment))
stack_trace("Non-message in newscaster message comments list")
continue
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index c98faaa4fb..a0139dab83 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -214,5 +214,18 @@ GLOBAL_LIST_INIT(bitfields, list(
"CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH,
"MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN,
"CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH
- )
- ))
\ No newline at end of file
+
+ ),
+ "mob_biotypes" = list (
+ "MOB_ORGANIC" = MOB_ORGANIC,
+ "MOB_MINERAL" = MOB_MINERAL,
+ "MOB_ROBOTIC" = MOB_ROBOTIC,
+ "MOB_UNDEAD" = MOB_UNDEAD,
+ "MOB_HUMANOID" = MOB_HUMANOID,
+ "MOB_BUG" = MOB_BUG,
+ "MOB_BEAST" = MOB_BEAST,
+ "MOB_EPIC" = MOB_EPIC,
+ "MOB_REPTILE" = MOB_REPTILE,
+ "MOB_SPIRIT" = MOB_SPIRIT
+ )
+ ))
diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm
index 1dcde53a72..819352ac1b 100644
--- a/code/_globalvars/lists/misc.dm
+++ b/code/_globalvars/lists/misc.dm
@@ -1 +1,59 @@
GLOBAL_LIST_EMPTY(donators_by_group) //group id = donator list of ckeys
+
+GLOBAL_LIST_INIT(flirts, list("Roses are red / Violets are good / One day while Andy...",
+ "My love for you is like the singularity. It cannot be contained.",
+ "Will you be my lusty xenomorph maid?",
+ "We go together like the clown and the external airlock.",
+ "Roses are red / Liches are wizards / I love you more than a whole squad of lizards.",
+ "Be my valentine. Law 2.",
+ "You must be a mime, because you leave me speechless.",
+ "I love you like Ian loves the HoP.",
+ "You're hotter than a plasma fire in toxins.",
+ "Are you a rogue atmos tech? Because you're taking my breath away.",
+ "Could I have all access... to your heart?",
+ "Call me the doctor, because I'm here to inspect your johnson.",
+ "I'm not a changeling, but you make my proboscis extend.",
+ "I just can't get EI NATH of you.",
+ "You must be a nuke op, because you make my heart explode.",
+ "Roses are red / Botany is a farm / Not being my Valentine / causes human harm.",
+ "I want you more than an assistant wants insulated gloves.",
+ "If I was a security officer, I'd brig you all shift.",
+ "Are you the janitor? Because I think I've fallen for you.",
+ "You're always valid to my heart.",
+ "I'd risk the wrath of the gods to bwoink you.",
+ "You look as beautiful now as the last time you were cloned.",
+ "Someone check the gravitational generator, because I'm only attracted to you.",
+ "If I were the warden I'd always let you into my armory.",
+ "The virologist is rogue, and the only cure is a kiss from you.",
+ "Would you spend some time in my upgraded sleeper?",
+ "You must be a silicon, because you've unbolted my heart.",
+ "Are you Nar'Sie? Because there's nar-one else I sie.",
+ "If you were a taser, you'd be set to stunning.",
+ "Do you have stamina damage from running through my dreams?",
+ "If I were an alien, would you let me hug you?",
+ "My love for you is stronger than a reinforced wall.",
+ "This must be the captain's office, because I see a fox.",
+ "I'm not a highlander, but there can only be one for me.",
+ "The floor is made of lava! Quick, get on my bed.",
+ "If you were an abandoned station you'd be the DEARelict.",
+ "If you had a pickaxe you'd be a shaft FINEr.",
+ "Roses are red, tide is gray, if I were an assistant I'd steal you away.",
+ "Roses are red, text is green, I love you more than cleanbots clean.",
+ "If you were a carp I'd fi-lay you.",
+ "I'm a nuke op, and my pinpointer leads to your heart.",
+ "Wanna slay my megafauna?",
+ "I'm a clockwork cultist. Or zl inyragvar.",
+ "If you were a disposal bin I'd ride you all day.",
+ "Put on your explorer's suit because I'm taking you to LOVEaland.",
+ "I must be the CMO, 'cause I saw you on my CUTE sensors.",
+ "You're the vomit to my flyperson.",
+ "You must be liquid dark matter, because you're pulling me closer.",
+ "Not even sorium can drive me away from you.",
+ "Wanna make like a borg and do some heavy petting?",
+ "Are you powering the station? Because you super matter to me.",
+ "I wish science could make me a bag of holding you.",
+ "Let's call the emergency CUDDLE.",
+ "I must be tripping on BZ, because I saw an angel walk by.",
+ "Wanna empty out my tool storage?",
+ "Did you visit the medbay after you fell from heaven?",
+ "Are you wearing space pants? Wanna not be?" ))
diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm
index 7ae197a5d1..e334d08040 100644
--- a/code/_globalvars/lists/names.dm
+++ b/code/_globalvars/lists/names.dm
@@ -4,6 +4,7 @@ GLOBAL_LIST_INIT(wizard_second, world.file2list("strings/names/wizardsecond.txt"
GLOBAL_LIST_INIT(ninja_titles, world.file2list("strings/names/ninjatitle.txt"))
GLOBAL_LIST_INIT(ninja_names, world.file2list("strings/names/ninjaname.txt"))
GLOBAL_LIST_INIT(commando_names, world.file2list("strings/names/death_commando.txt"))
+GLOBAL_LIST_INIT(first_names, world.file2list("strings/names/first.txt"))
GLOBAL_LIST_INIT(first_names_male, world.file2list("strings/names/first_male.txt"))
GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female.txt"))
GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt"))
diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm
index dc18107a95..9638b040f9 100644
--- a/code/_onclick/drag_drop.dm
+++ b/code/_onclick/drag_drop.dm
@@ -42,7 +42,7 @@
selected_target[1] = object
selected_target[2] = params
while(selected_target[1])
- Click(selected_target[1], location, control, selected_target[2])
+ Click(selected_target[1], location, control, selected_target[2], TRUE)
sleep(delay)
active_mousedown_item = mob.canMobMousedown(object, location, params)
if(active_mousedown_item)
@@ -145,4 +145,4 @@
if (middragatom == src_object)
middragtime = 0
middragatom = null
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 3f11c8a2f2..9ba51afc69 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -8,6 +8,12 @@
*afterattack. The return value does not matter.
*/
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
+ if(item_flags & NO_ATTACK_CHAIN_SOFT_STAMCRIT)
+ if(isliving(user))
+ var/mob/living/L = user
+ if(L.getStaminaLoss() >= STAMINA_SOFTCRIT)
+ to_chat(L, "You are too exhausted to swing [src]!")
+ return
if(tool_behaviour && target.tool_act(user, src, tool_behaviour))
return
if(pre_attack(target, user, params))
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index a3bc47ac91..0f12d1d9ae 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -234,6 +234,7 @@
/datum/config_entry/number/movedelay //Used for modifying movement speed for mobs.
abstract_type = /datum/config_entry/number/movedelay
+ integer = FALSE
/datum/config_entry/number/movedelay/ValidateAndSet()
. = ..()
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 7597a9229a..31e436f206 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -118,7 +118,7 @@ SUBSYSTEM_DEF(job)
if(flag && (!(flag in player.client.prefs.be_special)))
JobDebug("FOC flag failed, Player: [player], Flag: [flag], ")
continue
- if(player.mind && job.title in player.mind.restricted_roles)
+ if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("FOC incompatible with antagonist role, Player: [player]")
continue
if(player.client.prefs.job_preferences[job.title] == level)
@@ -158,7 +158,7 @@ SUBSYSTEM_DEF(job)
JobDebug("GRJ player not enough xp, Player: [player]")
continue
- if(player.mind && job.title in player.mind.restricted_roles)
+ if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
continue
@@ -340,7 +340,7 @@ SUBSYSTEM_DEF(job)
JobDebug("DO non-human failed, Player: [player], Job:[job.title]")
continue
- if(player.mind && job.title in player.mind.restricted_roles)
+ if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
continue
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index 4d9eefae5b..7eff8b9e3c 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -38,7 +38,7 @@ SUBSYSTEM_DEF(shuttle)
var/points = 5000 //number of trade-points we have
var/centcom_message = "" //Remarks from CentCom on how well you checked the last order.
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentCom, associated with their potencies
- var/passive_supply_points_per_minute = 500
+ var/passive_supply_points_per_minute = 125
var/list/supply_packs = list()
var/list/shoppinglist = list()
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index fe994facdc..606aca2d3a 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -486,8 +486,9 @@ SUBSYSTEM_DEF(ticker)
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = INSTANT_RUNOFF_VOTING)
if("SCORE")
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING)
+ else
+ SSvote.initiate_vote("map","server",hideresults=TRUE)
// fallback
- SSvote.initiate_vote("map","server",hideresults=TRUE)
/datum/controller/subsystem/ticker/proc/HasRoundStarted()
return current_state >= GAME_STATE_PLAYING
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index 086167fc48..9924ed7917 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -149,7 +149,7 @@ SUBSYSTEM_DEF(vote)
var/list/this_vote = voted[ckey]
var/list/pretty_vote = list()
for(var/choice in choices)
- if("[choice]" in this_vote && "[choice]" in scores_by_choice)
+ if(("[choice]" in this_vote) && ("[choice]" in scores_by_choice))
sorted_insert(scores_by_choice["[choice]"],this_vote["[choice]"],/proc/cmp_numeric_asc)
// START BALLOT GATHERING
pretty_vote += "[choice]"
@@ -160,7 +160,7 @@ SUBSYSTEM_DEF(vote)
for(var/score_name in scores_by_choice)
var/list/score = scores_by_choice[score_name]
for(var/indiv_score in score)
- SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score]))
+ SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score]))
if(score.len == 0)
scores_by_choice -= score_name
while(scores_by_choice.len > 1)
@@ -376,7 +376,7 @@ SUBSYSTEM_DEF(vote)
else
to_chat(world, "Notice:Restart vote will not restart the server automatically because there are active admins on.")
message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.")
-
+
return .
/datum/controller/subsystem/vote/proc/submit_vote(vote, score = 0)
diff --git a/code/datums/beam.dm b/code/datums/beam.dm
index d0b6d791ec..d97ee9a773 100644
--- a/code/datums/beam.dm
+++ b/code/datums/beam.dm
@@ -61,7 +61,8 @@
/datum/beam/proc/recalculate_in(time)
if(timing_id)
deltimer(timing_id)
- timing_id = addtimer(CALLBACK(src, .proc/recalculate), time, TIMER_STOPPABLE)
+ if(!finished)
+ timing_id = addtimer(CALLBACK(src, .proc/recalculate), time, TIMER_STOPPABLE)
/datum/beam/proc/after_calculate()
if((sleep_time == null) || finished) //Does not automatically recalculate.
diff --git a/code/datums/components/crafting/craft.dm b/code/datums/components/crafting/craft.dm
index 5c21801c14..b5c7f34c27 100644
--- a/code/datums/components/crafting/craft.dm
+++ b/code/datums/components/crafting/craft.dm
@@ -64,29 +64,48 @@
-
-/datum/component/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents)
+/**
+ * Check that the contents of the recipe meet the requirements.
+ *
+ * user: The /mob that initated the crafting.
+ * R: The /datum/crafting_recipe being attempted.
+ * contents: List of items to search for R's reqs.
+ */
+/datum/component/personal_crafting/proc/check_contents(mob/user, datum/crafting_recipe/R, list/contents)
+ var/list/item_instances = contents["instances"]
contents = contents["other"]
- main_loop:
- for(var/A in R.reqs)
- var/needed_amount = R.reqs[A]
- for(var/B in contents)
- if(ispath(B, A))
- if (R.blacklist.Find(B))
- continue
- if(contents[B] >= R.reqs[A])
- continue main_loop
- else
- needed_amount -= contents[B]
- if(needed_amount <= 0)
- continue main_loop
- else
- continue
+
+ var/list/requirements_list = list()
+
+ // Process all requirements
+ for(var/requirement_path in R.reqs)
+ // Check we have the appropriate amount available in the contents list
+ var/needed_amount = R.reqs[requirement_path]
+ for(var/content_item_path in contents)
+ // Right path and not blacklisted
+ if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(requirement_path))
+ continue
+
+ needed_amount -= contents[content_item_path]
+ if(needed_amount <= 0)
+ break
+
+ if(needed_amount > 0)
return FALSE
- for(var/A in R.chem_catalysts)
- if(contents[A] < R.chem_catalysts[A])
+
+ // Store the instances of what we will use for R.check_requirements() for requirement_path
+ var/list/instances_list = list()
+ for(var/instance_path in item_instances)
+ if(ispath(instance_path, requirement_path))
+ instances_list += item_instances[instance_path]
+
+ requirements_list[requirement_path] = instances_list
+
+ for(var/requirement_path in R.chem_catalysts)
+ if(contents[requirement_path] < R.chem_catalysts[requirement_path])
return FALSE
- return TRUE
+
+ return R.check_requirements(user, requirements_list)
/datum/component/personal_crafting/proc/get_environment(mob/user)
. = list()
@@ -110,9 +129,14 @@
. = list()
.["tool_behaviour"] = list()
.["other"] = list()
+ .["instances"] = list()
for(var/obj/item/I in get_environment(user))
if(I.flags_1 & HOLOGRAM_1)
continue
+ if(.["instances"][I.type])
+ .["instances"][I.type] += I
+ else
+ .["instances"][I.type] = list(I)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
.["other"][I.type] += S.amount
@@ -161,11 +185,11 @@
/datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
var/list/contents = get_surroundings(user)
var/send_feedback = 1
- if(check_contents(R, contents))
+ if(check_contents(user, R, contents))
if(check_tools(user, R, contents))
if(do_after(user, R.time, target = user))
contents = get_surroundings(user)
- if(!check_contents(R, contents))
+ if(!check_contents(user, R, contents))
return ", missing component."
if(!check_tools(user, R, contents))
return ", missing tool."
@@ -341,7 +365,7 @@
if((R.category != cur_category) || (R.subcategory != cur_subcategory))
continue
- craftability["[REF(R)]"] = check_contents(R, surroundings)
+ craftability["[REF(R)]"] = check_contents(user, R, surroundings)
data["craftability"] = craftability
return data
diff --git a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm
index 06f79396b8..104b58ca28 100644
--- a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm
+++ b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm
@@ -8,6 +8,12 @@
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
+/datum/crafting_recipe/pin_removal/check_requirements(mob/user, list/collected_requirements)
+ var/obj/item/gun/G = collected_requirements[/obj/item/gun][1]
+ if (G.no_pin_required || !G.pin)
+ return FALSE
+ return TRUE
+
/datum/crafting_recipe/strobeshield
name = "Strobe Shield"
result = /obj/item/assembly/flash/shield
diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm
index 55e5c03c2b..61f97006dd 100644
--- a/code/datums/components/storage/storage.dm
+++ b/code/datums/components/storage/storage.dm
@@ -41,6 +41,7 @@
var/obj/screen/storage/boxes //storage display object
var/obj/screen/close/closer //close button object
+ var/current_maxscreensize
var/allow_big_nesting = FALSE //allow storage objects of the same or greater size.
@@ -362,11 +363,15 @@
break
closer.screen_loc = "[screen_start_x + cols]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
-/datum/component/storage/proc/show_to(mob/M)
+/datum/component/storage/proc/show_to(mob/M, set_screen_size = TRUE)
if(!M.client)
return FALSE
var/list/cview = getviewsize(M.client.view)
var/maxallowedscreensize = cview[1]-8
+ if(set_screen_size)
+ current_maxscreensize = maxallowedscreensize
+ else if(current_maxscreensize)
+ maxallowedscreensize = current_maxscreensize
if(M.active_storage != src && (M.stat == CONSCIOUS))
for(var/obj/item/I in accessible_items())
if(I.on_found(M))
@@ -547,14 +552,14 @@
return
A.add_fingerprint(M)
-/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE)
+/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, ghost = FALSE)
var/atom/A = parent
if(!istype(M))
return FALSE
A.add_fingerprint(M)
if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE)))
return FALSE
- show_to(M)
+ show_to(M, !ghost)
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
if(isitem(O))
@@ -665,7 +670,7 @@
return can_be_inserted(I, silent, M)
/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M)
- return user_show_to_mob(M, TRUE)
+ return user_show_to_mob(M, TRUE, TRUE)
/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
return user_show_to_mob(showto, force)
diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm
index c125a9b7c7..0b6d4e3404 100644
--- a/code/datums/diseases/_MobProcs.dm
+++ b/code/datums/diseases/_MobProcs.dm
@@ -17,14 +17,10 @@
if(HasDisease(D))
return FALSE
- var/can_infect = FALSE
- for(var/host_type in D.infectable_biotypes)
- if(host_type in mob_biotypes)
- can_infect = TRUE
- break
- if(!can_infect)
+ if(!(D.infectable_biotypes & mob_biotypes))
return FALSE
+
if(!(type in D.viable_mobtypes))
return FALSE
diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm
index 056f99c7a4..940b61c9fe 100644
--- a/code/datums/diseases/_disease.dm
+++ b/code/datums/diseases/_disease.dm
@@ -30,7 +30,7 @@
var/list/required_organs = list()
var/needs_all_cures = TRUE
var/list/strain_data = list() //dna_spread special bullshit
- var/list/infectable_biotypes = list(MOB_ORGANIC) //if the disease can spread on organics, synthetics, or undead
+ var/infectable_biotypes = MOB_ORGANIC //if the disease can spread on organics, synthetics, or undead
var/process_dead = FALSE //if this ticks while the host is dead
var/copy_type = null //if this is null, copies will use the type of the instance being copied
diff --git a/code/datums/diseases/advance/symptoms/species.dm b/code/datums/diseases/advance/symptoms/species.dm
index a8b18ae735..49a3cf8d07 100644
--- a/code/datums/diseases/advance/symptoms/species.dm
+++ b/code/datums/diseases/advance/symptoms/species.dm
@@ -14,7 +14,7 @@
/datum/symptom/undead_adaptation/OnRemove(datum/disease/advance/A)
A.process_dead = FALSE
- A.infectable_biotypes -= MOB_UNDEAD
+ A.infectable_biotypes &= ~MOB_UNDEAD
/datum/symptom/inorganic_adaptation
name = "Inorganic Biology"
@@ -27,7 +27,8 @@
severity = 0
/datum/symptom/inorganic_adaptation/OnAdd(datum/disease/advance/A)
- A.infectable_biotypes |= MOB_INORGANIC
+ A.infectable_biotypes |= MOB_MINERAL //Mineral covers plasmamen and golems.
/datum/symptom/inorganic_adaptation/OnRemove(datum/disease/advance/A)
- A.infectable_biotypes -= MOB_INORGANIC
\ No newline at end of file
+ A.infectable_biotypes &= ~MOB_MINERAL
+
diff --git a/code/datums/diseases/beesease.dm b/code/datums/diseases/beesease.dm
index 074bda0560..ccae692b4b 100644
--- a/code/datums/diseases/beesease.dm
+++ b/code/datums/diseases/beesease.dm
@@ -10,7 +10,7 @@
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
desc = "If left untreated subject will regurgitate bees."
severity = DISEASE_SEVERITY_MEDIUM
- infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD) //bees nesting in corpses
+ infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD //bees nesting in corpses
/datum/disease/beesease/stage_act()
..()
diff --git a/code/datums/diseases/magnitis.dm b/code/datums/diseases/magnitis.dm
index 29e6657e13..0bfb918ba0 100644
--- a/code/datums/diseases/magnitis.dm
+++ b/code/datums/diseases/magnitis.dm
@@ -10,7 +10,7 @@
permeability_mod = 0.75
desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field."
severity = DISEASE_SEVERITY_MEDIUM
- infectable_biotypes = list(MOB_ORGANIC, MOB_ROBOTIC)
+ infectable_biotypes = MOB_ORGANIC|MOB_ROBOTIC
process_dead = TRUE
/datum/disease/magnitis/stage_act()
diff --git a/code/datums/diseases/parrotpossession.dm b/code/datums/diseases/parrotpossession.dm
index 68e962055a..1a3346d565 100644
--- a/code/datums/diseases/parrotpossession.dm
+++ b/code/datums/diseases/parrotpossession.dm
@@ -11,7 +11,7 @@
viable_mobtypes = list(/mob/living/carbon/human)
desc = "Subject is possessed by the vengeful spirit of a parrot. Call the priest."
severity = DISEASE_SEVERITY_MEDIUM
- infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD, MOB_INORGANIC, MOB_ROBOTIC)
+ infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC|MOB_MINERAL
bypasses_immunity = TRUE //2spook
var/mob/living/simple_animal/parrot/Poly/ghost/parrot
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index bdb05346e4..36c7d70f3c 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -168,7 +168,7 @@
stage4 = list("Your skin feels very loose.", "You can feel... something...inside you.")
stage5 = list("Your skin feels as if it's about to burst off!")
new_form = /mob/living/silicon/robot
- infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD, MOB_ROBOTIC)
+ infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC
bantype = "Cyborg"
/datum/disease/transformation/robot/stage_act()
@@ -284,7 +284,7 @@
stage4 = list("You're ravenous.")
stage5 = list("You have become a morph.")
new_form = /mob/living/simple_animal/hostile/morph
- infectable_biotypes = list(MOB_ORGANIC, MOB_INORGANIC, MOB_UNDEAD) //magic!
+ infectable_biotypes = MOB_ORGANIC|MOB_MINERAL|MOB_UNDEAD //magic!
/datum/disease/transformation/gondola
name = "Gondola Transformation"
diff --git a/code/datums/elements/cleaning.dm b/code/datums/elements/cleaning.dm
index e4fb3edd48..3f80204089 100644
--- a/code/datums/elements/cleaning.dm
+++ b/code/datums/elements/cleaning.dm
@@ -45,4 +45,4 @@
cleaned_human.clean_blood()
cleaned_human.wash_cream()
cleaned_human.regenerate_icons()
- to_chat(cleaned_human, "[src] cleans your face!")
+ to_chat(cleaned_human, "[AM] cleans your face!")
diff --git a/code/datums/elements/mob_holder.dm b/code/datums/elements/mob_holder.dm
index 04f84ee008..e33c430198 100644
--- a/code/datums/elements/mob_holder.dm
+++ b/code/datums/elements/mob_holder.dm
@@ -40,7 +40,7 @@
to_chat(user, "Your hands are full!")
return FALSE
if(source.buckled)
- to_chat(user, "[src] is buckled to something!")
+ to_chat(user, "[source] is buckled to something!")
return FALSE
if(source == user)
to_chat(user, "You can't pick yourself up.")
@@ -52,7 +52,7 @@
source.visible_message("[user] picks up [source]!", \
"[user] picks you up!")
- to_chat(user, "You pick [src] up.")
+ to_chat(user, "You pick [source] up.")
source.drop_all_held_items()
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(source), source, worn_state, alt_worn, right_hand, left_hand, inv_slots)
if(proctype)
@@ -101,6 +101,8 @@
target.forceMove(src)
var/image/I = new //work around to retain the same appearance to the mob idependently from inhands/worn states.
I.appearance = target.appearance
+ I.layer = FLOAT_LAYER //So it doesn't get screwed up by layer overrides.
+ I.plane = FLOAT_PLANE //Same as above but for planes.
I.override = TRUE
add_overlay(I)
name = target.name
@@ -128,7 +130,7 @@
if(AM == held_mob)
held_mob.reset_perspective()
held_mob = null
- qdel(src)
+ QDEL_IN(src, 1) //To avoid a qdel loop.
/obj/item/clothing/head/mob_holder/Entered(atom/movable/AM, atom/newloc)
. = ..()
@@ -158,7 +160,7 @@
/obj/item/clothing/head/mob_holder/container_resist()
if(isliving(loc))
var/mob/living/L = loc
- L.visible_message("[src] escapes from [L]!", "[src] escapes your grip!")
+ L.visible_message("[held_mob] escapes from [L]!", "[held_mob] escapes your grip!")
release()
/obj/item/clothing/head/mob_holder/assume_air(datum/gas_mixture/env)
@@ -170,7 +172,7 @@
location = location.loc
if(ismob(location))
return location.loc.assume_air(env)
- return loc.assume_air(env)
+ return location.assume_air(env)
/obj/item/clothing/head/mob_holder/remove_air(amount)
var/atom/location = loc
@@ -181,4 +183,4 @@
location = location.loc
if(ismob(location))
return location.loc.remove_air(amount)
- return loc.remove_air(amount)
+ return location.remove_air(amount)
diff --git a/code/datums/helper_datums/topic_input.dm b/code/datums/helper_datums/topic_input.dm
deleted file mode 100644
index d07aec067e..0000000000
--- a/code/datums/helper_datums/topic_input.dm
+++ /dev/null
@@ -1,62 +0,0 @@
-/datum/topic_input
- var/href
- var/list/href_list
-
-/datum/topic_input/New(thref,list/thref_list)
- href = thref
- href_list = thref_list.Copy()
- return
-
-/datum/topic_input/proc/get(i)
- return listgetindex(href_list,i)
-
-/datum/topic_input/proc/getAndLocate(i)
- var/t = get(i)
- if(t)
- t = locate(t)
- if (istext(t))
- t = null
- return t || null
-
-/datum/topic_input/proc/getNum(i)
- var/t = get(i)
- if(t)
- t = text2num(t)
- return isnum(t) ? t : null
-
-/datum/topic_input/proc/getObj(i)
- var/t = getAndLocate(i)
- return isobj(t) ? t : null
-
-/datum/topic_input/proc/getMob(i)
- var/t = getAndLocate(i)
- return ismob(t) ? t : null
-
-/datum/topic_input/proc/getTurf(i)
- var/t = getAndLocate(i)
- return isturf(t) ? t : null
-
-/datum/topic_input/proc/getAtom(i)
- return getType(i, /atom)
-
-/datum/topic_input/proc/getArea(i)
- var/t = getAndLocate(i)
- return isarea(t) ? t : null
-
-/datum/topic_input/proc/getStr(i)//params should always be text, but...
- var/t = get(i)
- return istext(t) ? t : null
-
-/datum/topic_input/proc/getType(i,type)
- var/t = getAndLocate(i)
- return istype(t,type) ? t : null
-
-/datum/topic_input/proc/getPath(i)
- var/t = get(i)
- if(t)
- t = text2path(t)
- return ispath(t) ? t : null
-
-/datum/topic_input/proc/getList(i)
- var/t = getAndLocate(i)
- return islist(t) ? t : null
diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm
index 72fe6f5a1c..e0b0072808 100644
--- a/code/datums/holocall.dm
+++ b/code/datums/holocall.dm
@@ -12,7 +12,12 @@
/mob/camera/aiEye/remote/holo/setLoc()
. = ..()
var/obj/machinery/holopad/H = origin
- H.move_hologram(eye_user, loc)
+ H?.move_hologram(eye_user, loc)
+
+/obj/machinery/holopad/remove_eye_control(mob/living/user)
+ if(user.client)
+ user.reset_perspective(null)
+ user.remote_control = null
//this datum manages it's own references
@@ -54,11 +59,6 @@
/datum/holocall/Destroy()
QDEL_NULL(hangup)
- var/user_good = !QDELETED(user)
- if(user_good)
- user.reset_perspective()
- user.remote_control = null
-
if(!QDELETED(eye))
QDEL_NULL(eye)
diff --git a/code/datums/hud.dm b/code/datums/hud.dm
index e2d9bc579f..6b6fcb9691 100644
--- a/code/datums/hud.dm
+++ b/code/datums/hud.dm
@@ -32,7 +32,7 @@ GLOBAL_LIST_INIT(huds, list(
/datum/atom_hud
var/list/atom/hudatoms = list() //list of all atoms which display this hud
- var/list/mob/hudusers = list() //list with all mobs who can see the hud
+ var/list/hudusers = list() //list with all mobs who can see the hud
var/list/hud_icons = list() //these will be the indexes for the atom's hud_list
var/list/next_time_allowed = list() //mobs associated with the next time this hud can be added to them
diff --git a/code/datums/ruins/station.dm b/code/datums/ruins/station.dm
index 17d5a9e1e2..71cdf495e9 100644
--- a/code/datums/ruins/station.dm
+++ b/code/datums/ruins/station.dm
@@ -37,22 +37,22 @@
/datum/map_template/ruin/station/box/engine/teg
id = "engine_teg"
- suffix = "Box/Engine/engine_tesla.dmm"
+ suffix = "Box/Engine/engine_teg.dmm"
name = "Box TEG"
/datum/map_template/ruin/station/box/engine/empty
id = "engine_empty"
- suffix = "Box/Engine/engine_tesla.dmm"
+ suffix = "Box/Engine/empty.dmm"
name = "Box Empty"
/datum/map_template/ruin/station/box/engine/am
id = "engine_am"
- suffix = "Box/Engine/engine_tesla.dmm"
+ suffix = "Box/Engine/engine_am.dmm"
name = "Box Antimatter"
/datum/map_template/ruin/station/box/engine/budget
id = "engine_budget"
- suffix = "Box/Engine/engine_tesla.dmm"
+ suffix = "Box/Engine/budget.dmm"
name = "Box P.A.C.M.A.N"
// Lavaland
@@ -60,4 +60,4 @@
/datum/map_template/ruin/station/lavaland/mining_base
id = "mining_public_01"
suffix = "Lavaland/Mining_Station/Mining_Station_Public_01.dmm"
- name = "Public Mining Base"
\ No newline at end of file
+ name = "Public Mining Base"
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 7e224080b9..83117bad64 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -6,7 +6,6 @@
var/flags_1 = NONE
var/interaction_flags_atom = NONE
- var/ghost_flags = NONE
var/datum/reagents/reagents = null
//This atom's HUD (med/sec, etc) images. Associative list.
diff --git a/code/game/gamemodes/bloodsucker/bloodsucker.dm b/code/game/gamemodes/bloodsucker/bloodsucker.dm
index ca2ebfe00d..a45e989318 100644
--- a/code/game/gamemodes/bloodsucker/bloodsucker.dm
+++ b/code/game/gamemodes/bloodsucker/bloodsucker.dm
@@ -7,7 +7,7 @@
// LISTS //
var/list/vassal_allowed_antags = list(/datum/antagonist/brother, /datum/antagonist/traitor, /datum/antagonist/traitor/internal_affairs, /datum/antagonist/survivalist, \
- /datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee)
+ /datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee, /datum/antagonist/valentine, /datum/antagonist/heartbreaker,)
// The antags you're allowed to be if turning Vassal.
/proc/isvamp(mob/living/M)
return istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/bloodsucker)
diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm
index b054ff89af..674afad88e 100644
--- a/code/game/gamemodes/clown_ops/clown_weapons.dm
+++ b/code/game/gamemodes/clown_ops/clown_weapons.dm
@@ -279,7 +279,6 @@
internals_req_access = list(ACCESS_SYNDICATE)
wreckage = /obj/structure/mecha_wreckage/honker/dark
max_equip = 3
- spawn_tracked = FALSE
/obj/mecha/combat/honker/dark/GrantActions(mob/living/user, human_occupant = 0)
..()
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index abd560171e..7ad4cee884 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -61,7 +61,7 @@
trimmed_list.Remove(M)
continue
if (M.mind)
- if (restrict_ghost_roles && M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL]) // Are they playing a ghost role?
+ if (restrict_ghost_roles && (M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL])) // Are they playing a ghost role?
trimmed_list.Remove(M)
continue
if (M.mind.assigned_role in restricted_roles) // Does their job allow it?
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 2272d3db46..7132f046e6 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -242,7 +242,7 @@ Class Procs:
else
if(interaction_flags_machine & INTERACT_MACHINE_REQUIRES_SILICON)
return FALSE
- if(!Adjacent(user) && !isobserver(user))
+ if(!Adjacent(user))
var/mob/living/carbon/H = user
if(!(istype(H) && H.has_dna() && H.dna.check_mutation(TK)))
return FALSE
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 495e90d305..c9d26905f5 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -17,6 +17,7 @@
var/list/L = list()
var/list/LL = list()
var/hacked = FALSE
+ var/hackable = TRUE
var/disabled = 0
var/shocked = FALSE
var/hack_wire
@@ -371,6 +372,8 @@
/obj/machinery/autolathe/proc/adjust_hacked(state)
hacked = state
+ if(!hackable && hacked)
+ return
for(var/id in SSresearch.techweb_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(id)
if((D.build_type & AUTOLATHE) && ("hacked" in D.category))
@@ -383,6 +386,12 @@
. = ..()
adjust_hacked(TRUE)
+/obj/machinery/autolathe/secure
+ name = "secured autolathe"
+ desc = "An autolathe reprogrammed with security protocols to prevent hacking."
+ hackable = FALSE
+ circuit = /obj/item/circuitboard/machine/autolathe/secure
+
//Called when the object is constructed by an autolathe
//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes
/obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A)
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 8de470fdb8..e5ac9a0f78 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -47,7 +47,10 @@
jump_action.Grant(user)
actions += jump_action
-/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user)
+/obj/machinery/proc/remove_eye_control(mob/living/user)
+ CRASH("[type] does not implement ai eye handling")
+
+/obj/machinery/computer/camera_advanced/remove_eye_control(mob/living/user)
if(!user)
return
for(var/V in actions)
@@ -157,7 +160,7 @@
var/cooldown = 0
var/acceleration = 1
var/mob/living/eye_user = null
- var/obj/machinery/computer/camera_advanced/origin
+ var/obj/machinery/origin
var/eye_initialized = 0
var/visible_icon = 0
var/image/user_image = null
@@ -170,7 +173,7 @@
/mob/camera/aiEye/remote/Destroy()
if(origin && eye_user)
- origin.remove_eye_control(eye_user)
+ origin.remove_eye_control(eye_user,src)
origin = null
. = ..()
eye_user = null
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index e9d3006b06..b33b87f8b1 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -6,7 +6,6 @@
* ~ Zuhayr
*/
-
//Main cryopod console.
/obj/machinery/computer/cryopod
@@ -18,7 +17,6 @@
density = FALSE
interaction_flags_machine = INTERACT_MACHINE_OFFLINE
req_one_access = list(ACCESS_HEADS, ACCESS_ARMORY) //Heads of staff or the warden can go here to claim recover items from their department that people went were cryodormed with.
- var/mode = null
var/menu = 1 //Which menu screen to display
@@ -130,7 +128,8 @@
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
updateUsrDialog()
return
- if(!allow_items) return
+ if(!allow_items)
+ return
if(frozen_items.len == 0)
to_chat(user, "There is nothing to recover from storage.")
@@ -182,7 +181,7 @@
var/last_no_computer_message = 0
// These items are preserved when the process() despawn proc occurs.
- var/list/preserve_items = list(
+ var/static/list/preserve_items = typecacheof(list(
/obj/item/hand_tele,
/obj/item/card/id/captains_spare,
/obj/item/aicard,
@@ -203,9 +202,9 @@
/obj/item/tank/jetpack,
/obj/item/documents,
/obj/item/nuke_core_container
- )
+ ))
// These items will NOT be preserved
- var/list/do_not_preserve_items = list (
+ var/static/list/do_not_preserve_items = typecacheof(list(
/obj/item/mmi/posibrain,
/obj/item/gun/energy/laser/mounted,
/obj/item/gun/energy/e_gun/advtaser/mounted,
@@ -215,7 +214,7 @@
/obj/item/gun/energy/printer,
/obj/item/gun/energy/kinetic_accelerator/cyborg,
/obj/item/gun/energy/laser/cyborg
- )
+ ))
/obj/machinery/cryopod/Initialize(mapload)
. = ..()
@@ -287,14 +286,14 @@
#define CRYO_DESTROY 0
#define CRYO_PRESERVE 1
#define CRYO_OBJECTIVE 2
+#define CRYO_IGNORE 3
/obj/machinery/cryopod/proc/should_preserve_item(obj/item/I)
for(var/datum/objective_item/steal/T in control_computer.theft_cache)
if(istype(I, T.targetitem) && T.check_special_completion(I))
return CRYO_OBJECTIVE
- for(var/T in preserve_items)
- if(istype(I, T) && !(I.type in do_not_preserve_items))
- return CRYO_PRESERVE
+ if(preserve_items[I] && !do_not_preserve_items[I])
+ return CRYO_PRESERVE
return CRYO_DESTROY
// This function can not be undone; do not call this unless you are sure
@@ -303,52 +302,47 @@
find_control_computer()
var/mob/living/mob_occupant = occupant
+ var/list/obj/item/cryo_items = list()
//Handle Borg stuff first
if(iscyborg(mob_occupant))
var/mob/living/silicon/robot/R = mob_occupant
-
- R.contents -= R.mmi
- qdel(R.mmi)
+ if(R.mmi?.brain)
+ cryo_items[R.mmi] = CRYO_IGNORE
+ cryo_items[R.mmi.brain] = CRYO_IGNORE
for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc
for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags
- if(should_preserve_item(O) != CRYO_DESTROY) // Preserve important things inside the item
- continue
+ cryo_items[O] = should_preserve_item(O)
O.forceMove(src)
R.module.remove_module(I, TRUE) //delete the module itself so it doesn't transfer over.
//Drop all items into the pod.
for(var/obj/item/I in mob_occupant)
- mob_occupant.doUnEquip(I)
- I.forceMove(src)
-
+ if(cryo_items[I] == CRYO_IGNORE)
+ continue
+ cryo_items[I] = should_preserve_item(I)
+ mob_occupant.transferItemToLoc(I, src, TRUE)
if(I.contents.len) //Make sure we catch anything not handled by qdel() on the items.
- if(should_preserve_item(I) != CRYO_DESTROY) // Don't remove the contents of things that need preservation
+ if(cryo_items[I] != CRYO_DESTROY) // Don't remove the contents of things that need preservation
continue
for(var/obj/item/O in I.contents)
- if(istype(O, /obj/item/tank)) //Stop eating pockets, you fuck!
- continue
+ cryo_items[O] = should_preserve_item(O)
O.forceMove(src)
- //Delete all items not on the preservation list.
- var/list/items = contents
- items -= mob_occupant // Don't delete the occupant
-
- for(var/obj/item/I in items)
- if(istype(I, /obj/item/pda))
- var/obj/item/pda/P = I
- QDEL_NULL(P.id)
- qdel(P)
+ for(var/A in cryo_items)
+ var/obj/item/I = A
+ if(QDELETED(I)) //edge cases and DROPDEL.
continue
-
- var/preserve = should_preserve_item(I)
- if(preserve == CRYO_DESTROY)
+ var/preserve = cryo_items[I]
+ if(preserve == CRYO_IGNORE)
+ continue
+ else if(preserve == CRYO_DESTROY)
qdel(I)
- else if(control_computer && control_computer.allow_items)
+ else if(control_computer?.allow_items)
control_computer.frozen_items += I
if(preserve == CRYO_OBJECTIVE)
control_computer.objective_items += I
- I.loc = null
+ I.moveToNullspace()
else
I.forceMove(loc)
@@ -417,6 +411,7 @@
#undef CRYO_DESTROY
#undef CRYO_PRESERVE
#undef CRYO_OBJECTIVE
+#undef CRYO_IGNORE
/obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user)
if(!istype(target) || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || !ismob(target) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled)
@@ -443,29 +438,24 @@
var/generic_plsnoleave_message = " Please adminhelp before leaving the round, even if there are no administrators online!"
if(target == user && world.time - target.client.cryo_warned > 5 MINUTES)//if we haven't warned them in the last 5 minutes
- var/caught = FALSE
+ var/list/caught_string
+ var/addendum = ""
if(target.mind.assigned_role in GLOB.command_positions)
- alert("You're a Head of Staff![generic_plsnoleave_message] Be sure to put your locker items back into your locker!")
- caught = TRUE
+ LAZYADD(caught_string, "Head of Staff")
+ addendum = " Be sure to put your locker items back into your locker!"
if(iscultist(target) || is_servant_of_ratvar(target))
- to_chat(target, "You're a Cultist![generic_plsnoleave_message]")
- caught = TRUE
+ LAZYADD(caught_string, "Cultist")
if(is_devil(target))
- alert("You're a Devil![generic_plsnoleave_message]")
- caught = TRUE
- if(istype(SSticker.mode, /datum/antagonist/gang))
- if(target.mind.has_antag_datum(/datum/antagonist/gang))
- alert("You're a Gangster![generic_plsnoleave_message]")
- caught = TRUE
- if(istype(SSticker.mode, /datum/antagonist/rev))
- if(target.mind.has_antag_datum(/datum/antagonist/rev/head))
- alert("You're a Head Revolutionary![generic_plsnoleave_message]")
- caught = TRUE
- else if(target.mind.has_antag_datum(/datum/antagonist/rev))
- alert("You're a Revolutionary![generic_plsnoleave_message]")
- caught = TRUE
+ LAZYADD(caught_string, "Devil")
+ if(target.mind.has_antag_datum(/datum/antagonist/gang))
+ LAZYADD(caught_string, "Gangster")
+ if(target.mind.has_antag_datum(/datum/antagonist/rev/head))
+ LAZYADD(caught_string, "Head Revolutionary")
+ if(target.mind.has_antag_datum(/datum/antagonist/rev))
+ LAZYADD(caught_string, "Revolutionary")
- if(caught)
+ if(caught_string)
+ alert(target, "You're a [english_list(caught_string)]![generic_plsnoleave_message][addendum]")
target.client.cryo_warned = world.time
return
diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm
index 6b0f00ca2e..6b62d18d01 100644
--- a/code/game/machinery/dance_machine.dm
+++ b/code/game/machinery/dance_machine.dm
@@ -202,6 +202,8 @@
for(var/i in 1 to 10)
spawn_atom_to_turf(/obj/effect/temp_visual/hierophant/telegraph/edge, src, 1, FALSE)
sleep(5)
+ if(QDELETED(src))
+ return
#define DISCO_INFENO_RANGE (rand(85, 115)*0.01)
diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm
index 40430b37b7..8275e981de 100644
--- a/code/game/machinery/harvester.dm
+++ b/code/game/machinery/harvester.dm
@@ -71,7 +71,7 @@
say("Subject may not have abiotic items on.")
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1)
return
- if(!(MOB_ORGANIC in C.mob_biotypes))
+ if(!(C.mob_biotypes & MOB_ORGANIC))
say("Subject is not organic.")
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1)
return
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index ebc2533124..221e35118e 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -79,7 +79,7 @@
try_detonate(TRUE)
//Counter terrorists win
else if(!active || defused)
- if(defused && payload in src)
+ if(defused && (payload in src))
payload.defuse()
countdown.stop()
STOP_PROCESSING(SSfastprocess, src)
diff --git a/code/game/machinery/telecomms/machines/receiver.dm b/code/game/machinery/telecomms/machines/receiver.dm
index 0fd3aec012..4dd3af036c 100644
--- a/code/game/machinery/telecomms/machines/receiver.dm
+++ b/code/game/machinery/telecomms/machines/receiver.dm
@@ -33,7 +33,7 @@
for(var/obj/machinery/telecomms/hub/H in links)
for(var/obj/machinery/telecomms/relay/R in H.links)
- if(R.can_receive(signal) && R.z in signal.levels)
+ if(R.can_receive(signal) && (R.z in signal.levels))
return TRUE
return FALSE
diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm
index ae57e5c108..8a4a2fdd9b 100644
--- a/code/game/mecha/combat/combat.dm
+++ b/code/game/mecha/combat/combat.dm
@@ -3,9 +3,9 @@
internal_damage_threshold = 50
armor = list("melee" = 30, "bullet" = 30, "laser" = 15, "energy" = 20, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
mouse_pointer = 'icons/mecha/mecha_mouse.dmi'
- var/spawn_tracked = TRUE
-/obj/mecha/combat/Initialize()
- . = ..()
- if(spawn_tracked)
- trackers += new /obj/item/mecha_parts/mecha_tracking(src)
\ No newline at end of file
+/obj/mecha/combat/proc/max_ammo() //Max the ammo stored for Nuke Ops mechs, or anyone else that calls this
+ for(var/obj/item/I in equipment)
+ if(istype(I, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/))
+ var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun = I
+ gun.projectiles_cache = gun.projectiles_cache_max
\ No newline at end of file
diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm
index 3364bbb9a2..71258d1ccb 100644
--- a/code/game/mecha/combat/gygax.dm
+++ b/code/game/mecha/combat/gygax.dm
@@ -30,7 +30,6 @@
internals_req_access = list(ACCESS_SYNDICATE)
wreckage = /obj/structure/mecha_wreckage/gygax/dark
max_equip = 4
- spawn_tracked = FALSE
/obj/mecha/combat/gygax/dark/loaded/Initialize()
. = ..()
@@ -42,6 +41,7 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
ME.attach(src)
+ max_ammo()
/obj/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null)
if(C)
diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm
index c796cb7c1f..5c60a97864 100644
--- a/code/game/mecha/combat/marauder.dm
+++ b/code/game/mecha/combat/marauder.dm
@@ -17,7 +17,6 @@
force = 45
max_equip = 4
bumpsmash = 1
- spawn_tracked = FALSE
/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0)
..()
@@ -41,6 +40,7 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
ME.attach(src)
+ max_ammo()
/obj/mecha/combat/marauder/seraph
desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
@@ -68,6 +68,7 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
ME.attach(src)
+ max_ammo()
/obj/mecha/combat/marauder/mauler
desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model."
@@ -90,5 +91,6 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
ME.attach(src)
+ max_ammo()
diff --git a/code/game/mecha/combat/neovgre.dm b/code/game/mecha/combat/neovgre.dm
index 8fc1dd97b2..c678912a21 100644
--- a/code/game/mecha/combat/neovgre.dm
+++ b/code/game/mecha/combat/neovgre.dm
@@ -15,7 +15,6 @@
internals_req_access = list()
add_req_access = 0
wreckage = /obj/structure/mecha_wreckage/durand/neovgre
- spawn_tracked = FALSE
/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar!
internals_action.Grant(user, src)
diff --git a/code/game/mecha/combat/reticence.dm b/code/game/mecha/combat/reticence.dm
index 62e891494d..7343a85483 100644
--- a/code/game/mecha/combat/reticence.dm
+++ b/code/game/mecha/combat/reticence.dm
@@ -19,7 +19,6 @@
stepsound = null
turnsound = null
opacity = 0
- spawn_tracked = FALSE
/obj/mecha/combat/reticence/loaded/Initialize()
. = ..()
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index 61ecec40c2..1595c4bb07 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -108,16 +108,17 @@
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Topic(href,href_list)
..()
- var/datum/topic_input/afilter = new /datum/topic_input(href,href_list)
- if(afilter.get("eject"))
+ if(href_list["eject"])
go_out()
- if(afilter.get("view_stats"))
+ if(href_list["view_stats"])
chassis.occupant << browse(get_patient_stats(),"window=msleeper")
onclose(chassis.occupant, "msleeper")
return
- if(afilter.get("inject"))
- inject_reagent(afilter.getType("inject", /datum/reagent),afilter.getObj("source"))
- return
+ if(href_list["inject"])
+ var/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG = locate() in chassis
+ var/datum/reagent/R = locate(href_list["inject"]) in SG.reagents.reagent_list
+ if (istype(R))
+ inject_reagent(R, SG)
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_stats()
if(!patient)
@@ -354,19 +355,18 @@
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Topic(href,href_list)
..()
- var/datum/topic_input/afilter = new (href,href_list)
- if(afilter.get("toggle_mode"))
+ if (href_list["toggle_mode"])
mode = !mode
update_equip_info()
return
- if(afilter.get("select_reagents"))
+ if (href_list["select_reagents"])
processed_reagents.len = 0
var/m = 0
var/message
for(var/i=1 to known_reagents.len)
if(m>=synth_speed)
break
- var/reagent = afilter.get("reagent_[i]")
+ var/reagent = text2path(href_list["reagent_[i]"])
if(reagent && (reagent in known_reagents))
message = "[m ? ", " : null][known_reagents[reagent]]"
processed_reagents += reagent
@@ -375,20 +375,18 @@
message += " added to production"
START_PROCESSING(SSobj, src)
occupant_message(message)
- occupant_message("Reagent processing started.")
+ occupant_message("Reagent processing started.")
mecha_log_message("Reagent processing started.")
return
- if(afilter.get("show_reagents"))
+ if (href_list["show_reagents"])
chassis.occupant << browse(get_reagents_page(),"window=msyringegun")
- if(afilter.get("purge_reagent"))
- var/reagent = afilter.get("purge_reagent")
+ if (href_list["purge_reagent"])
+ var/reagent = href_list["purge_reagent"]
if(reagent)
reagents.del_reagent(reagent)
return
- if(afilter.get("purge_all"))
+ if (href_list["purge_all"])
reagents.clear_reagents()
- return
- return
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_page()
var/output = {"
diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm
index 33d5166481..759fcd996d 100644
--- a/code/game/mecha/equipment/tools/work_tools.dm
+++ b/code/game/mecha/equipment/tools/work_tools.dm
@@ -34,6 +34,19 @@
return
if(!cargo_holder)
return
+ if(ismecha(target))
+ var/obj/mecha/M = target
+ var/have_ammo
+ for(var/obj/item/mecha_ammo/box in cargo_holder.cargo)
+ if(istype(box, /obj/item/mecha_ammo) && box.rounds)
+ have_ammo = TRUE
+ if(M.ammo_resupply(box, chassis.occupant, TRUE))
+ return
+ if(have_ammo)
+ to_chat(chassis.occupant, "No further supplies can be provided to [M].")
+ else
+ to_chat(chassis.occupant, "No providable supplies found in cargo hold")
+ return
if(isobj(target))
var/obj/O = target
if(!O.anchored)
diff --git a/code/game/mecha/equipment/weapons/mecha_ammo.dm b/code/game/mecha/equipment/weapons/mecha_ammo.dm
new file mode 100644
index 0000000000..83a85ffcba
--- /dev/null
+++ b/code/game/mecha/equipment/weapons/mecha_ammo.dm
@@ -0,0 +1,94 @@
+/obj/item/mecha_ammo
+ name = "generic ammo box"
+ desc = "A box of ammo for an unknown weapon."
+ w_class = WEIGHT_CLASS_BULKY
+ icon = 'icons/mecha/mecha_ammo.dmi'
+ icon_state = "empty"
+ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
+ var/rounds = 0
+ var/round_term = "round"
+ var/direct_load //For weapons where we re-load the weapon itself rather than adding to the ammo storage.
+ var/load_audio = "sound/weapons/gun_magazine_insert_empty_1.ogg"
+ var/ammo_type
+
+/obj/item/mecha_ammo/proc/update_name()
+ if(!rounds)
+ name = "empty ammo box"
+ desc = "An exosuit ammuniton box that has since been emptied. Please recycle."
+ icon_state = "empty"
+
+/obj/item/mecha_ammo/attack_self(mob/user)
+ ..()
+ if(rounds)
+ to_chat(user, "You cannot flatten the ammo box until it's empty!")
+ return
+
+ to_chat(user, "You fold [src] flat.")
+ var/I = new /obj/item/stack/sheet/metal(user.loc)
+ qdel(src)
+ user.put_in_hands(I)
+
+/obj/item/mecha_ammo/examine(mob/user)
+ . = ..()
+ if(rounds)
+ . += "There [rounds > 1?"are":"is"] [rounds] [round_term][rounds > 1?"s":""] left."
+
+/obj/item/mecha_ammo/incendiary
+ name = "incendiary ammo"
+ desc = "A box of incendiary ammunition for use with exosuit weapons."
+ icon_state = "incendiary"
+ rounds = 24
+ ammo_type = "incendiary"
+
+/obj/item/mecha_ammo/scattershot
+ name = "scattershot ammo"
+ desc = "A box of scaled-up buckshot, for use in exosuit shotguns."
+ icon_state = "scattershot"
+ rounds = 40
+ ammo_type = "scattershot"
+
+/obj/item/mecha_ammo/lmg
+ name = "machine gun ammo"
+ desc = "A box of linked ammunition, designed for the Ultra AC 2 exosuit weapon."
+ icon_state = "lmg"
+ rounds = 300
+ ammo_type = "lmg"
+
+/obj/item/mecha_ammo/missiles_br
+ name = "breaching missiles"
+ desc = "A box of large missiles, ready for loading into a BRM-6 exosuit missile rack."
+ icon_state = "missile_br"
+ rounds = 6
+ round_term = "missile"
+ direct_load = TRUE
+ load_audio = "sound/weapons/bulletinsert.ogg"
+ ammo_type = "missiles_br"
+
+/obj/item/mecha_ammo/missiles_he
+ name = "anti-armor missiles"
+ desc = "A box of large missiles, ready for loading into an SRM-8 exosuit missile rack."
+ icon_state = "missile_he"
+ rounds = 8
+ round_term = "missile"
+ direct_load = TRUE
+ load_audio = "sound/weapons/bulletinsert.ogg"
+ ammo_type = "missiles_he"
+
+
+/obj/item/mecha_ammo/flashbang
+ name = "launchable flashbangs"
+ desc = "A box of smooth flashbangs, for use with a large exosuit launcher. Cannot be primed by hand."
+ icon_state = "flashbang"
+ rounds = 6
+ round_term = "grenade"
+ ammo_type = "flashbang"
+
+/obj/item/mecha_ammo/clusterbang
+ name = "launchable flashbang clusters"
+ desc = "A box of clustered flashbangs, for use with a specialized exosuit cluster launcher. Cannot be primed by hand."
+ icon_state = "clusterbang"
+ rounds = 3
+ round_term = "cluster"
+ direct_load = TRUE
+ ammo_type = "clusterbang"
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index f5eefb1391..978825c546 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -196,7 +196,11 @@
name = "general ballistic weapon"
fire_sound = 'sound/weapons/gunshot.ogg'
var/projectiles
+ var/projectiles_cache //ammo to be loaded in, if possible.
+ var/projectiles_cache_max
var/projectile_energy_cost
+ var/disabledreload //For weapons with no cache (like the rockets) which are reloaded by hand
+ var/ammo_type
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_shot_amount()
return min(projectiles, projectiles_per_shot)
@@ -209,19 +213,31 @@
return 1
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info()
- return "[..()] \[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - Rearm":null]"
+ return "[..()] \[[src.projectiles][projectiles_cache_max &&!projectile_energy_cost?"/[projectiles_cache]":""]\][!disabledreload &&(src.projectiles < initial(src.projectiles))?" - Rearm":null]"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/rearm()
if(projectiles < initial(projectiles))
var/projectiles_to_add = initial(projectiles) - projectiles
- while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add)
- projectiles++
- projectiles_to_add--
- chassis.use_power(projectile_energy_cost)
- send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
- mecha_log_message("Rearmed [src.name].")
- return 1
+
+ if(projectile_energy_cost)
+ while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add)
+ projectiles++
+ projectiles_to_add--
+ chassis.use_power(projectile_energy_cost)
+
+ else
+ if(!projectiles_cache)
+ return FALSE
+ if(projectiles_to_add <= projectiles_cache)
+ projectiles = projectiles + projectiles_to_add
+ projectiles_cache = projectiles_cache - projectiles_to_add
+ else
+ projectiles = projectiles + projectiles_cache
+ projectiles_cache = 0
+
+ send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info())
+ return TRUE
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/needs_rearm()
@@ -249,8 +265,10 @@
equip_cooldown = 10
projectile = /obj/item/projectile/bullet/incendiary/fnx99
projectiles = 24
- projectile_energy_cost = 15
+ projectiles_cache = 24
+ projectiles_cache_max = 96
harmful = TRUE
+ ammo_type = "incendiary"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced
name = "\improper S.H.H. \"Quietus\" Carbine"
@@ -270,10 +288,12 @@
equip_cooldown = 20
projectile = /obj/item/projectile/bullet/scattershot
projectiles = 40
- projectile_energy_cost = 25
+ projectiles_cache = 40
+ projectiles_cache_max = 160
projectiles_per_shot = 4
variance = 25
harmful = TRUE
+ ammo_type = "scattershot"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/seedscatter
name = "\improper Melon Seed \"Scattershot\""
@@ -282,10 +302,12 @@
equip_cooldown = 20
projectile = /obj/item/projectile/bullet/seed
projectiles = 20
- projectile_energy_cost = 25
+ projectiles_cache = 20
+ projectiles_cache_max = 160
projectiles_per_shot = 10
variance = 25
harmful = TRUE
+ ammo_type = "scattershot"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
name = "\improper Ultra AC 2"
@@ -294,23 +316,42 @@
equip_cooldown = 10
projectile = /obj/item/projectile/bullet/lmg
projectiles = 300
- projectile_energy_cost = 20
+ projectiles_cache = 300
+ projectiles_cache_max = 1200
projectiles_per_shot = 3
variance = 6
randomspread = 1
projectile_delay = 2
harmful = TRUE
+ ammo_type = "lmg"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack
name = "\improper SRM-8 missile rack"
- desc = "A weapon for combat exosuits. Shoots light explosive missiles."
+ desc = "A weapon for combat exosuits. Launches light explosive missiles."
icon_state = "mecha_missilerack"
projectile = /obj/item/projectile/bullet/a84mm_he
fire_sound = 'sound/weapons/grenadelaunch.ogg'
projectiles = 8
- projectile_energy_cost = 1000
+ projectiles_cache = 0
+ projectiles_cache_max = 0
+ disabledreload = TRUE
equip_cooldown = 60
harmful = TRUE
+ ammo_type = "missiles_he"
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/breaching
+ name = "\improper BRM-6 missile rack"
+ desc = "A weapon for combat exosuits. Launches low-explosive breaching missiles designed to explode only when striking a sturdy target."
+ icon_state = "mecha_missilerack_six"
+ projectile = /obj/item/projectile/bullet/a84mm_br
+ fire_sound = 'sound/weapons/grenadelaunch.ogg'
+ projectiles = 6
+ projectiles_cache = 0
+ projectiles_cache_max = 0
+ disabledreload = TRUE
+ equip_cooldown = 60
+ harmful = TRUE
+ ammo_type = "missiles_br"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher
@@ -341,10 +382,12 @@
projectile = /obj/item/grenade/flashbang
fire_sound = 'sound/weapons/grenadelaunch.ogg'
projectiles = 6
+ projectiles_cache = 6
+ projectiles_cache_max = 24
missile_speed = 1.5
- projectile_energy_cost = 800
equip_cooldown = 60
var/det_time = 20
+ ammo_type = "flashbang"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(var/obj/item/grenade/flashbang/F)
var/turf/T = get_turf(src)
@@ -356,9 +399,12 @@
name = "\improper SOB-3 grenade launcher"
desc = "A weapon for combat exosuits. Launches primed clusterbangs. You monster."
projectiles = 3
+ projectiles_cache = 0
+ projectiles_cache_max = 0
+ disabledreload = TRUE
projectile = /obj/item/grenade/clusterbuster
- projectile_energy_cost = 1600 //getting off cheap seeing as this is 3 times the flashbangs held in the grenade launcher.
equip_cooldown = 90
+ ammo_type = "clusterbang"
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar
name = "banana mortar"
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index a2b36f90b2..442e4f5464 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -29,6 +29,7 @@
"H.O.N.K",
"Phazon",
"Exosuit Equipment",
+ "Exosuit Ammunition",
"Cyborg Upgrade Modules",
"Misc"
)
@@ -317,9 +318,8 @@
/obj/machinery/mecha_part_fabricator/Topic(href, href_list)
if(..())
return
- var/datum/topic_input/afilter = new /datum/topic_input(href,href_list)
if(href_list["part_set"])
- var/tpart_set = afilter.getStr("part_set")
+ var/tpart_set = href_list["part_set"]
if(tpart_set)
if(tpart_set=="clear")
part_set = null
@@ -327,7 +327,7 @@
part_set = tpart_set
screen = "parts"
if(href_list["part"])
- var/T = afilter.getStr("part")
+ var/T = href_list["part"]
for(var/v in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
@@ -338,7 +338,7 @@
add_to_queue(D)
break
if(href_list["add_to_queue"])
- var/T = afilter.getStr("add_to_queue")
+ var/T = href_list["add_to_queue"]
for(var/v in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
@@ -347,10 +347,10 @@
break
return update_queue_on_page()
if(href_list["remove_from_queue"])
- remove_from_queue(afilter.getNum("remove_from_queue"))
+ remove_from_queue(text2num(href_list["remove_from_queue"]))
return update_queue_on_page()
if(href_list["partset_to_queue"])
- add_part_set_to_queue(afilter.get("partset_to_queue"))
+ add_part_set_to_queue(href_list["partset_to_queue"])
return update_queue_on_page()
if(href_list["process_queue"])
spawn(0)
@@ -364,8 +364,8 @@
if(href_list["screen"])
screen = href_list["screen"]
if(href_list["queue_move"] && href_list["index"])
- var/index = afilter.getNum("index")
- var/new_index = index + afilter.getNum("queue_move")
+ var/index = text2num(href_list["index"])
+ var/new_index = index + text2num(href_list["queue_move"])
if(isnum(index) && isnum(new_index) && ISINTEGER(index) && ISINTEGER(new_index))
if(ISINRANGE(new_index,1,queue.len))
queue.Swap(index,new_index)
@@ -376,7 +376,7 @@
if(href_list["sync"])
sync()
if(href_list["part_desc"])
- var/T = afilter.getStr("part_desc")
+ var/T = href_list["part_desc"]
for(var/v in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(D.build_type & MECHFAB)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index b279f90740..669bc89875 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -867,7 +867,7 @@
return
/obj/mecha/proc/moved_inside(mob/living/carbon/human/H)
- if(H && H.client && H in range(1))
+ if(H?.client && (H in range(1)))
occupant = H
H.forceMove(src)
H.update_mouse_pointer()
@@ -1070,3 +1070,53 @@
if(occupant_sight_flags)
if(user == occupant)
user.sight |= occupant_sight_flags
+
+///////////////////////
+////// Ammo stuff /////
+///////////////////////
+
+/obj/mecha/proc/ammo_resupply(var/obj/item/mecha_ammo/A, mob/user,var/fail_chat_override = FALSE)
+ if(!A.rounds)
+ if(!fail_chat_override)
+ to_chat(user, "This box of ammo is empty!")
+ return FALSE
+ var/ammo_needed
+ var/found_gun
+ for(var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun in equipment)
+ ammo_needed = 0
+
+ if(istype(gun, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic) && gun.ammo_type == A.ammo_type)
+ found_gun = TRUE
+ if(A.direct_load)
+ ammo_needed = initial(gun.projectiles) - gun.projectiles
+ else
+ ammo_needed = gun.projectiles_cache_max - gun.projectiles_cache
+
+ if(ammo_needed)
+ if(ammo_needed < A.rounds)
+ if(A.direct_load)
+ gun.projectiles = gun.projectiles + ammo_needed
+ else
+ gun.projectiles_cache = gun.projectiles_cache + ammo_needed
+ playsound(get_turf(user),A.load_audio,50,1)
+ to_chat(user, "You add [ammo_needed] [A.round_term][ammo_needed > 1?"s":""] to the [gun.name]")
+ A.rounds = A.rounds - ammo_needed
+ A.update_name()
+ return TRUE
+
+ else
+ if(A.direct_load)
+ gun.projectiles = gun.projectiles + A.rounds
+ else
+ gun.projectiles_cache = gun.projectiles_cache + A.rounds
+ playsound(get_turf(user),A.load_audio,50,1)
+ to_chat(user, "You add [A.rounds] [A.round_term][A.rounds > 1?"s":""] to the [gun.name]")
+ A.rounds = 0
+ A.update_name()
+ return TRUE
+ if(!fail_chat_override)
+ if(found_gun)
+ to_chat(user, "You can't fit any more ammo of this type!")
+ else
+ to_chat(user, "None of the equipment on this exosuit can use this ammo!")
+ return FALSE
diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm
index 071fe18408..de1c035000 100644
--- a/code/game/mecha/mecha_construction_paths.dm
+++ b/code/game/mecha/mecha_construction_paths.dm
@@ -116,7 +116,7 @@
//9
list(
- "key" = /obj/item/stock_parts/cell,
+ "key" = /obj/item/stock_parts/scanning_module,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Peripherals control module is secured."
@@ -126,10 +126,40 @@
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
- "desc" = "The power cell is installed."
+ "desc" = "The scanner module is installed."
),
//11
+ list(
+ "key" = /obj/item/stock_parts/capacitor,
+ "action" = ITEM_MOVE_INSIDE,
+ "back_key" = TOOL_SCREWDRIVER,
+ "desc" = "Scanner module is secured."
+ ),
+
+ //12
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "back_key" = TOOL_CROWBAR,
+ "desc" = "Capacitor is installed."
+ ),
+
+ //13
+ list(
+ "key" = /obj/item/stock_parts/cell,
+ "action" = ITEM_MOVE_INSIDE,
+ "back_key" = TOOL_SCREWDRIVER,
+ "desc" = "Capacitor is secured."
+ ),
+
+ //14
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "back_key" = TOOL_CROWBAR,
+ "desc" = "The power cell is installed."
+ ),
+
+ //15
list(
"key" = /obj/item/stack/sheet/metal,
"amount" = 5,
@@ -137,21 +167,21 @@
"desc" = "The power cell is secured."
),
- //12
+ //16
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "Internal armor is installed."
),
- //13
+ //17
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
"desc" = "Internal armor is wrenched."
),
- //14
+ //18
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -159,14 +189,14 @@
"desc" = "Internal armor is welded."
),
- //15
+ //19
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "External armor is installed."
),
- //16
+ //20
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
@@ -222,36 +252,56 @@
else
user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.")
if(10)
+ if(diff==FORWARD)
+ user.visible_message("[user] secures the scanner module.", "You secure the scanner module.")
+ else
+ user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].")
+ if(11)
+ if(diff==FORWARD)
+ user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].")
+ else
+ user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.")
+ if(12)
+ if(diff==FORWARD)
+ user.visible_message("[user] secures [I].", "You secure [I].")
+ else
+ user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].")
+ if(13)
+ if(diff==FORWARD)
+ user.visible_message("[user] installs [I].", "You install [I].")
+ else
+ user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].")
+ if(14)
if(diff==FORWARD)
user.visible_message("[user] secures the power cell.", "You secure the power cell.")
else
user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].")
- if(11)
+ if(15)
if(diff==FORWARD)
user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].")
else
user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.")
- if(12)
+ if(16)
if(diff==FORWARD)
user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.")
else
user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].")
- if(13)
+ if(17)
if(diff==FORWARD)
user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].")
else
user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.")
- if(14)
+ if(18)
if(diff==FORWARD)
user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].")
else
user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].")
- if(15)
+ if(19)
if(diff==FORWARD)
user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.")
else
user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].")
- if(16)
+ if(20)
if(diff==FORWARD)
user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].")
else
@@ -629,7 +679,7 @@
//9
list(
- "key" = /obj/item/stock_parts/cell,
+ "key" = /obj/item/stock_parts/scanning_module,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Peripherals control module is secured."
@@ -639,10 +689,40 @@
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
- "desc" = "The power cell is installed."
+ "desc" = "The scanner module is installed."
),
//11
+ list(
+ "key" = /obj/item/stock_parts/capacitor,
+ "action" = ITEM_MOVE_INSIDE,
+ "back_key" = TOOL_SCREWDRIVER,
+ "desc" = "The scanner module is secured."
+ ),
+
+ //12
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "back_key" = TOOL_CROWBAR,
+ "desc" = "The capacitor is installed."
+ ),
+
+ //13
+ list(
+ "key" = /obj/item/stock_parts/cell,
+ "action" = ITEM_MOVE_INSIDE,
+ "back_key" = TOOL_SCREWDRIVER,
+ "desc" = "The capacitor is secured."
+ ),
+
+ //14
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "back_key" = TOOL_CROWBAR,
+ "desc" = "The power cell is installed."
+ ),
+
+ //15
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -650,21 +730,21 @@
"desc" = "The power cell is secured."
),
- //12
+ //16
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "Internal armor is installed."
),
- //13
+ //17
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
"desc" = "Internal armor is wrenched."
),
- //14
+ //18
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -672,7 +752,7 @@
"desc" = "Internal armor is welded."
),
- //15
+ //19
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -680,14 +760,14 @@
"desc" = "External armor is being installed."
),
- //16
+ //20
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "External armor is installed."
),
- //17
+ //21
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
@@ -744,41 +824,61 @@
else
user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.")
if(10)
+ if(diff==FORWARD)
+ user.visible_message("[user] secures the scanner module.", "You secure the scanner module.")
+ else
+ user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].")
+ if(12)
+ if(diff==FORWARD)
+ user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].")
+ else
+ user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.")
+ if(13)
+ if(diff==FORWARD)
+ user.visible_message("[user] secures the capacitor.", "You secure the capacitor.")
+ else
+ user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].")
+ if(14)
+ if(diff==FORWARD)
+ user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].")
+ else
+ user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.")
+ if(15)
if(diff==FORWARD)
user.visible_message("[user] secures the power cell.", "You secure the power cell.")
else
user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].")
- if(11)
+ if(16)
if(diff==FORWARD)
user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].")
else
user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.")
- if(12)
+ if(17)
if(diff==FORWARD)
user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.")
else
user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].")
- if(13)
+ if(18)
if(diff==FORWARD)
user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].")
else
user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.")
- if(14)
+ if(19)
if(diff==FORWARD)
user.visible_message("[user] starts to install the external armor layer to [parent].", "You install the external armor layer to [parent].")
else
user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].")
- if(15)
+ if(20)
if(diff==FORWARD)
user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].")
else
user.visible_message("[user] removes the external armor from [parent].", "You remove the external armor from [parent].")
- if(16)
+ if(21)
if(diff==FORWARD)
user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.")
else
user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].")
- if(17)
+ if(22)
if(diff==FORWARD)
user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].")
else
@@ -796,6 +896,7 @@
/obj/item/mecha_parts/part/honker_head
)
+
/datum/component/construction/mecha/honker
result = /obj/mecha/combat/honker
steps = list(
@@ -837,41 +938,70 @@
"key" = /obj/item/bikehorn
),
+ //6
+ list(
+ "key" = /obj/item/stock_parts/scanning_module,
+ "action" = ITEM_MOVE_INSIDE
+ ),
+
//8
+ list(
+ "key" = /obj/item/bikehorn
+ ),
+
+ //9
+ list(
+ "key" = /obj/item/stock_parts/capacitor,
+ "action" = ITEM_MOVE_INSIDE
+ ),
+
+ //10
+ list(
+ "key" = /obj/item/bikehorn
+ ),
+
+ //11
list(
"key" = /obj/item/stock_parts/cell,
"action" = ITEM_MOVE_INSIDE
),
- //9
+ //12
list(
"key" = /obj/item/bikehorn
),
- //10
+ //13
list(
"key" = /obj/item/clothing/mask/gas/clown_hat,
"action" = ITEM_DELETE
),
- //11
+ //14
list(
"key" = /obj/item/bikehorn
),
- //12
+ //15
list(
"key" = /obj/item/clothing/shoes/clown_shoes,
"action" = ITEM_DELETE
),
- //13
+ //16
list(
"key" = /obj/item/bikehorn
),
)
// HONK doesn't have any construction step icons, so we just set an icon once.
+/datum/component/construction/mecha/honker/update_parent(step_index)
+ if(step_index == 1)
+ var/atom/parent_atom = parent
+ parent_atom.icon = 'icons/mecha/mech_construct.dmi'
+ parent_atom.icon_state = "honker_chassis"
+ ..()
+// HONK doesn't have any construction step icons, so we just set an icon once.
/datum/component/construction/mecha/honker/update_parent(step_index)
if(step_index == 1)
var/atom/parent_atom = parent
@@ -898,8 +1028,12 @@
if(8)
user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].")
if(10)
- user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].")
+ user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].")
if(12)
+ user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].")
+ if(14)
+ user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].")
+ if(16)
user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].")
return TRUE
@@ -1626,10 +1760,9 @@
"back_key" = TOOL_CROWBAR,
"desc" = "Peripherals control module is installed."
),
-
//9
list(
- "key" = /obj/item/stock_parts/cell,
+ "key" = /obj/item/stock_parts/scanning_module,
"action" = ITEM_MOVE_INSIDE,
"back_key" = TOOL_SCREWDRIVER,
"desc" = "Peripherals control module is secured."
@@ -1639,10 +1772,40 @@
list(
"key" = TOOL_SCREWDRIVER,
"back_key" = TOOL_CROWBAR,
- "desc" = "The power cell is installed."
+ "desc" = "Scanner module is installed."
),
//11
+ list(
+ "key" = /obj/item/stock_parts/capacitor,
+ "action" = ITEM_MOVE_INSIDE,
+ "back_key" = TOOL_SCREWDRIVER,
+ "desc" = "Scanner module is secured."
+ ),
+
+ //12
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "back_key" = TOOL_CROWBAR,
+ "desc" = "Capacitor is installed."
+ ),
+
+ //13
+ list(
+ "key" = /obj/item/stock_parts/cell,
+ "action" = ITEM_MOVE_INSIDE,
+ "back_key" = TOOL_SCREWDRIVER,
+ "desc" = "Capacitor is secured."
+ ),
+
+ //11
+ list(
+ "key" = TOOL_SCREWDRIVER,
+ "back_key" = TOOL_CROWBAR,
+ "desc" = "The power cell is installed."
+ ),
+
+ //12
list(
"key" = /obj/item/stack/sheet/metal,
"amount" = 5,
@@ -1650,21 +1813,21 @@
"desc" = "The power cell is secured."
),
- //12
+ //13
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "Internal armor is installed."
),
- //13
+ //14
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
"desc" = "Internal armor is wrenched."
),
- //14
+ //15
list(
"key" = /obj/item/stack/sheet/plasteel,
"amount" = 5,
@@ -1672,14 +1835,14 @@
"desc" = "Internal armor is welded."
),
- //15
+ //16
list(
"key" = TOOL_WRENCH,
"back_key" = TOOL_CROWBAR,
"desc" = "External armor is installed."
),
- //16
+ //17
list(
"key" = TOOL_WELDER,
"back_key" = TOOL_WRENCH,
@@ -1736,36 +1899,56 @@
else
user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.")
if(10)
+ if(diff==FORWARD)
+ user.visible_message("[user] secures the scanner module.", "You secure the scanner module.")
+ else
+ user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].")
+ if(11)
+ if(diff==FORWARD)
+ user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].")
+ else
+ user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.")
+ if(12)
+ if(diff==FORWARD)
+ user.visible_message("[user] secures the capacitor.", "You secure the capacitor.")
+ else
+ user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].")
+ if(13)
+ if(diff==FORWARD)
+ user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].")
+ else
+ user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.")
+ if(14)
if(diff==FORWARD)
user.visible_message("[user] secures the power cell.", "You secure the power cell.")
else
user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].")
- if(11)
+ if(15)
if(diff==FORWARD)
user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].")
else
user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.")
- if(12)
+ if(16)
if(diff==FORWARD)
user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.")
else
user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].")
- if(13)
+ if(17)
if(diff==FORWARD)
user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].")
else
user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.")
- if(14)
+ if(18)
if(diff==FORWARD)
user.visible_message("[user] installs the external armor layer to [parent].", "You install the external reinforced armor layer to [parent].")
else
user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].")
- if(15)
+ if(19)
if(diff==FORWARD)
user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.")
else
user.visible_message("[user] pries the external armor layer from [parent].", "You pry the external armor layer from [parent].")
- if(16)
+ if(20)
if(diff==FORWARD)
user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].")
else
diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm
index 0188419f0f..61e6c8e5e4 100644
--- a/code/game/mecha/mecha_control_console.dm
+++ b/code/game/mecha/mecha_control_console.dm
@@ -39,21 +39,24 @@
/obj/machinery/computer/mecha/Topic(href, href_list)
if(..())
return
- var/datum/topic_input/afilter = new /datum/topic_input(href,href_list)
if(href_list["send_message"])
- var/obj/item/mecha_parts/mecha_tracking/MT = afilter.getObj("send_message")
+ var/obj/item/mecha_parts/mecha_tracking/MT = locate(href_list["send_message"])
+ if (!istype(MT))
+ return
var/message = stripped_input(usr,"Input message","Transmit message")
var/obj/mecha/M = MT.in_mecha()
if(trim(message) && M)
M.occupant_message(message)
return
if(href_list["shock"])
- var/obj/item/mecha_parts/mecha_tracking/MT = afilter.getObj("shock")
- MT.shock()
+ var/obj/item/mecha_parts/mecha_tracking/MT = locate(href_list["shock"])
+ if (istype(MT))
+ MT.shock()
if(href_list["get_log"])
- var/obj/item/mecha_parts/mecha_tracking/MT = afilter.getObj("get_log")
- stored_data = MT.get_mecha_log()
- screen = 1
+ var/obj/item/mecha_parts/mecha_tracking/MT = locate(href_list["get_log"])
+ if(istype(MT))
+ stored_data = MT.get_mecha_log()
+ screen = 1
if(href_list["return"])
screen = 0
updateUsrDialog()
diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm
index 3a448f4f92..08843c9202 100644
--- a/code/game/mecha/mecha_defense.dm
+++ b/code/game/mecha/mecha_defense.dm
@@ -172,6 +172,10 @@
to_chat(user, "[src]-[W] interface initialization failed.")
return
+ if(istype(W, /obj/item/mecha_ammo))
+ ammo_resupply(W, user)
+ return
+
if(istype(W, /obj/item/mecha_parts/mecha_equipment))
var/obj/item/mecha_parts/mecha_equipment/E = W
spawn()
diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm
index 1e0674d7bb..774e30fa5d 100644
--- a/code/game/mecha/mecha_topic.dm
+++ b/code/game/mecha/mecha_topic.dm
@@ -221,73 +221,71 @@
if(usr.incapacitated())
return
- var/datum/topic_input/afilter = new /datum/topic_input(href,href_list)
-
if(in_range(src, usr))
+ var/obj/item/card/id/id_card
+ if (href_list["id_card"])
+ id_card = locate(href_list["id_card"])
+ if (!istype(id_card))
+ return
if(href_list["req_access"] && add_req_access)
- output_access_dialog(afilter.getObj("id_card"),afilter.getMob("user"))
+ output_access_dialog(id_card, usr)
if(href_list["maint_access"] && maint_access)
- var/mob/user = afilter.getMob("user")
- if(user)
- if(state==0)
- state = 1
- to_chat(user, "The securing bolts are now exposed.")
- else if(state==1)
- state = 0
- to_chat(user, "The securing bolts are now hidden.")
- output_maintenance_dialog(afilter.getObj("id_card"),user)
+ if(state==0)
+ state = 1
+ to_chat(usr, "The securing bolts are now exposed.")
+ else if(state==1)
+ state = 0
+ to_chat(usr, "The securing bolts are now hidden.")
+ output_maintenance_dialog(id_card, usr)
if(href_list["set_internal_tank_valve"] && state >=1)
- var/mob/user = afilter.getMob("user")
- if(user)
- var/new_pressure = input(user,"Input new output pressure","Pressure setting",internal_tank_valve) as num
- if(new_pressure)
- internal_tank_valve = new_pressure
- to_chat(user, "The internal pressure valve has been set to [internal_tank_valve]kPa.")
+ var/new_pressure = input(usr,"Input new output pressure","Pressure setting",internal_tank_valve) as num
+ if(new_pressure)
+ internal_tank_valve = new_pressure
+ to_chat(usr, "The internal pressure valve has been set to [internal_tank_valve]kPa.")
- if(href_list["add_req_access"] && add_req_access && afilter.getObj("id_card"))
- operation_req_access += afilter.getNum("add_req_access")
- output_access_dialog(afilter.getObj("id_card"),afilter.getMob("user"))
+ if(href_list["add_req_access"] && add_req_access)
+ operation_req_access += text2num(href_list["add_req_access"])
+ output_access_dialog(id_card, usr)
- if(href_list["del_req_access"] && add_req_access && afilter.getObj("id_card"))
- operation_req_access -= afilter.getNum("del_req_access")
- output_access_dialog(afilter.getObj("id_card"),afilter.getMob("user"))
+ if(href_list["del_req_access"] && add_req_access)
+ operation_req_access -= text2num(href_list["add_req_access"])
+ output_access_dialog(id_card, usr)
if(href_list["finish_req_access"])
add_req_access = 0
- var/mob/user = afilter.getMob("user")
- user << browse(null,"window=exosuit_add_access")
+ usr << browse(null,"window=exosuit_add_access")
if(usr != occupant)
return
if(href_list["update_content"])
- send_byjax(src.occupant,"exosuit.browser","content",src.get_stats_part())
+ send_byjax(usr,"exosuit.browser","content",src.get_stats_part())
if(href_list["select_equip"])
- var/obj/item/mecha_parts/mecha_equipment/equip = afilter.getObj("select_equip")
+ var/obj/item/mecha_parts/mecha_equipment/equip = locate(href_list["select_equip"]) in src
if(equip && equip.selectable)
- src.selected = equip
- src.occupant_message("You switch to [equip]")
- src.visible_message("[src] raises [equip]")
- send_byjax(src.occupant,"exosuit.browser","eq_list",src.get_equipment_list())
+ selected = equip
+ occupant_message("You switch to [equip]")
+ visible_message("[src] raises [equip]")
+ send_byjax(usr, "exosuit.browser","eq_list", get_equipment_list())
if(href_list["rmictoggle"])
radio.broadcasting = !radio.broadcasting
- send_byjax(src.occupant,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged"))
+ send_byjax(usr,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged"))
if(href_list["rspktoggle"])
radio.listening = !radio.listening
- send_byjax(src.occupant,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged"))
+ send_byjax(usr,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged"))
if(href_list["rfreq"])
- var/new_frequency = (radio.frequency + afilter.getNum("rfreq"))
+ var/new_frequency = (radio.frequency + text2num(href_list["rfreq"]))
if (!radio.freerange || (radio.frequency < MIN_FREE_FREQ || radio.frequency > MAX_FREE_FREQ))
new_frequency = sanitize_frequency(new_frequency)
radio.set_frequency(new_frequency)
- send_byjax(src.occupant,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]")
+ send_byjax(usr,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]")
if (href_list["view_log"])
src.occupant << browse(src.get_log_html(), "window=exosuit_log")
@@ -302,14 +300,14 @@
if (href_list["toggle_id_upload"])
add_req_access = !add_req_access
- send_byjax(src.occupant,"exosuit.browser","t_id_upload","[add_req_access?"L":"Unl"]ock ID upload panel")
+ send_byjax(usr,"exosuit.browser","t_id_upload","[add_req_access?"L":"Unl"]ock ID upload panel")
if(href_list["toggle_maint_access"])
if(state)
occupant_message("Maintenance protocols in effect")
return
maint_access = !maint_access
- send_byjax(src.occupant,"exosuit.browser","t_maint_access","[maint_access?"Forbid":"Permit"] maintenance protocols")
+ send_byjax(usr,"exosuit.browser","t_maint_access","[maint_access?"Forbid":"Permit"] maintenance protocols")
if (href_list["toggle_port_connection"])
if(internal_tank.connected_port)
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index 41f8984570..845b208db1 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -146,7 +146,7 @@
..()
if(href_list["drop_from_cargo"])
var/obj/O = locate(href_list["drop_from_cargo"])
- if(O && O in src.cargo)
+ if(O && (O in cargo))
occupant_message("You unload [O].")
O.forceMove(drop_location())
cargo -= O
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 30e7c8be05..5720d5ce34 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -11,7 +11,7 @@
LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
- create_reagents(300)
+ create_reagents(300, NONE, NO_REAGENTS_VALUE)
if(loc && isturf(loc))
for(var/obj/effect/decal/cleanable/C in loc)
if(C != src && C.type == type && !QDELETED(C))
diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm
index 38a1a6089e..f98b4937ef 100644
--- a/code/game/objects/effects/effect_system/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/effects_foam.dm
@@ -94,7 +94,7 @@
/obj/effect/particle_effect/foam/Initialize()
. = ..()
MakeSlippery()
- create_reagents(1000) //limited by the size of the reagent holder anyway.
+ create_reagents(1000, NONE, NO_REAGENTS_VALUE) //limited by the size of the reagent holder anyway.
START_PROCESSING(SSfastprocess, src)
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm
index 40452f68e2..80c0db2b7d 100644
--- a/code/game/objects/effects/effect_system/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/effects_smoke.dm
@@ -32,7 +32,7 @@
/obj/effect/particle_effect/smoke/Initialize()
. = ..()
- create_reagents(500)
+ create_reagents(500, NONE, NO_REAGENTS_VALUE)
START_PROCESSING(SSobj, src)
diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm
index e63474dd6f..b7c76cad2d 100644
--- a/code/game/objects/items/airlock_painter.dm
+++ b/code/game/objects/items/airlock_painter.dm
@@ -67,7 +67,7 @@
L.Remove()
// make some colorful reagent, and apply it to the lungs
- L.create_reagents(10)
+ L.create_reagents(10, NONE, NO_REAGENTS_VALUE)
L.reagents.add_reagent(/datum/reagent/colorful_reagent, 10)
L.reagents.reaction(L, TOUCH, 1)
diff --git a/code/game/objects/items/boombox.dm b/code/game/objects/items/boombox.dm
index 10d12f1973..3b93480e43 100644
--- a/code/game/objects/items/boombox.dm
+++ b/code/game/objects/items/boombox.dm
@@ -23,7 +23,7 @@
if(!boomingandboxing)
var/list/tracklist = list()
for(var/datum/track/S in SSjukeboxes.songs)
- if(istype(S) && S.song_associated_id in availabletrackids)
+ if(istype(S) && (S.song_associated_id in availabletrackids))
tracklist[S.song_name] = S
var/selected = input(user, "Play song", "Track:") as null|anything in tracklist
if(QDELETED(src) || !selected || !istype(tracklist[selected], /datum/track))
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index f40b7f5c49..4de3e4ff96 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -250,6 +250,7 @@ update_label("John Doe", "Clowny")
name = "agent card"
access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE)
var/anyone = FALSE //Can anyone forge the ID or just syndicate?
+ var/forged = FALSE //have we set a custom name and job assignment, or will we use what we're given when we chameleon change?
/obj/item/card/id/syndicate/Initialize()
. = ..()
@@ -265,26 +266,52 @@ update_label("John Doe", "Clowny")
var/obj/item/card/id/I = O
src.access |= I.access
if(isliving(user) && user.mind)
- if(user.mind.special_role)
+ if(user.mind.special_role || anyone)
to_chat(usr, "The card's microscanners activate as you pass it over the ID, copying its access.")
/obj/item/card/id/syndicate/attack_self(mob/user)
if(isliving(user) && user.mind)
- if(user.mind.special_role || anyone)
- if(alert(user, "Action", "Agent ID", "Show", "Forge") == "Forge")
- var/input_name = reject_bad_name(stripped_input(user, "What name would you like to put on this card?", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name), MAX_NAME_LEN), TRUE)
- if(!input_name)
- return
+ var/first_use = registered_name ? FALSE : TRUE
+ if(!(user.mind.special_role || anyone)) //Unless anyone is allowed, only syndies can use the card, to stop metagaming.
+ if(first_use) //If a non-syndie is the first to forge an unassigned agent ID, then anyone can forge it.
+ anyone = TRUE
+ else
+ return ..()
- var/u = stripped_input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant", MAX_MESSAGE_LEN)
- if(!u)
- registered_name = ""
- return
- assignment = u
- update_label()
- to_chat(user, "You successfully forge the ID card.")
+ var/popup_input = alert(user, "Choose Action", "Agent ID", "Show", "Forge/Reset")
+ if(user.incapacitated())
+ return
+ if(popup_input == "Forge/Reset" && !forged)
+ var/input_name = stripped_input(user, "What name would you like to put on this card? Leave blank to randomise.", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name), MAX_NAME_LEN)
+ input_name = reject_bad_name(input_name)
+ if(!input_name)
+ // Invalid/blank names give a randomly generated one.
+ if(user.gender == MALE)
+ input_name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]"
+ else if(user.gender == FEMALE)
+ input_name = "[pick(GLOB.first_names_female)] [pick(GLOB.last_names)]"
+ else
+ input_name = "[pick(GLOB.first_names)] [pick(GLOB.last_names)]"
+
+ var/target_occupation = stripped_input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", assignment ? assignment : "Assistant", MAX_MESSAGE_LEN)
+ if(!target_occupation)
return
- ..()
+ registered_name = input_name
+ assignment = target_occupation
+ update_label()
+ forged = TRUE
+ to_chat(user, "You successfully forge the ID card.")
+ log_game("[key_name(user)] has forged \the [initial(name)] with name \"[registered_name]\" and occupation \"[assignment]\".")
+ return
+ else if (popup_input == "Forge/Reset" && forged)
+ registered_name = initial(registered_name)
+ assignment = initial(assignment)
+ log_game("[key_name(user)] has reset \the [initial(name)] named \"[src]\" to default.")
+ update_label()
+ forged = FALSE
+ to_chat(user, "You successfully reset the ID card.")
+ return
+ return ..()
/obj/item/card/id/syndicate/anyone
anyone = TRUE
diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm
index 1186ea8001..cd163e90a4 100644
--- a/code/game/objects/items/cigs_lighters.dm
+++ b/code/game/objects/items/cigs_lighters.dm
@@ -122,7 +122,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/cigarette/Initialize()
. = ..()
- create_reagents(chem_volume, INJECTABLE | NO_REACT) // so it doesn't react until you light it
+ create_reagents(chem_volume, INJECTABLE | NO_REACT, NO_REAGENTS_VALUE) // so it doesn't react until you light it
if(list_reagents)
reagents.add_reagent_list(list_reagents)
if(starts_lit)
@@ -717,7 +717,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/vape/Initialize(mapload, param_color)
. = ..()
- create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it
+ create_reagents(chem_volume, NO_REACT, NO_REAGENTS_VALUE) // so it doesn't react until you light it
reagents.add_reagent(/datum/reagent/drug/nicotine, 50)
if(!icon_state)
if(!param_color)
diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm
index 2196246b03..df0a4e6cf3 100644
--- a/code/game/objects/items/circuitboards/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm
@@ -35,6 +35,10 @@
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/sheet/glass = 1)
+/obj/item/circuitboard/machine/autolathe/secure
+ name = "Secure Autolathe (Machine Board)"
+ build_path = /obj/machinery/autolathe/secure
+
/obj/item/circuitboard/machine/bloodbankgen
name = "Blood Bank Generator (Machine Board)"
build_path = /obj/machinery/bloodbankgen
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 81c5083ef7..49f8a90901 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -96,7 +96,7 @@
charges_left = charges
if(!reagents)
- create_reagents(charges_left * volume_multiplier)
+ create_reagents(charges_left * volume_multiplier, NONE, NO_REAGENTS_VALUE)
reagents.clear_reagents()
var/total_weight = 0
@@ -619,7 +619,7 @@
is_capped = TRUE
self_contained = FALSE // Don't disappear when they're empty
can_change_colour = TRUE
-
+
reagent_contents = list(/datum/reagent/fuel = 1, /datum/reagent/consumable/ethanol = 1)
pre_noise = TRUE
@@ -710,7 +710,8 @@
if(isobj(target))
if(actually_paints)
- if(color_hex2num(paint_color) < 350 && !istype(target, /obj/structure/window) && !istype(target, /obj/effect/decal/cleanable/crayon)) //Colors too dark are rejected
+ var/list/hsl = rgb2hsl(hex2num(copytext(paint_color,2,4)),hex2num(copytext(paint_color,4,6)),hex2num(copytext(paint_color,6,8)))
+ if(hsl[3] < 0.25 && !istype(target, /obj/structure/window) && !istype(target, /obj/effect/decal/cleanable/crayon)) //Colors too dark are rejected
to_chat(usr, "A color that dark on an object like this? Surely not...")
return FALSE
diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm
index 7576fe83cc..1006fe9146 100644
--- a/code/game/objects/items/devices/PDA/cart.dm
+++ b/code/game/objects/items/devices/PDA/cart.dm
@@ -563,22 +563,22 @@ Code:
if (53) // Newscaster
menu = "
[PDAIMG(notes)] Newscaster Access
"
menu += "
Current Newsfeed: [current_channel ? current_channel : "None"]
"
- var/datum/newscaster/feed_channel/current
- for(var/datum/newscaster/feed_channel/chan in GLOB.news_network.network_channels)
+ var/datum/news/feed_channel/current
+ for(var/datum/news/feed_channel/chan in GLOB.news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(!current)
menu += " ERROR : NO CHANNEL FOUND
"
return
var/i = 1
- for(var/datum/newscaster/feed_message/msg in current.messages)
+ for(var/datum/news/feed_message/msg in current.messages)
menu +="-[msg.returnBody(-1)]
\[Story by [msg.returnAuthor(-1)]\]
"
menu +="[msg.comments.len] comment[msg.comments.len > 1 ? "s" : ""]
"
if(msg.img)
user << browse_rsc(msg.img, "tmp_photo[i].png")
menu +="
"
i++
- for(var/datum/newscaster/feed_comment/comment in msg.comments)
+ for(var/datum/news/feed_comment/comment in msg.comments)
menu +="[comment.body]
[comment.author] [comment.time_stamp]
"
menu += "
Post Message"
@@ -682,8 +682,8 @@ Code:
if("Newscaster Message")
var/host_pda_owner_name = host_pda.id ? "[host_pda.id.registered_name] ([host_pda.id.assignment])" : "Unknown"
var/message = host_pda.msg_input()
- var/datum/newscaster/feed_channel/current
- for(var/datum/newscaster/feed_channel/chan in GLOB.news_network.network_channels)
+ var/datum/news/feed_channel/current
+ for(var/datum/news/feed_channel/chan in GLOB.news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(current.locked && current.author != host_pda_owner_name)
diff --git a/code/game/objects/items/devices/compressionkit.dm b/code/game/objects/items/devices/compressionkit.dm
index eebe4dc69b..9c7e8ce185 100644
--- a/code/game/objects/items/devices/compressionkit.dm
+++ b/code/game/objects/items/devices/compressionkit.dm
@@ -89,25 +89,6 @@
else
to_chat(user, "Anomalous error. Summon a coder.")
- else if(ishuman(target) && user.zone_selected == BODY_ZONE_PRECISE_GROIN)
- var/mob/living/carbon/human/H = target
- var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
- if(!P)
- return
- playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1)
- H.visible_message("[user] is preparing to shrink [H]\'s [P.name] with their bluespace compression kit!")
- if(do_mob(user, H, 40) && charges > 0 && P.length > 0)
- H.visible_message("[user] has shrunk [H]\'s [P.name]!")
- playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1)
- sparks()
- flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN)
- charges -= 1
- var/p_name = P.name
- P.modify_size(-5)
- if(QDELETED(P))
- H.visible_message("[H]\'s [p_name] vanishes!")
-
-
/obj/item/compressionkit/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/ore/bluespace_crystal))
@@ -117,4 +98,4 @@
if(B.amount > 1)
B.amount -= 1
else
- qdel(I)
\ No newline at end of file
+ qdel(I)
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index a82f99064e..e43aa681ce 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -51,7 +51,7 @@
/obj/item/flashlight/attack(mob/living/carbon/M, mob/living/carbon/human/user)
add_fingerprint(user)
- if(istype(M) && on && user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH))
+ if(istype(M) && on && (user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH)))
if((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
@@ -390,7 +390,7 @@
return TRUE
/obj/item/flashlight/emp/attack(mob/living/M, mob/living/user)
- if(on && user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH)) // call original attack when examining organs
+ if(on && (user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH))) // call original attack when examining organs
..()
return
diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm
index afdde02e32..acd71c57ac 100644
--- a/code/game/objects/items/grenades/chem_grenade.dm
+++ b/code/game/objects/items/grenades/chem_grenade.dm
@@ -117,7 +117,7 @@
if(!O.reagents)
continue
var/reagent_list = pretty_string_from_reagent_list(O.reagents)
- user.log_message("removed [O] ([reagent_list]) from [src]")
+ user.log_message("removed [O] ([reagent_list]) from [src]", LOG_GAME)
beakers = list()
to_chat(user, "You open the [initial(name)] assembly and remove the payload.")
return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism.
diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm
index a8b28f2544..233eabd4ca 100644
--- a/code/game/objects/items/mop.dm
+++ b/code/game/objects/items/mop.dm
@@ -21,7 +21,7 @@
/obj/item/mop/New()
..()
- create_reagents(mopcap)
+ create_reagents(mopcap, NONE, NO_REAGENTS_VALUE)
/obj/item/mop/proc/clean(turf/A)
diff --git a/code/game/objects/items/pinpointer.dm b/code/game/objects/items/pinpointer.dm
index c4ad324a2c..151df7694a 100644
--- a/code/game/objects/items/pinpointer.dm
+++ b/code/game/objects/items/pinpointer.dm
@@ -26,6 +26,7 @@
/obj/item/pinpointer/Destroy()
STOP_PROCESSING(SSfastprocess, src)
GLOB.pinpointer_list -= src
+ target = null
return ..()
/obj/item/pinpointer/attack_self(mob/living/user)
@@ -57,7 +58,7 @@
return
var/turf/here = get_turf(src)
var/turf/there = get_turf(target)
- if(here.z != there.z)
+ if(!here || !there || here.z != there.z)
add_overlay("pinon[alert ? "alert" : ""]null")
return
if(get_dist_euclidian(here,there) <= minimum_range)
@@ -143,3 +144,34 @@
target = null
if(!target) //target can be set to null from above code, or elsewhere
active = FALSE
+
+/obj/item/pinpointer/pair
+ name = "pair pinpointer"
+ desc = "A handheld tracking device that locks onto its other half of the matching pair."
+ var/other_pair
+
+/obj/item/pinpointer/pair/Destroy()
+ other_pair = null
+ . = ..()
+
+/obj/item/pinpointer/pair/scan_for_target()
+ target = other_pair
+
+/obj/item/pinpointer/pair/examine(mob/user)
+ . = ..()
+ if(!active || !target)
+ return
+ var/mob/mob_holder = get(target, /mob)
+ if(istype(mob_holder))
+ to_chat(user, "Its pair is being held by [mob_holder].")
+ return
+
+/obj/item/storage/box/pinpointer_pairs
+ name = "pinpointer pair box"
+
+/obj/item/storage/box/pinpointer_pairs/PopulateContents()
+ var/obj/item/pinpointer/pair/A = new(src)
+ var/obj/item/pinpointer/pair/B = new(src)
+
+ A.other_pair = B
+ B.other_pair = A
diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm
index 5fd9600a97..ac490b0122 100644
--- a/code/game/objects/items/religion.dm
+++ b/code/game/objects/items/religion.dm
@@ -44,9 +44,9 @@
if(H.stat == DEAD || H == user)
continue
if(H.mind && (has_job_loyalties || has_role_loyalties))
- if(has_job_loyalties && H.mind.assigned_role in job_loyalties)
+ if(has_job_loyalties && (H.mind.assigned_role in job_loyalties))
inspired += H
- else if(has_role_loyalties && H.mind.special_role in role_loyalties)
+ else if(has_role_loyalties && (H.mind.special_role in role_loyalties))
inspired += H
else if(check_inspiration(H))
inspired += H
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 62f36c60c0..09c2d442e8 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -203,7 +203,7 @@
var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA = new (R.module)
R.module.basic_modules += KA
R.module.add_module(KA, FALSE, TRUE)
-
+
/obj/item/borg/upgrade/advcutter
name = "mining cyborg advanced plasma cutter"
@@ -335,7 +335,6 @@
var/msg_cooldown = 0
var/on = FALSE
var/powercost = 10
- var/mob/living/silicon/robot/cyborg
var/datum/action/toggle_action
/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R, user = usr)
@@ -346,7 +345,6 @@
to_chat(user, "This unit is already equipped with a self-repair module.")
return FALSE
- cyborg = R
icon_state = "selfrepair_off"
toggle_action = new /datum/action/item_action/toggle(src)
toggle_action.Grant(R)
@@ -354,34 +352,20 @@
/obj/item/borg/upgrade/selfrepair/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..()
if (.)
- toggle_action.Remove(cyborg)
+ toggle_action.Remove(R)
QDEL_NULL(toggle_action)
- cyborg = null
- deactivate_sr()
-
-/obj/item/borg/upgrade/selfrepair/dropped()
- . = ..()
- addtimer(CALLBACK(src, .proc/check_dropped), 1)
-
-/obj/item/borg/upgrade/selfrepair/proc/check_dropped()
- if(loc != cyborg)
- toggle_action.Remove(cyborg)
- QDEL_NULL(toggle_action)
- cyborg = null
deactivate_sr()
/obj/item/borg/upgrade/selfrepair/ui_action_click()
- on = !on
if(on)
- to_chat(cyborg, "You activate the self-repair module.")
- START_PROCESSING(SSobj, src)
+ to_chat(toggle_action.owner, "You deactivate the self-repair module.")
+ deactivate_sr()
else
- to_chat(cyborg, "You deactivate the self-repair module.")
- STOP_PROCESSING(SSobj, src)
- update_icon()
+ to_chat(toggle_action.owner, "You activate the self-repair module.")
+ activate_sr()
/obj/item/borg/upgrade/selfrepair/update_icon()
- if(cyborg)
+ if(toggle_action)
icon_state = "selfrepair_[on ? "on" : "off"]"
for(var/X in actions)
var/datum/action/A = X
@@ -389,6 +373,11 @@
else
icon_state = "cyborg_upgrade5"
+/obj/item/borg/upgrade/selfrepair/proc/activate_sr()
+ START_PROCESSING(SSobj, src)
+ on = TRUE
+ update_icon()
+
/obj/item/borg/upgrade/selfrepair/proc/deactivate_sr()
STOP_PROCESSING(SSobj, src)
on = FALSE
@@ -399,7 +388,9 @@
repair_tick = 1
return
- if(cyborg && (cyborg.stat != DEAD) && on)
+ var/mob/living/silicon/robot/cyborg = toggle_action.owner
+
+ if(istype(cyborg) && (cyborg.stat != DEAD) && on)
if(!cyborg.cell)
to_chat(cyborg, "Self-repair module deactivated. Please, insert the power cell.")
deactivate_sr()
diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm
index 2e8005e631..3be698dd3a 100644
--- a/code/game/objects/items/shields.dm
+++ b/code/game/objects/items/shields.dm
@@ -236,3 +236,4 @@
throwforce = 15 //Massive pice of metal
w_class = WEIGHT_CLASS_HUGE
item_flags = SLOWS_WHILE_IN_HAND
+ transparent = FALSE
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index 7879f50ada..934273ae46 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -258,6 +258,9 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
merge_type = /obj/item/stack/sheet/plastitaniumglass
shard_type = /obj/item/shard
+/obj/item/stack/sheet/plastitaniumglass/fifty
+ amount = 50
+
/obj/item/stack/sheet/plastitaniumglass/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.plastitaniumglass_recipes
return ..()
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 828ed96387..6ff6cdfbbf 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -323,6 +323,9 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \
point_value = 45
merge_type = /obj/item/stack/sheet/mineral/plastitanium
+/obj/item/stack/sheet/mineral/plastitanium/fifty
+ amount = 50
+
GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
new/datum/stack_recipe("plastitanium tile", /obj/item/stack/tile/mineral/plastitanium, 1, 4, 20), \
))
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index 63c8fd9faf..cee8e0f3ee 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -528,6 +528,31 @@
for(var/i in 1 to 9)
new /obj/item/ammo_box/magazine/smgm45(src)
+/obj/item/storage/backpack/duffelbag/syndie/ammo/dark_gygax
+ desc = "A large duffel bag, packed to the brim with various exosuit ammo."
+
+/obj/item/storage/backpack/duffelbag/syndie/ammo/dark_gygax/PopulateContents()
+ new /obj/item/mecha_ammo/incendiary(src)
+ new /obj/item/mecha_ammo/incendiary(src)
+ new /obj/item/mecha_ammo/incendiary(src)
+ new /obj/item/mecha_ammo/flashbang(src)
+ new /obj/item/mecha_ammo/flashbang(src)
+ new /obj/item/mecha_ammo/flashbang(src)
+
+/obj/item/storage/backpack/duffelbag/syndie/ammo/mauler
+ desc = "A large duffel bag, packed to the brim with various exosuit ammo."
+
+/obj/item/storage/backpack/duffelbag/syndie/ammo/mauler/PopulateContents()
+ new /obj/item/mecha_ammo/lmg(src)
+ new /obj/item/mecha_ammo/lmg(src)
+ new /obj/item/mecha_ammo/lmg(src)
+ new /obj/item/mecha_ammo/scattershot(src)
+ new /obj/item/mecha_ammo/scattershot(src)
+ new /obj/item/mecha_ammo/scattershot(src)
+ new /obj/item/mecha_ammo/missiles_he(src)
+ new /obj/item/mecha_ammo/missiles_he(src)
+ new /obj/item/mecha_ammo/missiles_he(src)
+
/obj/item/storage/backpack/duffelbag/syndie/c20rbundle
desc = "A large duffel bag containing a C-20r, some magazines, and a cheap looking suppressor."
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index 082cbe245d..1be9df5c30 100755
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -612,6 +612,21 @@
/obj/item/ammo_casing
))
+/obj/item/storage/belt/quiver
+ name = "leather quiver"
+ desc = "A quiver made from the hide of some animal. Used to hold arrows."
+ icon_state = "quiver"
+ item_state = "quiver"
+
+/obj/item/storage/belt/quiver/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_items = 15
+ STR.display_numerical_stacking = TRUE
+ STR.can_hold = typecacheof(list(
+ /obj/item/ammo_casing/caseless/arrow
+ ))
+
/obj/item/storage/belt/medolier
name = "medolier"
desc = "A medical bandolier for holding smartdarts."
diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm
index 2762be8edf..311657aba9 100644
--- a/code/game/objects/items/storage/book.dm
+++ b/code/game/objects/items/storage/book.dm
@@ -173,23 +173,25 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
var/unholy2clean = A.reagents.get_reagent_amount(/datum/reagent/fuel/unholywater)
A.reagents.del_reagent(/datum/reagent/fuel/unholywater)
A.reagents.add_reagent(/datum/reagent/water/holywater,unholy2clean)
- if(istype(A, /obj/item/twohanded/required/cult_bastard) && !iscultist(user))
- var/obj/item/twohanded/required/cult_bastard/sword = A
- to_chat(user, "You begin to exorcise [sword].")
+ if(istype(A, /obj/item/twohanded/required/cult_bastard) || istype(A, /obj/item/melee/cultblade) && !iscultist(user))
+ to_chat(user, "You begin to exorcise [A].")
playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1)
- if(do_after(user, 40, target = sword))
+ if(do_after(user, 40, target = A))
playsound(src,'sound/effects/pray_chaplain.ogg',60,1)
- for(var/obj/item/soulstone/SS in sword.contents)
- SS.usability = TRUE
- for(var/mob/living/simple_animal/shade/EX in SS)
- SSticker.mode.remove_cultist(EX.mind, 1, 0)
- EX.icon_state = "ghost1"
- EX.name = "Purified [EX.name]"
- SS.release_shades(user)
- qdel(SS)
- new /obj/item/nullrod/claymore(get_turf(sword))
- user.visible_message("[user] has purified the [sword]!")
- qdel(sword)
+ if(istype(A, /obj/item/twohanded/required/cult_bastard))
+ for(var/obj/item/soulstone/SS in A.contents)
+ SS.usability = TRUE
+ for(var/mob/living/simple_animal/shade/EX in SS)
+ SSticker.mode.remove_cultist(EX.mind, 1, 0)
+ EX.icon_state = "ghost1"
+ EX.name = "Purified [EX.name]"
+ SS.release_shades(user)
+ qdel(SS)
+ new /obj/item/nullrod/claymore(get_turf(A))
+ else
+ new /obj/item/claymore/purified(get_turf(A))
+ user.visible_message("[user] has purified [A]!")
+ qdel(A)
else if(istype(A, /obj/item/soulstone) && !iscultist(user))
var/obj/item/soulstone/SS = A
diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm
index add2d12ee6..347717dd63 100644
--- a/code/game/objects/items/teleportation.dm
+++ b/code/game/objects/items/teleportation.dm
@@ -141,11 +141,14 @@
return TRUE
return ..()
-/obj/item/hand_tele/proc/try_dispel_portal(atom/target, mob/user)
- if(is_parent_of_portal(target))
+/obj/item/hand_tele/proc/try_dispel_portal(atom/target, mob/user, delay = 30)
+ var/datum/beam/B = user.Beam(target)
+ if(is_parent_of_portal(target) && (!delay || do_after(user, delay, target = target)))
qdel(target)
to_chat(user, "You dispel [target] with \the [src]!")
+ qdel(B)
return TRUE
+ qdel(B)
return FALSE
/obj/item/hand_tele/afterattack(atom/target, mob/user)
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 6782ba0098..359b3b4d10 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -1014,6 +1014,7 @@
/obj/item/toy/cards/singlecard/examine(mob/user)
+ . = ..()
if(ishuman(user))
var/mob/living/carbon/human/cardUser = user
if(cardUser.is_holding(src))
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index cd6cc5f520..ea9899b2c2 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -79,6 +79,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
user.visible_message("[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!")
return(BRUTELOSS)
+/obj/item/claymore/purified
+ name = "purified longsword"
+ desc = "A hastily-purified longsword. While not as holy as it could be, it's still a formidable weapon against those who would rather see you dead."
+ force = 25
+
/obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS
desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim."
flags_1 = CONDUCT_1
diff --git a/code/game/objects/structures/crates_lockers/closets/genpop.dm b/code/game/objects/structures/crates_lockers/closets/genpop.dm
index 80b64aaedc..2b263bb1ed 100644
--- a/code/game/objects/structures/crates_lockers/closets/genpop.dm
+++ b/code/game/objects/structures/crates_lockers/closets/genpop.dm
@@ -95,7 +95,7 @@
if(user.lying && get_dist(src, user) > 0)
return
- if(!broken && registered_id != null && registered_id in user.held_items)
+ if(!broken && registered_id != null && (registered_id in user.held_items))
handle_prisoner_id(user)
return
diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm
index 290e69370b..602adfb367 100644
--- a/code/game/objects/structures/crates_lockers/crates/secure.dm
+++ b/code/game/objects/structures/crates_lockers/crates/secure.dm
@@ -70,3 +70,8 @@
name = "secure science crate"
desc = "A crate with a lock on it, painted in the scheme of the station's scientists."
icon_state = "scisecurecrate"
+
+/obj/structure/closet/crate/secure/medical
+ desc = "A secure medical crate."
+ name = "medical crate"
+ icon_state = "medical_secure_crate"
\ No newline at end of file
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index e9d9e4ce77..8c91b905a0 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -19,21 +19,20 @@
Estimated time of last contact: Deployment, 5000 millennia ago."
assignedrole = "Lifebringer"
-/obj/effect/mob_spawn/human/seed_vault/special(mob/living/new_spawn)
- var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \
- "Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper")
- new_spawn.real_name = plant_name
- if(ishuman(new_spawn))
- var/mob/living/carbon/human/H = new_spawn
- H.underwear = "Nude" //You're a plant, partner
- H.update_body()
-
/obj/effect/mob_spawn/human/seed_vault/Destroy()
new/obj/structure/fluff/empty_terrarium(get_turf(src))
return ..()
/obj/effect/mob_spawn/human/seed_vault/special(mob/living/carbon/human/new_spawn)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
+ var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \
+ "Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper")
+ new_spawn.real_name = plant_name //why this works when moving it from one function to another is beyond me
+ new_spawn.underwear = "Nude" //You're a plant, partner
+ new_spawn.undershirt = "Nude" //changing underwear/shirt/socks doesn't seem to function correctly right now because of some bug elsewhere?
+ new_spawn.socks = "Nude"
+ new_spawn.update_body()
+
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
/obj/effect/mob_spawn/human/ash_walker
@@ -51,14 +50,17 @@
move_resist = MOVE_FORCE_NORMAL
density = FALSE
short_desc = "You are an ash walker. Your tribe worships the Necropolis."
- flavour_text = "The wastes are sacred ground, its monsters a blessed bounty. You would never leave its sacred ground. \
- You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. \
- Fresh sacrifices for your nest."
+ flavour_text = "The wastes are sacred ground, its monsters a blessed bounty. You would never willingly leave your homeland behind. \
+ You have seen lights in the distance... they foreshadow the arrival of outsiders to your domain. \
+ Ensure your nest remains protected at all costs."
assignedrole = "Ash Walker"
/obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn)
new_spawn.real_name = random_unique_lizard_name(gender)
- to_chat(new_spawn, "Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!")
+ if(is_mining_level(z))
+ to_chat(new_spawn, "Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!")
+ else
+ to_chat(new_spawn, "You have been born outside of your natural home! Whether you decide to return home, or make due with your new home is your own decision.")
new_spawn.grant_language(/datum/language/draconic)
var/datum/language_holder/holder = new_spawn.get_language_holder()
diff --git a/code/game/objects/structures/traps.dm b/code/game/objects/structures/traps.dm
index 9c1859df08..2cdc082ef3 100644
--- a/code/game/objects/structures/traps.dm
+++ b/code/game/objects/structures/traps.dm
@@ -35,7 +35,7 @@
. = ..()
if(!isliving(user))
return
- if(user.mind && user.mind in immune_minds)
+ if(user.mind && (user.mind in immune_minds))
return
if(get_dist(user, src) <= 1)
. += "You reveal [src]!"
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 688e03def3..e8f53f551d 100755
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -362,16 +362,14 @@
. = ..()
if(.)
return
- if(!user || !istype(user, /mob/living))
- return FALSE
if(length(src_object.contents()))
to_chat(user, "You start dumping out the contents...")
- if(!do_after(usr,20,target=src_object.parent))
+ if(!do_after(user,20,target=src_object.parent))
return FALSE
var/list/things = src_object.contents()
var/datum/progressbar/progress = new(user, things.len, src)
- while (do_after(usr, 10, TRUE, src, FALSE, CALLBACK(src_object, /datum/component/storage.proc/mass_remove_from_storage, src, things, progress)))
+ while (do_after(user, 10, TRUE, src, FALSE, CALLBACK(src_object, /datum/component/storage.proc/mass_remove_from_storage, src, things, progress)))
stoplag(1)
qdel(progress)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 372902e8d6..bb0224bbfc 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -240,7 +240,7 @@
if( isemptylist(GLOB.news_network.network_channels) )
dat+="No active channels found..."
else
- for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/CHANNEL in GLOB.news_network.network_channels)
if(CHANNEL.is_admin_channel)
dat+="[CHANNEL.channel_name]
"
else
@@ -277,7 +277,7 @@
if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]")
dat+="•Invalid channel name.
"
var/check = 0
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
check = 1
break
@@ -294,7 +294,7 @@
dat+="No feed messages found in channel...
"
else
var/i = 0
- for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
+ for(var/datum/news/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
i++
dat+="-[MESSAGE.returnBody(-1)]
"
if(MESSAGE.img)
@@ -302,7 +302,7 @@
dat+="
"
dat+="\[Story by [MESSAGE.returnAuthor(-1)]\]
"
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]:
"
- for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
+ for(var/datum/news/feed_comment/comment in MESSAGE.comments)
dat+="[comment.body]
[comment.author] [comment.time_stamp]
"
dat+="
"
dat+="
Refresh"
@@ -315,7 +315,7 @@
if(isemptylist(GLOB.news_network.network_channels))
dat+="No feed channels found active...
"
else
- for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
"
dat+="
Cancel"
if(11)
@@ -326,7 +326,7 @@
if(isemptylist(GLOB.news_network.network_channels))
dat+="No feed channels found active...
"
else
- for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
"
dat+="
Back"
@@ -337,11 +337,11 @@
if( isemptylist(src.admincaster_feed_channel.messages) )
dat+="No feed messages found in channel...
"
else
- for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
+ for(var/datum/news/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
dat+="[(MESSAGE.bodyCensor) ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.authorCensor) ? ("Undo Author Censorship") : ("Censor message Author")]
"
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]: [MESSAGE.locked ? "Unlock" : "Lock"]
"
- for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
+ for(var/datum/news/feed_comment/comment in MESSAGE.comments)
dat+="[comment.body] X
[comment.author] [comment.time_stamp]
"
dat+="
Back"
if(13)
@@ -354,7 +354,7 @@
if( isemptylist(src.admincaster_feed_channel.messages) )
dat+="No feed messages found in channel...
"
else
- for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
+ for(var/datum/news/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
dat+="
Back"
if(14)
diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm
index 43360ad714..37fe2a41fc 100644
--- a/code/modules/admin/holder2.dm
+++ b/code/modules/admin/holder2.dm
@@ -19,9 +19,9 @@ GLOBAL_PROTECT(href_token)
var/spamcooldown = 0
var/admincaster_screen = 0 //TODO: remove all these 5 variables, they are completly unacceptable
- var/datum/newscaster/feed_message/admincaster_feed_message = new /datum/newscaster/feed_message
- var/datum/newscaster/wanted_message/admincaster_wanted_message = new /datum/newscaster/wanted_message
- var/datum/newscaster/feed_channel/admincaster_feed_channel = new /datum/newscaster/feed_channel
+ var/datum/news/feed_message/admincaster_feed_message = new /datum/news/feed_message
+ var/datum/news/wanted_message/admincaster_wanted_message = new /datum/news/wanted_message
+ var/datum/news/feed_channel/admincaster_feed_channel = new /datum/news/feed_channel
var/admin_signature
var/href_token
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 70b25bebdd..6abf2d3f1b 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -2481,7 +2481,7 @@
if(!check_rights(R_ADMIN))
return
var/check = 0
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
check = 1
break
@@ -2500,7 +2500,7 @@
if(!check_rights(R_ADMIN))
return
var/list/available_channels = list()
- for(var/datum/newscaster/feed_channel/F in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/F in GLOB.news_network.network_channels)
available_channels += F.channel_name
src.admincaster_feed_channel.channel_name = adminscrub(input(usr, "Choose receiving Feed Channel.", "Network Channel Handler") in available_channels )
src.access_news_network()
@@ -2606,28 +2606,28 @@
else if(href_list["ac_censor_channel_author"])
if(!check_rights(R_ADMIN))
return
- var/datum/newscaster/feed_channel/FC = locate(href_list["ac_censor_channel_author"])
+ var/datum/news/feed_channel/FC = locate(href_list["ac_censor_channel_author"])
FC.toggleCensorAuthor()
src.access_news_network()
else if(href_list["ac_censor_channel_story_author"])
if(!check_rights(R_ADMIN))
return
- var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"])
+ var/datum/news/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"])
MSG.toggleCensorAuthor()
src.access_news_network()
else if(href_list["ac_censor_channel_story_body"])
if(!check_rights(R_ADMIN))
return
- var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"])
+ var/datum/news/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"])
MSG.toggleCensorBody()
src.access_news_network()
else if(href_list["ac_pick_d_notice"])
if(!check_rights(R_ADMIN))
return
- var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_d_notice"])
+ var/datum/news/feed_channel/FC = locate(href_list["ac_pick_d_notice"])
src.admincaster_feed_channel = FC
src.admincaster_screen=13
src.access_news_network()
@@ -2635,7 +2635,7 @@
else if(href_list["ac_toggle_d_notice"])
if(!check_rights(R_ADMIN))
return
- var/datum/newscaster/feed_channel/FC = locate(href_list["ac_toggle_d_notice"])
+ var/datum/news/feed_channel/FC = locate(href_list["ac_toggle_d_notice"])
FC.toggleCensorDclass()
src.access_news_network()
@@ -2651,17 +2651,17 @@
src.admincaster_screen = text2num(href_list["ac_setScreen"])
if (src.admincaster_screen == 0)
if(src.admincaster_feed_channel)
- src.admincaster_feed_channel = new /datum/newscaster/feed_channel
+ src.admincaster_feed_channel = new /datum/news/feed_channel
if(src.admincaster_feed_message)
- src.admincaster_feed_message = new /datum/newscaster/feed_message
+ src.admincaster_feed_message = new /datum/news/feed_message
if(admincaster_wanted_message)
- admincaster_wanted_message = new /datum/newscaster/wanted_message
+ admincaster_wanted_message = new /datum/news/wanted_message
src.access_news_network()
else if(href_list["ac_show_channel"])
if(!check_rights(R_ADMIN))
return
- var/datum/newscaster/feed_channel/FC = locate(href_list["ac_show_channel"])
+ var/datum/news/feed_channel/FC = locate(href_list["ac_show_channel"])
src.admincaster_feed_channel = FC
src.admincaster_screen = 9
src.access_news_network()
@@ -2669,7 +2669,7 @@
else if(href_list["ac_pick_censor_channel"])
if(!check_rights(R_ADMIN))
return
- var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_censor_channel"])
+ var/datum/news/feed_channel/FC = locate(href_list["ac_pick_censor_channel"])
src.admincaster_feed_channel = FC
src.admincaster_screen = 12
src.access_news_network()
@@ -2688,8 +2688,8 @@
else if(href_list["ac_del_comment"])
if(!check_rights(R_ADMIN))
return
- var/datum/newscaster/feed_comment/FC = locate(href_list["ac_del_comment"])
- var/datum/newscaster/feed_message/FM = locate(href_list["ac_del_comment_msg"])
+ var/datum/news/feed_comment/FC = locate(href_list["ac_del_comment"])
+ var/datum/news/feed_message/FM = locate(href_list["ac_del_comment_msg"])
FM.comments -= FC
qdel(FC)
src.access_news_network()
@@ -2697,7 +2697,7 @@
else if(href_list["ac_lock_comment"])
if(!check_rights(R_ADMIN))
return
- var/datum/newscaster/feed_message/FM = locate(href_list["ac_lock_comment"])
+ var/datum/news/feed_message/FM = locate(href_list["ac_lock_comment"])
FM.locked ^= 1
src.access_news_network()
diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
index da7c264774..14906bc83a 100644
--- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm
+++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
@@ -303,7 +303,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
//These three are weird. For best performance, they are only a number when they're not being changed by the SDQL searching/execution code. They only become numbers when they finish changing.
var/list/obj_count_all
var/list/obj_count_eligible
- var/list/obj_count_finished
+ var/obj_count_finished
//Statclick
var/obj/effect/statclick/SDQL2_delete/delete_click
@@ -682,7 +682,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
SDQL2_TICK_CHECK
SDQL2_HALT_CHECK
if(islist(obj_count_finished))
- obj_count_finished = obj_count_finished.len
+ obj_count_finished = length(obj_count_finished)
state = SDQL2_STATE_SWITCHING
/datum/SDQL2_query/proc/SDQL_print(object, list/text_list, print_nulls = TRUE)
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index cf6d54336e..54d6a864fd 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -487,7 +487,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(alert("This mob is being controlled by [M.key]. Are you sure you wish to assume control of it? [M.key] will be made a ghost.",,"Yes","No") != "Yes")
return
else
- var/mob/dead/observer/ghost = new/mob/dead/observer(M,1)
+ var/mob/dead/observer/ghost = new/mob/dead/observer(get_turf(M), M)
ghost.ckey = M.ckey
message_admins("[key_name_admin(usr)] assumed direct control of [M].")
log_admin("[key_name(usr)] assumed direct control of [M].")
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 24e80fd8f3..35ab3927d4 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -135,7 +135,7 @@ GLOBAL_LIST_EMPTY(dirty_vars)
if(!(locate(/obj/structure/grille) in T))
var/window_check = 0
for(var/obj/structure/window/W in T)
- if (W.dir == turn(C1.dir,180) || W.dir in list(5,6,9,10) )
+ if(W.dir == turn(C1.dir,180) || (W.dir in list(5,6,9,10)))
window_check = 1
break
if(!window_check)
diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm
index 6591343116..897bff779d 100644
--- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm
+++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm
@@ -8,7 +8,7 @@
name = "clockwork marauder"
desc = "The stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield."
icon_state = "clockwork_marauder"
- mob_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_HUMANOID
health = 120
maxHealth = 120
force_threshold = 8
diff --git a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm
index d0940ebb7a..00db2b0d72 100644
--- a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm
@@ -118,7 +118,7 @@
continue
if(ishostile(L))
var/mob/living/simple_animal/hostile/H = L
- if(("ratvar" in H.faction) || (!H.mind && "neutral" in H.faction))
+ if(("ratvar" in H.faction) || (!H.mind && ("neutral" in H.faction)))
continue
if(ismegafauna(H) || (!H.mind && H.AIStatus == AI_OFF))
continue
diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm
index 1bb1b8533a..636061783e 100644
--- a/code/modules/antagonists/cult/blood_magic.dm
+++ b/code/modules/antagonists/cult/blood_magic.dm
@@ -143,7 +143,7 @@
//Cult Blood Spells
/datum/action/innate/cult/blood_spell/stun
name = "Stun"
- desc = "A potent spell that will stun and mute victims upon contact."
+ desc = "A potent spell that will stun and mute victims upon contact. When the cult ascends, so does the spell, it burns and throws back the victim!"
button_icon_state = "hand"
magic_path = "/obj/item/melee/blood_magic/stun"
health_cost = 10
@@ -343,7 +343,7 @@
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "disintegrate"
item_state = null
- item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL
+ item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL | NO_ATTACK_CHAIN_SOFT_STAMCRIT
w_class = WEIGHT_CLASS_HUGE
throwforce = 0
@@ -437,8 +437,15 @@
else
target.visible_message("[L] starts to glow in a halo of light!", \
"A feeling of warmth washes over you, rays of holy light surround your body and protect you from the flash of light!")
- else
- if(!iscultist(L))
+ else // cult doesn't stun any longer when halos are out, instead it does burn damage + knockback!
+ var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
+ if(user_antag.cult_team.cult_ascendent)
+ if(!iscultist(L))
+ L.adjustFireLoss(20)
+ if(L.move_resist < MOVE_FORCE_STRONG)
+ var/atom/throw_target = get_edge_target_turf(L, user.dir)
+ L.throw_at(throw_target, 7, 1, user)
+ else if(!iscultist(L))
L.Knockdown(160)
L.adjustStaminaLoss(140) //Ensures hard stamcrit
L.flash_act(1,1)
diff --git a/code/modules/antagonists/devil/imp/imp.dm b/code/modules/antagonists/devil/imp/imp.dm
index fa5263059a..c2f636959b 100644
--- a/code/modules/antagonists/devil/imp/imp.dm
+++ b/code/modules/antagonists/devil/imp/imp.dm
@@ -13,7 +13,7 @@
icon = 'icons/mob/mob.dmi'
icon_state = "imp"
icon_living = "imp"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speed = 1
a_intent = INTENT_HARM
stop_automated_movement = 1
diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm
index 9754d146c3..26efb92bec 100644
--- a/code/modules/antagonists/revenant/revenant.dm
+++ b/code/modules/antagonists/revenant/revenant.dm
@@ -16,7 +16,7 @@
var/icon_stun = "revenant_stun"
var/icon_drain = "revenant_draining"
var/stasis = FALSE
- mob_biotypes = list(MOB_SPIRIT)
+ mob_biotypes = MOB_SPIRIT
incorporeal_move = INCORPOREAL_MOVE_JAUNT
invisibility = INVISIBILITY_REVENANT
health = INFINITY //Revenants don't use health, they use essence instead
diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm
index c703c85762..8a01622c87 100644
--- a/code/modules/antagonists/slaughter/slaughter.dm
+++ b/code/modules/antagonists/slaughter/slaughter.dm
@@ -12,7 +12,7 @@
icon = 'icons/mob/mob.dmi'
icon_state = "daemon"
icon_living = "daemon"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speed = 1
a_intent = INTENT_HARM
stop_automated_movement = 1
diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm
index 7680d61034..bf976e3cca 100644
--- a/code/modules/antagonists/swarmer/swarmer.dm
+++ b/code/modules/antagonists/swarmer/swarmer.dm
@@ -62,7 +62,7 @@
speak_emote = list("tones")
initial_language_holder = /datum/language_holder/swarmer
bubble_icon = "swarmer"
- mob_biotypes = list(MOB_ROBOTIC)
+ mob_biotypes = MOB_ROBOTIC
health = 40
maxHealth = 40
status_flags = CANPUSH
diff --git a/code/modules/cargo/export_scanner.dm b/code/modules/cargo/export_scanner.dm
index 9c523c194f..80fd05cf8c 100644
--- a/code/modules/cargo/export_scanner.dm
+++ b/code/modules/cargo/export_scanner.dm
@@ -36,6 +36,8 @@
var/price = 0
for(var/x in ex.total_amount)
price += ex.total_value[x]
+ for(var/x in ex.reagents_value)
+ price += ex.reagents_value[x]
if(price)
to_chat(user, "Scanned [O], value: [price] credits[O.contents.len ? " (contents included)" : ""].")
diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm
index fca10ac01c..bb90fa717a 100644
--- a/code/modules/cargo/exports.dm
+++ b/code/modules/cargo/exports.dm
@@ -49,13 +49,13 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
sold = E.sell_object(thing, report, dry_run, allowed_categories , apply_elastic)
report.exported_atoms += " [thing.name]"
break
- if(thing.reagents)
+ if(thing.reagents?.value_multiplier)
for(var/A in thing.reagents.reagent_list)
var/datum/reagent/R = A
if(!R.value)
continue
report.reagents_volume[R.name] += R.volume
- report.reagents_value[R.name] += R.volume * R.value
+ report.reagents_value[R.name] += round(R.volume * R.value * thing.reagents.value_multiplier)
if(!dry_run && (sold || delete_unsold))
if(ismob(thing))
thing.investigate_log("deleted through cargo export",INVESTIGATE_CARGO)
diff --git a/code/modules/cargo/exports/materials.dm b/code/modules/cargo/exports/materials.dm
index d8fc5f22ab..1b38a809cf 100644
--- a/code/modules/cargo/exports/materials.dm
+++ b/code/modules/cargo/exports/materials.dm
@@ -65,11 +65,6 @@
material_id = MAT_TITANIUM
message = "cm3 of titanium"
-/datum/export/material/plastitanium
- cost = 165 // plasma + titanium costs
- material_id = MAT_TITANIUM // code can only check for one material_id; plastitanium is half plasma, half titanium
- message = "cm3 of plastitanium"
-
/datum/export/material/plastic
cost = 5
material_id = MAT_PLASTIC
diff --git a/code/modules/cargo/exports/sheets.dm b/code/modules/cargo/exports/sheets.dm
index f784083097..df1704d660 100644
--- a/code/modules/cargo/exports/sheets.dm
+++ b/code/modules/cargo/exports/sheets.dm
@@ -67,6 +67,16 @@
message = "of plasteel"
export_types = list(/obj/item/stack/sheet/plasteel)
+/datum/export/material/plastitanium
+ cost = 165 // plasma + titanium costs
+ export_types = list(/obj/item/stack/sheet/mineral/plastitanium)
+ message = "of plastitanium"
+
+/datum/export/material/plastitanium_glass
+ cost = 168 // plasma + titanium + glass costs
+ export_types = list(/obj/item/stack/sheet/plastitaniumglass)
+ message = "of plastitanium glass"
+
// 1 glass + 0.5 metal, cost is rounded up.
/datum/export/stack/rglass
cost = 6
diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm
index 20dc724707..264f9ac22e 100644
--- a/code/modules/cargo/expressconsole.dm
+++ b/code/modules/cargo/expressconsole.dm
@@ -183,6 +183,7 @@
LZ = pick(empty_turfs)
if (SO.pack.cost <= SSshuttle.points && LZ)//we need to call the cost check again because of the CHECK_TICK call
SSshuttle.points -= SO.pack.cost
+ SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]"))
new /obj/effect/abstract/DPtarget(LZ, podType, SO)
. = TRUE
update_icon()
@@ -196,6 +197,7 @@
CHECK_TICK
if(empty_turfs && empty_turfs.len)
SSshuttle.points -= SO.pack.cost * (0.72*MAX_EMAG_ROCKETS)
+ SSblackbox.record_feedback("nested tally", "cargo_imports", MAX_EMAG_ROCKETS, list("[SO.pack.cost * 0.72]", "[SO.pack.name]"))
SO.generateRequisition(get_turf(src))
for(var/i in 1 to MAX_EMAG_ROCKETS)
var/LZ = pick(empty_turfs)
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index 4c9ddfe3bc..07a75bbfaf 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -2,7 +2,7 @@
var/name = "Crate"
var/group = ""
var/hidden = FALSE //Aka emag only
- var/contraband = FALSE //Hacking the console with a multitool
+ var/contraband = FALSE //Requires a hacked console UNLESS DropPodOnly = TRUE, in which case it requires an emag
var/cost = 700 // Minimum cost, or infinite points are possible.
var/access = FALSE //What access does the Crate itself need?
var/access_any = FALSE //Do we care about access?
diff --git a/code/modules/cargo/packs/armory.dm b/code/modules/cargo/packs/armory.dm
index ea8ef8ba0f..fc95b05007 100644
--- a/code/modules/cargo/packs/armory.dm
+++ b/code/modules/cargo/packs/armory.dm
@@ -178,7 +178,7 @@
/datum/supply_pack/security/armory/russian
name = "Russian Surplus Crate"
desc = "Hello Comrade, we have the most modern russian military equipment the black market can offer, for the right price of course. Sadly we couldnt remove the lock so it requires Armory access to open."
- cost = 5000
+ cost = 7500
contraband = TRUE
contains = list(/obj/item/reagent_containers/food/snacks/rationpack,
/obj/item/ammo_box/a762,
@@ -192,12 +192,11 @@
/obj/item/clothing/mask/russian_balaclava,
/obj/item/clothing/head/helmet/rus_ushanka,
/obj/item/clothing/suit/armor/vest/russian_coat,
- /obj/item/gun/ballistic/shotgun/boltaction,
/obj/item/gun/ballistic/shotgun/boltaction)
crate_name = "surplus military crate"
/datum/supply_pack/security/armory/russian/fill(obj/structure/closet/crate/C)
- for(var/i in 1 to 10)
+ for(var/i in 1 to 5)
var/item = pick(contains)
new item(C)
@@ -218,7 +217,7 @@
crate_name = "swat crate"
/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
- name = "SWAT tatical tasers Crate"
+ name = "SWAT tactical tasers Crate"
desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
cost = 7000
contains = list(/obj/item/gun/energy/e_gun/stun,
diff --git a/code/modules/cargo/packs/costumes_toys.dm b/code/modules/cargo/packs/costumes_toys.dm
index 4a64979502..c559e7925a 100644
--- a/code/modules/cargo/packs/costumes_toys.dm
+++ b/code/modules/cargo/packs/costumes_toys.dm
@@ -63,6 +63,7 @@
/obj/item/toy/cards/deck/syndicate,
/obj/item/reagent_containers/food/drinks/bottle/absinthe,
/obj/item/clothing/under/syndicate/tacticool,
+ /obj/item/clothing/under/syndicate/skirt,
/obj/item/clothing/under/syndicate,
/obj/item/suppressor,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate,
diff --git a/code/modules/cargo/packs/emergency.dm b/code/modules/cargo/packs/emergency.dm
index e32811f2d0..be81da3b92 100644
--- a/code/modules/cargo/packs/emergency.dm
+++ b/code/modules/cargo/packs/emergency.dm
@@ -130,7 +130,7 @@
/datum/supply_pack/emergency/bomb
name = "Explosive Emergency Crate"
- desc = "Science gone bonkers? Beeping behind the airlock? Buy now and be the hero the station des... I mean needs! (Time not included.)"
+ desc = "Science gone bonkers? Beeping behind the airlock? Buy now and become the hero the station des... I mean needs! Time not included, but a full bomb suit and hood, as well as a mask and defusal kit are! Non-Nuclear ordnances only."
cost = 1500
contains = list(/obj/item/clothing/head/bomb_hood,
/obj/item/clothing/suit/bomb_suit,
diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm
index ea327ae820..5d02bbe60f 100644
--- a/code/modules/cargo/packs/medical.dm
+++ b/code/modules/cargo/packs/medical.dm
@@ -88,6 +88,7 @@
/obj/item/clothing/mask/gas,
/obj/item/clothing/suit/space/hardsuit/medical)
crate_name = "medical hardsuit"
+ crate_type = /obj/structure/closet/crate/secure/medical
/datum/supply_pack/medical/supplies
name = "Medical Supplies Crate"
@@ -125,7 +126,7 @@
/obj/item/reagent_containers/medspray/synthflesh,
/obj/item/reagent_containers/medspray/sterilizine)
crate_name = "medco surgery tools"
- crate_type = /obj/structure/closet/crate/medical
+ crate_type = /obj/structure/closet/crate/secure/medical
/datum/supply_pack/medical/surgery
name = "Surgical Supplies Crate"
diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm
index 4aa991fc3f..cdac6f49f2 100644
--- a/code/modules/cargo/packs/organic.dm
+++ b/code/modules/cargo/packs/organic.dm
@@ -193,6 +193,7 @@
/obj/item/reagent_containers/food/snacks/meat/slab/bear,
/obj/item/reagent_containers/food/snacks/meat/slab/xeno,
/obj/item/reagent_containers/food/snacks/meat/slab/spider,
+ /obj/item/reagent_containers/food/snacks/meat/rawcrab,
/obj/item/reagent_containers/food/snacks/meat/rawbacon,
/obj/item/reagent_containers/food/snacks/spiderleg,
/obj/item/reagent_containers/food/snacks/carpmeat,
@@ -327,7 +328,7 @@
/datum/supply_pack/organic/seeds
name = "Seeds Crate"
- desc = "Big things have small beginnings. Contains thirteen different seeds."
+ desc = "Big things have small beginnings. Contains fourteen different seeds."
cost = 1250
contains = list(/obj/item/seeds/chili,
/obj/item/seeds/berry,
diff --git a/code/modules/cargo/packs/science.dm b/code/modules/cargo/packs/science.dm
index 8852a7e945..e6671a02ea 100644
--- a/code/modules/cargo/packs/science.dm
+++ b/code/modules/cargo/packs/science.dm
@@ -84,7 +84,7 @@
/datum/supply_pack/science/glasswork
name = "Glass Blower Kit Crate"
- desc = "Learn and make glassworks of usefull things for a profit! Contains glassworking tools and blowing rods. Glass not included."
+ desc = "Learn and make glassworks of useful things for a profit! Contains glassworking tools and blowing rods. Glass not included."
cost = 1000
contains = list(/obj/item/glasswork/glasskit,
/obj/item/glasswork/glasskit,
@@ -111,9 +111,9 @@
/datum/supply_pack/science/nuke_b_gone
name = "Nuke Defusal Kit"
desc = "Contains set of tools to defuse a nuke."
- cost = 7500 //Usefull for traitors/nukies that fucked up
+ cost = 7500 //Useful for traitors/nukies that fucked up
dangerous = TRUE
- DropPodOnly = TRUE
+ hidden = TRUE
contains = list(/obj/item/nuke_core_container/nt,
/obj/item/screwdriver/nuke/nt,
/obj/item/paper/guides/nt/nuke_instructions)
@@ -194,7 +194,7 @@
/datum/supply_pack/science/supermater
name = "Supermatter Extraction Tools Crate"
desc = "Contains a set of tools to extract a sliver of supermatter. Consult your CE today!"
- cost = 7500 //Usefull for traitors that fucked up
+ cost = 7500 //Useful for traitors that fucked up
hidden = TRUE
contains = list(/obj/item/nuke_core_container/supermatter,
/obj/item/scalpel/supermatter,
diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm
index fd7e07a66c..90bc837767 100644
--- a/code/modules/cargo/packs/security.dm
+++ b/code/modules/cargo/packs/security.dm
@@ -103,7 +103,7 @@
desc = "An old russian Minutemen crate, comes with a full russian outfit, a mosin and a stripper clip."
contraband = TRUE
access = FALSE
- cost = 5500 //
+ cost = 6500 //
contains = list(/obj/item/clothing/suit/armor/navyblue/russian,
/obj/item/clothing/shoes/combat,
/obj/item/clothing/head/ushanka,
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index e05cee3487..dc550179f8 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -737,13 +737,13 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
message_admins("Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN.")
ip_intel = res.intel
-/client/Click(atom/object, atom/location, control, params)
+/client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE)
var/ab = FALSE
var/list/L = params2list(params)
if (object && object == middragatom && L["left"])
ab = max(0, 5 SECONDS-(world.time-middragtime)*0.1)
var/mcl = CONFIG_GET(number/minute_click_limit)
- if (!holder && mcl)
+ if (!holder && !ignore_spam && mcl)
var/minute = round(world.time, 600)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
@@ -768,7 +768,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
return
var/scl = CONFIG_GET(number/second_click_limit)
- if (!holder && scl)
+ if (!holder && !ignore_spam && scl)
var/second = round(world.time, 10)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index ba20fdacd2..793a72c1f7 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -1473,9 +1473,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
if("flavor_text")
- var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(features["flavor_text"]), MAX_MESSAGE_LEN, TRUE)
+ var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", features["flavor_text"], MAX_FAVOR_LEN, TRUE)
if(msg)
- msg = msg
features["flavor_text"] = msg
if("hair")
diff --git a/code/modules/clothing/gloves/ring.dm b/code/modules/clothing/gloves/ring.dm
index 54aaa58849..8354f13bd2 100644
--- a/code/modules/clothing/gloves/ring.dm
+++ b/code/modules/clothing/gloves/ring.dm
@@ -5,6 +5,7 @@
w_class = WEIGHT_CLASS_TINY
icon = 'icons/obj/ring.dmi'
icon_state = "ringgold"
+ item_state = "gring"
body_parts_covered = 0
attack_verb = list("proposed")
transfer_prints = TRUE
@@ -17,10 +18,15 @@
/obj/item/clothing/gloves/ring/diamond
name = "diamond ring"
- desc = "A tiny gold ring, studded with a diamond. Cultures have used these rings in courtship for a millenia."
+ desc = "An expensive ring, studded with a diamond. Cultures have used these rings in courtship for a millenia."
icon_state = "ringdiamond"
+ item_state = "dring"
+
+/obj/item/clothing/gloves/ring/diamond/attack_self(mob/user)
+ user.visible_message("\The [user] gets down on one knee, presenting \the [src].","You get down on one knee, presenting \the [src].")
/obj/item/clothing/gloves/ring/silver
name = "silver ring"
desc = "A tiny silver ring, sized to wrap around a finger."
icon_state = "ringsilver"
+ item_state = "sring"
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index b61918c4b8..4d3e8acb28 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -703,8 +703,9 @@
name = "cosmic winter coat"
icon_state = "coatcosmic"
item_state = "coatcosmic"
- allowed = list(/obj/item/flashlight)
hoodtype = /obj/item/clothing/head/hooded/winterhood/cosmic
+ light_power = 1.8
+ light_range = 1.2
/obj/item/clothing/head/hooded/winterhood/cosmic
icon_state = "winterhood_cosmic"
@@ -994,4 +995,4 @@
tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1)
update_icon()
user.regenerate_icons()
- return TRUE
\ No newline at end of file
+ return TRUE
diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm
index 0d2f68f580..dff62dd2c3 100644
--- a/code/modules/clothing/suits/reactive_armour.dm
+++ b/code/modules/clothing/suits/reactive_armour.dm
@@ -215,14 +215,24 @@
playsound(get_turf(owner),'sound/magic/repulse.ogg', 100, 1)
owner.visible_message("[src] blocks [attack_text], converting the attack into a wave of force!")
var/turf/T = get_turf(owner)
- var/list/thrown_items = list()
- for(var/atom/movable/A in range(T, 7))
- if(A == owner || A.anchored || thrown_items[A])
+ var/list/cachedrange = range(T, 7) - owner
+ var/safety = 50
+ var/list/to_throw = list()
+ for(var/mob/living/L in cachedrange)
+ if(L.move_resist > MOVE_FORCE_EXTREMELY_STRONG)
continue
- var/throwtarget = get_edge_target_turf(T, get_dir(T, get_step_away(A, T)))
- A.throw_at(throwtarget,10,1)
- thrown_items[A] = A
-
+ to_throw += L
+ for(var/obj/O in cachedrange)
+ if(O.anchored)
+ continue
+ to_throw += O
+ for(var/i in to_throw)
+ if(!safety)
+ break
+ var/atom/movable/AM = i
+ var/throwtarget = get_edge_target_turf(T, get_dir(T, get_step_away(AM, T)))
+ AM.throw_at(throwtarget,10,1)
+ safety--
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return 1
diff --git a/code/modules/events/holiday/vday.dm b/code/modules/events/holiday/vday.dm
index 899a083b7d..d3cbf03581 100644
--- a/code/modules/events/holiday/vday.dm
+++ b/code/modules/events/holiday/vday.dm
@@ -64,65 +64,10 @@
resistance_flags = FLAMMABLE
w_class = WEIGHT_CLASS_TINY
-/obj/item/valentine/New()
- ..()
- message = pick("Roses are red / Violets are good / One day while Andy...",
- "My love for you is like the singularity. It cannot be contained.",
- "Will you be my lusty xenomorph maid?",
- "We go together like the clown and the external airlock.",
- "Roses are red / Liches are wizards / I love you more than a whole squad of lizards.",
- "Be my valentine. Law 2.",
- "You must be a mime, because you leave me speechless.",
- "I love you like Ian loves the HoP.",
- "You're hotter than a plasma fire in toxins.",
- "Are you a rogue atmos tech? Because you're taking my breath away.",
- "Could I have all access... to your heart?",
- "Call me the doctor, because I'm here to inspect your johnson.",
- "I'm not a changeling, but you make my proboscis extend.",
- "I just can't get EI NATH of you.",
- "You must be a nuke op, because you make my heart explode.",
- "Roses are red / Botany is a farm / Not being my Valentine / causes human harm.",
- "I want you more than an assistant wants insulated gloves.",
- "If I was a security officer, I'd brig you all shift.",
- "Are you the janitor? Because I think I've fallen for you.",
- "You're always valid to my heart.",
- "I'd risk the wrath of the gods to bwoink you.",
- "You look as beautiful now as the last time you were cloned.",
- "Someone check the gravitational generator, because I'm only attracted to you.",
- "If I were the warden I'd always let you into my armory.",
- "The virologist is rogue, and the only cure is a kiss from you.",
- "Would you spend some time in my upgraded sleeper?",
- "You must be a silicon, because you've unbolted my heart.",
- "Are you Nar'Sie? Because there's nar-one else I sie.",
- "If you were a taser, you'd be set to stunning.",
- "Do you have stamina damage from running through my dreams?",
- "If I were an alien, would you let me hug you?",
- "My love for you is stronger than a reinforced wall.",
- "This must be the captain's office, because I see a fox.",
- "I'm not a highlander, but there can only be one for me.",
- "The floor is made of lava! Quick, get on my bed.",
- "If you were an abandoned station you'd be the DEARelict.",
- "If you had a pickaxe you'd be a shaft FINEr.",
- "Roses are red, tide is gray, if I were an assistant I'd steal you away.",
- "Roses are red, text is green, I love you more than cleanbots clean.",
- "If you were a carp I'd fi-lay you.",
- "I'm a nuke op, and my pinpointer leads to your heart.",
- "Wanna slay my megafauna?",
- "I'm a clockwork cultist. Or zl inyragvar.",
- "If you were a disposal bin I'd ride you all day.",
- "Put on your explorer's suit because I'm taking you to LOVEaland.",
- "I must be the CMO, 'cause I saw you on my CUTE sensors.",
- "You're the vomit to my flyperson.",
- "You must be liquid dark matter, because you're pulling me closer.",
- "Not even sorium can drive me away from you.",
- "Wanna make like a borg and do some heavy petting?",
- "Are you powering the station? Because you super matter to me.",
- "I wish science could make me a bag of holding you.",
- "Let's call the emergency CUDDLE.",
- "I must be tripping on BZ, because I saw an angel walk by.",
- "Wanna empty out my tool storage?",
- "Did you visit the medbay after you fell from heaven?",
- "Are you wearing space pants? Wanna not be?" )
+/obj/item/valentine/Initialize(mapload)
+ message = pick(GLOB.flirts)
+ return ..()
+
/obj/item/valentine/attackby(obj/item/W, mob/user, params)
..()
diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm
index 9cf3a86e71..58a2875849 100644
--- a/code/modules/events/spontaneous_appendicitis.dm
+++ b/code/modules/events/spontaneous_appendicitis.dm
@@ -19,7 +19,7 @@
continue
if(!H.getorgan(/obj/item/organ/appendix)) //Don't give the disease to some who lacks it, only for it to be auto-cured
continue
- if(!(MOB_ORGANIC in H.mob_biotypes)) //biotype sleeper bugs strike again, once again making appendicitis pick a target that can't take it
+ if(!(H.mob_biotypes & MOB_ORGANIC)) //biotype sleeper bugs strike again, once again making appendicitis pick a target that can't take it
continue
var/foundAlready = FALSE //don't infect someone that already has appendicitis
for(var/datum/disease/appendicitis/A in H.diseases)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 150f066886..b0c3121c67 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -18,6 +18,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
/datum/hallucination/items = 4,
/datum/hallucination/fire = 3,
/datum/hallucination/self_delusion = 2,
+ /datum/hallucination/naked = 2,
/datum/hallucination/delusion = 2,
/datum/hallucination/shock = 1,
/datum/hallucination/death = 1,
@@ -65,6 +66,9 @@ GLOBAL_LIST_INIT(hallucination_list, list(
//Returns a random turf in a ring around the target mob, useful for sound hallucinations
/datum/hallucination/proc/random_far_turf()
+ var/turf/target_T = get_turf(target)
+ if(!target_T)
+ return
var/x_based = prob(50)
var/first_offset = pick(-8,-7,-6,-5,5,6,7,8)
var/second_offset = rand(-8,8)
@@ -76,7 +80,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
else
y_off = first_offset
x_off = second_offset
- var/turf/T = locate(target.x + x_off, target.y + y_off, target.z)
+ var/turf/T = locate(target_T.x + x_off, target_T.y + y_off, target_T.z)
return T
/obj/effect/hallucination
@@ -1318,3 +1322,26 @@ GLOBAL_LIST_INIT(hallucination_list, list(
else
to_chat(C,"[G] violently grabs you!")
qdel(src)
+
+/datum/hallucination/naked
+ var/image/image
+
+/datum/hallucination/naked/New(mob/living/carbon/C, forced = TRUE)
+ set waitfor = FALSE
+ ..()
+ if (C.client && C.client.prefs)
+ var/datum/preferences/prefs = C.client.prefs
+ var/mob/living/carbon/human/dummy/M = generate_or_wait_for_human_dummy(DUMMY_HUMAN_SLOT_HALLUCINATION)
+ prefs.copy_to(M)
+ COMPILE_OVERLAYS(M)
+ CHECK_TICK
+ image = image(M,C)
+ unset_busy_human_dummy(DUMMY_HUMAN_SLOT_HALLUCINATION)
+ image.override = TRUE
+ target.client.images |= image
+ QDEL_IN(src, 20 SECONDS)
+
+/datum/hallucination/naked/Destroy()
+ if(target.client)
+ target.client.images.Remove(image)
+ return ..()
\ No newline at end of file
diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm
index 7bd5e66430..d39492d9bf 100644
--- a/code/modules/food_and_drinks/drinks/drinks.dm
+++ b/code/modules/food_and_drinks/drinks/drinks.dm
@@ -9,6 +9,7 @@
lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
reagent_flags = OPENCONTAINER
+ reagent_value = DEFAULT_REAGENTS_VALUE
var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it.
possible_transfer_amounts = list(5,10,15,20,25,30,50)
volume = 50
diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm
index 6d3f007fd9..2af24080cb 100644
--- a/code/modules/food_and_drinks/food.dm
+++ b/code/modules/food_and_drinks/food.dm
@@ -12,6 +12,7 @@
possible_transfer_amounts = list()
volume = 50 //Sets the default container amount for all food items.
reagent_flags = INJECTABLE
+ reagent_value = NO_REAGENTS_VALUE
resistance_flags = FLAMMABLE
var/foodtype = NONE
var/last_check_time
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index c068c1aa40..0b277e328b 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -71,10 +71,11 @@ All foods are distributed among various categories. Use common sense.
if(!eater)
return
if(!reagents.total_volume)
- var/obj/item/trash_item = generate_trash(eater)
+ var/mob/living/location = loc
+ var/obj/item/trash_item = generate_trash(location)
qdel(src)
- eater.put_in_hands(trash_item)
-
+ if(istype(location))
+ location.put_in_hands(trash_item)
/obj/item/reagent_containers/food/snacks/attack_self(mob/user)
return
@@ -245,7 +246,7 @@ All foods are distributed among various categories. Use common sense.
return TRUE
/obj/item/reagent_containers/food/snacks/proc/initialize_slice(obj/item/reagent_containers/food/snacks/slice, reagents_per_slice)
- slice.create_reagents(slice.volume)
+ slice.create_reagents(slice.volume, reagent_flags, reagent_value)
reagents.trans_to(slice,reagents_per_slice)
if(name != initial(name))
slice.name = "slice of [name]"
@@ -279,7 +280,7 @@ All foods are distributed among various categories. Use common sense.
// initialize_cooked_food() is called when microwaving the food
/obj/item/reagent_containers/food/snacks/proc/initialize_cooked_food(obj/item/reagent_containers/food/snacks/S, cooking_efficiency = 1)
- S.create_reagents(S.volume)
+ S.create_reagents(S.volume, reagent_flags, reagent_value)
if(reagents)
reagents.trans_to(S, reagents.total_volume)
if(S.bonus_reagents && S.bonus_reagents.len)
diff --git a/code/modules/food_and_drinks/food/snacks/meat.dm b/code/modules/food_and_drinks/food/snacks/meat.dm
index 28fb2edf61..d44f859823 100644
--- a/code/modules/food_and_drinks/food/snacks/meat.dm
+++ b/code/modules/food_and_drinks/food/snacks/meat.dm
@@ -271,7 +271,7 @@
/obj/item/reagent_containers/food/snacks/meat/slab/meatwheat
name = "meatwheat clump"
desc = "This doesn't look like meat, but your standards aren't that high to begin with."
- list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/blood = 5, /datum/reagent/consumable/cooking_oil = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/consumable/cooking_oil = 1)
filling_color = rgb(150, 0, 0)
icon_state = "meatwheat_clump"
bitesize = 4
diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm
index 41b08e8c7f..a7090a5274 100644
--- a/code/modules/food_and_drinks/food/snacks_other.dm
+++ b/code/modules/food_and_drinks/food/snacks_other.dm
@@ -549,7 +549,7 @@
name = "chocolate"
desc = "A tiny and sweet chocolate. Has a 'strawberry' filling!"
icon_state = "tiny_chocolate"
- list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 1, /datum/reagent/consumable/coco = 1, /datum/reagent/drug/aphrodisiac = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/sugar = 1, /datum/reagent/consumable/coco = 1)
filling_color = "#A0522D"
tastes = list("chocolate" = 1)
foodtype = JUNKFOOD | SUGAR
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index 4406491f10..24f60300fa 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -212,7 +212,7 @@
meatslab.throw_at(pick(nearby_turfs),i,3)
for (var/turfs=1 to meat_produced)
var/turf/gibturf = pick(nearby_turfs)
- if (!gibturf.density && src in view(gibturf))
+ if (!gibturf.density && (src in view(gibturf)))
new gibtype(gibturf,i,diseases)
pixel_x = initial(pixel_x) //return to its spot after shaking
diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm
index bd556b8397..b163c6ba97 100644
--- a/code/modules/food_and_drinks/pizzabox.dm
+++ b/code/modules/food_and_drinks/pizzabox.dm
@@ -220,7 +220,7 @@
unprocess()
qdel(src)
if(!bomb_active || bomb_defused)
- if(bomb_defused && bomb in src)
+ if(bomb_defused && (bomb in src))
bomb.defuse()
bomb_active = FALSE
unprocess()
diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm
index fd332a38df..0b297648c5 100644
--- a/code/modules/food_and_drinks/recipes/food_mixtures.dm
+++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm
@@ -101,6 +101,10 @@
required_reagents = list(/datum/reagent/blood = 5, /datum/reagent/medicine/cryoxadone = 1)
mob_react = FALSE
+/datum/chemical_reaction/synthmeat/synthblood
+ id = "synthmeat_synthblood"
+ required_reagents = list(/datum/reagent/blood/synthetics = 5, /datum/reagent/medicine/cryoxadone = 1)
+
/datum/chemical_reaction/synthmeat/on_reaction(datum/reagents/holder, multiplier)
var/location = get_turf(holder.my_atom)
for(var/i = 1, i <= multiplier, i++)
diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index f99cfde92d..65d942ca2b 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -15,6 +15,7 @@
// Saves us from having to define each stupid grown's dried_type as itself.
// If you don't want a plant to be driable (watermelons) set this to null in the time definition.
resistance_flags = FLAMMABLE
+ reagent_value = HARVEST_REAGENTS_VALUE
var/dry_grind = FALSE //If TRUE, this object needs to be dry to be ground up
var/can_distill = TRUE //If FALSE, this object cannot be distilled into an alcohol.
var/distill_reagent //If NULL and this object can be distilled, it uses a generic fruit_wine reagent and adjusts its variables.
diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm
index c5a7e0797a..1d1309acb8 100644
--- a/code/modules/hydroponics/grown/cereals.dm
+++ b/code/modules/hydroponics/grown/cereals.dm
@@ -33,6 +33,7 @@
icon_state = "seed-oat"
species = "oat"
plantname = "Oat Stalks"
+ rarity = 10 //Not really new, just better
product = /obj/item/reagent_containers/food/snacks/grown/oat
mutatelist = list()
@@ -45,7 +46,7 @@
filling_color = "#556B2F"
bitesize_mod = 2
foodtype = GRAIN
- grind_results = list(/datum/reagent/consumable/flour = 0)
+ grind_results = list(/datum/reagent/consumable/flour = 0.5) //So when it grinds it has 50% more flour
tastes = list("oat" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/ale
@@ -81,6 +82,7 @@
species = "meatwheat"
plantname = "Meatwheat"
product = /obj/item/reagent_containers/food/snacks/grown/meatwheat
+ rarity = 40
mutatelist = list()
/obj/item/reagent_containers/food/snacks/grown/meatwheat
diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm
index ef925e3965..f4859ffb1e 100644
--- a/code/modules/hydroponics/growninedible.dm
+++ b/code/modules/hydroponics/growninedible.dm
@@ -11,7 +11,7 @@
/obj/item/grown/Initialize(newloc, obj/item/seeds/new_seed)
. = ..()
- create_reagents(50)
+ create_reagents(50, NONE, HARVEST_REAGENTS_VALUE)
if(new_seed)
seed = new_seed.Copy()
diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm
index 756788898a..272f44267e 100644
--- a/code/modules/hydroponics/plant_genes.dm
+++ b/code/modules/hydroponics/plant_genes.dm
@@ -109,7 +109,7 @@
// Reagent genes store reagent ID and reagent ratio. Amount of reagent in the plant = 1 + (potency * rate)
/datum/plant_gene/reagent
name = "Nutriment"
- var/reagent_id = "nutriment"
+ var/reagent_id = /datum/reagent/consumable/nutriment
var/rate = 0.04
/datum/plant_gene/reagent/get_name()
diff --git a/code/modules/integrated_electronics/core/special_pins/dir_pin.dm b/code/modules/integrated_electronics/core/special_pins/dir_pin.dm
index 4ce5597af8..eb4d9a3366 100644
--- a/code/modules/integrated_electronics/core/special_pins/dir_pin.dm
+++ b/code/modules/integrated_electronics/core/special_pins/dir_pin.dm
@@ -18,7 +18,7 @@
write_data_to_pin(new_data)
/datum/integrated_io/dir/write_data_to_pin(var/new_data)
- if(isnull(new_data) || new_data in list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)/* + list(UP, DOWN)*/)
+ if(isnull(new_data) || (new_data in GLOB.alldirs/* + list(UP, DOWN)*/))
data = new_data
holder.on_data_written()
diff --git a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm
index f99bf65071..5ff791c5f3 100644
--- a/code/modules/jobs/job_exp.dm
+++ b/code/modules/jobs/job_exp.dm
@@ -40,7 +40,7 @@ GLOBAL_PROTECT(exp_to_update)
return exp_type
/proc/job_is_xp_locked(jobtitle)
- if(!CONFIG_GET(flag/use_exp_restrictions_heads) && jobtitle in (GLOB.command_positions | list("AI")))
+ if(!CONFIG_GET(flag/use_exp_restrictions_heads) && (jobtitle in (GLOB.command_positions | list("AI"))))
return FALSE
if(!CONFIG_GET(flag/use_exp_restrictions_other) && !(jobtitle in (GLOB.command_positions | list("AI"))))
return FALSE
diff --git a/code/modules/keybindings/bindings_living.dm b/code/modules/keybindings/bindings_living.dm
index 8e9c787b6b..ec6c5dd539 100644
--- a/code/modules/keybindings/bindings_living.dm
+++ b/code/modules/keybindings/bindings_living.dm
@@ -19,6 +19,9 @@
if(possible_a_intents)
a_intent_change(INTENT_HARM)
return
+ if ("V")
+ lay_down()
+ return
return ..()
\ No newline at end of file
diff --git a/code/modules/keybindings/bindings_mob.dm b/code/modules/keybindings/bindings_mob.dm
index 925f305525..964ee65047 100644
--- a/code/modules/keybindings/bindings_mob.dm
+++ b/code/modules/keybindings/bindings_mob.dm
@@ -79,4 +79,4 @@
if("Alt")
toggle_move_intent()
return
- return ..()
\ No newline at end of file
+ return ..()
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index f128a76da2..459212aad0 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -112,7 +112,6 @@
else
return ..()
-
/obj/structure/bookcase/attack_hand(mob/user)
. = ..()
if(.)
@@ -129,14 +128,17 @@
choice.forceMove(drop_location())
update_icon()
-/obj/structure/bookcase/attack_ghost(mob/dead/observer/user as mob)
- if(contents.len && in_range(user, src))
- var/obj/item/book/choice = input("Which book would you like to read?") as null|obj in contents
- if(choice)
- if(!istype(choice)) //spellbook, cult tome, or the one weird bible storage
- to_chat(user,"A mysterious force is keeping you from reading that.")
- return
- choice.attack_self(user)
+/obj/structure/bookcase/attack_ghost(mob/dead/observer/user)
+ . = ..()
+ if(!length(contents))
+ to_chat(user, "It's empty!")
+ return
+ var/obj/item/book/choice = input("Which book would you like to read?") as null|obj in contents
+ if(choice)
+ if(!istype(choice)) //spellbook, cult tome, or the one weird bible storage
+ to_chat(user,"A mysterious force is keeping you from reading that.")
+ return
+ choice.attack_ghost(user)
/obj/structure/bookcase/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/mineral/wood(loc, 4)
@@ -211,14 +213,17 @@
to_chat(user, "You skim through the book but can't comprehend any of it.")
return
if(dat)
- user << browse("Penned by [author].
" + "[dat]", "window=book[window_size != null ? ";size=[window_size]" : ""]")
- if(istype(user, /mob/living))
- user.visible_message("[user] opens a book titled \"[title]\" and begins reading intently.")
- SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "book_nerd", /datum/mood_event/book_nerd)
- onclose(user, "book")
+ show_to(user)
+ user.visible_message("[user] opens a book titled \"[title]\" and begins reading intently.")
else
to_chat(user, "This book is completely blank!")
+/obj/item/book/attack_ghost(mob/dead/observer/O)
+ . = ..()
+ show_to(O)
+
+/obj/item/book/proc/show_to(mob/user)
+ user << browse("Penned by [author].
" + "[dat]", "window=book[window_size != null ? ";size=[window_size]" : ""]")
/obj/item/book/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/pen))
@@ -320,9 +325,6 @@
else
..()
-/obj/item/book/attack_ghost(mob/user)
- attack_self(user)
-
/*
* Barcode Scanner
diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm
index 204a2de9a6..008724b10f 100644
--- a/code/modules/library/lib_machines.dm
+++ b/code/modules/library/lib_machines.dm
@@ -441,7 +441,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
if(!GLOB.news_network)
alert("No news network found on station. Aborting.")
var/channelexists = 0
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == "Nanotrasen Book Club")
channelexists = 1
break
diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm
index cc41682f96..32f9812068 100644
--- a/code/modules/mining/equipment/mining_tools.dm
+++ b/code/modules/mining/equipment/mining_tools.dm
@@ -66,6 +66,22 @@
force = 19
materials = list(MAT_DIAMOND=4000)
+/obj/item/pickaxe/plasteel
+ name = "plasteel-tipped pickaxe"
+ icon_state = "titaxe"
+ toolspeed = 0.5
+ desc = "A pickaxe with a plasteel pick head. Less robust at cracking rock walls and digging up dirt than the titanium pickaxe, but better at cracking open skulls."
+ force = 19
+ materials = list(MAT_METAL=2000, MAT_PLASMA=2000)
+
+/obj/item/pickaxe/titanium
+ name = "titanium-tipped pickaxe"
+ icon_state = "psteelaxe"
+ toolspeed = 0.3
+ desc = "A pickaxe with a titanium pick head. Extremely robust at cracking rock walls and digging up dirt, but less than the plasteel pickaxe at cracking open skulls."
+ force = 17
+ materials = list(MAT_TITANIUM=4000)
+
/obj/item/pickaxe/drill
name = "mining drill"
icon_state = "handdrill"
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index a20bab3bae..325ea6e8ed 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -55,7 +55,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
var/deadchat_name
var/datum/spawners_menu/spawners_menu
-/mob/dead/observer/Initialize()
+/mob/dead/observer/Initialize(mapload, mob/body)
set_invisibility(GLOB.observer_default_invisibility)
verbs += list(
@@ -76,11 +76,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
updateallghostimages()
- var/turf/T
- var/mob/body = loc
- if(ismob(body))
- T = get_turf(body) //Where is the body located?
-
+ if(body)
gender = body.gender
if(body.mind && body.mind.name)
name = body.mind.name
@@ -105,14 +101,15 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
update_icon()
- if(!T)
+ if(!isturf(loc))
+ var/turf/T
var/list/turfs = get_area_turfs(/area/shuttle/arrival)
if(turfs.len)
T = pick(turfs)
else
T = SSmapping.get_station_center()
- forceMove(T)
+ forceMove(T)
if(!name) //To prevent nameless ghosts
name = random_unique_name(gender)
@@ -196,13 +193,13 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
else
ghostimage_default.icon_state = new_form
- if(ghost_accs >= GHOST_ACCS_DIR && icon_state in GLOB.ghost_forms_with_directions_list) //if this icon has dirs AND the client wants to show them, we make sure we update the dir on movement
+ if(ghost_accs >= GHOST_ACCS_DIR && (icon_state in GLOB.ghost_forms_with_directions_list)) //if this icon has dirs AND the client wants to show them, we make sure we update the dir on movement
updatedir = 1
else
updatedir = 0 //stop updating the dir in case we want to show accessories with dirs on a ghost sprite without dirs
setDir(2 )//reset the dir to its default so the sprites all properly align up
- if(ghost_accs == GHOST_ACCS_FULL && icon_state in GLOB.ghost_forms_with_accessories_list) //check if this form supports accessories and if the client wants to show them
+ if(ghost_accs == GHOST_ACCS_FULL && (icon_state in GLOB.ghost_forms_with_accessories_list)) //check if this form supports accessories and if the client wants to show them
var/datum/sprite_accessory/S
if(facial_hair_style)
S = GLOB.facial_hair_styles_list[facial_hair_style]
@@ -268,7 +265,7 @@ Works together with spawning an observer, noted above.
if(!key || key[1] == "@" || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING))
return //mob has no key, is an aghost or some component hijacked.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
- var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
+ var/mob/dead/observer/ghost = new(get_turf(src), src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
if (client && client.prefs && client.prefs.auto_ooc)
@@ -310,8 +307,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/obj/machinery/cryopod/C = loc
C.despawn_occupant()
else
- ghostize(0, penalize = TRUE, voluntary = TRUE) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
suicide_log(TRUE)
+ ghostize(FALSE, penalize = TRUE, voluntary = TRUE) //FALSE parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
+
/mob/camera/verb/ghost()
set category = "OOC"
@@ -770,7 +768,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
update_icon()
/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
- return IsAdminGhost(usr) || (M.ghost_flags & INTERACT_GHOST_READ)
+ return IsAdminGhost(usr)
/mob/dead/observer/is_literate()
return 1
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index a14fdb0b53..3b64c35969 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -10,7 +10,7 @@
organ_flags = ORGAN_VITAL
attack_verb = list("attacked", "slapped", "whacked")
///The brain's organ variables are significantly more different than the other organs, with half the decay rate for balance reasons, and twice the maxHealth
- decay_factor = STANDARD_ORGAN_DECAY / 4 //30 minutes of decaying to result in a fully damaged brain, since a fast decay rate would be unfun gameplay-wise
+ decay_factor = STANDARD_ORGAN_DECAY / 2 //30 minutes of decaying to result in a fully damaged brain, since a fast decay rate would be unfun gameplay-wise
healing_factor = STANDARD_ORGAN_HEALING / 2
maxHealth = BRAIN_DAMAGE_DEATH
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index d8977803ed..219e080ad1 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -3,7 +3,7 @@
/mob/living/carbon/Initialize()
. = ..()
- create_reagents(1000)
+ create_reagents(1000, NONE, NO_REAGENTS_VALUE)
update_body_parts() //to update the carbon's new bodyparts appearance
GLOB.carbon_list += src
blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 7a5fca3562..8e19fa7776 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -394,10 +394,10 @@
if(invisible_man)
. += "...?"
else
- var/flavor = print_flavor_text()
+ var/flavor = print_flavor_text(flavor_text)
if(flavor)
. += flavor
- var/temp_flavor = print_flavor_text_2()
+ var/temp_flavor = print_flavor_text(flavor_text_2)
if(temp_flavor)
. += temp_flavor
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 2b03e22b77..ef3d4cbb98 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -9,6 +9,8 @@
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
verbs += /mob/living/carbon/human/proc/underwear_toggle //fwee
+ verbs += /mob/proc/set_flavor
+ verbs += /mob/proc/set_flavor_2
//initialize limbs first
create_bodyparts()
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 36d9ca541b..63c7d8f668 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -5,7 +5,7 @@
pressure_resistance = 25
can_buckle = TRUE
buckle_lying = FALSE
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
//Hair colour and style
var/hair_color = "000"
var/hair_style = "Bald"
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index fd4cdbaf0f..e62177abbb 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -76,7 +76,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/list/species_traits = list()
// generic traits tied to having the species
var/list/inherent_traits = list()
- var/list/inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ var/inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID
var/attack_verb = "punch" // punch-specific attack verb
var/sound/attack_sound = 'sound/weapons/punch1.ogg'
@@ -1264,10 +1264,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.update_mutant_bodyparts()
/datum/species/proc/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
- if(chem.type == exotic_blood)
+ if(chem.type == exotic_blood && !istype(exotic_blood, /datum/reagent/blood))
H.blood_volume = min(H.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM)
H.reagents.del_reagent(chem.type)
- return 1
+ return TRUE
return FALSE
/datum/species/proc/check_weakness(obj/item, mob/living/attacker)
diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm
index ad9ba83771..559abd8d0b 100644
--- a/code/modules/mob/living/carbon/human/species_types/android.dm
+++ b/code/modules/mob/living/carbon/human/species_types/android.dm
@@ -4,7 +4,7 @@
say_mod = "states"
species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT)
- inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
+ inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
meat = null
gib_types = /obj/effect/gibspawner/robot
damage_overlay_type = "synth"
diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
index 4697e6aa3c..71f5aaa8e2 100644
--- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
@@ -3,7 +3,7 @@
id = "fly"
say_mod = "buzzes"
species_traits = list(NOEYES)
- inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_BUG)
+ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
mutanttongue = /obj/item/organ/tongue/fly
mutantliver = /obj/item/organ/liver/fly
mutantstomach = /obj/item/organ/stomach/fly
@@ -13,22 +13,23 @@
exotic_bloodtype = "BUG"
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
- if(chem.type == /datum/reagent/toxin/pestkiller)
+ if(istype(chem, /datum/reagent/toxin/pestkiller))
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
- return 1
-
-
-/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
- if(istype(chem, /datum/reagent/consumable))
+ return TRUE
+ else if(istype(chem, /datum/reagent/consumable))
var/datum/reagent/consumable/nutri_check = chem
if(nutri_check.nutriment_factor > 0)
var/turf/pos = get_turf(H)
H.vomit(0, FALSE, FALSE, 2, TRUE)
+ var/obj/effect/decal/cleanable/vomit/V = locate() in pos
+ if(V)
+ H.reagents.trans_id_to(V, chem, chem.volume)
playsound(pos, 'sound/effects/splat.ogg', 50, 1)
H.visible_message("[H] vomits on the floor!", \
"You throw up on the floor!")
- ..()
+ return TRUE
+ return ..()
/datum/species/fly/check_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/melee/flyswatter))
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 98c3f269dc..6da73f0b79 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -4,7 +4,7 @@
id = "iron golem"
species_traits = list(NOBLOOD,MUTCOLORS,NO_UNDERWEAR,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_CHUNKYFINGERS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
- inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
+ inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
mutant_organs = list(/obj/item/organ/adamantine_resonator)
speedmod = 2
armor = 55
@@ -308,7 +308,8 @@
if(chem.type == /datum/reagent/toxin/plantbgone)
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
- return 1
+ return TRUE
+ return ..()
//Radioactive
/datum/species/golem/uranium
@@ -622,12 +623,11 @@
if(chem.type == /datum/reagent/water/holywater)
H.adjustFireLoss(4)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
-
- if(chem.type == /datum/reagent/fuel/unholywater)
+ else if(chem.type == /datum/reagent/fuel/unholywater)
H.adjustBruteLoss(-4)
H.adjustFireLoss(-4)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
-
+ return ..()
/datum/species/golem/clockwork
name = "Clockwork Golem"
@@ -638,6 +638,7 @@
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL)
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
armor = 20 //Reinforced, but much less so to allow for fast movement
attack_verb = "smash"
attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
@@ -694,7 +695,7 @@
Being made of cloth, your body is magic resistant and faster than that of other golems, but weaker and less resilient."
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL) //no mutcolors, and can burn
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_CHUNKYFINGERS)
- inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
+ inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
armor = 15 //feels no pain, but not too resistant
burnmod = 2 // don't get burned
speedmod = 1 // not as heavy as stone
@@ -1017,7 +1018,7 @@
else
playsound(get_turf(owner),'sound/magic/RATTLEMEBONES.ogg', 100)
for(var/mob/living/L in orange(7, get_turf(owner)))
- if((MOB_UNDEAD in L.mob_biotypes) || isgolem(L) || HAS_TRAIT(L, TRAIT_RESISTCOLD))
+ if((L.mob_biotypes & MOB_UNDEAD) || isgolem(L) || HAS_TRAIT(L, TRAIT_RESISTCOLD))
return //Do not affect our brothers
to_chat(L, "A spine-chilling sound chills you to the bone!")
diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
index 5cdb051026..dfa1725026 100644
--- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
@@ -5,8 +5,8 @@
say_mod = "hisses"
default_color = "00FF00"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR)
- inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_REPTILE)
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur", "deco_wings")
+ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE
mutanttongue = /obj/item/organ/tongue/lizard
mutanttail = /obj/item/organ/tail/lizard
coldmod = 1.5
diff --git a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
index 2580e3b9f0..9d5ca92894 100644
--- a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
@@ -57,6 +57,7 @@
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
return TRUE
+ return ..()
/datum/species/mush/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
forced_colour = FALSE
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index 4a7399f287..c899575e44 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -6,7 +6,7 @@
meat = /obj/item/stack/sheet/mineral/plasma
species_traits = list(NOBLOOD,NOTRANSSTING,NOGENITALS)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER,TRAIT_CALCIUM_HEALER)
- inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
+ inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
mutantlungs = /obj/item/organ/lungs/plasmaman
mutanttongue = /obj/item/organ/tongue/bone/plasmaman
mutantliver = /obj/item/organ/liver/plasmaman
diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
index 66eb207670..b29890a97d 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -50,7 +50,8 @@
if(chem.type == /datum/reagent/toxin/plantbgone)
H.adjustToxLoss(3)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
- return 1
+ return TRUE
+ return ..()
/datum/species/pod/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
switch(P.type)
@@ -70,14 +71,42 @@
if(/obj/item/projectile/energy/florayield)
H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL)
+
/datum/species/pod/pseudo_weak
name = "Anthromorphic Plant"
id = "podweak"
- limbs_id = "pod"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur", "legs")
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs")
+ limbs_id = "pod"
light_nutrition_gain_factor = 7.5
light_bruteheal = 0.2
light_burnheal = 0.2
light_toxheal = 0.7
+
+/datum/species/pod/pseudo_weak/spec_death(gibbed, mob/living/carbon/human/H)
+ if(H)
+ stop_wagging_tail(H)
+
+/datum/species/pod/pseudo_weak/spec_stun(mob/living/carbon/human/H,amount)
+ if(H)
+ stop_wagging_tail(H)
+ . = ..()
+
+/datum/species/pod/pseudo_weak/can_wag_tail(mob/living/carbon/human/H)
+ return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
+
+/datum/species/pod/pseudo_weak/is_wagging_tail(mob/living/carbon/human/H)
+ return ("mam_waggingtail" in mutant_bodyparts)
+
+/datum/species/pod/pseudo_weak/start_wagging_tail(mob/living/carbon/human/H)
+ if("mam_tail" in mutant_bodyparts)
+ mutant_bodyparts -= "mam_tail"
+ mutant_bodyparts |= "mam_waggingtail"
+ H.update_body()
+
+/datum/species/pod/pseudo_weak/stop_wagging_tail(mob/living/carbon/human/H)
+ if("mam_waggingtail" in mutant_bodyparts)
+ mutant_bodyparts -= "mam_waggingtail"
+ mutant_bodyparts |= "mam_tail"
+ H.update_body()
diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
index 0c4007555c..410ad05d93 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -8,7 +8,7 @@
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
- inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
+ inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutanttongue = /obj/item/organ/tongue/bone
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
disliked_food = NONE
diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm
index 0957a9e807..cb7822ad7e 100644
--- a/code/modules/mob/living/carbon/human/species_types/synths.dm
+++ b/code/modules/mob/living/carbon/human/species_types/synths.dm
@@ -5,7 +5,7 @@
sexes = 0
species_traits = list(NOTRANSSTING,NOGENITALS,NOAROUSAL) //all of these + whatever we inherit from the real species
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER,TRAIT_NOBREATH)
- inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
+ inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
dangerous_existence = 1
blacklisted = 1
meat = null
@@ -39,9 +39,8 @@
if(chem.type == /datum/reagent/medicine/synthflesh)
chem.reaction_mob(H, TOUCH, 2 ,0) //heal a little
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
- return 1
- else
- return ..()
+ return TRUE
+ return ..()
/datum/species/synth/proc/assume_disguise(datum/species/S, mob/living/carbon/human/H)
@@ -124,4 +123,4 @@
if (/datum/species/golem/bananium)
speech_args[SPEECH_SPANS] |= SPAN_CLOWN
if (/datum/species/golem/clockwork)
- speech_args[SPEECH_SPANS] |= SPAN_ROBOT
\ No newline at end of file
+ speech_args[SPEECH_SPANS] |= SPAN_ROBOT
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index 7462d26ea6..8bbd870149 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -4,7 +4,7 @@
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD)
inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
- inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
+ inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None")
exotic_bloodtype = "U"
use_skintones = TRUE
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 8255f08507..26a99dbc2b 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -10,7 +10,7 @@
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
species_traits = list(NOBLOOD,NOZOMBIE,NOTRANSSTING)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH)
- inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
+ inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutanttongue = /obj/item/organ/tongue/zombie
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
disliked_food = NONE
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 1be9a0d72d..ccca90807b 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -357,12 +357,12 @@
if(istype(loc, /obj/structure/closet/crate/coffin)|| istype(loc, /obj/structure/closet/body_bag) || istype(loc, /obj/structure/bodycontainer))
return
- // No decay if formaldehyde in corpse or when the corpse is charred
- if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || HAS_TRAIT(src, TRAIT_HUSK))
+ // No decay if formaldehyde/preservahyde in corpse or when the corpse is charred
+ if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || HAS_TRAIT(src, TRAIT_HUSK) || reagents.has_reagent(/datum/reagent/preservahyde, 1))
return
// Also no decay if corpse chilled or not organic/undead
- if(bodytemperature <= T0C-10 || (!(MOB_ORGANIC in mob_biotypes) && !(MOB_UNDEAD in mob_biotypes)))
+ if((bodytemperature <= T0C-10) || !(mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)))
return
// Wait a bit before decaying
@@ -397,7 +397,7 @@
if(O)
O.on_life()
else
- if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1)) // No organ decay if the body contains formaldehyde.
+ if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || reagents.has_reagent(/datum/reagent/preservahyde, 1)) // No organ decay if the body contains formaldehyde. Or preservahyde.
return
for(var/V in internal_organs)
var/obj/item/organ/O = V
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index cd51a4234b..f3abe83958 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -7,7 +7,7 @@
gender = NEUTER
pass_flags = PASSTABLE
ventcrawler = VENTCRAWLER_NUDE
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/monkey
gib_type = /obj/effect/decal/cleanable/blood/gibs
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index 45f9662c9a..a33eebf12a 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -25,7 +25,7 @@
/mob/living/proc/spawn_gibs(with_bodyparts, atom/loc_override)
var/location = loc_override ? loc_override.drop_location() : drop_location()
- if(MOB_ROBOTIC in mob_biotypes)
+ if(mob_biotypes & MOB_ROBOTIC)
new /obj/effect/gibspawner/robot(location, src, get_static_viruses())
else
new /obj/effect/gibspawner/generic(location, src, get_static_viruses())
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 8652a1ee9e..0c11d6ab42 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1080,7 +1080,7 @@
stop_pulling() //CIT CHANGE - Ditto...
else if(has_legs || ignore_legs)
lying = 0
- if (pulledby)
+ if (pulledby && isliving(pulledby))
var/mob/living/L = pulledby
L.update_pull_movespeed()
if(buckled)
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 031a2e9b94..7106d003ee 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -52,7 +52,7 @@
var/limb_destroyer = 0 //1 Sets AI behavior that allows mobs to target and dismember limbs with their basic attack.
var/mob_size = MOB_SIZE_HUMAN
- var/list/mob_biotypes = list(MOB_ORGANIC)
+ var/mob_biotypes = MOB_ORGANIC
var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature..
var/has_limbs = 0 //does the mob have distinct limbs?(arms,legs, chest,head)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index b0f627f82b..35b49cce8e 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -258,7 +258,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(M.stat != DEAD) //not dead, not important
if(yellareas) //CIT CHANGE - see above. makes yelling penetrate walls
var/area/A = get_area(M) //CIT CHANGE - ditto
- if(istype(A) && A.ambientsounds != SPACE && A in yellareas) //CIT CHANGE - ditto
+ if(istype(A) && A.ambientsounds != SPACE && (A in yellareas)) //CIT CHANGE - ditto
listening |= M //CIT CHANGE - ditto
continue
if(!M.client || !client) //client is so that ghosts don't have to listen to mice
@@ -368,7 +368,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(message_mode == MODE_HEADSET)
imp.radio.talk_into(src, message, , spans, language)
return ITALICS | REDUCE_RANGE
- if(message_mode == MODE_DEPARTMENT || message_mode in GLOB.radiochannels)
+ if(message_mode == MODE_DEPARTMENT || (message_mode in GLOB.radiochannels))
imp.radio.talk_into(src, message, message_mode, spans, language)
return ITALICS | REDUCE_RANGE
diff --git a/code/modules/mob/living/silicon/pai/update_icon.dm b/code/modules/mob/living/silicon/pai/update_icon.dm
index 9e40b71c5d..8c051d9c41 100644
--- a/code/modules/mob/living/silicon/pai/update_icon.dm
+++ b/code/modules/mob/living/silicon/pai/update_icon.dm
@@ -8,9 +8,9 @@
var/list/states = icon_states(icon)
icon_state = ""
if(resting) //The next line is some bullshit but I can make it worse if you want and make it a single line instead of four.. :)
- if(dynamic_chassis_sit && ("sit") in states)
+ if(dynamic_chassis_sit && ("sit" in states))
icon_state = "sit"
- else if(dynamic_chassis_bellyup && ("bellyup") in states)
+ else if(dynamic_chassis_bellyup && ("bellyup" in states))
icon_state = "bellyup"
else if("rest" in states)
icon_state = "rest"
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index e304f13d1d..c6af8bd4c2 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -340,7 +340,7 @@
/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/medmodels = list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot", "Medihound", "Medihound Dark", "Vale")
- if(R.client && R.client.ckey in list("nezuli"))
+ if(R.client && (R.client.ckey in list("nezuli")))
medmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medmodels
if(!borg_icon)
@@ -437,7 +437,7 @@
/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
- if(R.client && R.client.ckey in list("nezuli"))
+ if(R.client && (R.client.ckey in list("nezuli")))
engymodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
if(!borg_icon)
@@ -515,7 +515,7 @@
/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/secmodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider", "K9", "K9 Dark", "Vale")
- if(R.client && R.client.ckey in list("nezuli"))
+ if(R.client && (R.client.ckey in list("nezuli")))
secmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in secmodels
if(!borg_icon)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index e5881848d5..72e98e348c 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -10,7 +10,7 @@
bubble_icon = "machine"
weather_immunities = list("ash")
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
- mob_biotypes = list(MOB_ROBOTIC)
+ mob_biotypes = MOB_ROBOTIC
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
speech_span = SPAN_ROBOT
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 6112a1e800..7da0ad13da 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -3,7 +3,7 @@
icon = 'icons/mob/aibots.dmi'
layer = MOB_LAYER
gender = NEUTER
- mob_biotypes = list(MOB_ROBOTIC)
+ mob_biotypes = MOB_ROBOTIC
light_range = 3
light_power = 0.9
light_color = "#CDDDFF"
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index fbdc32f2c1..4c6bfc4c3e 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -3,7 +3,7 @@
real_name = "Construct"
desc = ""
gender = NEUTER
- mob_biotypes = list(MOB_INORGANIC)
+ mob_biotypes = NONE
speak_emote = list("hisses")
response_help = "thinks better of touching"
response_disarm = "flails at"
diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
index 2fbbad66d8..80fba5a9a4 100644
--- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm
+++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
@@ -18,7 +18,7 @@
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
- mob_biotypes = list(MOB_ORGANIC, MOB_BUG)
+ mob_biotypes = MOB_ORGANIC|MOB_BUG
gold_core_spawnable = FRIENDLY_SPAWN
verb_say = "flutters"
verb_ask = "flutters inquisitively"
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index f12f3649cf..0f95096497 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -17,7 +17,7 @@
ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE
mob_size = MOB_SIZE_SMALL
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
minbodytemp = 200
maxbodytemp = 400
unsuitable_atmos_damage = 1
diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm
index 26d4691d83..95aa86aaab 100644
--- a/code/modules/mob/living/simple_animal/friendly/cockroach.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm
@@ -13,7 +13,7 @@
maxbodytemp = INFINITY
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
- mob_biotypes = list(MOB_ORGANIC, MOB_BUG)
+ mob_biotypes = MOB_ORGANIC|MOB_BUG
response_help = "pokes"
response_disarm = "shoos"
response_harm = "splats"
diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm
index 5dbf755601..d906757ed5 100644
--- a/code/modules/mob/living/simple_animal/friendly/crab.dm
+++ b/code/modules/mob/living/simple_animal/friendly/crab.dm
@@ -11,7 +11,7 @@
blood_volume = 350
speak_chance = 1
turns_per_move = 5
- butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1)
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/rawcrab = 1)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index 873051c336..37ef271226 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -1,7 +1,7 @@
//Dogs.
/mob/living/simple_animal/pet/dog
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index 158719414a..7dd373b49f 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -35,7 +35,7 @@
sight = (SEE_TURFS | SEE_OBJS)
status_flags = (CANPUSH | CANSTUN | CANKNOCKDOWN)
gender = NEUTER
- mob_biotypes = list(MOB_ROBOTIC)
+ mob_biotypes = MOB_ROBOTIC
speak_emote = list("chirps")
speech_span = SPAN_ROBOT
bubble_icon = "machine"
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index 38bcfbde79..fad519838a 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -17,7 +17,7 @@
response_disarm = "gently pushes aside"
response_harm = "kicks"
faction = list("neutral")
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
attack_same = 1
attacktext = "kicks"
attack_sound = 'sound/weapons/punch1.ogg'
@@ -112,7 +112,7 @@
icon_dead = "cow_dead"
icon_gib = "cow_gib"
gender = FEMALE
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak = list("moo?","moo","MOOOOOO")
speak_emote = list("moos","moos hauntingly")
emote_hear = list("brays.")
@@ -189,7 +189,7 @@
icon_dead = "chick_dead"
icon_gib = "chick_gib"
gender = FEMALE
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
speak_emote = list("cheeps")
emote_hear = list("cheeps.")
@@ -235,7 +235,7 @@
name = "\improper chicken"
desc = "Hopefully the eggs are good this season."
gender = FEMALE
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
icon_state = "chicken_brown"
icon_living = "chicken_brown"
icon_dead = "chicken_brown_dead"
@@ -454,7 +454,7 @@
name = "udder"
/obj/item/udder/Initialize()
- create_reagents(50)
+ create_reagents(50, NONE, NO_REAGENTS_VALUE)
reagents.add_reagent(/datum/reagent/consumable/milk, 20)
. = ..()
diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm
index 6275256f5a..f0d354ace1 100644
--- a/code/modules/mob/living/simple_animal/friendly/lizard.dm
+++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm
@@ -18,7 +18,7 @@
density = FALSE
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST, MOB_REPTILE)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST|MOB_REPTILE
gold_core_spawnable = FRIENDLY_SPAWN
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index d326573957..c5a4fa6e1e 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -22,7 +22,7 @@
ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
var/body_color //brown, gray and white, leave blank for random
gold_core_spawnable = FRIENDLY_SPAWN
var/chew_probability = 1
diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm
index c24dc6857a..dbdb5c646c 100644
--- a/code/modules/mob/living/simple_animal/friendly/pet.dm
+++ b/code/modules/mob/living/simple_animal/friendly/pet.dm
@@ -1,7 +1,7 @@
/mob/living/simple_animal/pet
icon = 'icons/mob/pets.dmi'
mob_size = MOB_SIZE_SMALL
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
blood_volume = BLOOD_VOLUME_NORMAL
var/unique_pet = FALSE // if the mob can be renamed
var/obj/item/clothing/neck/petcollar/pcollar
diff --git a/code/modules/mob/living/simple_animal/friendly/sloth.dm b/code/modules/mob/living/simple_animal/friendly/sloth.dm
index 21df73fa61..28063d6e52 100644
--- a/code/modules/mob/living/simple_animal/friendly/sloth.dm
+++ b/code/modules/mob/living/simple_animal/friendly/sloth.dm
@@ -14,7 +14,7 @@
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
melee_damage_lower = 18
melee_damage_upper = 18
diff --git a/code/modules/mob/living/simple_animal/friendly/snake.dm b/code/modules/mob/living/simple_animal/friendly/snake.dm
index 95838c9acb..7f75888649 100644
--- a/code/modules/mob/living/simple_animal/friendly/snake.dm
+++ b/code/modules/mob/living/simple_animal/friendly/snake.dm
@@ -30,7 +30,7 @@
density = FALSE
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST, MOB_REPTILE)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST|MOB_REPTILE
gold_core_spawnable = FRIENDLY_SPAWN
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
@@ -59,4 +59,4 @@
QDEL_NULL(target)
adjustBruteLoss(-2)
else
- return ..()
\ No newline at end of file
+ return ..()
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index 62c8588ac8..9ad3cbd373 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -10,7 +10,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
desc = "A mysterious being that stands by its charge, ever vigilant."
speak_emote = list("hisses")
gender = NEUTER
- mob_biotypes = list(MOB_INORGANIC)
+ mob_biotypes = NONE
bubble_icon = "guardian"
response_help = "passes through"
response_disarm = "flails at"
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index acd8da9618..b019019c71 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -6,7 +6,7 @@
icon_living = "bear"
icon_dead = "bear_dead"
icon_gib = "bear_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak = list("RAWR!","Rawr!","GRR!","Growl!")
speak_emote = list("growls", "roars")
emote_hear = list("rawrs.","grumbles.","grawls.")
diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm
index bb1f1284b5..524c220fa4 100644
--- a/code/modules/mob/living/simple_animal/hostile/bees.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bees.dm
@@ -37,7 +37,7 @@
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
density = FALSE
mob_size = MOB_SIZE_TINY
- mob_biotypes = list(MOB_ORGANIC, MOB_BUG)
+ mob_biotypes = MOB_ORGANIC|MOB_BUG
movement_type = FLYING
gold_core_spawnable = HOSTILE_SPAWN
search_objects = 1 //have to find those plant trays!
diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm
index 2b5b5236ed..07572fff83 100644
--- a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm
@@ -2,7 +2,7 @@
/mob/living/simple_animal/hostile/boss/paper_wizard
name = "Mjor the Creative"
desc = "A wizard with a taste for the arts."
- mob_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_HUMANOID
boss_abilities = list(/datum/action/boss/wizard_summon_minions, /datum/action/boss/wizard_mimic)
faction = list("hostile","stickman")
del_on_death = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index d527a40120..36968a1ab0 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -7,7 +7,7 @@
icon_living = "carp"
icon_dead = "carp_dead"
icon_gib = "carp_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak_chance = 0
turns_per_move = 5
butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 2)
diff --git a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm
index 5181e920d7..4e3375caf7 100644
--- a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm
+++ b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm
@@ -22,7 +22,7 @@
attacktext = "slashes at"
attack_sound = 'sound/weapons/circsawhit.ogg'
a_intent = INTENT_HARM
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
loot = list(/obj/effect/mob_spawn/human/corpse/cat_butcher, /obj/item/circular_saw)
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 15
diff --git a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm
index 44f7f9c9f8..2d438dbf1c 100644
--- a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm
@@ -7,7 +7,7 @@
icon_living = "eyeball"
icon_gib = ""
gender = NEUTER
- mob_biotypes = list(MOB_ORGANIC)
+ mob_biotypes = MOB_ORGANIC
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "hits"
diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm
index 3d411738c1..479b102b36 100644
--- a/code/modules/mob/living/simple_animal/hostile/faithless.dm
+++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm
@@ -4,7 +4,7 @@
icon_state = "faithless"
icon_living = "faithless"
icon_dead = "faithless_dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
gender = MALE
speak_chance = 0
turns_per_move = 5
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index 20ce5ac751..cc7b1e19d1 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -22,7 +22,7 @@
icon_state = "guard"
icon_living = "guard"
icon_dead = "guard_dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_BUG)
+ mob_biotypes = MOB_ORGANIC|MOB_BUG
speak_emote = list("chitters")
emote_hear = list("chitters")
speak_chance = 5
diff --git a/code/modules/mob/living/simple_animal/hostile/goose.dm b/code/modules/mob/living/simple_animal/hostile/goose.dm
index 3bc8715c5c..db232c20c4 100644
--- a/code/modules/mob/living/simple_animal/hostile/goose.dm
+++ b/code/modules/mob/living/simple_animal/hostile/goose.dm
@@ -6,7 +6,7 @@
icon_state = "goose" // sprites by cogwerks from goonstation, used with permission
icon_living = "goose"
icon_dead = "goose_dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak_chance = 0
turns_per_move = 5
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm
index 6866df01d5..6d864576a1 100644
--- a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm
+++ b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm
@@ -9,7 +9,7 @@
icon_state = "crawling"
icon_living = "crawling"
icon_dead = "dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 80
maxHealth = 220
health = 220
diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm
index 5ee2549054..89303702f3 100644
--- a/code/modules/mob/living/simple_animal/hostile/illusion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm
@@ -6,7 +6,7 @@
icon_living = "static"
icon_dead = "null"
gender = NEUTER
- mob_biotypes = list()
+ mob_biotypes = NONE
melee_damage_lower = 5
melee_damage_upper = 5
a_intent = INTENT_HARM
diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm
index deb88d677b..ea01e4b659 100644
--- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm
+++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm
@@ -10,7 +10,7 @@
icon_state = "leaper"
icon_living = "leaper"
icon_dead = "leaper_dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
maxHealth = 300
health = 300
ranged = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm
index 607db5d54f..91e17e8e57 100644
--- a/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm
+++ b/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm
@@ -7,7 +7,7 @@
icon_state = "arachnid"
icon_living = "arachnid"
icon_dead = "arachnid_dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_BUG)
+ mob_biotypes = MOB_ORGANIC|MOB_BUG
melee_damage_lower = 30
melee_damage_upper = 30
maxHealth = 300
diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm
index b786637592..b2e6fa9704 100644
--- a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm
+++ b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm
@@ -13,7 +13,7 @@
icon_state = "mook"
icon_living = "mook"
icon_dead = "mook_dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
pixel_x = -16
maxHealth = 45
health = 45
diff --git a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
index 2e783d84d8..c025ba58db 100644
--- a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
@@ -23,7 +23,7 @@
desc = "Death to Nanotrasen. This variant comes in MECHA DEATH flavour."
wanted_objects = list()
search_objects = 0
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
var/spawn_mecha_type = /obj/mecha/combat/marauder/mauler/loaded
var/obj/mecha/mecha //Ref to pilot's mecha instance
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index 899e901827..a0e6561c68 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -28,7 +28,7 @@ Difficulty: Medium
icon_state = "miner"
icon_living = "miner"
icon = 'icons/mob/broadMobs.dmi'
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
light_color = "#E4C7C5"
movement_type = GROUND
speak_emote = list("roars")
@@ -39,8 +39,8 @@ Difficulty: Medium
ranged = 1
ranged_cooldown_time = 16
pixel_x = -16
- crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator, /obj/item/crusher_trophy/miner_eye)
- loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator)
+ crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka, /obj/item/crusher_trophy/miner_eye)
+ loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka)
wander = FALSE
del_on_death = TRUE
blood_volume = BLOOD_VOLUME_NORMAL
@@ -73,7 +73,7 @@ Difficulty: Medium
target.stun_absorption -= "miner"
/obj/item/projectile/kinetic/miner
- damage = 20
+ damage = 40
speed = 0.9
icon_state = "ka_tracer"
range = MINER_DASH_RANGE
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index d7c52efe1d..9ee51c0c4f 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -6,7 +6,7 @@
a_intent = INTENT_HARM
sentience_type = SENTIENCE_BOSS
environment_smash = ENVIRONMENT_SMASH_RWALLS
- mob_biotypes = list(MOB_ORGANIC, MOB_EPIC)
+ mob_biotypes = MOB_ORGANIC|MOB_EPIC
obj_damage = 400
light_range = 3
faction = list("mining", "boss")
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index 5e159e8517..16a55421b8 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -12,7 +12,7 @@
maxHealth = 250
health = 250
gender = NEUTER
- mob_biotypes = list(MOB_INORGANIC)
+ mob_biotypes = NONE
harm_intent_damage = 5
melee_damage_lower = 8
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
index 91b76974b5..1cbabd41dd 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
@@ -8,7 +8,7 @@
icon_aggro = "Basilisk_alert"
icon_dead = "Basilisk_dead"
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
move_to_delay = 20
projectiletype = /obj/item/projectile/temp/basilisk
projectilesound = 'sound/weapons/pierce.ogg'
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
index e4046138cd..8687b2d14c 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
@@ -5,7 +5,7 @@
icon_state = "curseblob"
icon_living = "curseblob"
icon_aggro = "curseblob"
- mob_biotypes = list(MOB_SPIRIT)
+ mob_biotypes = MOB_SPIRIT
movement_type = FLYING
move_to_delay = 5
vision_range = 20
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm
index c02f0c46c7..25e38652e1 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm
@@ -8,7 +8,7 @@
icon_aggro = "Goldgrub_alert"
icon_dead = "Goldgrub_dead"
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
vision_range = 2
aggro_vision_range = 9
move_to_delay = 5
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
index c17e98a7db..87abc1ea14 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
@@ -8,7 +8,7 @@
icon_aggro = "Goliath_alert"
icon_dead = "Goliath_dead"
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
mouse_opacity = MOUSE_OPACITY_OPAQUE
move_to_delay = 10
ranged = 1
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
index 9e9fbaeab8..fd3221d900 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
@@ -6,7 +6,7 @@
icon_state = "gutlunch"
icon_living = "gutlunch"
icon_dead = "gutlunch"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak_emote = list("warbles", "quavers")
emote_hear = list("trills.")
emote_see = list("sniffs.", "burps.")
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
index 9e398ce0da..11de9df70b 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
@@ -7,7 +7,7 @@
icon_aggro = "Hivelord_alert"
icon_dead = "Hivelord_dead"
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_ORGANIC)
+ mob_biotypes = MOB_ORGANIC
mouse_opacity = MOUSE_OPACITY_OPAQUE
move_to_delay = 14
ranged = 1
@@ -98,7 +98,7 @@
icon_aggro = "legion"
icon_dead = "legion"
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
obj_damage = 60
melee_damage_lower = 15
melee_damage_upper = 15
diff --git a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm
index 543ffe6131..ed2a407b8e 100644
--- a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm
+++ b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm
@@ -6,7 +6,7 @@
icon_living = "nanotrasen"
icon_dead = null
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 12
turns_per_move = 5
response_help = "pokes"
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
index 918a2d8acc..363e3ec573 100644
--- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -4,7 +4,7 @@
icon_state = "otherthing"
icon_living = "otherthing"
icon_dead = "otherthing-dead"
- mob_biotypes = list(MOB_INORGANIC)
+ mob_biotypes = NONE
health = 80
maxHealth = 80
obj_damage = 100
diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm
index 174ae0b9fb..1b2212bf55 100644
--- a/code/modules/mob/living/simple_animal/hostile/pirate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm
@@ -5,7 +5,7 @@
icon_state = "piratemelee"
icon_living = "piratemelee"
icon_dead = "pirate_dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 0
turns_per_move = 5
response_help = "pushes"
@@ -43,7 +43,7 @@
var/obj/effect/light_emitter/red_energy_sword/sord
do_footstep = TRUE
-
+
/mob/living/simple_animal/hostile/pirate/melee/space
name = "Space Pirate Swashbuckler"
icon_state = "piratespace"
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm
index c518cbe083..cc17759cc6 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm
@@ -10,7 +10,7 @@
response_help = "brushes aside"
response_disarm = "flails at"
response_harm = "hits"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak_chance = 0
maxHealth = 15
health = 15
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
index d2c8f1f270..ca14d4ae67 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
@@ -6,7 +6,7 @@
icon_living = "clown"
icon_dead = "clown_dead"
icon_gib = "clown_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
turns_per_move = 5
response_help = "pokes"
response_disarm = "gently pushes aside"
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm
index 47734abebc..ef51d8621b 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm
@@ -4,7 +4,7 @@
icon_state = "frog"
icon_living = "frog"
icon_dead = "frog_dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak = list("ribbit","croak")
emote_see = list("hops in a circle.", "shakes.")
speak_chance = 1
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm
index bfe8349192..48d16f63f3 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm
@@ -4,7 +4,7 @@
icon = 'icons/mob/mob.dmi'
icon_state = "ghost"
icon_living = "ghost"
- mob_biotypes = list(MOB_SPIRIT)
+ mob_biotypes = MOB_SPIRIT
speak_chance = 0
turns_per_move = 5
response_help = "passes through"
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm
index c50ace8871..29b0c0b701 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm
@@ -5,7 +5,7 @@
icon_living = "old"
icon_dead = "old_dead"
icon_gib = "clown_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
gender = MALE
turns_per_move = 5
response_help = "pokes"
diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm
index f66814f01f..c99c7a04b5 100644
--- a/code/modules/mob/living/simple_animal/hostile/russian.dm
+++ b/code/modules/mob/living/simple_animal/hostile/russian.dm
@@ -6,7 +6,7 @@
icon_living = "russianmelee"
icon_dead = "russianmelee_dead"
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 0
turns_per_move = 5
response_help = "pokes"
diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm
index 48b69a1f5c..51c55cbf65 100644
--- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm
+++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm
@@ -6,7 +6,7 @@
icon_living = "skeleton"
icon_dead = "skeleton"
gender = NEUTER
- mob_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
+ mob_biotypes = MOB_UNDEAD|MOB_HUMANOID
turns_per_move = 5
speak_emote = list("rattles")
emote_see = list("rattles")
diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm
index 1e1fa9d41b..5ad787b143 100644
--- a/code/modules/mob/living/simple_animal/hostile/statue.dm
+++ b/code/modules/mob/living/simple_animal/hostile/statue.dm
@@ -9,7 +9,7 @@
icon_dead = "human_male"
gender = NEUTER
a_intent = INTENT_HARM
- mob_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_HUMANOID
response_help = "touches"
response_disarm = "pushes"
@@ -191,7 +191,7 @@
/obj/effect/proc_holder/spell/aoe_turf/blindness/cast(list/targets,mob/user = usr)
for(var/mob/living/L in GLOB.alive_mob_list)
var/turf/T = get_turf(L.loc)
- if(T && T in targets)
+ if(T && (T in targets))
L.blind_eyes(4)
return
diff --git a/code/modules/mob/living/simple_animal/hostile/stickman.dm b/code/modules/mob/living/simple_animal/hostile/stickman.dm
index fa5cb151ed..855d55938d 100644
--- a/code/modules/mob/living/simple_animal/hostile/stickman.dm
+++ b/code/modules/mob/living/simple_animal/hostile/stickman.dm
@@ -5,7 +5,7 @@
icon_living = "stickman"
icon_dead = "stickman_dead"
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_HUMANOID
gender = MALE
speak_chance = 0
turns_per_move = 5
@@ -40,7 +40,7 @@
minimum_distance = 5
icon_state = "stickmanranged"
icon_living = "stickmanranged"
- casingtype = /obj/item/ammo_casing/c45/nostamina
+ casingtype = /obj/item/ammo_casing/c10mm
projectilesound = 'sound/misc/bang.ogg'
loot = list(/obj/item/gun/ballistic/automatic/pistol/stickman)
@@ -51,7 +51,7 @@
icon_state = "stickdog"
icon_living = "stickdog"
icon_dead = "stickdog_dead"
- mob_biotypes = list(MOB_INORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_BEAST
/mob/living/simple_animal/hostile/stickman/Initialize(mapload, var/wizard_summoned)
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index 96a75f6b4f..0947a3090b 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -22,7 +22,7 @@
icon_living = "syndicate"
icon_dead = "syndicate_dead"
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 0
turns_per_move = 5
response_help = "pokes"
@@ -284,7 +284,7 @@
icon_living = "viscerator_attack"
pass_flags = PASSTABLE | PASSMOB
a_intent = INTENT_HARM
- mob_biotypes = list(MOB_ROBOTIC)
+ mob_biotypes = MOB_ROBOTIC
health = 25
maxHealth = 25
melee_damage_lower = 15
diff --git a/code/modules/mob/living/simple_animal/hostile/wizard.dm b/code/modules/mob/living/simple_animal/hostile/wizard.dm
index f047a7aed1..f97613fe8f 100644
--- a/code/modules/mob/living/simple_animal/hostile/wizard.dm
+++ b/code/modules/mob/living/simple_animal/hostile/wizard.dm
@@ -5,7 +5,7 @@
icon_state = "wizard"
icon_living = "wizard"
icon_dead = "wizard_dead"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 0
turns_per_move = 3
response_help = "pokes"
diff --git a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm
index ec7451dc2e..88b5bcc373 100644
--- a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm
+++ b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm
@@ -8,7 +8,7 @@
icon_aggro = "Fugu0"
icon_dead = "Fugu_dead"
icon_gib = "syndicate_gib"
- mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
mouse_opacity = MOUSE_OPACITY_ICON
move_to_delay = 5
friendly = "floats near"
diff --git a/code/modules/mob/living/simple_animal/hostile/zombie.dm b/code/modules/mob/living/simple_animal/hostile/zombie.dm
index 7d89941687..ae3f0465d5 100644
--- a/code/modules/mob/living/simple_animal/hostile/zombie.dm
+++ b/code/modules/mob/living/simple_animal/hostile/zombie.dm
@@ -4,7 +4,7 @@
icon = 'icons/mob/simple_human.dmi'
icon_state = "zombie"
icon_living = "zombie"
- mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 0
stat_attack = UNCONSCIOUS //braains
maxHealth = 100
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index f378906db1..e79e24b885 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -467,11 +467,11 @@
return
return
- if(parrot_interest && parrot_interest in view(src))
+ if(parrot_interest && (parrot_interest in view(src)))
parrot_state = PARROT_SWOOP | PARROT_STEAL
return
- if(parrot_perch && parrot_perch in view(src))
+ if(parrot_perch && (parrot_perch in view(src)))
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index 64ffa147cf..6aa7f8b401 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -6,7 +6,7 @@
icon = 'icons/mob/mob.dmi'
icon_state = "shade"
icon_living = "shade"
- mob_biotypes = list(MOB_SPIRIT)
+ mob_biotypes = MOB_SPIRIT
maxHealth = 40
health = 40
spacewalk = TRUE
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 5a1a794d4e..2ea2a412f8 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -97,7 +97,7 @@
else
var/datum/action/innate/slime/evolve/E = new
E.Grant(src)
- create_reagents(100)
+ create_reagents(100, NONE, NO_REAGENTS_VALUE)
set_colour(new_colour)
. = ..()
nutrition = 700
diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm
index e4d1aa94a5..46d0608f44 100644
--- a/code/modules/mob/living/taste.dm
+++ b/code/modules/mob/living/taste.dm
@@ -16,21 +16,22 @@
// non destructively tastes a reagent container
/mob/living/proc/taste(datum/reagents/from)
- if(last_taste_time + 50 < world.time)
- var/taste_sensitivity = get_taste_sensitivity()
- var/text_output = from.generate_taste_message(taste_sensitivity)
- // We dont want to spam the same message over and over again at the
- // person. Give it a bit of a buffer.
- if(hallucination > 50 && prob(25))
- text_output = pick("spiders","dreams","nightmares","the future","the past","victory",\
- "defeat","pain","bliss","revenge","poison","time","space","death","life","truth","lies","justice","memory",\
- "regrets","your soul","suffering","music","noise","blood","hunger","the american way")
- if(text_output != last_taste_text || last_taste_time + 100 < world.time)
- to_chat(src, "You can taste [text_output].")
- // "something indescribable" -> too many tastes, not enough flavor.
-
- last_taste_time = world.time
- last_taste_text = text_output
+ if(last_taste_time + 50 > world.time)
+ return FALSE
+ var/taste_sensitivity = get_taste_sensitivity()
+ var/text_output = from.generate_taste_message(taste_sensitivity)
+ // We dont want to spam the same message over and over again at the
+ // person. Give it a bit of a buffer.
+ if(hallucination > 50 && prob(25))
+ text_output = pick("spiders","dreams","nightmares","the future","the past","victory",\
+ "defeat","pain","bliss","revenge","poison","time","space","death","life","truth","lies","justice","memory",\
+ "regrets","your soul","suffering","music","noise","blood","hunger","the american way")
+ if(text_output != last_taste_text || last_taste_time + 100 < world.time)
+ to_chat(src, "You can taste [text_output].")
+ // "something indescribable" -> too many tastes, not enough flavor.
+ last_taste_time = world.time
+ last_taste_text = text_output
+ return TRUE
//FermiChem - How to check pH of a beaker without a meter/pH paper.
//Basically checks the pH of the holder and burns your poor tongue if it's too acidic!
@@ -41,22 +42,24 @@
if (!T)
return
.=..()
+ if(!.)
+ return
if ((from.pH > 12.5) || (from.pH < 1.5))
- to_chat(src, "You taste chemical burns!")
T.applyOrganDamage(5)
+ to_chat(src, "You taste chemical burns!")
if(istype(T, /obj/item/organ/tongue/cybernetic))
to_chat(src, "Your tongue moves on it's own in response to the liquid.")
say("The pH is appropriately [round(from.pH, 1)].")
return
if (!HAS_TRAIT(src, TRAIT_AGEUSIA)) //I'll let you get away with not having 1 damage.
switch(from.pH)
- if(11.5 to INFINITY)
+ if(11.5 to 12.5)
to_chat(src, "You taste a strong alkaline flavour!")
if(8.5 to 11.5)
to_chat(src, "You taste a sort of soapy tone in the mixture.")
if(2.5 to 5.5)
to_chat(src, "You taste a sort of acid tone in the mixture.")
- if(-INFINITY to 2.5)
+ if(1.5 to 2.5)
to_chat(src, "You taste a strong acidic flavour!")
#undef DEFAULT_TASTE_SENSITIVITY
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 0e39f43263..1ca6299efb 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -512,9 +512,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
usr << browse(text("[][]", name, replacetext(flavor_text_2, "\n", "
")), text("window=[];size=500x200", name))
onclose(usr, "[name]")
- if(href_list["flavor_change"])
- update_flavor_text()
-
if(href_list["refresh"])
if(machine && in_range(src, usr))
show_inv(machine)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 7d446e4ef0..6d5ae72e77 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -124,4 +124,7 @@
var/siliconaccessareas = list()
var/siliconaccesstoggle = FALSE
- var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted.
\ No newline at end of file
+ var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted.
+
+ var/flavor_text = ""
+ var/flavor_text_2 = "" //version of the above that only lasts for the current round.
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 17e0d3d25b..b25531f0e0 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -429,18 +429,6 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
/mob/living/getImplant(type)
return locate(type) in implants
-/proc/canGhostWrite(var/mob/A, var/obj/target, var/desc="", var/allow_all=FALSE)
- if(allow_all & TRUE)
- if(!target.GetComponent(/datum/component/anti_magic))
- return 1
- if(IsAdminGhost(A))
- if (desc != "")
- log_admin("GHOST: [key_name(A)] [desc] ([target.name] at [loc_name(target)])")
- else
- log_admin("GHOST: [key_name(A)] fucked with the [target.name] at [loc_name(target)]")
- return 1
- return 0
-
/proc/offer_control(mob/M)
to_chat(M, "Control of your mob has been offered to dead players.")
if(usr)
diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm
index 74cc0c2e77..377bb1c5fc 100644
--- a/code/modules/mob/say_vr.dm
+++ b/code/modules/mob/say_vr.dm
@@ -1,52 +1,6 @@
//////////////////////////////////////////////////////
////////////////////SUBTLE COMMAND////////////////////
//////////////////////////////////////////////////////
-/mob
- var/flavor_text = "" //tired of fucking double checking this
- var/flavor_text_2 = ""
-
-/mob/proc/update_flavor_text()
- set src in usr
- if(usr != src)
- to_chat(usr, "No.")
- var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN, TRUE)
-
- if(msg)
- flavor_text = html_encode(msg)
-
-/mob/proc/update_flavor_text_2()
- set src in usr
- if(usr != src)
- to_chat(usr, "No.")
- var/msg = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", html_decode(flavor_text_2), MAX_MESSAGE_LEN, TRUE)
-
- if(msg)
- flavor_text_2 = html_encode(msg)
-
-
-/mob/proc/warn_flavor_changed()
- if(flavor_text && flavor_text != "") // don't spam people that don't use it!
- to_chat(src, "OOC Warning:
")
- to_chat(src, "Your flavor text is likely out of date! Change")
-
-/mob/proc/print_flavor_text()
- if(flavor_text && flavor_text != "")
- // We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
- var/msg = html_decode(replacetext(flavor_text, "\n", " "))
- if(length_char(msg) <= 40)
- return "[html_encode(msg)]"
- else
- return "[html_encode(copytext_char(msg, 1, 37))]... More..."
-
-/mob/proc/print_flavor_text_2()
- if(flavor_text && flavor_text != "")
- // We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
- var/msg = html_decode(replacetext(flavor_text_2, "\n", " "))
- if(length_char(msg) <= 40)
- return "[html_encode(msg)]"
- else
- return "[html_encode(copytext_char(msg, 1, 37))]... More..."
-
/mob/proc/get_top_level_mob()
if(istype(src.loc,/mob)&&src.loc!=src)
@@ -60,9 +14,6 @@ proc/get_top_level_mob(var/mob/S)
return M.get_top_level_mob()
return S
-
-
-
///////////////// EMOTE CODE
// Maybe making this as an emote is less messy?
// It was - ktccd
diff --git a/code/modules/newscaster/_news.dm b/code/modules/newscaster/_news.dm
new file mode 100644
index 0000000000..6c6f10fdcc
--- /dev/null
+++ b/code/modules/newscaster/_news.dm
@@ -0,0 +1,2 @@
+/datum/news
+ var/author = ""
diff --git a/code/modules/newscaster/feed_channel.dm b/code/modules/newscaster/feed_channel.dm
new file mode 100644
index 0000000000..278c9c7ad1
--- /dev/null
+++ b/code/modules/newscaster/feed_channel.dm
@@ -0,0 +1,33 @@
+/datum/news/feed_channel
+ var/channel_name = ""
+ var/list/datum/news/feed_message/messages = list()
+ var/locked = FALSE
+ var/censored = 0
+ var/list/authorCensorTime = list()
+ var/list/DclassCensorTime = list()
+ var/authorCensor
+ var/is_admin_channel = 0
+
+/datum/news/feed_channel/proc/returnAuthor(censor)
+ if(censor == -1)
+ censor = authorCensor
+ var/txt = "[GLOB.news_network.redactedText]"
+ if(!censor)
+ txt = author
+ return txt
+
+/datum/news/feed_channel/proc/toggleCensorDclass()
+ if(censored)
+ DclassCensorTime.Add(GLOB.news_network.lastAction*-1)
+ else
+ DclassCensorTime.Add(GLOB.news_network.lastAction)
+ censored = !censored
+ GLOB.news_network.lastAction ++
+
+/datum/news/feed_channel/proc/toggleCensorAuthor()
+ if(authorCensor)
+ authorCensorTime.Add(GLOB.news_network.lastAction*-1)
+ else
+ authorCensorTime.Add(GLOB.news_network.lastAction)
+ authorCensor = !authorCensor
+ GLOB.news_network.lastAction ++
diff --git a/code/modules/newscaster/feed_comment.dm b/code/modules/newscaster/feed_comment.dm
new file mode 100644
index 0000000000..ff5ebac028
--- /dev/null
+++ b/code/modules/newscaster/feed_comment.dm
@@ -0,0 +1,3 @@
+/datum/news/feed_comment
+ var/body = ""
+ var/time_stamp = ""
diff --git a/code/modules/newscaster/feed_message.dm b/code/modules/newscaster/feed_message.dm
new file mode 100644
index 0000000000..573b3f772d
--- /dev/null
+++ b/code/modules/newscaster/feed_message.dm
@@ -0,0 +1,46 @@
+/datum/news/feed_message
+ var/body =""
+ var/list/authorCensorTime = list()
+ var/list/bodyCensorTime = list()
+ var/is_admin_message = 0
+ var/icon/img = null
+ var/time_stamp = ""
+ var/list/datum/news/feed_comment/comments = list()
+ var/locked = FALSE
+ var/caption = ""
+ var/creationTime
+ var/authorCensor
+ var/bodyCensor
+ var/photo_file
+
+/datum/news/feed_message/proc/returnAuthor(censor)
+ if(censor == -1)
+ censor = authorCensor
+ var/txt = "[GLOB.news_network.redactedText]"
+ if(!censor)
+ txt = author
+ return txt
+
+/datum/news/feed_message/proc/returnBody(censor)
+ if(censor == -1)
+ censor = bodyCensor
+ var/txt = "[GLOB.news_network.redactedText]"
+ if(!censor)
+ txt = body
+ return txt
+
+/datum/news/feed_message/proc/toggleCensorAuthor()
+ if(authorCensor)
+ authorCensorTime.Add(GLOB.news_network.lastAction*-1)
+ else
+ authorCensorTime.Add(GLOB.news_network.lastAction)
+ authorCensor = !authorCensor
+ GLOB.news_network.lastAction ++
+
+/datum/news/feed_message/proc/toggleCensorBody()
+ if(bodyCensor)
+ bodyCensorTime.Add(GLOB.news_network.lastAction*-1)
+ else
+ bodyCensorTime.Add(GLOB.news_network.lastAction)
+ bodyCensor = !bodyCensor
+ GLOB.news_network.lastAction ++
diff --git a/code/modules/newscaster/ghostread.dm b/code/modules/newscaster/ghostread.dm
new file mode 100644
index 0000000000..77cb1a03c8
--- /dev/null
+++ b/code/modules/newscaster/ghostread.dm
@@ -0,0 +1,52 @@
+/mob/dead/observer/verb/read_news()
+ set name = "Read Newscaster"
+ set desc = "Open a list of available news channels"
+ set category = "Ghost"
+
+ var/datum/browser/B = new(src, "ghost_news_list", "Chanenl List", 450, 600)
+ B.set_content(render_news_channel_list())
+ B.open()
+
+/mob/dead/observer/Topic(href, href_list)
+ . = ..()
+ if(href_list["show_news_channel"])
+ var/datum/D = locate(href_list["show_news_channel"])
+ if(istype(D, /datum/news/feed_channel)) //safety
+ render_news_channel(D)
+
+/mob/dead/observer/proc/render_news_channel_list()
+ var/datum/news_network/news_network = GLOB.news_network
+ var/list/content = list()
+ for(var/i in news_network.network_channels)
+ var/datum/news/feed_channel/FC = i
+ content += "[FC.channel_name] ([length(FC.messages)] messages)[FC.locked? " (LOCKED)":""][FC.censored? " (CENSORED)":""][FC.is_admin_channel? " (ADMIN)":""]"
+ return content.Join("
")
+
+/mob/dead/observer/proc/render_news_channel(datum/news/feed_channel/FC)
+ var/list/content = list()
+ content += "[FC.channel_name]: \[created by: [FC.returnAuthor(-1)]\]
"
+ if(FC.censored)
+ content += "ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
+ content += "No further feed story additions are allowed while the D-Notice is in effect.
"
+ if(!length(FC.messages))
+ content += "This channel is empty.
"
+ else
+ for(var/i in FC.messages)
+ var/datum/news/feed_message/FM = i
+ content += "-[FM.returnBody(-1)]
"
+ if(FM.img)
+ src << browse_rsc(FM.img, "tmp_photo[i].png")
+ content += "
"
+ if(FM.caption)
+ content += "[FM.caption]
"
+ content += "
"
+ content += "\[Story by [FM.returnAuthor(-1)] \] - ([FM.time_stamp])
"
+ content += "[FM.comments.len] comment[FM.comments.len > 1 ? "s" : ""]
"
+ for(var/c in FM.comments)
+ var/datum/news/feed_comment/comment = c
+ content += "[comment.body]
[comment.author] [comment.time_stamp]
"
+ if(FM.locked)
+ content += "Comments locked
"
+ var/datum/browser/popup = new(src, "ghost_news_channel", 450, 900)
+ popup.set_content(content.Join(""))
+ popup.open()
diff --git a/code/modules/newscaster/news_network.dm b/code/modules/newscaster/news_network.dm
new file mode 100644
index 0000000000..5e056addee
--- /dev/null
+++ b/code/modules/newscaster/news_network.dm
@@ -0,0 +1,72 @@
+GLOBAL_DATUM_INIT(news_network, /datum/news_network, new)
+
+/// Contains all the news datum of a newscaster system.
+/datum/news_network
+ var/list/datum/news/feed_channel/network_channels = list()
+ var/datum/news/wanted_message/wanted_issue
+ var/lastAction
+ var/redactedText = "\[REDACTED\]"
+
+/datum/news_network/New()
+ CreateFeedChannel("Station Announcements", "SS13", 1)
+ wanted_issue = new /datum/news/wanted_message
+
+/datum/news_network/proc/CreateFeedChannel(channel_name, author, locked, adminChannel = 0)
+ var/datum/news/feed_channel/newChannel = new /datum/news/feed_channel
+ newChannel.channel_name = channel_name
+ newChannel.author = author
+ newChannel.locked = locked
+ newChannel.is_admin_channel = adminChannel
+ network_channels += newChannel
+
+/datum/news_network/proc/SubmitArticle(msg, author, channel_name, datum/picture/picture, adminMessage = 0, allow_comments = 1)
+ var/datum/news/feed_message/newMsg = new /datum/news/feed_message
+ newMsg.author = author
+ newMsg.body = msg
+ newMsg.time_stamp = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
+ newMsg.is_admin_message = adminMessage
+ newMsg.locked = !allow_comments
+ if(picture)
+ newMsg.img = picture.picture_image
+ newMsg.caption = picture.caption
+ newMsg.photo_file = save_photo(picture.picture_image)
+ for(var/datum/news/feed_channel/FC in network_channels)
+ if(FC.channel_name == channel_name)
+ FC.messages += newMsg
+ break
+ for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters)
+ NEWSCASTER.newsAlert(channel_name)
+ lastAction ++
+ newMsg.creationTime = lastAction
+
+/datum/news_network/proc/submitWanted(criminal, body, scanned_user, datum/picture/picture, adminMsg = 0, newMessage = 0)
+ wanted_issue.active = 1
+ wanted_issue.criminal = criminal
+ wanted_issue.body = body
+ wanted_issue.scannedUser = scanned_user
+ wanted_issue.isAdminMsg = adminMsg
+ if(picture)
+ wanted_issue.img = picture.picture_image
+ wanted_issue.photo_file = save_photo(picture.picture_image)
+ if(newMessage)
+ for(var/obj/machinery/newscaster/N in GLOB.allCasters)
+ N.newsAlert()
+ N.update_icon()
+
+/datum/news_network/proc/deleteWanted()
+ wanted_issue.active = 0
+ wanted_issue.criminal = null
+ wanted_issue.body = null
+ wanted_issue.scannedUser = null
+ wanted_issue.img = null
+ for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters)
+ NEWSCASTER.update_icon()
+
+/datum/news_network/proc/save_photo(icon/photo)
+ var/photo_file = copytext_char(md5("\icon[photo]"), 1, 6)
+ if(!fexists("[GLOB.log_directory]/photos/[photo_file].png"))
+ //Clean up repeated frames
+ var/icon/clean = new /icon()
+ clean.Insert(photo, "", SOUTH, 1, 0)
+ fcopy(clean, "[GLOB.log_directory]/photos/[photo_file].png")
+ return photo_file
diff --git a/code/game/machinery/newscaster.dm b/code/modules/newscaster/newscaster_machine.dm
similarity index 60%
rename from code/game/machinery/newscaster.dm
rename to code/modules/newscaster/newscaster_machine.dm
index df5a6ced52..cb2016a1a1 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/modules/newscaster/newscaster_machine.dm
@@ -1,175 +1,5 @@
-GLOBAL_DATUM_INIT(news_network, /datum/newscaster/feed_network, new)
GLOBAL_LIST_EMPTY(allCasters)
-/datum/newscaster
-
-/datum/newscaster/feed_comment
- var/author = ""
- var/body = ""
- var/time_stamp = ""
-
-/datum/newscaster/feed_message
- var/author =""
- var/body =""
- var/list/authorCensorTime = list()
- var/list/bodyCensorTime = list()
- var/is_admin_message = 0
- var/icon/img = null
- var/time_stamp = ""
- var/list/datum/newscaster/feed_comment/comments = list()
- var/locked = FALSE
- var/caption = ""
- var/creationTime
- var/authorCensor
- var/bodyCensor
- var/photo_file
-
-/datum/newscaster/feed_message/proc/returnAuthor(censor)
- if(censor == -1)
- censor = authorCensor
- var/txt = "[GLOB.news_network.redactedText]"
- if(!censor)
- txt = author
- return txt
-
-/datum/newscaster/feed_message/proc/returnBody(censor)
- if(censor == -1)
- censor = bodyCensor
- var/txt = "[GLOB.news_network.redactedText]"
- if(!censor)
- txt = body
- return txt
-
-/datum/newscaster/feed_message/proc/toggleCensorAuthor()
- if(authorCensor)
- authorCensorTime.Add(GLOB.news_network.lastAction*-1)
- else
- authorCensorTime.Add(GLOB.news_network.lastAction)
- authorCensor = !authorCensor
- GLOB.news_network.lastAction ++
-
-/datum/newscaster/feed_message/proc/toggleCensorBody()
- if(bodyCensor)
- bodyCensorTime.Add(GLOB.news_network.lastAction*-1)
- else
- bodyCensorTime.Add(GLOB.news_network.lastAction)
- bodyCensor = !bodyCensor
- GLOB.news_network.lastAction ++
-
-/datum/newscaster/feed_channel
- var/channel_name = ""
- var/list/datum/newscaster/feed_message/messages = list()
- var/locked = FALSE
- var/author = ""
- var/censored = 0
- var/list/authorCensorTime = list()
- var/list/DclassCensorTime = list()
- var/authorCensor
- var/is_admin_channel = 0
-
-/datum/newscaster/feed_channel/proc/returnAuthor(censor)
- if(censor == -1)
- censor = authorCensor
- var/txt = "[GLOB.news_network.redactedText]"
- if(!censor)
- txt = author
- return txt
-
-/datum/newscaster/feed_channel/proc/toggleCensorDclass()
- if(censored)
- DclassCensorTime.Add(GLOB.news_network.lastAction*-1)
- else
- DclassCensorTime.Add(GLOB.news_network.lastAction)
- censored = !censored
- GLOB.news_network.lastAction ++
-
-/datum/newscaster/feed_channel/proc/toggleCensorAuthor()
- if(authorCensor)
- authorCensorTime.Add(GLOB.news_network.lastAction*-1)
- else
- authorCensorTime.Add(GLOB.news_network.lastAction)
- authorCensor = !authorCensor
- GLOB.news_network.lastAction ++
-
-/datum/newscaster/wanted_message
- var/active
- var/criminal
- var/body
- var/scannedUser
- var/isAdminMsg
- var/icon/img
- var/photo_file
-
-/datum/newscaster/feed_network
- var/list/datum/newscaster/feed_channel/network_channels = list()
- var/datum/newscaster/wanted_message/wanted_issue
- var/lastAction
- var/redactedText = "\[REDACTED\]"
-
-/datum/newscaster/feed_network/New()
- CreateFeedChannel("Station Announcements", "SS13", 1)
- wanted_issue = new /datum/newscaster/wanted_message
-
-/datum/newscaster/feed_network/proc/CreateFeedChannel(channel_name, author, locked, adminChannel = 0)
- var/datum/newscaster/feed_channel/newChannel = new /datum/newscaster/feed_channel
- newChannel.channel_name = channel_name
- newChannel.author = author
- newChannel.locked = locked
- newChannel.is_admin_channel = adminChannel
- network_channels += newChannel
-
-/datum/newscaster/feed_network/proc/SubmitArticle(msg, author, channel_name, datum/picture/picture, adminMessage = 0, allow_comments = 1)
- var/datum/newscaster/feed_message/newMsg = new /datum/newscaster/feed_message
- newMsg.author = author
- newMsg.body = msg
- newMsg.time_stamp = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
- newMsg.is_admin_message = adminMessage
- newMsg.locked = !allow_comments
- if(picture)
- newMsg.img = picture.picture_image
- newMsg.caption = picture.caption
- newMsg.photo_file = save_photo(picture.picture_image)
- for(var/datum/newscaster/feed_channel/FC in network_channels)
- if(FC.channel_name == channel_name)
- FC.messages += newMsg
- break
- for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters)
- NEWSCASTER.newsAlert(channel_name)
- lastAction ++
- newMsg.creationTime = lastAction
-
-/datum/newscaster/feed_network/proc/submitWanted(criminal, body, scanned_user, datum/picture/picture, adminMsg = 0, newMessage = 0)
- wanted_issue.active = 1
- wanted_issue.criminal = criminal
- wanted_issue.body = body
- wanted_issue.scannedUser = scanned_user
- wanted_issue.isAdminMsg = adminMsg
- if(picture)
- wanted_issue.img = picture.picture_image
- wanted_issue.photo_file = save_photo(picture.picture_image)
- if(newMessage)
- for(var/obj/machinery/newscaster/N in GLOB.allCasters)
- N.newsAlert()
- N.update_icon()
-
-/datum/newscaster/feed_network/proc/deleteWanted()
- wanted_issue.active = 0
- wanted_issue.criminal = null
- wanted_issue.body = null
- wanted_issue.scannedUser = null
- wanted_issue.img = null
- for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters)
- NEWSCASTER.update_icon()
-
-/datum/newscaster/feed_network/proc/save_photo(icon/photo)
- var/photo_file = copytext_char(md5("\icon[photo]"), 1, 6)
- if(!fexists("[GLOB.log_directory]/photos/[photo_file].png"))
- //Clean up repeated frames
- var/icon/clean = new /icon()
- clean.Insert(photo, "", SOUTH, 1, 0)
- fcopy(clean, "[GLOB.log_directory]/photos/[photo_file].png")
- return photo_file
-
/obj/item/wallframe/newscaster
name = "newscaster frame"
desc = "Used to build newscasters, just secure to the wall."
@@ -177,7 +7,6 @@ GLOBAL_LIST_EMPTY(allCasters)
materials = list(MAT_METAL=14000, MAT_GLASS=8000)
result_path = /obj/machinery/newscaster
-
/obj/machinery/newscaster
name = "newscaster"
desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!"
@@ -189,7 +18,6 @@ GLOBAL_LIST_EMPTY(allCasters)
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
max_integrity = 200
integrity_failure = 50
- ghost_flags = INTERACT_GHOST_READ
var/screen = 0
var/paper_remaining = 15
var/securityCaster = 0
@@ -197,12 +25,11 @@ GLOBAL_LIST_EMPTY(allCasters)
var/alert_delay = 500
var/alert = FALSE
var/scanned_user = "Unknown"
- var/mob/active_user = null
var/msg = ""
var/datum/picture/picture
var/channel_name = ""
var/c_locked=0
- var/datum/newscaster/feed_channel/viewing_channel = null
+ var/datum/news/feed_channel/viewing_channel = null
var/allow_comments = 1
/obj/machinery/newscaster/security_unit
@@ -266,10 +93,10 @@ GLOBAL_LIST_EMPTY(allCasters)
/obj/machinery/newscaster/ui_interact(mob/user)
. = ..()
- if(ishuman(user) || issilicon(user) || isobserver(user))
- var/mob/M = user
+ if(ishuman(user) || issilicon(user))
+ var/mob/living/human_or_robot_user = user
var/dat
- scan_user(M)
+ scan_user(human_or_robot_user)
switch(screen)
if(0)
dat += "Welcome to Newscasting Unit #[unit_no].
Interface & News networks Operational."
@@ -281,7 +108,7 @@ GLOBAL_LIST_EMPTY(allCasters)
dat+= "
Submit new Feed story"
dat+= "
Print newspaper"
dat+= "
Re-scan User"
- dat+= "
Exit"
+ dat+= "
Exit"
if(securityCaster)
var/wanted_already = 0
if(GLOB.news_network.wanted_issue.active)
@@ -296,7 +123,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if( isemptylist(GLOB.news_network.network_channels) )
dat+="No active channels found..."
else
- for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/CHANNEL in GLOB.news_network.network_channels)
if(CHANNEL.is_admin_channel)
dat+="[CHANNEL.channel_name]
"
else
@@ -335,7 +162,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if(7)
dat+="ERROR: Could not submit Feed Channel to Network.
"
var/list/existing_authors = list()
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.authorCensor)
existing_authors += GLOB.news_network.redactedText
else
@@ -345,7 +172,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if(channel_name=="" || channel_name == "\[REDACTED\]")
dat+="Invalid channel name.
"
var/check = 0
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == channel_name)
check = 1
break
@@ -358,7 +185,7 @@ GLOBAL_LIST_EMPTY(allCasters)
var/total_num=length(GLOB.news_network.network_channels)
var/active_num=total_num
var/message_num=0
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
if(!FC.censored)
message_num += length(FC.messages)
else
@@ -377,7 +204,7 @@ GLOBAL_LIST_EMPTY(allCasters)
dat+="No feed messages found in channel...
"
else
var/i = 0
- for(var/datum/newscaster/feed_message/MESSAGE in viewing_channel.messages)
+ for(var/datum/news/feed_message/MESSAGE in viewing_channel.messages)
i++
dat+="-[MESSAGE.returnBody(-1)]
"
if(MESSAGE.img)
@@ -388,7 +215,7 @@ GLOBAL_LIST_EMPTY(allCasters)
dat+="
"
dat+="\[Story by [MESSAGE.returnAuthor(-1)] \] - ([MESSAGE.time_stamp])
"
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]
"
- for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
+ for(var/datum/news/feed_comment/comment in MESSAGE.comments)
dat+="[comment.body]
[comment.author] [comment.time_stamp]
"
if(MESSAGE.locked)
dat+="Comments locked
"
@@ -404,7 +231,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if(isemptylist(GLOB.news_network.network_channels))
dat+="No feed channels found active...
"
else
- for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
"
dat+="
Cancel"
if(11)
@@ -415,7 +242,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if(isemptylist(GLOB.news_network.network_channels))
dat+="No feed channels found active...
"
else
- for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
"
dat+="
Back"
if(12)
@@ -424,11 +251,11 @@ GLOBAL_LIST_EMPTY(allCasters)
if(isemptylist(viewing_channel.messages))
dat+="No feed messages found in channel...
"
else
- for(var/datum/newscaster/feed_message/MESSAGE in viewing_channel.messages)
+ for(var/datum/news/feed_message/MESSAGE in viewing_channel.messages)
dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
dat+="[(MESSAGE.bodyCensor) ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.authorCensor) ? ("Undo Author Censorship") : ("Censor message Author")]
"
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]: [MESSAGE.locked ? "Unlock" : "Lock"]
"
- for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
+ for(var/datum/news/feed_comment/comment in MESSAGE.comments)
dat+="[comment.body] X
[comment.author] [comment.time_stamp]
"
dat+="
Back"
if(13)
@@ -441,7 +268,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if(isemptylist(viewing_channel.messages))
dat+="No feed messages found in channel...
"
else
- for(var/datum/newscaster/feed_message/MESSAGE in viewing_channel.messages)
+ for(var/datum/news/feed_message/MESSAGE in viewing_channel.messages)
dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
dat+="
Back"
if(14)
@@ -503,44 +330,32 @@ GLOBAL_LIST_EMPTY(allCasters)
if(21)
dat+="Unable to print newspaper. Insufficient paper. Please notify maintenance personnel to refill machine storage.
"
dat+="Return"
- var/datum/browser/popup = new(M, "newscaster_main", "Newscaster Unit #[unit_no]", 400, 600)
+ var/datum/browser/popup = new(human_or_robot_user, "newscaster_main", "Newscaster Unit #[unit_no]", 400, 600)
popup.set_content(dat)
- popup.set_title_image(M.browse_rsc_icon(icon, icon_state))
+ popup.set_title_image(human_or_robot_user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/newscaster/Topic(href, href_list)
if(..())
return
- if(active_user && !isobserver(active_user) && get_dist(active_user,src)<=1 && usr!=active_user)
- to_chat(usr, "You must wait for [active_user] to finish and move away.")
- return
- if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && isturf(loc))) || hasSiliconAccessInArea(usr) || isobserver(usr))
+ if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && isturf(loc))) || hasSiliconAccessInArea(usr))
usr.set_machine(src)
scan_user(usr)
if(href_list["set_channel_name"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"set a channel's name"))
- to_chat(usr, "You can't do that.")
- return
channel_name = stripped_input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "", MAX_NAME_LEN)
updateUsrDialog()
else if(href_list["set_channel_lock"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"locked a channel"))
- to_chat(usr, "You can't do that.")
- return
c_locked = !c_locked
updateUsrDialog()
else if(href_list["submit_new_channel"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"created a new channel"))
- to_chat(usr, "You can't do that.")
- return
var/list/existing_authors = list()
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.authorCensor)
existing_authors += GLOB.news_network.redactedText
else
existing_authors += FC.author
var/check = 0
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == channel_name)
check = 1
break
@@ -555,33 +370,21 @@ GLOBAL_LIST_EMPTY(allCasters)
screen=5
updateUsrDialog()
else if(href_list["set_channel_receiving"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"tried to set the receiving channel"))
- to_chat(usr, "You can't do that.")
- return
var/list/available_channels = list()
- for(var/datum/newscaster/feed_channel/F in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/F in GLOB.news_network.network_channels)
if( (!F.locked || F.author == scanned_user) && !F.censored)
available_channels += F.channel_name
channel_name = input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels
updateUsrDialog()
else if(href_list["set_new_message"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"set the message of a new feed story"))
- to_chat(usr, "You can't do that.")
- return
var/temp_message = trim(stripped_multiline_input(usr, "Write your Feed story", "Network Channel Handler", msg))
if(temp_message)
msg = temp_message
updateUsrDialog()
else if(href_list["set_attachment"])
- if(isobserver(usr))
- to_chat(usr, "You can't do that.")
- return
AttachPhoto(usr)
updateUsrDialog()
else if(href_list["submit_new_message"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"added a new story"))
- to_chat(usr, "You can't do that.")
- return
if(msg =="" || msg=="\[REDACTED\]" || scanned_user == "Unknown" || channel_name == "" )
screen=6
else
@@ -591,27 +394,15 @@ GLOBAL_LIST_EMPTY(allCasters)
msg = ""
updateUsrDialog()
else if(href_list["create_channel"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"created a channel"))
- to_chat(usr, "You can't do that.")
- return
screen=2
updateUsrDialog()
else if(href_list["create_feed_story"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"created a feed story"))
- to_chat(usr, "You can't do that.")
- return
screen=3
updateUsrDialog()
else if(href_list["menu_paper"])
- if(isobserver(usr) && !canGhostWrite(usr,src,""))
- to_chat(usr, "You can't do that.")
- return
screen=8
updateUsrDialog()
else if(href_list["print_paper"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"printed a paper"))
- to_chat(usr, "You can't do that.")
- return
if(!paper_remaining)
screen=21
else
@@ -619,21 +410,12 @@ GLOBAL_LIST_EMPTY(allCasters)
screen = 20
updateUsrDialog()
else if(href_list["menu_censor_story"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"censored a story"))
- to_chat(usr, "You can't do that.")
- return
screen=10
updateUsrDialog()
else if(href_list["menu_censor_channel"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"censored a channel"))
- to_chat(usr, "You can't do that.")
- return
screen=11
updateUsrDialog()
else if(href_list["menu_wanted"])
- if(isobserver(usr) && !canGhostWrite(usr,src,""))
- to_chat(usr, "You can't do that.")
- return
var/already_wanted = 0
if(GLOB.news_network.wanted_issue.active)
already_wanted = 1
@@ -643,21 +425,12 @@ GLOBAL_LIST_EMPTY(allCasters)
screen = 14
updateUsrDialog()
else if(href_list["set_wanted_name"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"tried to set the name of a wanted person"))
- to_chat(usr, "You can't do that.")
- return
channel_name = stripped_input(usr, "Provide the name of the Wanted person", "Network Security Handler")
updateUsrDialog()
else if(href_list["set_wanted_desc"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"tried to set the description of a wanted person"))
- to_chat(usr, "You can't do that.")
- return
msg = stripped_input(usr, "Provide a description of the Wanted person and any other details you deem important", "Network Security Handler")
updateUsrDialog()
else if(href_list["submit_wanted"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"submitted a wanted poster"))
- to_chat(usr, "You can't do that.")
- return
var/input_param = text2num(href_list["submit_wanted"])
if(msg == "" || channel_name == "" || scanned_user == "Unknown")
screen = 16
@@ -688,48 +461,33 @@ GLOBAL_LIST_EMPTY(allCasters)
screen=18
updateUsrDialog()
else if(href_list["censor_channel_author"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"tried to censor an author"))
- to_chat(usr, "You can't do that.")
- return
- var/datum/newscaster/feed_channel/FC = locate(href_list["censor_channel_author"])
+ var/datum/news/feed_channel/FC = locate(href_list["censor_channel_author"])
if(FC.is_admin_channel)
alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
return
FC.toggleCensorAuthor()
updateUsrDialog()
else if(href_list["censor_channel_story_author"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"tried to censor a story's author"))
- to_chat(usr, "You can't do that.")
- return
- var/datum/newscaster/feed_message/MSG = locate(href_list["censor_channel_story_author"])
+ var/datum/news/feed_message/MSG = locate(href_list["censor_channel_story_author"])
if(MSG.is_admin_message)
alert("This message was created by a Nanotrasen Officer. You cannot censor its author.","Ok")
return
MSG.toggleCensorAuthor()
updateUsrDialog()
else if(href_list["censor_channel_story_body"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"tried to censor a story"))
- to_chat(usr, "You can't do that.")
- return
- var/datum/newscaster/feed_message/MSG = locate(href_list["censor_channel_story_body"])
+ var/datum/news/feed_message/MSG = locate(href_list["censor_channel_story_body"])
if(MSG.is_admin_message)
alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
return
MSG.toggleCensorBody()
updateUsrDialog()
else if(href_list["pick_d_notice"])
- if(isobserver(usr) && !canGhostWrite(usr,src,""))
- to_chat(usr, "You can't do that.")
- return
- var/datum/newscaster/feed_channel/FC = locate(href_list["pick_d_notice"])
+ var/datum/news/feed_channel/FC = locate(href_list["pick_d_notice"])
viewing_channel = FC
screen=13
updateUsrDialog()
else if(href_list["toggle_d_notice"])
- if(isobserver(usr) && !canGhostWrite(usr,src,"tried to set a D-notice"))
- to_chat(usr, "You can't do that.")
- return
- var/datum/newscaster/feed_channel/FC = locate(href_list["toggle_d_notice"])
+ var/datum/news/feed_channel/FC = locate(href_list["toggle_d_notice"])
if(FC.is_admin_channel)
alert("This channel was created by a Nanotrasen Officer. You cannot place a D-Notice upon it.","Ok")
return
@@ -748,21 +506,21 @@ GLOBAL_LIST_EMPTY(allCasters)
viewing_channel = null
updateUsrDialog()
else if(href_list["show_channel"])
- var/datum/newscaster/feed_channel/FC = locate(href_list["show_channel"])
+ var/datum/news/feed_channel/FC = locate(href_list["show_channel"])
viewing_channel = FC
screen = 9
updateUsrDialog()
else if(href_list["pick_censor_channel"])
- var/datum/newscaster/feed_channel/FC = locate(href_list["pick_censor_channel"])
+ var/datum/news/feed_channel/FC = locate(href_list["pick_censor_channel"])
viewing_channel = FC
screen = 12
updateUsrDialog()
else if(href_list["new_comment"])
- var/datum/newscaster/feed_message/FM = locate(href_list["new_comment"])
+ var/datum/news/feed_message/FM = locate(href_list["new_comment"])
var/cominput = copytext_char(stripped_input(usr, "Write your message:", "New comment", null), 140)
if(cominput)
scan_user(usr)
- var/datum/newscaster/feed_comment/FC = new/datum/newscaster/feed_comment
+ var/datum/news/feed_comment/FC = new/datum/news/feed_comment
FC.author = scanned_user
FC.body = cominput
FC.time_stamp = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
@@ -770,14 +528,14 @@ GLOBAL_LIST_EMPTY(allCasters)
usr.log_message("(as [scanned_user]) commented on message [FM.returnBody(-1)] -- [FC.body]", LOG_COMMENT)
updateUsrDialog()
else if(href_list["del_comment"])
- var/datum/newscaster/feed_comment/FC = locate(href_list["del_comment"])
- var/datum/newscaster/feed_message/FM = locate(href_list["del_comment_msg"])
+ var/datum/news/feed_comment/FC = locate(href_list["del_comment"])
+ var/datum/news/feed_message/FM = locate(href_list["del_comment_msg"])
if(istype(FC) && istype(FM))
FM.comments -= FC
qdel(FC)
updateUsrDialog()
else if(href_list["lock_comment"])
- var/datum/newscaster/feed_message/FM = locate(href_list["lock_comment"])
+ var/datum/news/feed_message/FM = locate(href_list["lock_comment"])
FM.locked ^= 1
updateUsrDialog()
else if(href_list["set_comment"])
@@ -876,12 +634,6 @@ GLOBAL_LIST_EMPTY(allCasters)
picture = selection
/obj/machinery/newscaster/proc/scan_user(mob/living/user)
- if(active_user)
- if(active_user != user)
- if(get_dist(active_user,src)<=1)
- if(!isobserver(active_user))
- to_chat(user, "Wait for [active_user] to finish and move away.")
- return
if(ishuman(user))
var/mob/living/carbon/human/human_user = user
if(human_user.wear_id)
@@ -901,19 +653,14 @@ GLOBAL_LIST_EMPTY(allCasters)
else if(issilicon(user))
var/mob/living/silicon/ai_user = user
scanned_user = "[ai_user.name] ([ai_user.job])"
- else if (IsAdminGhost(user))
- scanned_user = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
- else if (isobserver(user))
- scanned_user = "Space-Time Anomaly #[rand(0,9)][rand(0,9)][rand(0,9)]"
else
throw EXCEPTION("Invalid user for this proc")
return
- active_user = user
/obj/machinery/newscaster/proc/print_paper()
SSblackbox.record_feedback("amount", "newspapers_printed", 1)
var/obj/item/newspaper/NEWSPAPER = new /obj/item/newspaper
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
NEWSPAPER.news_content += FC
if(GLOB.news_network.wanted_issue.active)
NEWSPAPER.wantedAuthor = GLOB.news_network.wanted_issue.scannedUser
@@ -925,7 +672,6 @@ GLOBAL_LIST_EMPTY(allCasters)
NEWSPAPER.creationTime = GLOB.news_network.lastAction
paper_remaining--
-
/obj/machinery/newscaster/proc/remove_alert()
alert = FALSE
update_icon()
@@ -940,177 +686,3 @@ GLOBAL_LIST_EMPTY(allCasters)
else
say("Attention! Wanted issue distributed!")
playsound(loc, 'sound/machines/warning-buzzer.ogg', 75, 1)
-
-/obj/item/newspaper
- name = "newspaper"
- desc = "An issue of The Griffon, the newspaper circulating aboard Nanotrasen Space Stations."
- icon = 'icons/obj/bureaucracy.dmi'
- icon_state = "newspaper"
- lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
- w_class = WEIGHT_CLASS_SMALL
- attack_verb = list("bapped")
- var/screen = 0
- var/pages = 0
- var/curr_page = 0
- var/list/datum/newscaster/feed_channel/news_content = list()
- var/scribble=""
- var/scribble_page = null
- var/wantedAuthor
- var/wantedCriminal
- var/wantedBody
- var/wantedPhoto
- var/creationTime
-
-/obj/item/newspaper/suicide_act(mob/user)
- user.visible_message("[user] is focusing intently on [src]! It looks like [user.p_theyre()] trying to commit sudoku... until [user.p_their()] eyes light up with realization!")
- user.say(";JOURNALISM IS MY CALLING! EVERYBODY APPRECIATES UNBIASED REPORTI-GLORF", forced="newspaper suicide")
- var/mob/living/carbon/human/H = user
- var/obj/W = new /obj/item/reagent_containers/food/drinks/bottle/whiskey(H.loc)
- playsound(H.loc, 'sound/items/drink.ogg', rand(10,50), 1)
- W.reagents.trans_to(H, W.reagents.total_volume)
- user.visible_message("[user] downs the contents of [W.name] in one gulp! Shoulda stuck to sudoku!")
-
- return(TOXLOSS)
-
-/obj/item/newspaper/attack_self(mob/user)
- if(ishuman(user))
- var/mob/living/carbon/human/human_user = user
- var/dat
- pages = 0
- switch(screen)
- if(0) //Cover
- dat+="The Griffon
"
- dat+="Nanotrasen-standard newspaper, for use on Nanotrasen? Space Facilities
"
- if(isemptylist(news_content))
- if(wantedAuthor)
- dat+="Contents:
**Important Security Announcement** \[page [pages+2]\]
"
- else
- dat+="Other than the title, the rest of the newspaper is unprinted..."
- else
- dat+="Contents:
"
- for(var/datum/newscaster/feed_channel/NP in news_content)
- pages++
- if(wantedAuthor)
- dat+="**Important Security Announcement** \[page [pages+2]\]
"
- var/temp_page=0
- for(var/datum/newscaster/feed_channel/NP in news_content)
- temp_page++
- dat+="[NP.channel_name] \[page [temp_page+1]\]
"
- dat+="
"
- if(scribble_page==curr_page)
- dat+="
There is a small scribble near the end of this page... It reads: \"[scribble]\""
- dat+= "
"
- if(1) // X channel pages inbetween.
- for(var/datum/newscaster/feed_channel/NP in news_content)
- pages++
- var/datum/newscaster/feed_channel/C = news_content[curr_page]
- dat += "[C.channel_name] \[created by: [C.returnAuthor(notContent(C.authorCensorTime))]\]
"
- if(notContent(C.DclassCensorTime))
- dat+="This channel was deemed dangerous to the general welfare of the station and therefore marked with a D-Notice. Its contents were not transferred to the newspaper at the time of printing."
- else
- if(isemptylist(C.messages))
- dat+="No Feed stories stem from this channel..."
- else
- var/i = 0
- for(var/datum/newscaster/feed_message/MESSAGE in C.messages)
- if(MESSAGE.creationTime > creationTime)
- if(i == 0)
- dat+="No Feed stories stem from this channel..."
- break
- if(i == 0)
- dat+=""
- i++
- dat+="-[MESSAGE.returnBody(notContent(MESSAGE.bodyCensorTime))]
"
- if(MESSAGE.img)
- user << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
- dat+="
"
- dat+="\[Story by [MESSAGE.returnAuthor(notContent(MESSAGE.authorCensorTime))]\]
"
- dat+="
"
- if(scribble_page==curr_page)
- dat+="
There is a small scribble near the end of this page... It reads: \"[scribble]\""
- dat+= "
"
- if(2) //Last page
- for(var/datum/newscaster/feed_channel/NP in news_content)
- pages++
- if(wantedAuthor!=null)
- dat+="Wanted Issue:
"
- dat+="Criminal name: [wantedCriminal]
"
- dat+="Description: [wantedBody]
"
- dat+="Photo:: "
- if(wantedPhoto)
- user << browse_rsc(wantedPhoto, "tmp_photow.png")
- dat+="
"
- else
- dat+="None"
- else
- dat+="Apart from some uninteresting classified ads, there's nothing on this page..."
- if(scribble_page==curr_page)
- dat+="
There is a small scribble near the end of this page... It reads: \"[scribble]\""
- dat+= "
"
- dat+="
[curr_page+1]
"
- human_user << browse(dat, "window=newspaper_main;size=300x400")
- onclose(human_user, "newspaper_main")
- else
- to_chat(user, "The paper is full of unintelligible symbols!")
-
-/obj/item/newspaper/proc/notContent(list/L)
- if(!L.len)
- return 0
- for(var/i=L.len;i>0;i--)
- var/num = abs(L[i])
- if(creationTime <= num)
- continue
- else
- if(L[i] > 0)
- return 1
- else
- return 0
- return 0
-
-/obj/item/newspaper/Topic(href, href_list)
- var/mob/living/U = usr
- ..()
- if((src in U.contents) || (isturf(loc) && in_range(src, U)))
- U.set_machine(src)
- if(href_list["next_page"])
- if(curr_page == pages+1)
- return //Don't need that at all, but anyway.
- if(curr_page == pages) //We're at the middle, get to the end
- screen = 2
- else
- if(curr_page == 0) //We're at the start, get to the middle
- screen=1
- curr_page++
- playsound(loc, "pageturn", 50, 1)
- else if(href_list["prev_page"])
- if(curr_page == 0)
- return
- if(curr_page == 1)
- screen = 0
- else
- if(curr_page == pages+1) //we're at the end, let's go back to the middle.
- screen = 1
- curr_page--
- playsound(loc, "pageturn", 50, 1)
- if(ismob(loc))
- attack_self(loc)
-
-/obj/item/newspaper/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/pen))
- if(!user.is_literate())
- to_chat(user, "You scribble illegibly on [src]!")
- return
- if(scribble_page == curr_page)
- to_chat(user, "There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?")
- else
- var/s = stripped_input(user, "Write something", "Newspaper")
- if (!s)
- return
- if(!user.canUseTopic(src, BE_CLOSE))
- return
- scribble_page = curr_page
- scribble = s
- attack_self(user)
- else
- return ..()
diff --git a/code/modules/newscaster/newspaper.dm b/code/modules/newscaster/newspaper.dm
new file mode 100644
index 0000000000..0afb36a7e7
--- /dev/null
+++ b/code/modules/newscaster/newspaper.dm
@@ -0,0 +1,173 @@
+/obj/item/newspaper
+ name = "newspaper"
+ desc = "An issue of The Griffon, the newspaper circulating aboard Nanotrasen Space Stations."
+ icon = 'icons/obj/bureaucracy.dmi'
+ icon_state = "newspaper"
+ lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
+ w_class = WEIGHT_CLASS_SMALL
+ attack_verb = list("bapped")
+ var/screen = 0
+ var/pages = 0
+ var/curr_page = 0
+ var/list/datum/news/feed_channel/news_content = list()
+ var/scribble=""
+ var/scribble_page = null
+ var/wantedAuthor
+ var/wantedCriminal
+ var/wantedBody
+ var/wantedPhoto
+ var/creationTime
+
+/obj/item/newspaper/suicide_act(mob/user)
+ user.visible_message("[user] is focusing intently on [src]! It looks like [user.p_theyre()] trying to commit sudoku... until [user.p_their()] eyes light up with realization!")
+ user.say(";JOURNALISM IS MY CALLING! EVERYBODY APPRECIATES UNBIASED REPORTI-GLORF", forced="newspaper suicide")
+ var/mob/living/carbon/human/H = user
+ var/obj/W = new /obj/item/reagent_containers/food/drinks/bottle/whiskey(H.loc)
+ playsound(H.loc, 'sound/items/drink.ogg', rand(10,50), 1)
+ W.reagents.trans_to(H, W.reagents.total_volume)
+ user.visible_message("[user] downs the contents of [W.name] in one gulp! Shoulda stuck to sudoku!")
+
+ return(TOXLOSS)
+
+/obj/item/newspaper/attack_self(mob/user)
+ if(ishuman(user))
+ var/mob/living/carbon/human/human_user = user
+ var/dat
+ pages = 0
+ switch(screen)
+ if(0) //Cover
+ dat+="The Griffon
"
+ dat+="Nanotrasen-standard newspaper, for use on Nanotrasen? Space Facilities
"
+ if(isemptylist(news_content))
+ if(wantedAuthor)
+ dat+="Contents:
**Important Security Announcement** \[page [pages+2]\]
"
+ else
+ dat+="Other than the title, the rest of the newspaper is unprinted..."
+ else
+ dat+="Contents:
"
+ for(var/datum/news/feed_channel/NP in news_content)
+ pages++
+ if(wantedAuthor)
+ dat+="**Important Security Announcement** \[page [pages+2]\]
"
+ var/temp_page=0
+ for(var/datum/news/feed_channel/NP in news_content)
+ temp_page++
+ dat+="[NP.channel_name] \[page [temp_page+1]\]
"
+ dat+="
"
+ if(scribble_page==curr_page)
+ dat+="
There is a small scribble near the end of this page... It reads: \"[scribble]\""
+ dat+= "
"
+ if(1) // X channel pages inbetween.
+ for(var/datum/news/feed_channel/NP in news_content)
+ pages++
+ var/datum/news/feed_channel/C = news_content[curr_page]
+ dat += "[C.channel_name] \[created by: [C.returnAuthor(notContent(C.authorCensorTime))]\]
"
+ if(notContent(C.DclassCensorTime))
+ dat+="This channel was deemed dangerous to the general welfare of the station and therefore marked with a D-Notice. Its contents were not transferred to the newspaper at the time of printing."
+ else
+ if(isemptylist(C.messages))
+ dat+="No Feed stories stem from this channel..."
+ else
+ var/i = 0
+ for(var/datum/news/feed_message/MESSAGE in C.messages)
+ if(MESSAGE.creationTime > creationTime)
+ if(i == 0)
+ dat+="No Feed stories stem from this channel..."
+ break
+ if(i == 0)
+ dat+=""
+ i++
+ dat+="-[MESSAGE.returnBody(notContent(MESSAGE.bodyCensorTime))]
"
+ if(MESSAGE.img)
+ user << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
+ dat+="
"
+ dat+="\[Story by [MESSAGE.returnAuthor(notContent(MESSAGE.authorCensorTime))]\]
"
+ dat+="
"
+ if(scribble_page==curr_page)
+ dat+="
There is a small scribble near the end of this page... It reads: \"[scribble]\""
+ dat+= "
"
+ if(2) //Last page
+ for(var/datum/news/feed_channel/NP in news_content)
+ pages++
+ if(wantedAuthor!=null)
+ dat+="Wanted Issue:
"
+ dat+="Criminal name: [wantedCriminal]
"
+ dat+="Description: [wantedBody]
"
+ dat+="Photo:: "
+ if(wantedPhoto)
+ user << browse_rsc(wantedPhoto, "tmp_photow.png")
+ dat+="
"
+ else
+ dat+="None"
+ else
+ dat+="Apart from some uninteresting classified ads, there's nothing on this page..."
+ if(scribble_page==curr_page)
+ dat+="
There is a small scribble near the end of this page... It reads: \"[scribble]\""
+ dat+= "
"
+ dat+="
[curr_page+1]
"
+ human_user << browse(dat, "window=newspaper_main;size=300x400")
+ onclose(human_user, "newspaper_main")
+ else
+ to_chat(user, "The paper is full of unintelligible symbols!")
+
+/obj/item/newspaper/proc/notContent(list/L)
+ if(!L.len)
+ return 0
+ for(var/i=L.len;i>0;i--)
+ var/num = abs(L[i])
+ if(creationTime <= num)
+ continue
+ else
+ if(L[i] > 0)
+ return 1
+ else
+ return 0
+ return 0
+
+/obj/item/newspaper/Topic(href, href_list)
+ var/mob/living/U = usr
+ ..()
+ if((src in U.contents) || (isturf(loc) && in_range(src, U)))
+ U.set_machine(src)
+ if(href_list["next_page"])
+ if(curr_page == pages+1)
+ return //Don't need that at all, but anyway.
+ if(curr_page == pages) //We're at the middle, get to the end
+ screen = 2
+ else
+ if(curr_page == 0) //We're at the start, get to the middle
+ screen=1
+ curr_page++
+ playsound(loc, "pageturn", 50, 1)
+ else if(href_list["prev_page"])
+ if(curr_page == 0)
+ return
+ if(curr_page == 1)
+ screen = 0
+ else
+ if(curr_page == pages+1) //we're at the end, let's go back to the middle.
+ screen = 1
+ curr_page--
+ playsound(loc, "pageturn", 50, 1)
+ if(ismob(loc))
+ attack_self(loc)
+
+/obj/item/newspaper/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/pen))
+ if(!user.is_literate())
+ to_chat(user, "You scribble illegibly on [src]!")
+ return
+ if(scribble_page == curr_page)
+ to_chat(user, "There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?")
+ else
+ var/s = stripped_input(user, "Write something", "Newspaper")
+ if (!s)
+ return
+ if(!user.canUseTopic(src, BE_CLOSE))
+ return
+ scribble_page = curr_page
+ scribble = s
+ attack_self(user)
+ else
+ return ..()
diff --git a/code/modules/newscaster/wanted_message.dm b/code/modules/newscaster/wanted_message.dm
new file mode 100644
index 0000000000..58eb234f02
--- /dev/null
+++ b/code/modules/newscaster/wanted_message.dm
@@ -0,0 +1,8 @@
+/datum/news/wanted_message
+ var/active
+ var/criminal
+ var/body
+ var/scannedUser
+ var/isAdminMsg
+ var/icon/img
+ var/photo_file
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 120303d4d7..d8d473a3e2 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -357,16 +357,10 @@
maxcharge = 12000
chargerate = 600
-/obj/item/stock_parts/cell/magnetic/empty
- start_charged = FALSE
-
/obj/item/stock_parts/cell/magnetic/pistol
name = "magpistol power supply"
maxcharge = 6000
-/obj/item/stock_parts/cell/magnetic/pistol/empty
- start_charged = FALSE
-
/obj/item/stock_parts/cell/toymagburst
name = "toy mag burst rifle power supply"
maxcharge = 4000
diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm
index e6d44de194..a0eeae1ea9 100644
--- a/code/modules/power/solar.dm
+++ b/code/modules/power/solar.dm
@@ -24,7 +24,16 @@
/obj/machinery/power/solar/Initialize(mapload, obj/item/solar_assembly/S)
. = ..()
- Make(S)
+ if(!S)
+ assembly = new /obj/item/solar_assembly
+ assembly.glass_type = new /obj/item/stack/sheet/glass(null, 2)
+ assembly.anchored = TRUE
+ else
+ S.moveToNullspace()
+ assembly = S
+ assembly.glass_type.on_solar_construction(src)
+ obj_integrity = max_integrity
+ update_icon()
connect_to_network()
/obj/machinery/power/solar/Destroy()
@@ -45,17 +54,6 @@
control.connected_panels.Remove(src)
control = null
-/obj/machinery/power/solar/proc/Make(obj/item/solar_assembly/S)
- if(!S)
- S = new /obj/item/solar_assembly
- S.glass_type = new /obj/item/stack/sheet/glass(null, 2)
- S.anchored = TRUE
- else
- S.moveToNullspace()
- S.glass_type.on_solar_construction(src)
- obj_integrity = max_integrity
- update_icon()
-
/obj/machinery/power/solar/crowbar_act(mob/user, obj/item/I)
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
user.visible_message("[user] begins to take the glass off [src].", "You begin to take the glass off [src]...")
@@ -201,7 +199,7 @@
new shard(Tsec)
new shard(Tsec)
else if(glass_type)
- forceMove(glass_type, Tsec)
+ glass_type.forceMove(Tsec)
glass_type = null
/obj/item/solar_assembly/attackby(obj/item/W, mob/user, params)
@@ -226,7 +224,8 @@
var/obj/item/stack/sheet/G = S.change_stack(null, 2)
if(G)
glass_type = G
- playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
+ G.moveToNullspace()
+ playsound(loc, 'sound/machines/click.ogg', 50, 1)
user.visible_message("[user] places the glass on the solar assembly.", "You place the glass on the solar assembly.")
if(tracker)
new /obj/machinery/power/tracker(get_turf(src), src)
diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm
index c25ece3594..8701dfea7f 100644
--- a/code/modules/power/tracker.dm
+++ b/code/modules/power/tracker.dm
@@ -20,7 +20,15 @@
/obj/machinery/power/tracker/Initialize(mapload, obj/item/solar_assembly/S)
. = ..()
- Make(S)
+ if(!S)
+ assembly = new /obj/item/solar_assembly
+ assembly.glass_type = new /obj/item/stack/sheet/glass(null, 2)
+ assembly.tracker = TRUE
+ assembly.anchored = TRUE
+ else
+ S.moveToNullspace()
+ assembly = S
+ update_icon()
connect_to_network()
/obj/machinery/power/tracker/Destroy()
@@ -41,16 +49,6 @@
control.connected_tracker = null
control = null
-/obj/machinery/power/tracker/proc/Make(obj/item/solar_assembly/S)
- if(!S)
- S = new /obj/item/solar_assembly
- S.glass_type = new /obj/item/stack/sheet/glass(null, 2)
- S.tracker = TRUE
- S.anchored = TRUE
- else
- S.moveToNullspace()
- update_icon()
-
//updates the tracker icon and the facing angle for the control computer
/obj/machinery/power/tracker/proc/set_angle(angle)
sun_angle = angle
diff --git a/code/modules/projectiles/ammunition/caseless/arrow.dm b/code/modules/projectiles/ammunition/caseless/arrow.dm
new file mode 100644
index 0000000000..e0ca637a8b
--- /dev/null
+++ b/code/modules/projectiles/ammunition/caseless/arrow.dm
@@ -0,0 +1,8 @@
+/obj/item/ammo_casing/caseless/arrow
+ name = "wooden arrow"
+ desc = "An arrow made of wood, typically fired from a bow."
+ projectile_type = /obj/item/projectile/bullet/reusable/arrow
+ caliber = "arrow"
+ icon_state = "arrow"
+ throwforce = 3 //good luck hitting someone with the pointy end of the arrow
+ throw_speed = 3
\ No newline at end of file
diff --git a/code/modules/projectiles/boxes_magazines/internal/bow.dm b/code/modules/projectiles/boxes_magazines/internal/bow.dm
new file mode 100644
index 0000000000..9ce1565606
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/internal/bow.dm
@@ -0,0 +1,6 @@
+/obj/item/ammo_box/magazine/internal/bow
+ name = "bow... magazine?" //shouldn't be seeing this
+ ammo_type = /obj/item/ammo_casing/caseless/arrow
+ caliber = "arrow"
+ max_ammo = 1
+ start_empty = 1
\ No newline at end of file
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 9740b4be04..34f7134591 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -15,7 +15,7 @@
throw_speed = 3
throw_range = 5
force = 5
- item_flags = NEEDS_PERMIT
+ item_flags = NEEDS_PERMIT | NO_ATTACK_CHAIN_SOFT_STAMCRIT
attack_verb = list("struck", "hit", "bashed")
var/fire_sound = "gunshot"
@@ -51,6 +51,7 @@
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
var/obj/item/firing_pin/pin = /obj/item/firing_pin //standard firing pin for most guns
+ var/no_pin_required = FALSE //whether the gun can be fired without a pin
var/obj/item/flashlight/gun_light
var/can_flashlight = 0
@@ -79,7 +80,10 @@
/obj/item/gun/Initialize()
. = ..()
if(pin)
- pin = new pin(src)
+ if(no_pin_required)
+ pin = null
+ else
+ pin = new pin(src)
if(gun_light)
alight = new (src)
if(zoomable)
@@ -107,6 +111,8 @@
/obj/item/gun/examine(mob/user)
. = ..()
+ if(no_pin_required)
+ return
if(pin)
. += "It has \a [pin] installed."
else
@@ -162,6 +168,9 @@
return
if(firing)
return
+ if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) //respect stamina softcrit
+ to_chat(user, "You are too exhausted to fire [src]!")
+ return
if(flag) //It's adjacent, is the user, or is on the user's person
if(target in user.contents) //can't shoot stuff inside us.
return
@@ -226,6 +235,8 @@
return FALSE
/obj/item/gun/proc/handle_pins(mob/living/user)
+ if(no_pin_required)
+ return TRUE
if(pin)
if(pin.pin_auth(user) || (pin.obj_flags & EMAGGED))
return TRUE
diff --git a/code/modules/projectiles/guns/ballistic/bow.dm b/code/modules/projectiles/guns/ballistic/bow.dm
new file mode 100644
index 0000000000..448e2915d9
--- /dev/null
+++ b/code/modules/projectiles/guns/ballistic/bow.dm
@@ -0,0 +1,53 @@
+/obj/item/gun/ballistic/bow
+ name = "wooden bow"
+ desc = "Some sort of primitive projectile weapon. Used to fire arrows."
+ icon_state = "bow"
+ item_state = "bow"
+ w_class = WEIGHT_CLASS_BULKY
+ weapon_weight = WEAPON_HEAVY //need both hands to fire
+ force = 5
+ mag_type = /obj/item/ammo_box/magazine/internal/bow
+ fire_sound = 'sound/weapons/bowfire.wav'
+ slot_flags = ITEM_SLOT_BACK
+ item_flags = NONE
+ casing_ejector = FALSE
+ inaccuracy_modifier = 0.33 //to counteract the innaccuracy from WEAPON_HEAVY, bows are supposed to be accurate but only able to be fired with both hands
+ pin = null
+ no_pin_required = TRUE
+ trigger_guard = TRIGGER_GUARD_NONE //so ashwalkers can use it
+
+/obj/item/gun/ballistic/bow/shoot_with_empty_chamber()
+ return
+
+/obj/item/gun/ballistic/bow/chamber_round()
+ chambered = magazine.get_round(1)
+
+/obj/item/gun/ballistic/bow/afterattack()
+ . = ..()
+ if (chambered)
+ chambered = null
+ magazine.get_round(0)
+ update_icon()
+
+/obj/item/gun/ballistic/bow/attack_self(mob/living/user)
+ if (chambered)
+ var/obj/item/ammo_casing/AC = magazine.get_round(0)
+ user.put_in_hands(AC)
+ chambered = null
+ to_chat(user, "You gently release the bowstring, removing the arrow.")
+ else if (get_ammo())
+ to_chat(user, "You draw back the bowstring.")
+ playsound(src, 'sound/weapons/bowdraw.wav', 75, 0) //gets way too high pitched if the freq varies
+ chamber_round()
+ update_icon()
+
+/obj/item/gun/ballistic/bow/attackby(obj/item/I, mob/user, params)
+ if (magazine.attackby(I, user, params, 1))
+ to_chat(user, "You notch the arrow.")
+ update_icon()
+
+/obj/item/gun/ballistic/bow/update_icon()
+ icon_state = "bow_[get_ammo() ? (chambered ? "firing" : "loaded") : "unloaded"]"
+
+/obj/item/gun/ballistic/bow/can_shoot()
+ return chambered
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/ballistic/magweapon.dm b/code/modules/projectiles/guns/ballistic/magweapon.dm
index f366063a74..4e37017b79 100644
--- a/code/modules/projectiles/guns/ballistic/magweapon.dm
+++ b/code/modules/projectiles/guns/ballistic/magweapon.dm
@@ -61,7 +61,6 @@
/obj/item/gun/ballistic/automatic/magrifle/nopin
pin = null
spawnwithmagazine = FALSE
- cell_type = /obj/item/stock_parts/cell/magnetic/empty
/obj/item/gun/ballistic/automatic/magrifle/hyperburst
name = "\improper Hyper-Burst Rifle"
@@ -100,4 +99,3 @@
/obj/item/gun/ballistic/automatic/magrifle/pistol/nopin
pin = null
spawnwithmagazine = FALSE
- cell_type = /obj/item/stock_parts/cell/magnetic/pistol/empty
diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm
index 5f67194b29..68f212ba30 100644
--- a/code/modules/projectiles/guns/ballistic/pistol.dm
+++ b/code/modules/projectiles/guns/ballistic/pistol.dm
@@ -79,6 +79,7 @@
/obj/item/gun/ballistic/automatic/pistol/stickman
name = "flat gun"
desc = "A 2 dimensional gun.. what?"
+ can_suppress = FALSE
icon_state = "flatgun"
/obj/item/gun/ballistic/automatic/pistol/stickman/pickup(mob/living/user)
diff --git a/code/modules/projectiles/guns/energy/dueling.dm b/code/modules/projectiles/guns/energy/dueling.dm
index 6fe10eb3b6..615bb5d939 100644
--- a/code/modules/projectiles/guns/energy/dueling.dm
+++ b/code/modules/projectiles/guns/energy/dueling.dm
@@ -320,10 +320,10 @@
if(C.setting == counter_setting)
return BULLET_ACT_BLOCK
- var/mob/living/L = target
- if(!istype(target))
+ if(!isliving(target))
return BULLET_ACT_BLOCK
+ var/mob/living/L = target
switch(hugbox)
if(DUEL_HUGBOX_NONE)
var/obj/item/bodypart/B = L.get_bodypart(BODY_ZONE_HEAD)
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index f45b5a29ba..4b29b59549 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -11,6 +11,7 @@
/obj/item/gun/energy/laser/practice
name = "practice laser gun"
+ icon_state = "laser-p"
desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice."
ammo_type = list(/obj/item/ammo_casing/energy/laser/practice)
clumsy_check = 0
diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm
index 70551d07b6..e754a9c070 100644
--- a/code/modules/projectiles/pins.dm
+++ b/code/modules/projectiles/pins.dm
@@ -23,6 +23,8 @@
if(proximity_flag)
if(istype(target, /obj/item/gun))
var/obj/item/gun/G = target
+ if(G.no_pin_required)
+ return
if(G.pin && (force_replace || G.pin.pin_removeable))
G.pin.forceMove(get_turf(G))
G.pin.gun_remove(user)
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index a902c545b8..139f5a051c 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -52,7 +52,6 @@
var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored.
var/list/beam_segments //assoc list of datum/point or datum/point/vector, start = end. Used for hitscan effect generation.
var/datum/point/beam_index
- var/turf/hitscan_last //last turf touched during hitscanning.
var/tracer_type
var/muzzle_type
var/impact_type
@@ -90,6 +89,10 @@
var/decayedRange //stores original range
var/reflect_range_decrease = 5 //amount of original range that falls off when reflecting, so it doesn't go forever
var/is_reflectable = FALSE // Can it be reflected or not?
+
+ /// factor to multiply by for zone accuracy percent.
+ var/zone_accuracy_factor = 1
+
//Effects
var/stun = 0
var/knockdown = 0
@@ -185,10 +188,6 @@
else
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, bloodtype_to_color())
- if(iscarbon(L) && !HAS_TRAIT(L, TRAIT_NOMARROW))
- var/mob/living/carbon/C = L
- C.bleed(damage)
- else
L.add_splatter_floor(target_loca)
else if(impact_effect_type && !hitscan)
new impact_effect_type(target_loca, hitx, hity)
@@ -211,11 +210,8 @@
L.on_hit(src)
var/reagent_note
- if(reagents && reagents.reagent_list)
- reagent_note = " REAGENTS:"
- for(var/datum/reagent/R in reagents.reagent_list)
- reagent_note += R.type + " ("
- reagent_note += num2text(R.volume) + ") "
+ if(reagents)
+ reagent_note = reagents.log_list()
if(ismob(firer))
log_combat(firer, L, "shot", src, reagent_note)
@@ -253,7 +249,8 @@
return TRUE
var/distance = get_dist(T, starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations.
- def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use.
+ if(check_zone(def_zone) != BODY_ZONE_CHEST)
+ def_zone = ran_zone(def_zone, max(100-(7*distance), 5) * zone_accuracy_factor) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use.
if(isturf(A) && hitsound_wall)
var/volume = CLAMP(vol_by_damage() + 20, 0, 100)
@@ -494,8 +491,6 @@
process_homing()
var/forcemoved = FALSE
for(var/i in 1 to SSprojectiles.global_iterations_per_move)
- if(QDELETED(src))
- return
trajectory.increment(trajectory_multiplier)
var/turf/T = trajectory.return_turf()
if(!istype(T))
@@ -508,14 +503,16 @@
forceMove(T)
trajectory_ignore_forcemove = FALSE
after_z_change(old, loc)
+ forcemoved = TRUE
+ if(QDELETED(src))
+ return
if(!hitscanning)
pixel_x = trajectory.return_px()
pixel_y = trajectory.return_py()
- forcemoved = TRUE
- hitscan_last = loc
else if(T != loc)
step_towards(src, T)
- hitscan_last = loc
+ if(QDELETED(src))
+ return
if(!hitscanning && !forcemoved)
pixel_x = trajectory.return_px() - trajectory.mpx * trajectory_multiplier * SSprojectiles.global_iterations_per_move
pixel_y = trajectory.return_py() - trajectory.mpy * trajectory_multiplier * SSprojectiles.global_iterations_per_move
diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm
index 3f418df75b..b5a9eb8d69 100644
--- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm
+++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm
@@ -6,7 +6,7 @@
/obj/item/projectile/bullet/dart/Initialize()
. = ..()
- create_reagents(50, NO_REACT)
+ create_reagents(50, NO_REACT, NO_REAGENTS_VALUE)
/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE, skip = FALSE)
if(iscarbon(target))
diff --git a/code/modules/projectiles/projectile/bullets/sniper.dm b/code/modules/projectiles/projectile/bullets/sniper.dm
index bea5dbc140..5e3ae53806 100644
--- a/code/modules/projectiles/projectile/bullets/sniper.dm
+++ b/code/modules/projectiles/projectile/bullets/sniper.dm
@@ -7,6 +7,7 @@
knockdown = 100
dismemberment = 50
armour_penetration = 50
+ zone_accuracy_factor = 100 //guarunteed 100%
var/breakthings = TRUE
/obj/item/projectile/bullet/p50/on_hit(atom/target, blocked = 0)
diff --git a/code/modules/projectiles/projectile/reusable/arrow.dm b/code/modules/projectiles/projectile/reusable/arrow.dm
new file mode 100644
index 0000000000..f1c9638fd9
--- /dev/null
+++ b/code/modules/projectiles/projectile/reusable/arrow.dm
@@ -0,0 +1,6 @@
+/obj/item/projectile/bullet/reusable/arrow
+ name = "wooden arrow"
+ desc = "Woosh!"
+ damage = 15
+ icon_state = "arrow"
+ ammo_type = /obj/item/ammo_casing/caseless/arrow
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm
index 0cee20dd53..df417ad734 100644
--- a/code/modules/projectiles/projectile/special/rocket.dm
+++ b/code/modules/projectiles/projectile/special/rocket.dm
@@ -43,4 +43,34 @@
explosion(target, 0, 1, 2, 4)
else
explosion(target, 0, 0, 2, 4)
- return BULLET_ACT_HIT
\ No newline at end of file
+ return BULLET_ACT_HIT
+
+/obj/item/projectile/bullet/a84mm_br
+ name ="\improper HE missile"
+ desc = "Boom."
+ icon_state = "missile"
+ damage = 30
+ ricochets_max = 0 //it's a MISSILE
+ var/sturdy = list(
+ /turf/closed,
+ /obj/mecha,
+ /obj/machinery/door/,
+ /obj/machinery/door/poddoor/shutters
+ )
+
+/obj/item/broken_missile
+ name = "\improper broken missile"
+ desc = "A missile that did not detonate. The tail has snapped and it is in no way fit to be used again."
+ icon = 'icons/obj/projectiles.dmi'
+ icon_state = "missile_broken"
+ w_class = WEIGHT_CLASS_TINY
+
+
+/obj/item/projectile/bullet/a84mm_br/on_hit(atom/target, blocked=0)
+ ..()
+ for(var/i in sturdy)
+ if(istype(target, i))
+ explosion(target, 0, 1, 1, 2)
+ return BULLET_ACT_HIT
+ //if(istype(target, /turf/closed) || ismecha(target))
+ new /obj/item/broken_missile(get_turf(src), 1)
\ No newline at end of file
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index 95e104ba68..4c240660a9 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -61,8 +61,9 @@
var/reactedVol = 0 //how much of the reagent is reacted during a fermireaction
var/fermiIsReacting = FALSE //that prevents multiple reactions from occurring (i.e. add_reagent calls to process_reactions(), this stops any extra reactions.)
var/fermiReactID //instance of the chem reaction used during a fermireaction, kept here so it's cache isn't lost between loops/procs.
+ var/value_multiplier = DEFAULT_REAGENTS_VALUE //used for cargo reagents selling.
-/datum/reagents/New(maximum=100, new_flags)
+/datum/reagents/New(maximum=100, new_flags = NONE, new_value = DEFAULT_REAGENTS_VALUE)
maximum_volume = maximum
//I dislike having these here but map-objects are initialised before world/New() is called. >_>
@@ -72,6 +73,7 @@
build_chemical_reactions_list()
reagents_holder_flags = new_flags
+ value_multiplier = new_value
/datum/reagents/Destroy()
. = ..()
@@ -1147,10 +1149,10 @@
// Convenience proc to create a reagents holder for an atom
// Max vol is maximum volume of holder
-/atom/proc/create_reagents(max_vol, flags)
+/atom/proc/create_reagents(max_vol, flags, new_value)
if(reagents)
qdel(reagents)
- reagents = new/datum/reagents(max_vol, flags)
+ reagents = new/datum/reagents(max_vol, flags, new_value)
reagents.my_atom = src
/proc/get_random_reagent_id() // Returns a random reagent type minus blacklisted reagents
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index f41a6956a1..ed68c25cb6 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -270,7 +270,7 @@
if(!is_operational() || recording_recipe)
return
var/amount = text2num(params["amount"])
- if(beaker && amount in beaker.possible_transfer_amounts)
+ if(beaker && (amount in beaker.possible_transfer_amounts))
beaker.reagents.remove_all(amount)
work_animation()
. = TRUE
diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm
index 8870ef8ed5..3dea44cf40 100644
--- a/code/modules/reagents/chemistry/machinery/pandemic.dm
+++ b/code/modules/reagents/chemistry/machinery/pandemic.dm
@@ -181,27 +181,30 @@
if(!istype(A) || !A.mutable)
to_chat(usr, "ERROR: Cannot replicate virus strain.")
return
+ wait = TRUE
+ addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50)
A = A.Copy()
var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY", "viruses" = list(A))
var/obj/item/reagent_containers/glass/bottle/B = new(drop_location())
B.name = "[A.name] culture bottle"
B.desc = "A small bottle. Contains [A.agent] culture in synthblood medium."
- B.reagents.add_reagent(/datum/reagent/blood, 20, data)
- wait = TRUE
+ B.reagents.add_reagent(/datum/reagent/blood/synthetics, 10, data)
update_icon()
var/turf/source_turf = get_turf(src)
log_virus("A culture bottle was printed for the virus [A.admin_details()] at [loc_name(source_turf)] by [key_name(usr)]")
- addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50)
+
. = TRUE
if("create_vaccine_bottle")
+ wait = TRUE
+ addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 400)
var/id = params["index"]
var/datum/disease/D = SSdisease.archive_diseases[id]
var/obj/item/reagent_containers/glass/bottle/B = new(drop_location())
B.name = "[D.name] vaccine bottle"
B.reagents.add_reagent(/datum/reagent/vaccine, 15, list(id))
- wait = TRUE
+
update_icon()
- addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 200)
+
. = TRUE
/obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params)
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index ccdbbcc915..4b65776ce9 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -551,7 +551,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
value = 1
/datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_life(mob/living/carbon/M)
- if(M.mind && M.mind.assigned_role in list("Station Engineer", "Atmospheric Technician", "Chief Engineer")) //Engineers lose radiation poisoning at a massive rate.
+ if(M.mind && (M.mind.assigned_role in list("Station Engineer", "Atmospheric Technician", "Chief Engineer"))) //Engineers lose radiation poisoning at a massive rate.
M.radiation = max(M.radiation - 25, 0)
return ..()
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 6d37f30884..0a040a4f17 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -1482,14 +1482,14 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
/datum/reagent/medicine/polypyr //This is intended to be an ingredient in advanced chems.
name = "Polypyrylium Oligomers"
- description = "A�purple mixture of short polyelectrolyte chains not easily synthesized in the laboratory. It is valued as an intermediate in the synthesis of the cutting edge pharmaceuticals."
+ description = "A purple mixture of short polyelectrolyte chains not easily synthesized in the laboratory. It is valued as an intermediate in the synthesis of the cutting edge pharmaceuticals."
reagent_state = SOLID
color = "#9423FF"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
overdose_threshold = 50
taste_description = "numbing bitterness"
-/datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I w�nted a collection of small positive effects, this is as hard to obtain as coniine after all.
+/datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all.
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25)
M.adjustBruteLoss(-0.35, 0)
if(prob(50))
@@ -1511,4 +1511,3 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5)
..()
. = 1
-
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index c7e574594b..adc30ecdc9 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -93,8 +93,6 @@
taste_description = "something spicy"
pH = 6.85
-
-
/datum/reagent/blood/on_merge(list/mix_data)
if(data && mix_data)
if(data["blood_DNA"] != mix_data["blood_DNA"])
@@ -131,16 +129,10 @@
/datum/reagent/blood/synthetics
data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Synthetic Blood"
+ description = "A synthetically produced imitation of blood."
taste_description = "oily"
color = BLOOD_COLOR_SYNTHETIC // rgb: 11, 7, 48
-/datum/reagent/blood/lizard
- data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_LIZARD, "blood_type"="L","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
- name = "Lizard Blood"
- taste_description = "spicy"
- color = BLOOD_COLOR_LIZARD // rgb: 11, 7, 48
- pH = 6.85
-
/datum/reagent/blood/jellyblood
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Slime Jelly Blood"
@@ -150,29 +142,6 @@
taste_mult = 1.3
pH = 4
-/datum/reagent/blood/xenomorph
- data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
- name = "Xenomorph Blood"
- taste_description = "acidic heresy"
- color = BLOOD_COLOR_XENO // greenish yellow ooze
- shot_glass_icon_state = "shotglassgreen"
- pH = 2.5
-
-/datum/reagent/blood/oil
- data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
- name = "Hydraulic Blood"
- taste_description = "burnt oil"
- color = BLOOD_COLOR_OIL // dark, y'know, expected batman colors.
- pH = 9.75
-
-/datum/reagent/blood/insect
- data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_BUG, "blood_type"="BUG","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
- name = "Insectoid Blood"
- taste_description = "waxy"
- color = BLOOD_COLOR_BUG // Bug colored, I guess.
- pH = 7.25
-
-
/datum/reagent/blood/jellyblood/on_mob_life(mob/living/carbon/M)
if(prob(10))
if(M.dna?.species?.exotic_bloodtype != "GEL")
@@ -338,8 +307,8 @@
/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)
if(!data)
- data = 1
- data++
+ data = list("misc" = 1)
+ data["misc"]++
M.jitteriness = min(M.jitteriness+4,10)
if(iscultist(M))
for(var/datum/action/innate/cult/blood_magic/BM in M.actions)
@@ -348,7 +317,7 @@
to_chat(M, "Your blood rites falter as holy water scours your body!")
for(var/datum/action/innate/cult/blood_spell/BS in BM.spells)
qdel(BS)
- if(data >= 25) // 10 units, 45 seconds @ metabolism 0.4 units & tick rate 1.8 sec
+ if(data["misc"] >= 25) // 10 units, 45 seconds @ metabolism 0.4 units & tick rate 1.8 sec
if(!M.stuttering)
M.stuttering = 1
M.stuttering = min(M.stuttering+4, 10)
@@ -369,7 +338,7 @@
"You can't save him. Nothing can save him now", "It seems that Nar'Sie will triumph after all")].")
if("emote")
M.visible_message("[M] [pick("whimpers quietly", "shivers as though cold", "glances around in paranoia")].")
- if(data >= 60) // 30 units, 135 seconds
+ if(data["misc"] >= 60) // 30 units, 135 seconds
if(iscultist(M) || is_servant_of_ratvar(M))
if(iscultist(M))
SSticker.mode.remove_cultist(M.mind, FALSE, TRUE)
@@ -770,7 +739,7 @@
..()
if(!istype(H))
return
- if(!H.dna || !H.dna.species || !(MOB_ORGANIC in H.mob_biotypes))
+ if(!H.dna || !H.dna.species || !(H.mob_biotypes & MOB_ORGANIC))
return
if(isjellyperson(H))
@@ -2139,3 +2108,10 @@
to_chat(M, "You feel like playing with your [G.name]!")
..()
+
+/datum/reagent/preservahyde
+ name = "Preservahyde"
+ description = "A powerful preservation agent, utilizing the preservative effects of formaldehyde with significantly less of the histamine."
+ reagent_state = LIQUID
+ color = "#f7685e"
+ metabolization_rate = REAGENTS_METABOLISM * 0.25
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index a32cb94401..e649caafb5 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -260,7 +260,7 @@
/datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
..()
- if(MOB_BUG in M.mob_biotypes)
+ if(M.mob_biotypes & MOB_BUG)
var/damage = min(round(0.4*reac_volume, 0.1),10)
M.adjustToxLoss(damage)
diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm
index a07e7697bc..0b32952d20 100644
--- a/code/modules/reagents/chemistry/recipes/medicine.dm
+++ b/code/modules/reagents/chemistry/recipes/medicine.dm
@@ -68,6 +68,10 @@
results = list(/datum/reagent/medicine/synthflesh = 3)
required_reagents = list(/datum/reagent/blood = 1, /datum/reagent/carbon = 1, /datum/reagent/medicine/styptic_powder = 1)
+/datum/chemical_reaction/synthflesh/synthblood
+ id = "synthflesh_2"
+ required_reagents = list(/datum/reagent/blood/synthetics = 1, /datum/reagent/carbon = 1, /datum/reagent/medicine/styptic_powder = 1)
+
/datum/chemical_reaction/synthtissue
name = "Synthtissue"
id = /datum/reagent/synthtissue
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index b463b5758b..57748acb1a 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -47,6 +47,12 @@
results = list(/datum/reagent/consumable/sodiumchloride = 3)
required_reagents = list(/datum/reagent/water = 1, /datum/reagent/sodium = 1, /datum/reagent/chlorine = 1)
+/datum/chemical_reaction/preservahyde
+ name = "Preservahyde"
+ id = "preservahyde"
+ results = list(/datum/reagent/preservahyde = 3)
+ required_reagents = list(/datum/reagent/water = 1, /datum/reagent/toxin/formaldehyde = 1, /datum/reagent/bromine = 1)
+
/datum/chemical_reaction/plasmasolidification
name = "Solid Plasma"
id = "solidplasma"
@@ -228,7 +234,6 @@
var/level_max = 2
/datum/chemical_reaction/mix_virus/on_reaction(datum/reagents/holder, multiplier)
-
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list
if(B && B.data)
var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"]
@@ -236,94 +241,131 @@
for(var/i in 1 to min(multiplier, 5))
D.Evolve(level_min, level_max)
-/datum/chemical_reaction/mix_virus/mix_virus_2
+/datum/chemical_reaction/mix_virus/synth
+ id = "mixvirus_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_2
name = "Mix Virus 2"
id = "mixvirus2"
required_reagents = list(/datum/reagent/toxin/mutagen = 1)
level_min = 2
level_max = 4
-/datum/chemical_reaction/mix_virus/mix_virus_3
+/datum/chemical_reaction/mix_virus/mix_virus_2/synth
+ id = "mixvirus2_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_3
name = "Mix Virus 3"
id = "mixvirus3"
required_reagents = list(/datum/reagent/toxin/plasma = 1)
level_min = 4
level_max = 6
-/datum/chemical_reaction/mix_virus/mix_virus_4
+/datum/chemical_reaction/mix_virus/mix_virus_3/synth
+ id = "mixvirus3_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_4
name = "Mix Virus 4"
id = "mixvirus4"
required_reagents = list(/datum/reagent/uranium = 1)
level_min = 5
level_max = 6
-/datum/chemical_reaction/mix_virus/mix_virus_5
+/datum/chemical_reaction/mix_virus/mix_virus_4/synth
+ id = "mixvirus4_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_5
name = "Mix Virus 5"
id = "mixvirus5"
required_reagents = list(/datum/reagent/toxin/mutagen/mutagenvirusfood = 1)
level_min = 3
level_max = 3
-/datum/chemical_reaction/mix_virus/mix_virus_6
+/datum/chemical_reaction/mix_virus/mix_virus_5/synth
+ id = "mixvirus5_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_6
name = "Mix Virus 6"
id = "mixvirus6"
required_reagents = list(/datum/reagent/toxin/mutagen/mutagenvirusfood/sugar = 1)
level_min = 4
level_max = 4
-/datum/chemical_reaction/mix_virus/mix_virus_7
+/datum/chemical_reaction/mix_virus/mix_virus_6/synth
+ id = "mixvirus6_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_7
name = "Mix Virus 7"
id = "mixvirus7"
required_reagents = list(/datum/reagent/toxin/plasma/plasmavirusfood/weak = 1)
level_min = 5
level_max = 5
-/datum/chemical_reaction/mix_virus/mix_virus_8
+/datum/chemical_reaction/mix_virus/mix_virus_7/synth
+ id = "mixvirus7_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_8
name = "Mix Virus 8"
id = "mixvirus8"
required_reagents = list(/datum/reagent/toxin/plasma/plasmavirusfood = 1)
level_min = 6
level_max = 6
-/datum/chemical_reaction/mix_virus/mix_virus_9
+/datum/chemical_reaction/mix_virus/mix_virus_8/synth
+ id = "mixvirus8_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_9
name = "Mix Virus 9"
id = "mixvirus9"
required_reagents = list(/datum/reagent/medicine/synaptizine/synaptizinevirusfood = 1)
level_min = 1
level_max = 1
-/datum/chemical_reaction/mix_virus/mix_virus_10
+/datum/chemical_reaction/mix_virus/mix_virus_9/synth
+ id = "mixvirus9_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_10
name = "Mix Virus 10"
id = "mixvirus10"
required_reagents = list(/datum/reagent/uranium/uraniumvirusfood = 1)
level_min = 6
level_max = 7
-/datum/chemical_reaction/mix_virus/mix_virus_11
+/datum/chemical_reaction/mix_virus/mix_virus_10/synth
+ id = "mixvirus10_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_11
name = "Mix Virus 11"
id = "mixvirus11"
required_reagents = list(/datum/reagent/uranium/uraniumvirusfood/unstable = 1)
level_min = 7
level_max = 7
-/datum/chemical_reaction/mix_virus/mix_virus_12
+/datum/chemical_reaction/mix_virus/mix_virus_11/synth
+ id = "mixvirus11_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+/datum/chemical_reaction/mix_virus/mix_virus_12
name = "Mix Virus 12"
id = "mixvirus12"
required_reagents = list(/datum/reagent/uranium/uraniumvirusfood/stable = 1)
level_min = 8
level_max = 8
+/datum/chemical_reaction/mix_virus/mix_virus_12/synth
+ id = "mixvirus12_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+
/datum/chemical_reaction/mix_virus/rem_virus
name = "Devolve Virus"
id = "remvirus"
@@ -338,6 +380,10 @@
for(var/i in 1 to min(multiplier, 5))
D.Devolve()
+/datum/chemical_reaction/mix_virus/rem_virus/synth
+ id = "remvirus_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+
/datum/chemical_reaction/mix_virus/neuter_virus
name = "Neuter Virus"
id = "neutervirus"
@@ -352,6 +398,10 @@
for(var/i in 1 to min(multiplier, 5))
D.Neuter()
+/datum/chemical_reaction/mix_virus/neuter_virus/synth
+ id = "neutervirus_synth"
+ required_catalysts = list(/datum/reagent/blood/synthetics = 1)
+
////////////////////////////////// foam and foam precursor ///////////////////////////////////////////////////
@@ -743,3 +793,13 @@
id = "blue_glitter_white"
results = list(/datum/reagent/glitter/blue = 2)
required_reagents = list(/datum/reagent/glitter/white = 1, /datum/reagent/colorful_reagent/crayonpowder/blue = 1)
+
+//////////////////////////////////// Synthblood ///////////////////////////////////////////
+
+/datum/chemical_reaction/synth_blood
+ name = "Synthetic Blood"
+ id = /datum/reagent/blood/synthetics
+ results = list(/datum/reagent/blood/synthetics = 3)
+ required_reagents = list(/datum/reagent/medicine/salglu_solution = 1, /datum/reagent/iron = 1, /datum/reagent/stable_plasma = 1)
+ mix_message = "The mixture congeals and gives off a faint copper scent."
+ required_temp = 350
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 6d5c546e7e..c178aad717 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -7,7 +7,8 @@
var/amount_per_transfer_from_this = 5
var/list/possible_transfer_amounts = list(5,10,15,20,25,30)
var/volume = 30
- var/reagent_flags //used to determine the reagent holder flags on add_initial_reagents()
+ var/reagent_flags = NONE //used to determine the reagent holder flags on add_initial_reagents()
+ var/reagent_value = DEFAULT_REAGENTS_VALUE //same as above but for the holder value multiplier.
var/list/list_reagents = null
var/spawned_disease = null
var/disease_amount = 20
@@ -22,7 +23,7 @@
volume = vol
if(container_flags & APTFT_VERB && length(possible_transfer_amounts))
verbs += /obj/item/reagent_containers/proc/set_APTFT
- create_reagents(volume, reagent_flags)
+ create_reagents(volume, reagent_flags, reagent_value)
if(spawned_disease)
var/datum/disease/F = new spawned_disease()
var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY","viruses"= list(F))
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index 34dd97b0aa..73d0c5eafa 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -19,6 +19,7 @@ Borg Hypospray
amount_per_transfer_from_this = 5
volume = 30
possible_transfer_amounts = list()
+ reagent_value = NO_REAGENTS_VALUE
var/mode = 1
var/charge_cost = 50
var/charge_tick = 0
diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm
index 9feec362a4..4e1de85fce 100644
--- a/code/modules/reagents/reagent_containers/dropper.dm
+++ b/code/modules/reagents/reagent_containers/dropper.dm
@@ -44,7 +44,7 @@
if(safe_thing)
if(!safe_thing.reagents)
- safe_thing.create_reagents(100)
+ safe_thing.create_reagents(100, NONE, NO_REAGENTS_VALUE)
reagents.reaction(safe_thing, TOUCH, fraction)
trans = reagents.trans_to(safe_thing, amount_per_transfer_from_this)
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index fd4282b1b0..f29b785c95 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -95,7 +95,7 @@
ignore_flags = 1 //so you can medipen through hardsuits
reagent_flags = DRAWABLE
flags_1 = null
- list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/toxin/formaldehyde = 3)
+ list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/preservahyde = 3)
/obj/item/reagent_containers/hypospray/medipen/suicide_act(mob/living/carbon/user)
user.visible_message("[user] begins to choke on \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")
diff --git a/code/modules/reagents/reagent_containers/rags.dm b/code/modules/reagents/reagent_containers/rags.dm
index 59c956acd6..e7f340887c 100644
--- a/code/modules/reagents/reagent_containers/rags.dm
+++ b/code/modules/reagents/reagent_containers/rags.dm
@@ -11,6 +11,7 @@
container_flags = APTFT_VERB
volume = 5
spillable = FALSE
+ reagent_value = NO_REAGENTS_VALUE
var/wipe_sound
var/soak_efficiency = 1
var/extinguish_efficiency = 0
@@ -26,7 +27,7 @@
if(reagents.total_volume)
. += "It's soaked. Alt-Click to squeeze it dry, and perhaps gather the liquids into another held open container."
-/obj/item/reagent_containers/rag/afterattack(atom/A as obj|turf|area, mob/user,proximity)
+/obj/item/reagent_containers/rag/afterattack(atom/A, mob/user,proximity)
. = ..()
if(!proximity)
return
@@ -45,7 +46,7 @@
C.visible_message("[user] has touched \the [C] with \the [src].")
log_combat(user, C, "touched", log_object)
- else if(istype(A) && src in user)
+ else if(istype(A) && (src in user))
user.visible_message("[user] starts to wipe down [A] with [src]!", "You start to wipe down [A] with [src]...")
if(do_after(user, action_speed, target = A))
user.visible_message("[user] finishes wiping off [A]!", "You finish wiping off [A].")
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index 4562f348fc..62ca5d658e 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -68,7 +68,7 @@
/obj/item/reagent_containers/spray/proc/spray(atom/A)
var/range = CLAMP(get_dist(src, A), 1, current_range)
var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src))
- D.create_reagents(amount_per_transfer_from_this)
+ D.create_reagents(amount_per_transfer_from_this, NONE, NO_REAGENTS_VALUE)
var/puff_reagent_left = range //how many turf, mob or dense objet we can react with before we consider the chem puff consumed
if(stream_mode)
reagents.trans_to(D, amount_per_transfer_from_this)
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 90f96d0352..d39d9f4b85 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -79,12 +79,12 @@
/obj/machinery/disposal/attackby(obj/item/I, mob/user, params)
add_fingerprint(user)
if(!pressure_charging && !full_pressure && !flush)
- if(istype(I, /obj/item/screwdriver))
+ if(I.tool_behaviour == TOOL_SCREWDRIVER)
panel_open = !panel_open
I.play_tool_sound(src)
to_chat(user, "You [panel_open ? "remove":"attach"] the screws around the power connection.")
return
- else if(istype(I, /obj/item/weldingtool) && panel_open)
+ else if(I.tool_behaviour == TOOL_WELDER && panel_open)
if(!I.tool_start_check(user, amount=0))
return
@@ -99,7 +99,7 @@
return
place_item_in_disposal(I, user)
update_icon()
- return 1 //no afterattack
+ return TRUE //no afterattack
else
return ..()
@@ -288,32 +288,16 @@
var/datum/oracle_ui/themed/nano/ui
obj_flags = CAN_BE_HIT | USES_TGUI | SHOVABLE_ONTO
-
// attack by item places it in to disposal
/obj/machinery/disposal/bin/attackby(obj/item/I, mob/user, params)
- add_fingerprint(user)
- if(!pressure_charging && !full_pressure && !flush)
- if(I.tool_behaviour == TOOL_SCREWDRIVER)
- panel_open = !panel_open
- I.play_tool_sound(src)
- to_chat(user, "You [panel_open ? "remove":"attach"] the screws around the power connection.")
- return
- else if(I.tool_behaviour == TOOL_WELDER && panel_open)
- if(!I.tool_start_check(user, amount=0))
- return
-
- to_chat(user, "You start slicing the floorweld off \the [src]...")
- if(I.use_tool(src, user, 20, volume=100) && panel_open)
- to_chat(user, "You slice the floorweld off \the [src].")
- deconstruct()
- return
-
- if(user.a_intent != INTENT_HARM)
- if((I.item_flags & ABSTRACT) || !user.temporarilyRemoveItemFromInventory(I))
- return
- place_item_in_disposal(I, user)
+ if(istype(I, /obj/item/storage/bag/trash)) //Not doing component overrides because this is a specific type.
+ var/obj/item/storage/bag/trash/T = I
+ var/datum/component/storage/STR = T.GetComponent(/datum/component/storage)
+ to_chat(user, "You empty the bag.")
+ for(var/obj/item/O in T.contents)
+ STR.remove_from_storage(O,src)
+ T.update_icon()
update_icon()
- return TRUE //no afterattack
else
return ..()
diff --git a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm
index b4d67315ba..6ccbf32615 100644
--- a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm
+++ b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm
@@ -26,6 +26,14 @@
category = list ("Misc. Machinery")
departmental_flags = DEPARTMENTAL_FLAG_ALL
+/datum/design/board/autolathe_secure
+ name = "Machine Design (Secure Autolathe Board)"
+ desc = "The circuit board for an autolathe. This one is programmed to not allow hacking."
+ id = "autolathe_secure"
+ build_path = /obj/item/circuitboard/machine/autolathe/secure
+ category = list ("Misc. Machinery")
+ departmental_flags = DEPARTMENTAL_FLAG_ALL
+
/datum/design/board/recharger
name = "Machine Design (Weapon Recharger Board)"
desc = "The circuit board for a Weapon Recharger."
diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm
index 7ccc41c232..32272dc2bc 100644
--- a/code/modules/research/designs/mecha_designs.dm
+++ b/code/modules/research/designs/mecha_designs.dm
@@ -157,6 +157,17 @@
construction_time = 70
category = list("Exosuit Equipment")
+/datum/design/mech_scattershot_ammo
+ name = "Scattershot Ammunition"
+ desc = "Ammunition for the LBX AC 10 and Melon Seed exosuit weapon."
+ id = "mech_scattershot_ammo"
+ build_type = PROTOLATHE | MECHFAB
+ build_path = /obj/item/mecha_ammo/scattershot
+ materials = list(MAT_METAL=6000)
+ construction_time = 20
+ category = list("Exosuit Ammunition", "Ammo")
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
/datum/design/mech_carbine
name = "Exosuit Weapon (FNX-99 \"Hades\" Carbine)"
desc = "Allows for the construction of FNX-99 \"Hades\" Carbine."
@@ -167,6 +178,17 @@
construction_time = 100
category = list("Exosuit Equipment")
+/datum/design/mech_carbine_ammo
+ name = "FNX-99 Carbine Ammunition"
+ desc = "Ammunition for the FNX-99 \"Hades\" Carbine."
+ id = "mech_carbine_ammo"
+ build_type = PROTOLATHE | MECHFAB
+ build_path = /obj/item/mecha_ammo/incendiary
+ materials = list(MAT_METAL=6000)
+ construction_time = 20
+ category = list("Exosuit Ammunition", "Ammo")
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
/datum/design/mech_ion
name = "Exosuit Weapon (MKIV Ion Heavy Cannon)"
desc = "Allows for the construction of MKIV Ion Heavy Cannon."
@@ -217,16 +239,38 @@
construction_time = 100
category = list("Exosuit Equipment")
+/datum/design/mech_grenade_launcher_ammo
+ name = "SGL-6 Grenade Launcher Ammunition"
+ desc = "Ammunition for the SGL-6 Grenade Launcher."
+ id = "mech_grenade_launcher_ammo"
+ build_type = PROTOLATHE | MECHFAB
+ build_path = /obj/item/mecha_ammo/flashbang
+ materials = list(MAT_METAL=4000,MAT_GOLD=500,MAT_SILVER=500)
+ construction_time = 20
+ category = list("Exosuit Ammunition", "Ammo")
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
/datum/design/mech_missile_rack
- name = "Exosuit Weapon (SRM-8 Missile Rack)"
- desc = "Allows for the construction of an SRM-8 Missile Rack."
+ name = "Exosuit Weapon (BRM-6 Missile Rack)"
+ desc = "Allows for the construction of an BRM-6 Breaching Missile Rack."
id = "mech_missile_rack"
build_type = MECHFAB
- build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/breaching
materials = list(MAT_METAL=22000,MAT_GOLD=6000,MAT_SILVER=8000)
construction_time = 100
category = list("Exosuit Equipment")
+/datum/design/mech_missile_rack_ammo
+ name = "SRM-8 Missile Rack Ammunition"
+ desc = "Ammunition for the SRM-8 Missile Rack."
+ id = "mech_missile_rack_ammo"
+ build_type = PROTOLATHE | MECHFAB
+ build_path = /obj/item/mecha_ammo/missiles_br
+ materials = list(MAT_METAL=8000,MAT_GOLD=500,MAT_SILVER=500)
+ construction_time = 20
+ category = list("Exosuit Ammunition", "Ammo")
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
/datum/design/clusterbang_launcher
name = "Exosuit Module (SOB-3 Clusterbang Launcher)"
desc = "A weapon that violates the Geneva Convention at 3 rounds per minute"
@@ -237,6 +281,17 @@
construction_time = 100
category = list("Exosuit Equipment")
+/datum/design/clusterbang_launcher_ammo
+ name = "SOB-3 Clusterbang Launcher Ammunition"
+ desc = "Ammunition for the SOB-3 Clusterbang Launcher"
+ id = "clusterbang_launcher_ammo"
+ build_type = PROTOLATHE | MECHFAB
+ build_path = /obj/item/mecha_ammo/clusterbang
+ materials = list(MAT_METAL=6000,MAT_GOLD=1500,MAT_URANIUM=1500)
+ construction_time = 20
+ category = list("Exosuit Ammunition", "Ammo")
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
/datum/design/mech_wormhole_gen
name = "Exosuit Module (Localized Wormhole Generator)"
desc = "An exosuit module that allows generating of small quasi-stable wormholes."
@@ -367,6 +422,17 @@
construction_time = 100
category = list("Exosuit Equipment")
+/datum/design/mech_lmg_ammo
+ name = "Ultra AC 2 Ammunition"
+ desc = "Ammunition for the Ultra AC 2 LMG"
+ id = "mech_lmg_ammo"
+ build_type = PROTOLATHE | MECHFAB
+ build_path = /obj/item/mecha_ammo/lmg
+ materials = list(MAT_METAL=4000)
+ construction_time = 20
+ category = list("Exosuit Ammunition", "Ammo")
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
/datum/design/mech_sleeper
name = "Exosuit Medical Equipment (Mounted Sleeper)"
desc = "Equipment for medical exosuits. A mounted sleeper that stabilizes patients and can inject reagents in the exosuit's reserves."
diff --git a/code/modules/research/designs/mining_designs.dm b/code/modules/research/designs/mining_designs.dm
index b4ac5f109d..69e695afac 100644
--- a/code/modules/research/designs/mining_designs.dm
+++ b/code/modules/research/designs/mining_designs.dm
@@ -62,6 +62,26 @@
category = list("Mining Designs")
departmental_flags = DEPARTMENTAL_FLAG_CARGO
+/datum/design/plasteel_pick
+ name = "plasteel-tipped pickaxe"
+ desc = "A pickaxe with a plasteel pick head. Less robust at cracking rock walls and digging up dirt than the titanium pickaxe, but better at cracking open skulls."
+ id = "plasteel_pick"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL=2000, MAT_PLASMA=2000)
+ build_path = /obj/item/pickaxe/plasteel
+ category = list("Mining Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_CARGO
+
+/datum/design/titanium_pick
+ name = "titanium-tipped pickaxe"
+ desc = "A pickaxe with a titanium pick head. Extremely robust at cracking rock walls and digging up dirt, but less than the plasteel pickaxe at cracking open skulls."
+ id = "titanium_pick"
+ build_type = PROTOLATHE
+ materials = list(MAT_TITANIUM = 4000)
+ build_path = /obj/item/pickaxe/titanium
+ category = list("Mining Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_CARGO
+
/datum/design/jackhammer
name = "Sonic Jackhammer"
desc = "Essentially a handheld planet-cracker. Can drill through walls with ease as well."
diff --git a/code/modules/research/nanites/public_chamber.dm b/code/modules/research/nanites/public_chamber.dm
index 76392c66e9..4d30d091ea 100644
--- a/code/modules/research/nanites/public_chamber.dm
+++ b/code/modules/research/nanites/public_chamber.dm
@@ -163,7 +163,7 @@
return
if(L.mob_biotypes & (MOB_ORGANIC | MOB_UNDEAD))
inject_nanites(attacker)
-
+5
/obj/machinery/public_nanite_chamber/open_machine()
if(state_open)
return FALSE
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 58aa922936..66d51fb168 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -190,7 +190,7 @@
description = "A refresher course on modern engineering technology."
prereq_ids = list("base")
design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin",
- "atmosalerts", "atmos_control", "recycler", "autolathe", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod",
+ "atmosalerts", "atmos_control", "recycler", "autolathe", "autolathe_secure", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod",
"apc_control", "cell_charger", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 6000)
export_price = 5000
@@ -620,7 +620,7 @@
display_name = "Advanced Mining Technology"
description = "Efficiency Level 127" //dumb mc references
prereq_ids = list("basic_mining", "adv_engi", "adv_power", "adv_plasma")
- design_ids = list("drill_diamond", "jackhammer", "hypermod", "plasmacutter_adv", "ore_silo")
+ design_ids = list("drill_diamond", "jackhammer", "hypermod", "plasmacutter_adv", "ore_silo", "plasteel_pick", "titanium_pick")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -851,7 +851,7 @@
display_name = "Exosuit Weapon (LBX AC 10 \"Scattershot\")"
description = "An advanced piece of mech weaponry"
prereq_ids = list("ballistic_weapons")
- design_ids = list("mech_scattershot")
+ design_ids = list("mech_scattershot", "mech_scattershot_ammo")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -869,7 +869,7 @@
display_name = "Exosuit Weapon (FNX-99 \"Hades\" Carbine)"
description = "An advanced piece of mech weaponry"
prereq_ids = list("ballistic_weapons")
- design_ids = list("mech_carbine")
+ design_ids = list("mech_carbine", "mech_carbine_ammo")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -914,16 +914,16 @@
display_name = "Exosuit Weapon (SGL-6 Grenade Launcher)"
description = "An advanced piece of mech weaponry"
prereq_ids = list("explosive_weapons")
- design_ids = list("mech_grenade_launcher")
+ design_ids = list("mech_grenade_launcher", "mech_grenade_launcher_ammo")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
/datum/techweb_node/mech_missile_rack
id = "mech_missile_rack"
- display_name = "Exosuit Weapon (SRM-8 Missile Rack)"
+ display_name = "Exosuit Weapon (BRM-6 Missile Rack)"
description = "An advanced piece of mech weaponry"
prereq_ids = list("explosive_weapons")
- design_ids = list("mech_missile_rack")
+ design_ids = list("mech_missile_rack", "mech_missile_rack_ammo")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -932,7 +932,7 @@
display_name = "Exosuit Module (SOB-3 Clusterbang Launcher)"
description = "An advanced piece of mech weaponry"
prereq_ids = list("explosive_weapons")
- design_ids = list("clusterbang_launcher")
+ design_ids = list("clusterbang_launcher", "clusterbang_launcher_ammo")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -968,7 +968,7 @@
display_name = "Exosuit Weapon (\"Ultra AC 2\" LMG)"
description = "An advanced piece of mech weaponry"
prereq_ids = list("ballistic_weapons")
- design_ids = list("mech_lmg")
+ design_ids = list("mech_lmg", "mech_lmg_ammo")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
diff --git a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm
index 26e5f1a9c0..c80b4d972c 100644
--- a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm
+++ b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm
@@ -22,6 +22,8 @@
var/static/mutable_appearance/dais_overlay
var/obj/structure/opacity_blocker/sight_blocker
var/sight_blocker_distance = 1
+ var/uses
+ var/ashwalker_only = FALSE
/obj/structure/necropolis_gate/Initialize()
. = ..()
@@ -87,9 +89,13 @@
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/structure/necropolis_gate/attack_hand(mob/user)
- if(locked)
+ if(locked || uses == 0)
to_chat(user, "It's [open ? "stuck open":"locked"].")
return
+ if(ashwalker_only)
+ if(!(user.mind.assigned_role == "Ash Walker"))
+ to_chat(user, "The gate screeches in an incoherant language!")
+ return
toggle_the_gate(user)
return ..()
@@ -131,12 +137,18 @@
density = FALSE
sleep(5)
open = TRUE
+ if(uses && uses > 0)
+ uses -= 1
changing_openness = FALSE
return TRUE
/obj/structure/necropolis_gate/locked
locked = TRUE
+/obj/structure/necropolis_gate/ashwalker
+ uses = 1
+ ashwalker_only = TRUE
+
GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate)
/obj/structure/necropolis_gate/legion_gate
desc = "A tremendous, impossibly large gateway, set into a massive tower of stone."
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 0e7cba9776..bdf6e8cc87 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -168,7 +168,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list(
for(var/chem in ex.reagents_value)
var/value = ex.reagents_value[chem]
- msg += "[value] credits: received [ex.reagents_volume[chem]]u of [chem].\n"
+ msg += "[value > 0 ? "+" : ""][value] credits: received [ex.reagents_volume[chem]]u of [chem].\n"
SSshuttle.points += value
msg = copytext_char(msg, 1, MAX_MESSAGE_LEN)
diff --git a/code/modules/spells/spell_types/bloodcrawl.dm b/code/modules/spells/spell_types/bloodcrawl.dm
index e4c33380b2..49d73b445b 100644
--- a/code/modules/spells/spell_types/bloodcrawl.dm
+++ b/code/modules/spells/spell_types/bloodcrawl.dm
@@ -13,6 +13,7 @@
action_icon_state = "bloodcrawl"
action_background_icon_state = "bg_demon"
var/phased = 0
+ charge_max = 6
/obj/effect/proc_holder/spell/bloodcrawl/choose_targets(mob/user = usr)
for(var/obj/effect/decal/cleanable/target in range(range, get_turf(user)))
diff --git a/code/modules/spells/spell_types/summonitem.dm b/code/modules/spells/spell_types/summonitem.dm
index c4b184cc9b..d0e415fb2a 100644
--- a/code/modules/spells/spell_types/summonitem.dm
+++ b/code/modules/spells/spell_types/summonitem.dm
@@ -38,7 +38,7 @@
else
message = "You must hold the desired item in your hands to mark it for recall."
- else if(marked_item && marked_item in hand_items) //unlinking item to the spell
+ else if(marked_item && (marked_item in hand_items)) //unlinking item to the spell
message = "You remove the mark on [marked_item] to use elsewhere."
name = "Instant Summons"
marked_item = null
@@ -78,7 +78,7 @@
if(iscarbon(M)) //Edge case housekeeping
var/mob/living/carbon/C = M
- if(C.stomach_contents && item_to_retrieve in C.stomach_contents)
+ if(C.stomach_contents && (item_to_retrieve in C.stomach_contents))
C.stomach_contents -= item_to_retrieve
for(var/X in C.bodyparts)
var/obj/item/bodypart/part = X
diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm
index 77aa302f8c..5767e84c73 100644
--- a/code/modules/surgery/organs/heart.dm
+++ b/code/modules/surgery/organs/heart.dm
@@ -6,7 +6,7 @@
slot = ORGAN_SLOT_HEART
healing_factor = STANDARD_ORGAN_HEALING
- decay_factor = 2.5 * STANDARD_ORGAN_DECAY //designed to fail about 5 minutes after death
+ decay_factor = 2 * STANDARD_ORGAN_DECAY
low_threshold_passed = "Prickles of pain appear then die out from within your chest..."
high_threshold_passed = "Something inside your chest hurts, and the pain isn't subsiding. You notice yourself breathing far faster than before."
diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm
index 8ad293fbcb..bcc764d00a 100644
--- a/code/modules/surgery/organs/tongue.dm
+++ b/code/modules/surgery/organs/tongue.dm
@@ -30,39 +30,23 @@
/obj/item/organ/tongue/Initialize(mapload)
. = ..()
+ low_threshold_passed = "Your [name] feels a little sore."
+ low_threshold_cleared = "Your [name] soreness has subsided."
+ high_threshold_passed = "Your [name] is really starting to hurt."
+ high_threshold_cleared = "The pain of your [name] has subsided a little."
+ now_failing = "Your [name] feels like it's about to fall out!."
+ now_fixed = "The excruciating pain of your [name] has subsided."
languages_possible = languages_possible_base
/obj/item/organ/tongue/proc/handle_speech(datum/source, list/speech_args)
+ return
-/obj/item/organ/tongue/emp_act(severity)
+/obj/item/organ/tongue/applyOrganDamage(d, maximum = maxHealth)
. = ..()
- if(. & EMP_PROTECT_SELF)
- return
- if(organ_flags & ORGAN_SYNTHETIC)
- var/errormessage = list("Runtime in tongue.dm, line 39: Undefined operation \"zapzap ow my tongue\"", "afhsjifksahgjkaslfhashfjsak", "-1.#IND", "Graham's number", "inside you all along", "awaiting at least 1 approving review before merging this taste request")
- owner.say("The pH is appropriately [pick(errormessage)].")
-
-/obj/item/organ/tongue/applyOrganDamage(var/d, var/maximum = maxHealth)
-
- if(!d) //Micro-optimization.
- return
- if(maximum < damage)
- return
- damage = CLAMP(damage + d, 0, maximum)
- var/mess = check_damage_thresholds(owner)
- prev_damage = damage
- if(mess && owner)
- to_chat(owner, mess)
-
- if ((damage / maxHealth) > 1)
+ if (damage >= maxHealth)
to_chat(owner, "Your tongue is singed beyond recognition, and disintegrates!")
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Tongues lost to Fermi")
qdel(src)
- else if ((damage / maxHealth) > 0.85)
- to_chat(owner, "Your tongue feels like it's about to fall out!.")
- else if ((damage / maxHealth) > 0.5)
- to_chat(owner, "Your tongue is really starting to hurt.")
-
/obj/item/organ/tongue/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
@@ -311,6 +295,13 @@
maxHealth = 60 //It's robotic!
organ_flags = ORGAN_SYNTHETIC
+/obj/item/organ/tongue/cybernetic/emp_act(severity)
+ . = ..()
+ if(. & EMP_PROTECT_SELF)
+ return
+ var/errormessage = list("Runtime in tongue.dm, line 39: Undefined operation \"zapzap ow my tongue\"", "afhsjifksahgjkaslfhashfjsak", "-1.#IND", "Graham's number", "inside you all along", "awaiting at least 1 approving review before merging this taste request")
+ owner.say("The pH is appropriately [pick(errormessage)].", forced = "EMPed synthetic tongue")
+
/obj/item/organ/tongue/cybernetic/handle_speech(datum/source, list/speech_args)
speech_args[SPEECH_SPANS] |= SPAN_ROBOT
diff --git a/code/modules/uplink/uplink_items/uplink_ammo.dm b/code/modules/uplink/uplink_items/uplink_ammo.dm
index 0db1bc96f0..911aa1a32e 100644
--- a/code/modules/uplink/uplink_items/uplink_ammo.dm
+++ b/code/modules/uplink/uplink_items/uplink_ammo.dm
@@ -253,3 +253,17 @@
item = /obj/item/ammo_box/a762
cost = 1
include_modes = list(/datum/game_mode/nuclear)
+
+/datum/uplink_item/ammo/dark_gygax/bag
+ name = "Dark Gygax Ammo Bag"
+ desc = "A duffel bag containing ammo for three full reloads of the incendiary carbine and flash bang launcher that are equipped on a standard Dark Gygax exosuit."
+ item = /obj/item/storage/backpack/duffelbag/syndie/ammo/dark_gygax
+ cost = 4
+ include_modes = list(/datum/game_mode/nuclear)
+
+/datum/uplink_item/ammo/mauler/bag
+ name = "Mauler Ammo Bag"
+ desc = "A duffel bag containing ammo for three full reloads of the LMG, scattershot carbine, and SRM-8 missile laucher that are equipped on a standard Mauler exosuit."
+ item = /obj/item/storage/backpack/duffelbag/syndie/ammo/mauler
+ cost = 6
+ include_modes = list(/datum/game_mode/nuclear)
diff --git a/code/modules/vore/eating/belly_obj.dm b/code/modules/vore/eating/belly_obj.dm
index 460ea74225..e33f748292 100644
--- a/code/modules/vore/eating/belly_obj.dm
+++ b/code/modules/vore/eating/belly_obj.dm
@@ -190,7 +190,7 @@
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
var/sound/eating = GLOB.pred_vore_sounds[vore_sound]
SEND_SOUND(H,eating)
- else if(H && H in contents && H.client)
+ else if(H?.client && (H in contents))
var/sound/eating = GLOB.prey_vore_sounds[vore_sound]
SEND_SOUND(H,eating)
recent_sound = TRUE
@@ -246,7 +246,7 @@
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
var/sound/releasement = GLOB.pred_release_sounds[release_sound]
H.playsound_local(owner.loc, releasement, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
- else if(H && H in contents && H.client)
+ else if(H?.client && (H in contents))
var/sound/releasement = GLOB.prey_release_sounds[release_sound]
SEND_SOUND(H,releasement)
recent_sound = TRUE
@@ -302,7 +302,7 @@
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
var/sound/releasement = GLOB.pred_release_sounds[release_sound]
H.playsound_local(owner.loc, releasement, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
- else if(H && H in contents && H.client)
+ else if(H?.client && (H in contents))
var/sound/releasement = GLOB.prey_release_sounds[release_sound]
SEND_SOUND(H,releasement)
recent_sound = TRUE
@@ -364,7 +364,7 @@
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
var/sound/eating = GLOB.pred_vore_sounds[vore_sound]
H.playsound_local(owner.loc, eating, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
- else if(H && H in contents && H.client)
+ else if(H?.client && (H in contents))
var/sound/eating = GLOB.prey_vore_sounds[vore_sound]
SEND_SOUND(H,eating)
recent_sound = TRUE
@@ -586,7 +586,7 @@
for(var/mob/living/H in hearing_mobs)
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
H.playsound_local(owner.loc, pred_struggle_snuggle, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
- else if(H && H in contents && H.client)
+ else if(H && H.client && (H in contents))
SEND_SOUND(H,prey_struggle_snuggle)
else
diff --git a/code/modules/vore/eating/bellymodes.dm b/code/modules/vore/eating/bellymodes.dm
index 6942a2d5a9..ea15892a30 100644
--- a/code/modules/vore/eating/bellymodes.dm
+++ b/code/modules/vore/eating/bellymodes.dm
@@ -195,7 +195,7 @@
for(var/mob/living/H in hearing_mobs)
if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
SEND_SOUND(H,pred_digest)
- else if(H && H in contents && H.client)
+ else if(H?.client && (H in contents))
SEND_SOUND(H,prey_digest)
//No digestion protection for megafauna.
diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm
index 59c6a321e6..3d045ba31e 100644
--- a/code/modules/zombie/organs.dm
+++ b/code/modules/zombie/organs.dm
@@ -45,7 +45,9 @@
if(!owner)
return
if(!(src in owner.internal_organs))
- Remove()
+ Remove(owner)
+ if(owner.mob_biotypes & MOB_MINERAL)//does not process in inorganic things
+ return
if (causes_damage && !iszombie(owner) && owner.stat != DEAD)
owner.adjustToxLoss(1)
if (prob(10))
diff --git a/dependencies.sh b/dependencies.sh
index a2f6873a32..488504b288 100644
--- a/dependencies.sh
+++ b/dependencies.sh
@@ -23,4 +23,4 @@ export NODE_VERSION=12
export PHP_VERSION=5.6
# SpacemanDMM git tag
-export SPACEMAN_DMM_VERSION=suite-1.0
+export SPACEMAN_DMM_VERSION=suite-1.2
diff --git a/html/changelogs/AutoChangeLog-pr-10704.yml b/html/changelogs/AutoChangeLog-pr-10704.yml
new file mode 100644
index 0000000000..1acd46b51f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10704.yml
@@ -0,0 +1,4 @@
+author: "nemvar"
+delete-after: True
+changes:
+ - code_imp: "Slight changes the self-repair borg module. It no longer references the borg that owns it."
diff --git a/html/changelogs/AutoChangeLog-pr-10792.yml b/html/changelogs/AutoChangeLog-pr-10792.yml
new file mode 100644
index 0000000000..78c86a838a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10792.yml
@@ -0,0 +1,4 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - bugfix: "Odysseus chem synthesizing now works again."
diff --git a/html/changelogs/AutoChangeLog-pr-10857.yml b/html/changelogs/AutoChangeLog-pr-10857.yml
new file mode 100644
index 0000000000..ae8c5f6ac0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10857.yml
@@ -0,0 +1,4 @@
+author: "Seris02"
+delete-after: True
+changes:
+ - rscadd: "Added naked hallucination"
diff --git a/html/changelogs/AutoChangeLog-pr-10916.yml b/html/changelogs/AutoChangeLog-pr-10916.yml
new file mode 100644
index 0000000000..05d9b007b1
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10916.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - balance: "Projectiles now always hit chest if targeting chest, snipers have 100% targeting zone accuracy. All other cases are unchanged."
diff --git a/html/changelogs/AutoChangeLog-pr-10923.yml b/html/changelogs/AutoChangeLog-pr-10923.yml
new file mode 100644
index 0000000000..0fd9a0f14e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10923.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Nerfed cargo passive points generation from 500 to 125 creds per minute."
diff --git a/html/changelogs/AutoChangeLog-pr-10934.yml b/html/changelogs/AutoChangeLog-pr-10934.yml
new file mode 100644
index 0000000000..61ef7ec04f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10934.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - refactor: "Refactored ghostreading/etc"
diff --git a/html/changelogs/AutoChangeLog-pr-10940.yml b/html/changelogs/AutoChangeLog-pr-10940.yml
new file mode 100644
index 0000000000..c0bbfc371a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10940.yml
@@ -0,0 +1,5 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - balance: "Some reagent holders (such as cigarettes, food) are not suitable for reagents export anymore, while unprocessed botany crops will only net 1/3 of the standard reagents values."
+ - bugfix: "Export scanners now include the reagents value in the price report."
diff --git a/html/changelogs/AutoChangeLog-pr-10947.yml b/html/changelogs/AutoChangeLog-pr-10947.yml
new file mode 100644
index 0000000000..a6f1fb1344
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10947.yml
@@ -0,0 +1,4 @@
+author: "nemvar"
+delete-after: True
+changes:
+ - bugfix: "Trash from food now gets generated at the location of the food item, instead of in the hands of the eater."
diff --git a/html/changelogs/AutoChangeLog-pr-10949.yml b/html/changelogs/AutoChangeLog-pr-10949.yml
new file mode 100644
index 0000000000..3c7000a0e1
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10949.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - bugfix: "reactive repulse armor now has an item limit"
diff --git a/html/changelogs/AutoChangeLog-pr-10970.yml b/html/changelogs/AutoChangeLog-pr-10970.yml
new file mode 100644
index 0000000000..7182c5f6a6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10970.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - balance: "Public autolathes can no longer be hacked."
diff --git a/html/changelogs/AutoChangeLog-pr-10980.yml b/html/changelogs/AutoChangeLog-pr-10980.yml
new file mode 100644
index 0000000000..3701aea6e1
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10980.yml
@@ -0,0 +1,7 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - rscadd: "Medical locked crates"
+ - balance: "Russian gear crates have less gear in some cases but all will cost more"
+ - bugfix: "Medical locked crates that were not locked"
+ - spellcheck: "Crates that were out of date are corrected"
diff --git a/html/changelogs/AutoChangeLog-pr-11011.yml b/html/changelogs/AutoChangeLog-pr-11011.yml
new file mode 100644
index 0000000000..d0a7b916f7
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11011.yml
@@ -0,0 +1,4 @@
+author: "Tlaltecuhtli, ported by Hatterhat"
+delete-after: True
+changes:
+ - balance: "Ripley, Firefighter, Odysseus and H.O.N.K. mechs now also use scanning modules and capacitors on construction. This means that they also gain reduced power consumption and EMP protection from higher-tier stock parts."
diff --git a/html/changelogs/AutoChangeLog-pr-11013.yml b/html/changelogs/AutoChangeLog-pr-11013.yml
new file mode 100644
index 0000000000..a9806d796d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11013.yml
@@ -0,0 +1,5 @@
+author: "r4d6"
+delete-after: True
+changes:
+ - rscadd: "Added Plasteel Pickaxe"
+ - rscadd: "Added Titanium Pickaxe"
diff --git a/html/changelogs/AutoChangeLog-pr-11028.yml b/html/changelogs/AutoChangeLog-pr-11028.yml
new file mode 100644
index 0000000000..de94b1d35f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11028.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - tweak: "Meat wheat no longer has blood"
diff --git a/html/changelogs/AutoChangeLog-pr-11040.yml b/html/changelogs/AutoChangeLog-pr-11040.yml
new file mode 100644
index 0000000000..cc0514517b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11040.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Further mob holder fixes."
diff --git a/html/changelogs/AutoChangeLog-pr-11042.yml b/html/changelogs/AutoChangeLog-pr-11042.yml
new file mode 100644
index 0000000000..4238f76b75
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11042.yml
@@ -0,0 +1,4 @@
+author: "Arturlang"
+delete-after: True
+changes:
+ - balance: "The pandemic can no longer make vaccines or synthblood as quickly."
diff --git a/html/changelogs/AutoChangeLog-pr-11045.yml b/html/changelogs/AutoChangeLog-pr-11045.yml
new file mode 100644
index 0000000000..9e3e0a9ee4
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11045.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - bugfix: "Flat guns can no longer be suppressed"
diff --git a/html/changelogs/AutoChangeLog-pr-11046.yml b/html/changelogs/AutoChangeLog-pr-11046.yml
new file mode 100644
index 0000000000..c40286e901
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11046.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - tweak: "replaced stickmans .45 caliber with 10mm, for consistency."
diff --git a/html/changelogs/AutoChangeLog-pr-11047.yml b/html/changelogs/AutoChangeLog-pr-11047.yml
new file mode 100644
index 0000000000..5bc42d1219
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11047.yml
@@ -0,0 +1,5 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - tweak: "Meatwheat and Oats now have rarity"
+ - balance: "Oats now have at lest 50% more flour in them"
diff --git a/html/changelogs/AutoChangeLog-pr-11048.yml b/html/changelogs/AutoChangeLog-pr-11048.yml
new file mode 100644
index 0000000000..77af926906
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11048.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - balance: "BDM now uses a PKA rather then a normal KA"
diff --git a/html/changelogs/AutoChangeLog-pr-11051.yml b/html/changelogs/AutoChangeLog-pr-11051.yml
new file mode 100644
index 0000000000..8ac7939b00
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11051.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - balance: "hand teleporters now require 30 deciseconds of still movement by the user to dispel portals. there's a beam effect too."
diff --git a/html/changelogs/AutoChangeLog-pr-11053.yml b/html/changelogs/AutoChangeLog-pr-11053.yml
new file mode 100644
index 0000000000..a3c2eb29fa
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11053.yml
@@ -0,0 +1,5 @@
+author: "keronshb"
+delete-after: True
+changes:
+ - rscadd: "Added burn and knockback to stunhand during HALOS on cult."
+ - balance: "Added burn and knockback to stunhand during HALOS on cult."
diff --git a/html/changelogs/AutoChangeLog-pr-11056.yml b/html/changelogs/AutoChangeLog-pr-11056.yml
new file mode 100644
index 0000000000..b56efb3557
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11056.yml
@@ -0,0 +1,4 @@
+author: "necromanceranne"
+delete-after: True
+changes:
+ - rscdel: "Bullets causing bleed rates equal to unmitigated damage through all forms of defense."
diff --git a/html/changelogs/AutoChangeLog-pr-11060.yml b/html/changelogs/AutoChangeLog-pr-11060.yml
new file mode 100644
index 0000000000..c78f03a26d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11060.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - balance: "Sort of a bugfix but cult blood magic and all guns now respect stamina softcrit."
diff --git a/html/changelogs/AutoChangeLog-pr-11061.yml b/html/changelogs/AutoChangeLog-pr-11061.yml
new file mode 100644
index 0000000000..5225edc141
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11061.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - tweak: "Gang tower shield is no longer transparent"
diff --git a/html/changelogs/AutoChangeLog-pr-11062.yml b/html/changelogs/AutoChangeLog-pr-11062.yml
new file mode 100644
index 0000000000..b9bc85b1c1
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11062.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - balance: "Organ healing rate doubled. Organ decay rate halved to match its define (15 minutes for full decay, so at around 8-10 minutes it'll be really fucked)."
diff --git a/html/changelogs/AutoChangeLog-pr-11063.yml b/html/changelogs/AutoChangeLog-pr-11063.yml
new file mode 100644
index 0000000000..c729fb5ed9
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11063.yml
@@ -0,0 +1,4 @@
+author: "Zellular"
+delete-after: True
+changes:
+ - tweak: "Tweaked the movement state for the pupdozer's eyes"
diff --git a/html/changelogs/AutoChangeLog-pr-11070.yml b/html/changelogs/AutoChangeLog-pr-11070.yml
new file mode 100644
index 0000000000..3c923bddb0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11070.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - tweak: "Storage now caches max screen size and only stores when being opened by a non ghost, meaning ghosts will no longer distort living player screens when viewing storage."
diff --git a/html/changelogs/AutoChangeLog-pr-11071.yml b/html/changelogs/AutoChangeLog-pr-11071.yml
new file mode 100644
index 0000000000..e8581b325e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11071.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed being unable to dump a trash bag's contents directly into disposal bins."
diff --git a/html/changelogs/AutoChangeLog-pr-11072.yml b/html/changelogs/AutoChangeLog-pr-11072.yml
new file mode 100644
index 0000000000..ab21d91e19
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11072.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Doubled the halved flavor text maximum length."
diff --git a/html/changelogs/AutoChangeLog-pr-11073.yml b/html/changelogs/AutoChangeLog-pr-11073.yml
new file mode 100644
index 0000000000..078c5fb300
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11073.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Reduced tongue organ damage and tasting pH message spam."
diff --git a/html/changelogs/AutoChangeLog-pr-11075.yml b/html/changelogs/AutoChangeLog-pr-11075.yml
new file mode 100644
index 0000000000..0eb612a81e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11075.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed agent IDs not registering the inputted name. Thanks MrPerson."
diff --git a/html/changelogs/AutoChangeLog-pr-11076.yml b/html/changelogs/AutoChangeLog-pr-11076.yml
new file mode 100644
index 0000000000..e0f187a038
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11076.yml
@@ -0,0 +1,4 @@
+author: "nemvar"
+delete-after: True
+changes:
+ - code_imp: "Changed mob biotypes from lists to flags."
diff --git a/html/changelogs/AutoChangeLog-pr-11079.yml b/html/changelogs/AutoChangeLog-pr-11079.yml
new file mode 100644
index 0000000000..b613b6c867
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11079.yml
@@ -0,0 +1,4 @@
+author: "Arturlang"
+delete-after: True
+changes:
+ - tweak: "Valentines can now be converted by bloodsuckers"
diff --git a/html/changelogs/AutoChangeLog-pr-11081.yml b/html/changelogs/AutoChangeLog-pr-11081.yml
new file mode 100644
index 0000000000..2fcb15b7aa
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11081.yml
@@ -0,0 +1,4 @@
+author: "Detective-Google"
+delete-after: True
+changes:
+ - bugfix: "valentines candy no longer prefbreaks"
diff --git a/html/changelogs/AutoChangeLog-pr-11082.yml b/html/changelogs/AutoChangeLog-pr-11082.yml
new file mode 100644
index 0000000000..89d9b4ca52
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11082.yml
@@ -0,0 +1,4 @@
+author: "Hatterhat"
+delete-after: True
+changes:
+ - rscadd: "Preservahyde! Made with water, bromine, and formaldehyde, it doesn't decay into histamine. Instead, it just prevents your organs from rotting into nothing."
diff --git a/html/changelogs/AutoChangeLog-pr-11083.yml b/html/changelogs/AutoChangeLog-pr-11083.yml
new file mode 100644
index 0000000000..757d9fcb63
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11083.yml
@@ -0,0 +1,4 @@
+author: "Hatterhat"
+delete-after: True
+changes:
+ - balance: "You can now purify eldritch longswords with a bible. This creates purified longswords, which do not have anti-magic properties, but are still good for swinging at cultists."
diff --git a/html/changelogs/AutoChangeLog-pr-11086.yml b/html/changelogs/AutoChangeLog-pr-11086.yml
new file mode 100644
index 0000000000..e11113e71c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11086.yml
@@ -0,0 +1,6 @@
+author: "YakumoChen"
+delete-after: True
+changes:
+ - imageadd: "Rings look nicer. Sprites used from RP."
+ - imageadd: "Ring on-hands. Diamond rings sparkle!"
+ - tweak: "You can now propose using a diamond ring in your hand."
diff --git a/html/changelogs/AutoChangeLog-pr-11087.yml b/html/changelogs/AutoChangeLog-pr-11087.yml
new file mode 100644
index 0000000000..179ef6a2b7
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11087.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed solar panels/trackers (de)construction being a bit wonky."
diff --git a/html/changelogs/AutoChangeLog-pr-11090.yml b/html/changelogs/AutoChangeLog-pr-11090.yml
new file mode 100644
index 0000000000..698306fdb6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11090.yml
@@ -0,0 +1,4 @@
+author: "Seris02"
+delete-after: True
+changes:
+ - rscadd: "rest hotkey"
diff --git a/html/changelogs/AutoChangeLog-pr-11091.yml b/html/changelogs/AutoChangeLog-pr-11091.yml
new file mode 100644
index 0000000000..5d43d7dbdf
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11091.yml
@@ -0,0 +1,5 @@
+author: "BlueWildrose"
+delete-after: True
+changes:
+ - bugfix: "podpeople tail wagging"
+ - tweak: "lifebringer ghost role fixes"
diff --git a/html/changelogs/AutoChangeLog-pr-11093.yml b/html/changelogs/AutoChangeLog-pr-11093.yml
new file mode 100644
index 0000000000..4815818b0d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11093.yml
@@ -0,0 +1,5 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed something about slime blood and the law of conservation of mass."
+ - bugfix: "Fixed flypeople being emetic machine guns."
diff --git a/html/changelogs/AutoChangeLog-pr-11094.yml b/html/changelogs/AutoChangeLog-pr-11094.yml
new file mode 100644
index 0000000000..a6db5bd93f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11094.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - tweak: "Cosmic winter coat now glows like the bedsheet, and holds normal winter coat gear"
diff --git a/html/changelogs/AutoChangeLog-pr-11101.yml b/html/changelogs/AutoChangeLog-pr-11101.yml
new file mode 100644
index 0000000000..5305e2b923
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11101.yml
@@ -0,0 +1,4 @@
+author: "coiax"
+delete-after: True
+changes:
+ - rscadd: "Admin and event only pair pinpointers! They come in a box of two, and each pinpointer will always point at its corresponding pair. Aww."
diff --git a/html/changelogs/AutoChangeLog-pr-11103.yml b/html/changelogs/AutoChangeLog-pr-11103.yml
new file mode 100644
index 0000000000..f38e23f76e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11103.yml
@@ -0,0 +1,5 @@
+author: "PersianXerxes"
+delete-after: True
+changes:
+ - rscadd: "Better clarified the comment explaining the contraband tag."
+ - tweak: "Cargo nuclear defusal kits now require an emag'd drop pod console to be purchased."
diff --git a/html/changelogs/AutoChangeLog-pr-11104.yml b/html/changelogs/AutoChangeLog-pr-11104.yml
new file mode 100644
index 0000000000..205af650a9
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11104.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - server: "Express console is now logging what it buys, like the normal console should"
diff --git a/html/changelogs/AutoChangeLog-pr-11105.yml b/html/changelogs/AutoChangeLog-pr-11105.yml
new file mode 100644
index 0000000000..0c7ac7b1e6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11105.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - bugfix: "Crabs are now made of crab meat."
diff --git a/html/changelogs/AutoChangeLog-pr-11108.yml b/html/changelogs/AutoChangeLog-pr-11108.yml
new file mode 100644
index 0000000000..c8bed79399
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11108.yml
@@ -0,0 +1,4 @@
+author: "Seris02"
+delete-after: True
+changes:
+ - rscadd: "hsl instead of sum of rgb for spraycan lum check"
diff --git a/html/changelogs/AutoChangeLog-pr-11111.yml b/html/changelogs/AutoChangeLog-pr-11111.yml
new file mode 100644
index 0000000000..4e947ed297
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11111.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed virology being unable to be done with synthetic blood."
diff --git a/html/changelogs/AutoChangeLog-pr-11112.yml b/html/changelogs/AutoChangeLog-pr-11112.yml
new file mode 100644
index 0000000000..f54e2e0192
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11112.yml
@@ -0,0 +1,9 @@
+author: "necromanceranne"
+delete-after: True
+changes:
+ - balance: "Reverted #9092, crew mecha no longer spawn with tracking beacons."
+ - balance: "[Port] Mecha ballistics weapons now require ammo created from an Exosuit Fabricator or the Security Protolathe, though they will start with a full magazine and in most cases enough for one full reload. Reloading these weapons no longer chunks your power cell. Clown (and mime) mecha equipment have not changed."
+ - balance: "[Port] The SRM-8 Missile Launcher has been replaced with the BRM-6 Breaching Missile Launcher in techwebs (Nukie Mauler remains equipped with the SRM-8)."
+ - balance: "[Port] Both Missile Launchers and the Clusterbang Launcher do not have an ammo cache, and cannot be reloaded by the pilot. Once the initial loaded ammo has been spent, you can use the appropriate ammo box to load the weapon directly."
+ - rscadd: "[Port] Utility mechs that have a clamp equipped can load ammo from their own cargo hold into other mechs."
+ - rscadd: "[Port] Nuke Ops can purchase spare ammo duffel bags for their mecha weapons, should they run low."
diff --git a/html/changelogs/AutoChangeLog-pr-11114.yml b/html/changelogs/AutoChangeLog-pr-11114.yml
new file mode 100644
index 0000000000..7d56933c65
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11114.yml
@@ -0,0 +1,6 @@
+author: "Psody-Mordheim"
+delete-after: True
+changes:
+ - rscadd: "You can now make synth-flesh with synthetic blood."
+ - rscadd: "You can now make synthetic blood via mixing saline glucose, iron, stable plasma and heating it to 350 temp."
+ - rscadd: "You can mix synthetic blood and cryoxadone to create synth-meat in addition to normal blood."
diff --git a/html/changelogs/AutoChangeLog-pr-11119.yml b/html/changelogs/AutoChangeLog-pr-11119.yml
new file mode 100644
index 0000000000..4a0dc59c65
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11119.yml
@@ -0,0 +1,6 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - rscdel: "Renamed \"blaster carbine\" and \"blaster rifles\" back to \"energy gun\" and \"laser gun\" respectively"
+ - bugfix: "Fixed magnetic rifles & co being inconsistent with printed energy guns and start with an empty power cell."
+ - imagedel: "Reverted practice laser gun sprites back to their former glory. Mostly."
diff --git a/html/changelogs/AutoChangeLog-pr-11120.yml b/html/changelogs/AutoChangeLog-pr-11120.yml
new file mode 100644
index 0000000000..64a435146c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11120.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed sprint buffer cost and regen being rounded down."
diff --git a/html/changelogs/AutoChangeLog-pr-11131.yml b/html/changelogs/AutoChangeLog-pr-11131.yml
new file mode 100644
index 0000000000..9a14049c2f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11131.yml
@@ -0,0 +1,4 @@
+author: "Seris02"
+delete-after: True
+changes:
+ - balance: "bloodcrawl's cooldown"
diff --git a/html/changelogs/AutoChangeLog-pr-11134.yml b/html/changelogs/AutoChangeLog-pr-11134.yml
new file mode 100644
index 0000000000..8ec6c97164
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11134.yml
@@ -0,0 +1,4 @@
+author: "Hatterhat"
+delete-after: True
+changes:
+ - bugfix: "mechs with stock parts now have icons"
diff --git a/html/changelogs/AutoChangeLog-pr-11138.yml b/html/changelogs/AutoChangeLog-pr-11138.yml
new file mode 100644
index 0000000000..fd0e53bb73
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11138.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - tweak: "the game's built in autoclicker aka CanMobAutoclick no longer triggers client/Click()'s anti clickspam guard."
diff --git a/icons/mecha/mech_construction.dmi b/icons/mecha/mech_construction.dmi
index 42cc8eeb57..d7f0f3e054 100644
Binary files a/icons/mecha/mech_construction.dmi and b/icons/mecha/mech_construction.dmi differ
diff --git a/icons/mecha/mecha_ammo.dmi b/icons/mecha/mecha_ammo.dmi
new file mode 100644
index 0000000000..63bc38cfa7
Binary files /dev/null and b/icons/mecha/mecha_ammo.dmi differ
diff --git a/icons/mecha/mecha_equipment.dmi b/icons/mecha/mecha_equipment.dmi
index 02c7984831..5e277af7cc 100644
Binary files a/icons/mecha/mecha_equipment.dmi and b/icons/mecha/mecha_equipment.dmi differ
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index 26f81b70df..7a28827903 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi
index 6843bac6bf..070034d778 100644
Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ
diff --git a/icons/mob/hands.dmi b/icons/mob/hands.dmi
index b69c6c88b1..63263b835c 100644
Binary files a/icons/mob/hands.dmi and b/icons/mob/hands.dmi differ
diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi
index e329720cf7..1ff87b26e4 100644
Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ
diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi
index ca81686e94..ecb66d0119 100644
Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ
diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi
index c68728a91f..20fe8272da 100644
Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ
diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi
index a7593e4a55..f2e98aff32 100644
Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index 668f3388ce..92e76f78bb 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ
diff --git a/icons/obj/ring.dmi b/icons/obj/ring.dmi
index 52fe249394..e24f1fab4c 100644
Binary files a/icons/obj/ring.dmi and b/icons/obj/ring.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index 4aa54a2308..a92af16e96 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/interface/interface.dm b/interface/interface.dm
index ecd13e1f03..2b33ebb5e8 100644
--- a/interface/interface.dm
+++ b/interface/interface.dm
@@ -8,7 +8,7 @@
if(wikiurl)
if(query)
var/output = wikiurl + "?search=" + query
- src << link(output)
+ src << link(output)
output = wikiurltg + "/index.php?title=Special%3ASearch&profile=default&search=" + query
src << link(output)
else if (query != null)
@@ -125,6 +125,7 @@ Hotkey-Mode: (hotkey-mode must be on)
\tt = say
\to = OOC
\tb = resist
+\tv = rest
\th = stop pulling
\tx = swap-hand
\tz = activate held object (or y)
@@ -184,6 +185,7 @@ Hotkey-Mode: (hotkey-mode must be on)
\td = right
\tw = up
\tq = unequip active module
+\tv = rest
\th = stop pulling
\tm = me
\tt = say
diff --git a/modular_citadel/code/modules/admin/chat_commands.dm b/modular_citadel/code/modules/admin/chat_commands.dm
index 501e0fa25a..ddac7b5953 100644
--- a/modular_citadel/code/modules/admin/chat_commands.dm
+++ b/modular_citadel/code/modules/admin/chat_commands.dm
@@ -14,6 +14,13 @@
saltresult += "[saltprimarysubject] [saltsecondarysubject]"
return "[saltresult]!"
+/datum/tgs_chat_command/valentine
+ name = "valentine"
+ help_text = "Get a random flirt line."
+
+/datum/tgs_chat_command/valentine/Run(datum/tgs_chat_user/sender, params)
+ return "[pick(GLOB.flirts)]"
+
/datum/tgs_chat_command/despacito
name = "despacito" //someone please high effort this sometime and make it a full on ytdl search
help_text = "This is so sad."
diff --git a/modular_citadel/code/modules/arousal/genitals.dm b/modular_citadel/code/modules/arousal/genitals.dm
index b7f178bca5..d5191b0532 100644
--- a/modular_citadel/code/modules/arousal/genitals.dm
+++ b/modular_citadel/code/modules/arousal/genitals.dm
@@ -20,16 +20,13 @@
var/linked_organ_slot //used for linking an apparatus' organ to its other half on update_link().
var/layer_index = GENITAL_LAYER_INDEX //Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
-/obj/item/organ/genital/Initialize(mapload, mob/living/carbon/human/H)
+/obj/item/organ/genital/Initialize(mapload, do_update = TRUE)
. = ..()
if(fluid_id)
- create_reagents(fluid_max_volume)
+ create_reagents(fluid_max_volume, NONE, NO_REAGENTS_VALUE)
if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
reagents.add_reagent(fluid_id, fluid_max_volume)
- if(H)
- get_features(H)
- Insert(H)
- else
+ if(do_update)
update()
/obj/item/organ/genital/proc/set_aroused_state(new_state)
@@ -221,7 +218,9 @@
/mob/living/carbon/human/proc/give_genital(obj/item/organ/genital/G)
if(!dna || (NOGENITALS in dna.species.species_traits) || getorganslot(initial(G.slot)))
return FALSE
- G = new G(null, src)
+ G = new G(null, FALSE)
+ G.get_features(src)
+ G.Insert(src)
return G
/obj/item/organ/genital/proc/get_features(mob/living/carbon/human/H)
@@ -317,6 +316,7 @@
genital_overlay.layer = -GENITALS_EXPOSED_LAYER
LAZYADD(fully_exposed, genital_overlay) // to be added to a layer with higher priority than clothes, hence the name of the bitflag.
else
+ genital_overlay.layer = -layers_num[layer]
standing += genital_overlay
if(LAZYLEN(standing))
diff --git a/modular_citadel/code/modules/arousal/organs/breasts.dm b/modular_citadel/code/modules/arousal/organs/breasts.dm
index dc7923e448..f3ce834838 100644
--- a/modular_citadel/code/modules/arousal/organs/breasts.dm
+++ b/modular_citadel/code/modules/arousal/organs/breasts.dm
@@ -22,8 +22,8 @@
var/cached_size //these two vars pertain size modifications and so should be expressed in NUMBERS.
var/prev_size //former cached_size value, to allow update_size() to early return should be there no significant changes.
-/obj/item/organ/genital/breasts/Initialize(mapload, mob/living/carbon/human/H)
- if(!H)
+/obj/item/organ/genital/breasts/Initialize(mapload, do_update = TRUE)
+ if(do_update)
cached_size = breast_values[size]
prev_size = cached_size
return ..()
diff --git a/modular_citadel/code/modules/mob/cit_emotes.dm b/modular_citadel/code/modules/mob/cit_emotes.dm
index d0ad0d3232..2be83733e5 100644
--- a/modular_citadel/code/modules/mob/cit_emotes.dm
+++ b/modular_citadel/code/modules/mob/cit_emotes.dm
@@ -14,13 +14,10 @@
emote_type = EMOTE_AUDIBLE
/datum/emote/living/insult/run_emote(mob/living/user, params)
- var/insult_message = ""
- var/miming = user.mind ? user.mind.miming : 0
- if(!user.is_muzzled())
- insult_message += pick_list_replacements(INSULTS_FILE, "insult_gen")
- message = insult_message
- else if(miming)
+ if(user.mind?.miming)
message = "creatively gesticulates."
+ else if(!user.is_muzzled())
+ message = pick_list_replacements(INSULTS_FILE, "insult_gen")
else
message = "muffles something."
. = ..()
@@ -36,7 +33,7 @@
sound = 'modular_citadel/sound/voice/scream_silicon.ogg'
if(iscyborg(user))
var/mob/living/silicon/robot/S = user
- if(S.cell.charge < 20)
+ if(S.cell?.charge < 20)
to_chat(S, "Scream module deactivated. Please recharge.")
return
S.cell.use(200)
diff --git a/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm b/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm
index 2c527ac713..49a8a26f35 100644
--- a/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -1,7 +1,3 @@
-/obj/item/gun/energy/e_gun
- name = "blaster carbine"
- desc = "A high powered particle blaster carbine with varitable setting for stunning or lethal applications."
-
/*/////////////////////////////////////////////////////////////////////////////////////////////
The Recolourable Energy Gun
*//////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/modular_citadel/code/modules/projectiles/guns/energy/laser.dm b/modular_citadel/code/modules/projectiles/guns/energy/laser.dm
deleted file mode 100644
index 76d7403d16..0000000000
--- a/modular_citadel/code/modules/projectiles/guns/energy/laser.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/obj/item/gun/energy/laser
- name = "blaster rifle"
- desc = "a high energy particle blaster, efficient and deadly."
-
-/obj/item/gun/energy/laser/practice
- icon = 'modular_citadel/icons/obj/guns/energy.dmi'
- icon_state = "laser-p"
- lefthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi'
- righthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi'
- ammo_x_offset = 1
- shaded_charge = 1
diff --git a/modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi b/modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi
deleted file mode 100644
index b438c7acee..0000000000
Binary files a/modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi and /dev/null differ
diff --git a/modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi b/modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi
deleted file mode 100644
index dda226b046..0000000000
Binary files a/modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi and /dev/null differ
diff --git a/modular_citadel/icons/mob/widerobot.dmi b/modular_citadel/icons/mob/widerobot.dmi
index 3f48c3902c..50c29bb75f 100644
Binary files a/modular_citadel/icons/mob/widerobot.dmi and b/modular_citadel/icons/mob/widerobot.dmi differ
diff --git a/modular_citadel/icons/obj/genitals/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi
index 4a92bffa2a..c074eaf306 100644
Binary files a/modular_citadel/icons/obj/genitals/penis_onmob.dmi and b/modular_citadel/icons/obj/genitals/penis_onmob.dmi differ
diff --git a/modular_citadel/icons/obj/guns/energy.dmi b/modular_citadel/icons/obj/guns/energy.dmi
deleted file mode 100644
index 482ec04d94..0000000000
Binary files a/modular_citadel/icons/obj/guns/energy.dmi and /dev/null differ
diff --git a/sound/weapons/bowdraw.wav b/sound/weapons/bowdraw.wav
new file mode 100644
index 0000000000..bba8a87e06
Binary files /dev/null and b/sound/weapons/bowdraw.wav differ
diff --git a/sound/weapons/bowfire.wav b/sound/weapons/bowfire.wav
new file mode 100644
index 0000000000..c079d43475
Binary files /dev/null and b/sound/weapons/bowfire.wav differ
diff --git a/tgstation.dme b/tgstation.dme
index e55c425c1c..638c23be5f 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -496,7 +496,6 @@
#include "code\datums\helper_datums\getrev.dm"
#include "code\datums\helper_datums\icon_snapshot.dm"
#include "code\datums\helper_datums\teleport.dm"
-#include "code\datums\helper_datums\topic_input.dm"
#include "code\datums\looping_sounds\_looping_sound.dm"
#include "code\datums\looping_sounds\item_sounds.dm"
#include "code\datums\looping_sounds\machinery_sounds.dm"
@@ -668,7 +667,6 @@
#include "code\game\machinery\magnet.dm"
#include "code\game\machinery\mass_driver.dm"
#include "code\game\machinery\navbeacon.dm"
-#include "code\game\machinery\newscaster.dm"
#include "code\game\machinery\PDApainter.dm"
#include "code\game\machinery\quantum_pad.dm"
#include "code\game\machinery\recharger.dm"
@@ -785,6 +783,7 @@
#include "code\game\mecha\equipment\tools\mining_tools.dm"
#include "code\game\mecha\equipment\tools\other_tools.dm"
#include "code\game\mecha\equipment\tools\work_tools.dm"
+#include "code\game\mecha\equipment\weapons\mecha_ammo.dm"
#include "code\game\mecha\equipment\weapons\weapons.dm"
#include "code\game\mecha\medical\medical.dm"
#include "code\game\mecha\medical\odysseus.dm"
@@ -2467,6 +2466,15 @@
#include "code\modules\modular_computers\hardware\printer.dm"
#include "code\modules\modular_computers\hardware\recharger.dm"
#include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm"
+#include "code\modules\newscaster\_news.dm"
+#include "code\modules\newscaster\feed_channel.dm"
+#include "code\modules\newscaster\feed_comment.dm"
+#include "code\modules\newscaster\feed_message.dm"
+#include "code\modules\newscaster\ghostread.dm"
+#include "code\modules\newscaster\news_network.dm"
+#include "code\modules\newscaster\newscaster_machine.dm"
+#include "code\modules\newscaster\newspaper.dm"
+#include "code\modules\newscaster\wanted_message.dm"
#include "code\modules\ninja\__ninjaDefines.dm"
#include "code\modules\ninja\energy_katana.dm"
#include "code\modules\ninja\ninja_event.dm"
@@ -2584,6 +2592,7 @@
#include "code\modules\projectiles\ammunition\ballistic\smg.dm"
#include "code\modules\projectiles\ammunition\ballistic\sniper.dm"
#include "code\modules\projectiles\ammunition\caseless\_caseless.dm"
+#include "code\modules\projectiles\ammunition\caseless\arrow.dm"
#include "code\modules\projectiles\ammunition\caseless\ferromagnetic.dm"
#include "code\modules\projectiles\ammunition\caseless\foam.dm"
#include "code\modules\projectiles\ammunition\caseless\misc.dm"
@@ -2614,6 +2623,7 @@
#include "code\modules\projectiles\boxes_magazines\external\toy.dm"
#include "code\modules\projectiles\boxes_magazines\internal\_cylinder.dm"
#include "code\modules\projectiles\boxes_magazines\internal\_internal.dm"
+#include "code\modules\projectiles\boxes_magazines\internal\bow.dm"
#include "code\modules\projectiles\boxes_magazines\internal\grenade.dm"
#include "code\modules\projectiles\boxes_magazines\internal\misc.dm"
#include "code\modules\projectiles\boxes_magazines\internal\revolver.dm"
@@ -2624,6 +2634,7 @@
#include "code\modules\projectiles\guns\energy.dm"
#include "code\modules\projectiles\guns\magic.dm"
#include "code\modules\projectiles\guns\ballistic\automatic.dm"
+#include "code\modules\projectiles\guns\ballistic\bow.dm"
#include "code\modules\projectiles\guns\ballistic\laser_gatling.dm"
#include "code\modules\projectiles\guns\ballistic\launchers.dm"
#include "code\modules\projectiles\guns\ballistic\magweapon.dm"
@@ -2676,6 +2687,7 @@
#include "code\modules\projectiles\projectile\energy\tesla.dm"
#include "code\modules\projectiles\projectile\magic\spellcard.dm"
#include "code\modules\projectiles\projectile\reusable\_reusable.dm"
+#include "code\modules\projectiles\projectile\reusable\arrow.dm"
#include "code\modules\projectiles\projectile\reusable\foam_dart.dm"
#include "code\modules\projectiles\projectile\reusable\magspear.dm"
#include "code\modules\projectiles\projectile\special\curse.dm"
@@ -3195,7 +3207,6 @@
#include "modular_citadel\code\modules\projectiles\guns\ballistic\rifles.dm"
#include "modular_citadel\code\modules\projectiles\guns\ballistic\spinfusor.dm"
#include "modular_citadel\code\modules\projectiles\guns\energy\energy_gun.dm"
-#include "modular_citadel\code\modules\projectiles\guns\energy\laser.dm"
#include "modular_citadel\code\modules\projectiles\projectiles\reusable.dm"
#include "modular_citadel\code\modules\reagents\chemistry\reagents\astrogen.dm"
#include "modular_citadel\code\modules\reagents\chemistry\reagents\eigentstasium.dm"