diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm
index fd2e56a53f..945ea515c7 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm
@@ -274,8 +274,7 @@
/area/ruin/powered/seedvault)
"Z" = (
/obj/item/disk/design_disk/plant_disk,
-/obj/machinery/autolathe{
- hacked = TRUE;
+/obj/machinery/autolathe/hacked{
desc = "This autolathe seems to have its safety light off."
},
/turf/open/floor/plasteel/freezer,
diff --git a/_maps/RandomRuins/SpaceRuins/arcade.dmm b/_maps/RandomRuins/SpaceRuins/arcade.dmm
new file mode 100644
index 0000000000..771c33c55b
--- /dev/null
+++ b/_maps/RandomRuins/SpaceRuins/arcade.dmm
@@ -0,0 +1,711 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/turf/open/floor/plating/asteroid,
+/area/ruin/powered)
+"c" = (
+/turf/closed/mineral/random/high_chance,
+/area/ruin/powered)
+"d" = (
+/turf/closed/wall/mineral/titanium/survival/pod,
+/area/ruin/powered)
+"e" = (
+/obj/machinery/computer/arcade,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"f" = (
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/machinery/vending/coffee,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"g" = (
+/obj/item/coin,
+/obj/item/toy/plush/random,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"h" = (
+/obj/effect/mob_spawn/human/corpse/assistant,
+/obj/effect/decal/cleanable/blood,
+/obj/item/toy/plush/random,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"i" = (
+/obj/machinery/light{
+ dir = 4
+ },
+/obj/item/toy/plush/random,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"j" = (
+/obj/machinery/light{
+ dir = 8
+ },
+/turf/open/floor/engine,
+/area/ruin/powered)
+"k" = (
+/obj/item/coin/gold,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"l" = (
+/turf/open/floor/engine,
+/area/ruin/powered)
+"m" = (
+/obj/item/coin/iron,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"n" = (
+/obj/item/toy/plush/random,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"o" = (
+/obj/item/kitchen/knife{
+ pixel_x = 5;
+ pixel_y = 11
+ },
+/obj/item/toy/plush/random,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"p" = (
+/turf/closed/wall/mineral/titanium/survival/nodiagonal,
+/area/ruin/powered)
+"q" = (
+/turf/open/floor/light/colour_cycle/dancefloor_b,
+/area/ruin/powered)
+"r" = (
+/turf/open/floor/light/colour_cycle/dancefloor_a,
+/area/ruin/powered)
+"s" = (
+/obj/machinery/door/airlock/external/glass,
+/obj/structure/fans/tiny,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"t" = (
+/obj/item/trash/chips,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"u" = (
+/obj/item/trash/cheesie,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"v" = (
+/obj/item/coin,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"w" = (
+/obj/item/coin/diamond,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"x" = (
+/obj/machinery/jukebox/disco/indestructible,
+/turf/open/floor/light/colour_cycle/dancefloor_b,
+/area/ruin/powered)
+"y" = (
+/obj/machinery/light,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"z" = (
+/obj/machinery/light{
+ dir = 4
+ },
+/turf/open/floor/engine,
+/area/ruin/powered)
+"A" = (
+/obj/machinery/door/airlock/external/glass,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"B" = (
+/obj/machinery/vending/cola/random,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"C" = (
+/obj/machinery/vending/snack/random,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"D" = (
+/obj/item/trash/can,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"E" = (
+/obj/item/trash/sosjerky,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"F" = (
+/obj/structure/closet/crate/trashcart,
+/turf/open/floor/plating/asteroid,
+/area/ruin/powered)
+"G" = (
+/obj/structure/chair/sofa/right,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"H" = (
+/obj/structure/chair/sofa/left,
+/obj/item/bedsheet/ian,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"I" = (
+/obj/item/aiModule/toyAI,
+/turf/open/floor/engine,
+/area/ruin/powered)
+"J" = (
+/obj/item/twohanded/dualsaber/toy,
+/turf/open/floor/light/colour_cycle/dancefloor_b,
+/area/ruin/powered)
+"K" = (
+/obj/item/gun/energy/pumpaction/toy,
+/turf/open/floor/engine,
+/area/ruin/powered)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+a
+a
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(3,1,1) = {"
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+a
+b
+b
+b
+b
+a
+a
+"}
+(4,1,1) = {"
+a
+a
+a
+b
+b
+b
+b
+b
+b
+b
+b
+a
+a
+b
+b
+b
+b
+b
+b
+a
+"}
+(5,1,1) = {"
+a
+a
+a
+b
+b
+c
+c
+c
+c
+b
+b
+b
+b
+b
+b
+c
+c
+c
+b
+b
+"}
+(6,1,1) = {"
+a
+a
+a
+b
+c
+c
+c
+c
+c
+b
+b
+b
+b
+c
+c
+c
+c
+c
+c
+b
+"}
+(7,1,1) = {"
+a
+a
+a
+b
+c
+c
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+c
+c
+c
+b
+"}
+(8,1,1) = {"
+a
+a
+a
+b
+c
+c
+d
+e
+j
+l
+l
+K
+j
+G
+B
+d
+c
+c
+b
+b
+"}
+(9,1,1) = {"
+a
+a
+a
+b
+c
+c
+d
+e
+k
+l
+v
+l
+l
+H
+C
+d
+c
+c
+b
+a
+"}
+(10,1,1) = {"
+a
+a
+b
+b
+c
+c
+d
+e
+l
+I
+l
+l
+l
+k
+B
+d
+c
+c
+b
+a
+"}
+(11,1,1) = {"
+a
+a
+b
+c
+c
+c
+d
+e
+l
+l
+w
+l
+y
+d
+d
+p
+c
+b
+b
+a
+"}
+(12,1,1) = {"
+a
+a
+b
+c
+c
+c
+d
+e
+m
+J
+r
+q
+l
+A
+l
+s
+b
+b
+b
+a
+"}
+(13,1,1) = {"
+a
+b
+b
+c
+c
+c
+d
+f
+l
+r
+x
+r
+l
+d
+d
+d
+b
+b
+b
+a
+"}
+(14,1,1) = {"
+a
+b
+b
+c
+c
+c
+d
+e
+l
+q
+r
+q
+D
+A
+l
+s
+b
+b
+b
+a
+"}
+(15,1,1) = {"
+a
+b
+b
+b
+c
+c
+d
+e
+t
+u
+l
+E
+y
+d
+d
+p
+b
+b
+b
+a
+"}
+(16,1,1) = {"
+a
+b
+b
+b
+c
+c
+d
+e
+g
+n
+t
+k
+l
+l
+B
+d
+c
+b
+b
+a
+"}
+(17,1,1) = {"
+a
+b
+b
+c
+c
+c
+d
+e
+h
+o
+D
+l
+D
+l
+C
+d
+c
+c
+b
+b
+"}
+(18,1,1) = {"
+a
+a
+b
+c
+c
+c
+d
+e
+i
+n
+E
+l
+z
+m
+B
+d
+c
+c
+c
+b
+"}
+(19,1,1) = {"
+a
+a
+b
+c
+c
+c
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+c
+c
+c
+b
+"}
+(20,1,1) = {"
+a
+a
+b
+b
+c
+c
+c
+c
+c
+c
+b
+F
+b
+c
+c
+c
+c
+c
+c
+b
+"}
+(21,1,1) = {"
+a
+a
+a
+b
+c
+c
+c
+c
+c
+c
+b
+b
+b
+c
+c
+c
+c
+c
+b
+b
+"}
+(22,1,1) = {"
+a
+a
+a
+b
+b
+c
+c
+c
+c
+b
+b
+b
+b
+b
+b
+c
+c
+b
+b
+a
+"}
+(23,1,1) = {"
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+a
+b
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(24,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+a
+a
+a
+"}
+(25,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+b
+b
+a
+a
+a
+a
+"}
diff --git a/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm b/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm
new file mode 100644
index 0000000000..c64050ce3a
--- /dev/null
+++ b/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm
@@ -0,0 +1,731 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/turf/open/floor/plating/asteroid,
+/area/ruin/powered)
+"c" = (
+/turf/closed/mineral/random/high_chance,
+/area/ruin/powered)
+"d" = (
+/turf/closed/wall/r_wall/rust,
+/area/ruin/powered)
+"e" = (
+/obj/machinery/mecha_part_fabricator,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"f" = (
+/turf/closed/wall/rust,
+/area/ruin/powered)
+"g" = (
+/obj/structure/table,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/stack/sheet/glass/fifty,
+/obj/item/stack/sheet/metal/fifty,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"h" = (
+/obj/machinery/mecha_part_fabricator,
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"i" = (
+/obj/structure/table,
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/item/stack/sheet/glass/fifty,
+/obj/item/stack/sheet/metal/fifty,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"j" = (
+/obj/structure/chair/sofa/right,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"k" = (
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"l" = (
+/obj/structure/chair/sofa/left,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"m" = (
+/obj/machinery/computer/rdconsole/production{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"n" = (
+/obj/effect/decal/cleanable/oil/streak,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"o" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"p" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"q" = (
+/obj/machinery/light{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/aug_manipulator,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"r" = (
+/obj/structure/table,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/organ/cyberimp/chest/reviver,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"s" = (
+/obj/structure/table,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/organ/cyberimp/arm/surgery,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"t" = (
+/obj/structure/table,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/storage/backpack/duffelbag/med/surgery,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"u" = (
+/obj/machinery/light{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"v" = (
+/obj/machinery/porta_turret/syndicate/energy{
+ mode = 1
+ },
+/turf/closed/wall/r_wall/rust,
+/area/ruin/powered)
+"w" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/computer/mech_bay_power_console{
+ dir = 4
+ },
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"x" = (
+/obj/effect/decal/cleanable/oil,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"y" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"z" = (
+/obj/structure/table,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/storage/belt/utility/full,
+/obj/item/clothing/glasses/welding,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"A" = (
+/obj/structure/table,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/mmi/posibrain{
+ pixel_y = 9
+ },
+/obj/item/mmi,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"B" = (
+/obj/structure/table/optable,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"C" = (
+/obj/machinery/mech_bay_recharge_port,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"D" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/mech_bay_recharge_floor,
+/area/ruin/powered)
+"E" = (
+/obj/machinery/computer/operating{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"F" = (
+/obj/structure/table,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/autosurgeon{
+ name = "rusted autosurgeon";
+ desc = "A device that automatically inserts an implant or organ into the user without the hassle of extensive surgery. It has a slot to insert an organ of implant. But this rusted version looks like it could only manage one implant....";
+ uses = 1
+ },
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"G" = (
+/obj/machinery/light,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/airalarm{
+ dir = 1;
+ pixel_y = -22
+ },
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"H" = (
+/obj/effect/decal/cleanable/oil,
+/obj/machinery/light,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"I" = (
+/obj/machinery/door/airlock/external/glass,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"J" = (
+/obj/machinery/atmospherics/components/unary/outlet_injector/on/layer1{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid,
+/area/ruin/powered)
+"K" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{
+ dir = 4
+ },
+/turf/closed/mineral/random/high_chance,
+/area/ruin/powered)
+"L" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{
+ dir = 4
+ },
+/turf/closed/wall/r_wall/rust,
+/area/ruin/powered)
+"M" = (
+/obj/structure/mecha_wreckage/ripley,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{
+ dir = 4
+ },
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"N" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{
+ dir = 4
+ },
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"O" = (
+/obj/machinery/turretid{
+ lethal = 1;
+ pixel_y = -25;
+ req_access = null
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/simple/cyan/hidden{
+ dir = 5
+ },
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"P" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/components/unary/vent_pump/on,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"Q" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{
+ dir = 1
+ },
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"R" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/simple/cyan/hidden,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"S" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{
+ dir = 9
+ },
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"T" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/atmospherics/components/unary/tank/air{
+ dir = 8
+ },
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"U" = (
+/obj/machinery/door/airlock/external/glass,
+/obj/structure/fans/tiny,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+"V" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/reagent_dispensers/fueltank,
+/turf/open/floor/plasteel,
+/area/ruin/powered)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(3,1,1) = {"
+a
+a
+a
+a
+b
+b
+c
+c
+c
+c
+J
+b
+b
+a
+a
+a
+a
+a
+a
+a
+"}
+(4,1,1) = {"
+a
+a
+a
+b
+c
+c
+c
+c
+c
+c
+K
+c
+b
+b
+b
+a
+a
+a
+a
+a
+"}
+(5,1,1) = {"
+a
+a
+b
+c
+c
+d
+d
+d
+d
+d
+L
+d
+c
+c
+b
+a
+a
+a
+a
+a
+"}
+(6,1,1) = {"
+a
+a
+b
+c
+d
+d
+m
+q
+w
+C
+M
+d
+d
+c
+b
+a
+a
+a
+a
+a
+"}
+(7,1,1) = {"
+a
+b
+b
+c
+d
+e
+n
+o
+x
+D
+N
+f
+d
+v
+b
+a
+a
+a
+a
+a
+"}
+(8,1,1) = {"
+a
+b
+c
+c
+d
+g
+o
+o
+y
+Q
+S
+I
+k
+U
+b
+a
+a
+a
+a
+a
+"}
+(9,1,1) = {"
+a
+b
+c
+c
+d
+h
+p
+r
+z
+o
+G
+f
+f
+d
+b
+a
+a
+a
+a
+a
+"}
+(10,1,1) = {"
+a
+b
+c
+c
+d
+i
+p
+s
+A
+o
+H
+f
+f
+d
+b
+a
+a
+a
+a
+a
+"}
+(11,1,1) = {"
+a
+b
+c
+c
+d
+j
+p
+t
+F
+o
+p
+I
+k
+U
+b
+a
+a
+a
+a
+a
+"}
+(12,1,1) = {"
+a
+b
+c
+c
+d
+l
+p
+p
+P
+R
+O
+f
+d
+v
+b
+b
+a
+a
+a
+a
+"}
+(13,1,1) = {"
+a
+b
+b
+c
+d
+d
+V
+u
+B
+E
+T
+d
+d
+c
+c
+b
+a
+a
+a
+a
+"}
+(14,1,1) = {"
+a
+a
+b
+c
+c
+d
+d
+d
+d
+d
+d
+d
+c
+c
+c
+b
+a
+a
+a
+a
+"}
+(15,1,1) = {"
+a
+a
+a
+b
+c
+c
+c
+c
+c
+c
+c
+c
+c
+c
+b
+b
+a
+a
+a
+a
+"}
+(16,1,1) = {"
+a
+a
+a
+b
+b
+b
+b
+c
+c
+c
+c
+b
+b
+b
+b
+a
+a
+a
+a
+a
+"}
+(17,1,1) = {"
+a
+a
+a
+a
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(18,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(19,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
+(20,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+"}
diff --git a/_maps/RandomRuins/SpaceRuins/bigape.dmm b/_maps/RandomRuins/SpaceRuins/bigape.dmm
new file mode 100644
index 0000000000..09e85e129d
--- /dev/null
+++ b/_maps/RandomRuins/SpaceRuins/bigape.dmm
@@ -0,0 +1,196 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/obj/structure/lattice,
+/turf/template_noop,
+/area/template_noop)
+"c" = (
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"d" = (
+/obj/structure/fans/tiny/invisible,
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"e" = (
+/obj/item/reagent_containers/food/snacks/grown/banana,
+/obj/item/reagent_containers/food/snacks/grown/banana,
+/obj/item/reagent_containers/food/snacks/grown/banana,
+/obj/item/reagent_containers/food/snacks/grown/banana,
+/obj/item/reagent_containers/food/snacks/grown/banana,
+/obj/structure/fans/tiny/invisible,
+/obj/structure/closet/secure_closet/freezer,
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"f" = (
+/obj/structure/chair/sofa/left{
+ dir = 4
+ },
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"g" = (
+/obj/item/flashlight/lamp/bananalamp{
+ brightness_on = 10
+ },
+/obj/structure/table/wood,
+/obj/structure/fans/tiny/invisible,
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"h" = (
+/obj/structure/table/wood,
+/obj/machinery/computer/security/wooden_tv,
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"i" = (
+/obj/structure/chair/sofa/right{
+ dir = 4
+ },
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"j" = (
+/obj/structure/sink/puddle,
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"k" = (
+/obj/structure/chair/sofa{
+ dir = 4
+ },
+/mob/living/simple_animal/hostile/gorilla{
+ AIStatus = null;
+ desc = "There is no need to be upset.";
+ dir = 4;
+ name = "Familiar Gorilla"
+ },
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"l" = (
+/obj/effect/overlay/palmtree_r,
+/obj/structure/fans/tiny/invisible,
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+"m" = (
+/obj/item/grown/bananapeel,
+/turf/open/floor/plating/beach/sand,
+/area/ruin/powered)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+a
+b
+a
+"}
+(2,1,1) = {"
+a
+a
+b
+b
+b
+b
+b
+b
+a
+a
+"}
+(3,1,1) = {"
+a
+a
+b
+b
+g
+d
+d
+b
+b
+a
+"}
+(4,1,1) = {"
+a
+a
+b
+d
+f
+k
+i
+d
+d
+b
+"}
+(5,1,1) = {"
+a
+a
+b
+e
+c
+c
+m
+j
+d
+b
+"}
+(6,1,1) = {"
+a
+a
+b
+d
+c
+h
+c
+l
+d
+b
+"}
+(7,1,1) = {"
+a
+b
+b
+b
+d
+d
+d
+b
+b
+a
+"}
+(8,1,1) = {"
+a
+b
+a
+a
+b
+b
+b
+b
+b
+b
+"}
+(9,1,1) = {"
+a
+b
+a
+a
+a
+b
+a
+a
+a
+b
+"}
+(10,1,1) = {"
+a
+a
+a
+a
+a
+b
+a
+a
+a
+a
+"}
diff --git a/_maps/RandomRuins/SpaceRuins/originalcontent.dmm b/_maps/RandomRuins/SpaceRuins/originalcontent.dmm
index 624aa03d7c..2945a06b25 100644
--- a/_maps/RandomRuins/SpaceRuins/originalcontent.dmm
+++ b/_maps/RandomRuins/SpaceRuins/originalcontent.dmm
@@ -742,6 +742,7 @@
/turf/open/indestructible/paper,
/area/ruin/powered)
"cc" = (
+/obj/item/book/granter/action/origami,
/mob/living/simple_animal/hostile/boss/paper_wizard,
/turf/open/indestructible/paper,
/area/ruin/powered)
@@ -912,6 +913,10 @@
},
/turf/open/indestructible/paper,
/area/ruin/powered)
+"Ns" = (
+/obj/item/paper/secretrecipe,
+/turf/open/indestructible/paper,
+/area/ruin/powered)
(1,1,1) = {"
aa
@@ -2246,7 +2251,7 @@ ap
az
af
al
-aA
+Ns
bW
ca
af
diff --git a/_maps/RandomRuins/SpaceRuins/spacehermit.dmm b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm
new file mode 100644
index 0000000000..341dcf7b99
--- /dev/null
+++ b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm
@@ -0,0 +1,2941 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"aa" = (
+/turf/template_noop,
+/area/template_noop)
+"ab" = (
+/turf/closed/mineral/random/low_chance,
+/area/ruin/unpowered)
+"ac" = (
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"ad" = (
+/obj/machinery/hydroponics/soil,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"ae" = (
+/turf/closed/wall/mineral/titanium,
+/area/ruin/powered)
+"af" = (
+/obj/effect/spawner/structure/window/shuttle,
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"ag" = (
+/obj/structure/shuttle/engine/propulsion/right{
+ dir = 4
+ },
+/turf/closed/wall/mineral/titanium,
+/area/ruin/powered)
+"ah" = (
+/obj/structure/table/wood,
+/obj/item/shovel,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"ai" = (
+/obj/structure/lattice,
+/turf/template_noop,
+/area/template_noop)
+"aj" = (
+/obj/machinery/computer/cryopod,
+/turf/closed/wall/mineral/titanium,
+/area/ruin/powered)
+"ak" = (
+/obj/structure/fluff/empty_cryostasis_sleeper,
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"al" = (
+/obj/machinery/status_display/shuttle,
+/turf/closed/wall/mineral/titanium,
+/area/ruin/powered)
+"am" = (
+/obj/item/circuitboard/computer/rdconsole,
+/obj/item/circuitboard/machine/protolathe/department/science,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"an" = (
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"ao" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 8
+ },
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"ap" = (
+/obj/machinery/light{
+ dir = 1
+ },
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"aq" = (
+/obj/machinery/computer{
+ desc = "A computer long since rendered non-functional due to lack of maintenance. Spitting out error messages.";
+ dir = 4;
+ name = "Broken Computer"
+ },
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"ar" = (
+/obj/machinery/door/airlock/titanium{
+ name = "Escape Pod Airlock"
+ },
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"as" = (
+/obj/machinery/light,
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"at" = (
+/obj/structure/shuttle/engine/propulsion/left{
+ dir = 4
+ },
+/turf/closed/wall/mineral/titanium,
+/area/ruin/powered)
+"au" = (
+/obj/item/seeds/tower,
+/obj/item/seeds/tower,
+/obj/item/seeds/tower,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"av" = (
+/obj/structure/table/wood,
+/obj/item/paper/crumpled{
+ info = "
So this is it, I guess.. Always thought I'd go out doing something stupid, but.. not like this.
Should anyone find this note, tell Jeremy Clarke he can kiss my ass. Launching the pod unprepared like that..
Well. Now that I'm keeling over here, I guess I should write how I came to be the last one standing here.
Four of us took this pod.. only three of us woke up though.. fourth pod is locked from the inside, we couldn't figure out how to get it open.
Me and the clown set up a farm s'we can survive at least a while.. though, he didn't seem to understand that man cannot live on banana alone.
Had a bunch of circuits on him for some reason when he eventually passed, whispered to me something about a chem dispenser.. I.. don't know what he meant by that. I was never good with machinary. Maybe he wanted space lube?
The assistant that we gave the space suit to go out and find help never came back.. I'm betting he found salvation and left us behind.. never can trust those grubby greytiders."
+ },
+/obj/item/pen,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aw" = (
+/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/stack/sheet/mineral/wood,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"ax" = (
+/obj/item/twohanded/spear,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"ay" = (
+/obj/item/grown/log,
+/obj/item/grown/log,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"az" = (
+/obj/structure/table/wood,
+/obj/item/storage/bag/plants/portaseeder,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aA" = (
+/turf/open/floor/plating/asteroid/airless,
+/area/ruin/unpowered)
+"aB" = (
+/obj/item/seeds/banana,
+/obj/item/seeds/banana,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aC" = (
+/obj/effect/mob_spawn/human/clown/corpse,
+/obj/structure/fans/tiny/invisible,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aD" = (
+/obj/item/mining_scanner,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aE" = (
+/obj/machinery/status_display/shuttle,
+/turf/closed/wall/mineral/titanium,
+/area/ruin/unpowered)
+"aF" = (
+/obj/item/pickaxe/emergency,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aG" = (
+/obj/structure/sink/puddle,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aH" = (
+/obj/structure/table/wood,
+/obj/item/storage/firstaid/regular,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aI" = (
+/obj/effect/mob_spawn/human/corpse/assistant,
+/turf/template_noop,
+/area/template_noop)
+"aJ" = (
+/obj/structure/table/wood,
+/obj/item/storage/bag/ore,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aK" = (
+/obj/structure/reagent_dispensers/fueltank,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aL" = (
+/obj/structure/table/wood,
+/obj/item/storage/toolbox/mechanical,
+/obj/item/clothing/head/welding,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aM" = (
+/mob/living/simple_animal/hostile/carp,
+/turf/template_noop,
+/area/template_noop)
+"aN" = (
+/obj/structure/mineral_door/sandstone,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aO" = (
+/mob/living/simple_animal/hostile/carp,
+/turf/open/floor/plating/asteroid/airless,
+/area/ruin/unpowered)
+"aP" = (
+/obj/item/stack/ore/gold,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aQ" = (
+/obj/item/stack/ore/gold,
+/obj/item/stack/ore/gold,
+/obj/item/stack/ore/gold,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aR" = (
+/obj/item/stack/ore/iron,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aS" = (
+/turf/closed/wall/mineral/iron,
+/area/ruin/unpowered)
+"aT" = (
+/obj/item/stack/ore/iron,
+/obj/item/stack/ore/iron,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aU" = (
+/obj/item/flashlight/lamp,
+/obj/structure/table/wood,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"aV" = (
+/obj/item/clothing/suit/space/orange,
+/turf/template_noop,
+/area/template_noop)
+"aW" = (
+/obj/item/clothing/head/helmet/space/orange,
+/turf/template_noop,
+/area/template_noop)
+"aX" = (
+/mob/living/simple_animal/hostile/carp/megacarp,
+/turf/template_noop,
+/area/template_noop)
+"aY" = (
+/obj/effect/mob_spawn/human/hermit{
+ flavour_text = "You've been late to awaken from your cryo slumber. Blasted machine, you set it to 10 days not 10 weeks! Where have the others gone while we were out? Did they manage to survive? These thoughts are dispelled by yet another recollection of how you got here... ";
+ job_description = "Space Hermit"
+ },
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"aZ" = (
+/turf/closed/wall/mineral/titanium,
+/area/ruin/unpowered)
+"ba" = (
+/obj/effect/spawner/structure/window/shuttle,
+/turf/open/floor/mineral/titanium,
+/area/ruin/unpowered)
+"bb" = (
+/obj/structure/shuttle/engine/propulsion/left{
+ dir = 4
+ },
+/turf/closed/wall/mineral/titanium,
+/area/ruin/unpowered)
+"bc" = (
+/obj/item/circuitboard/machine/circuit_imprinter,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bd" = (
+/obj/item/grown/bananapeel,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"be" = (
+/obj/effect/mob_spawn/human/corpse/cargo_tech,
+/obj/structure/fans/tiny/invisible,
+/obj/effect/decal/cleanable/vomit,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bf" = (
+/obj/item/clothing/glasses/meson,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bg" = (
+/obj/item/stock_parts/matter_bin,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bh" = (
+/obj/item/circuitboard/machine/autolathe,
+/turf/open/floor/mineral/titanium,
+/area/ruin/powered)
+"bi" = (
+/obj/item/stock_parts/manipulator,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bj" = (
+/obj/item/holosign_creator/atmos,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bk" = (
+/obj/structure/holosign/barrier/atmos,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bl" = (
+/obj/machinery/power/floodlight,
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bm" = (
+/obj/structure/cable{
+ icon_state = "1-4"
+ },
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bn" = (
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bo" = (
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bp" = (
+/obj/item/stack/ore/iron,
+/obj/item/stack/ore/iron,
+/obj/item/stack/ore/iron,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bq" = (
+/obj/structure/cable,
+/obj/machinery/power/port_gen/pacman{
+ active = 1;
+ anchored = 1;
+ sheets = 10
+ },
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"br" = (
+/obj/item/stack/ore/iron,
+/obj/item/stack/sheet/mineral/plasma,
+/obj/item/stack/sheet/mineral/plasma,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+"bs" = (
+/obj/item/flashlight/lamp/bananalamp,
+/turf/open/floor/plating/asteroid,
+/area/ruin/unpowered)
+
+(1,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aM
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ac
+aO
+aA
+aA
+aA
+aA
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(2,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aM
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+aA
+aA
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aA
+aA
+aa
+aa
+aa
+aa
+aM
+aa
+aa
+aa
+aa
+aa
+"}
+(3,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aA
+aa
+aa
+aa
+aa
+aW
+aa
+aM
+aa
+"}
+(4,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aV
+aI
+aX
+aa
+aa
+"}
+(5,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+aA
+aA
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(6,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aM
+aa
+aa
+aa
+"}
+(7,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aM
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+"}
+(8,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+af
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+"}
+(9,1,1) = {"
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+af
+aq
+af
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+"}
+(10,1,1) = {"
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ae
+ao
+ae
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+"}
+(11,1,1) = {"
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+af
+an
+an
+an
+af
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(12,1,1) = {"
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aA
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ae
+bh
+an
+an
+ae
+aZ
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(13,1,1) = {"
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aA
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+af
+aY
+ao
+ao
+ao
+ak
+ba
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(14,1,1) = {"
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aA
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+al
+aj
+ap
+an
+as
+aj
+aE
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(15,1,1) = {"
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+aA
+aa
+aa
+aa
+aA
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+af
+ak
+ao
+ao
+ao
+ak
+ba
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(16,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ah
+az
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aR
+ae
+ae
+an
+an
+an
+ae
+aZ
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aM
+"}
+(17,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aR
+ag
+ag
+af
+ar
+af
+at
+bb
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(18,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ad
+ac
+ac
+ac
+ac
+ab
+aH
+aJ
+aL
+ab
+ab
+aT
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+aR
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(19,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ad
+au
+ac
+aB
+am
+ac
+ac
+ac
+ac
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+bg
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(20,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ad
+aw
+bs
+aC
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(21,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aM
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ad
+ax
+ac
+aD
+aF
+ac
+ac
+ac
+ab
+ab
+ab
+aU
+bd
+ac
+ac
+bl
+bm
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(22,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ad
+ay
+ac
+ac
+ac
+aG
+ac
+ac
+ab
+ab
+ab
+av
+be
+ac
+ac
+ac
+bn
+bo
+bo
+bq
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+"}
+(23,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+bc
+bf
+ac
+ac
+ac
+ac
+ac
+ac
+br
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+"}
+(24,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ab
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+"}
+(25,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+aN
+ac
+ac
+ac
+ac
+aR
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+"}
+(26,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+"}
+(27,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aK
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+bp
+ac
+ac
+aR
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+aM
+"}
+(28,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aP
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+ac
+aR
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+"}
+(29,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aQ
+aP
+ac
+ac
+aR
+ac
+ac
+ac
+ac
+ab
+ac
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+"}
+(30,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+aP
+ac
+bg
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+"}
+(31,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ac
+ac
+ac
+ac
+aS
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+ab
+aA
+"}
+(32,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+bg
+ac
+ac
+ac
+ac
+ac
+aS
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aO
+ab
+ab
+"}
+(33,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+bj
+ac
+ac
+ac
+aS
+ab
+ab
+ab
+ab
+aA
+aa
+aA
+ab
+ab
+ab
+"}
+(34,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aS
+bi
+ac
+ac
+ac
+aS
+aS
+ab
+ab
+ab
+ab
+aA
+aa
+aA
+ab
+ab
+aA
+"}
+(35,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+aa
+aa
+aa
+aa
+aM
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aS
+ac
+ac
+ac
+ac
+aS
+aS
+ab
+ab
+ab
+aA
+aa
+aa
+aA
+ab
+ab
+ab
+"}
+(36,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aS
+aS
+aS
+bk
+bk
+aS
+aS
+aS
+aS
+ab
+ab
+aA
+aa
+aa
+aa
+ab
+ab
+ab
+"}
+(37,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aA
+aA
+aS
+aS
+aS
+bk
+aS
+aS
+aS
+aA
+aA
+ab
+aA
+aa
+aa
+aa
+aa
+aA
+aA
+"}
+(38,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aA
+ai
+ai
+ai
+ai
+ai
+ai
+ai
+ai
+aA
+aA
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(39,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+ai
+ai
+ai
+aa
+ai
+aa
+aa
+aA
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(40,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+ai
+aa
+aa
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(41,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(42,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+aA
+aA
+aA
+aA
+aA
+aA
+aA
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+aa
+aa
+aa
+aa
+aM
+aa
+aa
+aa
+"}
+(43,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+aA
+aA
+aA
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(44,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ac
+aa
+aa
+aa
+"}
+(45,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aa
+aa
+aa
+aa
+aM
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aM
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aM
+aa
+aa
+aa
+aa
+ac
+ab
+ac
+aa
+aa
+"}
+(46,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aM
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+aa
+aa
+"}
+(47,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+aa
+aa
+"}
+(48,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aM
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+ab
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ac
+ab
+ac
+aa
+aa
+"}
+(49,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aA
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aA
+aa
+aa
+aa
+aa
+aM
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ac
+aa
+aa
+aa
+aa
+"}
+(50,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+aa
+aa
+aa
+aa
+"}
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index dcd2c47cb2..60c91e51bb 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -515,10 +515,13 @@
/turf/closed/wall,
/area/security/main)
"abq" = (
-/turf/closed/wall,
+/turf/closed/wall/r_wall,
/area/crew_quarters/heads/hos)
"abr" = (
/obj/effect/spawner/structure/window/reinforced,
+/obj/machinery/door/poddoor/preopen{
+ id = "hos"
+ },
/turf/open/floor/plating,
/area/crew_quarters/heads/hos)
"abs" = (
@@ -846,8 +849,13 @@
},
/obj/structure/table/wood,
/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka,
-/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
-/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
+/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{
+ pixel_x = -5;
+ pixel_y = 5
+ },
+/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{
+ pixel_x = -5
+ },
/turf/open/floor/carpet,
/area/crew_quarters/heads/hos)
"abX" = (
@@ -1449,6 +1457,9 @@
"adm" = (
/obj/structure/disposalpipe/segment,
/obj/effect/spawner/structure/window/reinforced,
+/obj/machinery/door/poddoor/preopen{
+ id = "hos"
+ },
/turf/open/floor/plating,
/area/crew_quarters/heads/hos)
"adn" = (
@@ -1673,6 +1684,12 @@
"adM" = (
/obj/structure/cable{
icon_state = "4-8"
+ },
+/obj/machinery/button/door{
+ id = "hos";
+ name = "HoS Office Shutters";
+ pixel_y = -25;
+
},
/turf/open/floor/carpet,
/area/crew_quarters/heads/hos)
@@ -2053,6 +2070,9 @@
"aex" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/spawner/structure/window/reinforced,
+/obj/machinery/door/poddoor/preopen{
+ id = "hos"
+ },
/turf/open/floor/plating,
/area/crew_quarters/heads/hos)
"aey" = (
@@ -11691,7 +11711,7 @@
/area/maintenance/port/fore)
"aAW" = (
/obj/structure/rack,
-/obj/item/tank/jetpack/carbondioxide,
+/obj/item/tank/jetpack/carbondioxide/eva,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
@@ -11815,7 +11835,7 @@
/obj/machinery/light{
dir = 8
},
-/obj/item/tank/jetpack/carbondioxide,
+/obj/item/tank/jetpack/carbondioxide/eva,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
@@ -56882,12 +56902,6 @@
/obj/item/pen,
/turf/open/floor/plasteel/white,
/area/science/circuit)
-"ium" = (
-/mob/living/simple_animal/bot/cleanbot{
- name = "C.L.E.A.N."
- },
-/turf/open/floor/plasteel/white,
-/area/medical/medbay/central)
"izv" = (
/obj/machinery/vending/clothing,
/obj/machinery/light/small{
@@ -57122,6 +57136,12 @@
},
/turf/open/floor/plating,
/area/construction/mining/aux_base)
+"lKX" = (
+/mob/living/simple_animal/bot/cleanbot{
+ name = "C.L.E.A.N."
+ },
+/turf/open/floor/plasteel/white,
+/area/medical/medbay/central)
"lMg" = (
/obj/effect/turf_decal/stripes/line{
dir = 9
@@ -88468,7 +88488,7 @@ aaa
aaf
aaf
aaa
-abp
+adR
abP
aco
acO
@@ -88982,7 +89002,7 @@ aaa
aaa
aaf
aaa
-abp
+adR
abO
acq
acq
@@ -89496,15 +89516,15 @@ aaa
aaa
aaa
aaf
-abp
+adR
abR
abP
abP
abP
abP
-abp
-abp
-abp
+adR
+adR
+adR
agA
afU
ahF
@@ -94188,7 +94208,7 @@ blm
bmL
boi
bpw
-ium
+lKX
bsx
btX
bvj
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index c8e551b9fe..402633f42b 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -79373,12 +79373,12 @@
},
/obj/structure/window/reinforced,
/obj/structure/rack,
-/obj/item/tank/jetpack/carbondioxide{
+/obj/item/tank/jetpack/carbondioxide/eva{
pixel_x = 4;
pixel_y = -1
},
-/obj/item/tank/jetpack/carbondioxide,
-/obj/item/tank/jetpack/carbondioxide{
+/obj/item/tank/jetpack/carbondioxide/eva,
+/obj/item/tank/jetpack/carbondioxide/eva{
pixel_x = -4;
pixel_y = 1
},
@@ -80186,11 +80186,11 @@
/area/engine/storage)
"cEi" = (
/obj/structure/table/reinforced,
-/obj/item/tank/jetpack/carbondioxide{
+/obj/item/tank/jetpack/carbondioxide/eva{
pixel_x = 3;
pixel_y = 3
},
-/obj/item/tank/jetpack/carbondioxide,
+/obj/item/tank/jetpack/carbondioxide/eva,
/obj/machinery/power/apc{
dir = 4;
name = "Engineering Storage APC";
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 78ffa3881c..1bcb5c20a8 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -47699,12 +47699,12 @@
},
/obj/structure/window/reinforced,
/obj/structure/rack,
-/obj/item/tank/jetpack/carbondioxide{
+/obj/item/tank/jetpack/carbondioxide/eva{
pixel_x = 4;
pixel_y = -1
},
-/obj/item/tank/jetpack/carbondioxide,
-/obj/item/tank/jetpack/carbondioxide{
+/obj/item/tank/jetpack/carbondioxide/eva,
+/obj/item/tank/jetpack/carbondioxide/eva{
pixel_x = -4;
pixel_y = 1
},
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index f9792a736e..7935a2a3f9 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -16464,8 +16464,8 @@
/area/storage/eva)
"aNt" = (
/obj/structure/rack,
-/obj/item/tank/jetpack/carbondioxide,
-/obj/item/tank/jetpack/carbondioxide{
+/obj/item/tank/jetpack/carbondioxide/eva,
+/obj/item/tank/jetpack/carbondioxide/eva{
pixel_x = -4;
pixel_y = 1
},
@@ -35713,13 +35713,13 @@
/obj/structure/extinguisher_cabinet{
pixel_x = -26
},
-/obj/machinery/rnd/production/protolathe/department/medical,
/obj/effect/turf_decal/tile/blue{
dir = 1
},
/obj/effect/turf_decal/tile/blue{
dir = 4
},
+/obj/machinery/rnd/production/techfab/department/medical,
/turf/open/floor/plasteel/white,
/area/medical/medbay/central)
"bEw" = (
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index dbe8cfbb62..210bdf57a6 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -130,6 +130,7 @@
#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters)
#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params)
#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target)
+#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
// /mob/living signals
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm
index aa9c5cf34e..ee51fb6909 100644
--- a/code/__DEFINES/construction.dm
+++ b/code/__DEFINES/construction.dm
@@ -102,7 +102,7 @@
#define CAT_SANDWICH "Sandwiches"
#define CAT_SOUP "Soups"
#define CAT_SPAGHETTI "Spaghettis"
-#define CAT_SUSHI "Fish"
+#define CAT_FISH "Fish"
#define CAT_ICE "Frozen"
#define RCD_FLOORWALL 1
diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm
index 2c7a66ce40..15c7af5749 100644
--- a/code/__DEFINES/food.dm
+++ b/code/__DEFINES/food.dm
@@ -16,3 +16,4 @@
#define DRINK_GOOD 2
#define DRINK_VERYGOOD 3
#define DRINK_FANTASTIC 4
+#define FOOD_AMAZING 5
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 19710a89fe..fc8e7dda2f 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -114,8 +114,9 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define TRANSITIONEDGE 7 //Distance from edge to move to another z-level
-#define BE_CLOSE 1 //in the case of a silicon, to select if they need to be next to the atom
-#define NO_DEXTERY 1 //if other mobs (monkeys, aliens, etc) can use this
+#define BE_CLOSE TRUE //in the case of a silicon, to select if they need to be next to the atom
+#define NO_DEXTERY TRUE //if other mobs (monkeys, aliens, etc) can use this
+#define NO_TK TRUE
//used by canUseTopic()
//singularity defines
@@ -265,6 +266,15 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE))
+//pda icon reskins
+#define PDA_SKIN_CLASSIC "Classic"
+#define PDA_SKIN_ALT "Holographic"
+#define PDA_SKIN_RUGGED "Rugged"
+#define PDA_SKIN_MODERN "Modern"
+
+GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_SKIN_ALT = 'icons/obj/pda_alt.dmi',
+ PDA_SKIN_RUGGED = 'icons/obj/pda_rugged.dmi', PDA_SKIN_MODERN = 'icons/obj/pda_modern.dmi'))
+
//Color Defines
#define OOC_COLOR "#002eb8"
#define AOOC_COLOR "#b8002e"
@@ -479,4 +489,7 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE))
#define AREASELECT_CORNERA "corner A"
#define AREASELECT_CORNERB "corner B"
-#define PREF_SAVELOAD_COOLDOWN 5
\ No newline at end of file
+#define PREF_SAVELOAD_COOLDOWN 5
+
+#define VOMIT_TOXIC 1
+#define VOMIT_PURPLE 2
\ No newline at end of file
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 4b42595b48..1d1dda6d99 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -54,6 +54,10 @@
#define BODYPART_ORGANIC 1
#define BODYPART_ROBOTIC 2
+#define BODYPART_NOT_DISABLED 0
+#define BODYPART_DISABLED_DAMAGE 1
+#define BODYPART_DISABLED_PARALYSIS 2
+
#define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi'
#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi'
diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm
index b72a14468f..1c36120a0c 100644
--- a/code/__DEFINES/reactions.dm
+++ b/code/__DEFINES/reactions.dm
@@ -23,6 +23,11 @@
#define STIMULUM_ABSOLUTE_DROP 0.00000335
#define REACTION_OPPRESSION_THRESHOLD 5
#define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense.
+//Research point amounts
+#define NOBLIUM_RESEARCH_AMOUNT 1000
+#define BZ_RESEARCH_AMOUNT 150
+#define MIASMA_RESEARCH_AMOUNT 160
+#define STIMULUM_RESEARCH_AMOUNT 50
//Plasma fusion properties
#define FUSION_ENERGY_THRESHOLD 3e9 //Amount of energy it takes to start a fusion reaction
#define FUSION_TEMPERATURE_THRESHOLD 1000 //Temperature required to start a fusion reaction
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index f54a0542f4..ecd1ef1e21 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -102,7 +102,6 @@
#define FIRE_PRIORITY_SPACEDRIFT 30
#define FIRE_PRIORITY_FIELDS 30
#define FIRE_PRIOTITY_SMOOTHING 35
-#define FIRE_PRIORITY_ORBIT 35
#define FIRE_PRIORITY_NETWORKS 40
#define FIRE_PRIORITY_OBJ 40
#define FIRE_PRIORITY_ACID 40
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 12e222e1ef..7f3c063777 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -108,7 +108,16 @@
#define TRAIT_NOHARDCRIT "nohardcrit"
#define TRAIT_NOSOFTCRIT "nosoftcrit"
#define TRAIT_MINDSHIELD "mindshield"
+#define TRAIT_PARALYSIS_L_ARM "para-l-arm" //These are used for brain-based paralysis, where replacing the limb won't fix it
+#define TRAIT_PARALYSIS_R_ARM "para-r-arm"
+#define TRAIT_PARALYSIS_L_LEG "para-l-leg"
+#define TRAIT_PARALYSIS_R_LEG "para-r-leg"
+#define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism"
+#define TRAIT_STRONG_GRABBER "strong_grabber"
+#define TRAIT_CALCIUM_HEALER "calcium_healer"
+ //non-mob traits
+#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance"
#define TRAIT_AGEUSIA "ageusia"
@@ -130,6 +139,7 @@
#define TRAIT_CROCRIN_IMMUNE "crocin_immune"
#define TRAIT_NYMPHO "nymphomania"
#define TRAIT_MASO "masochism"
+#define TRAIT_PARA "paraplegic"
#define TRAIT_EMPATH "empath"
#define TRAIT_FRIENDLY "friendly"
#define TRAIT_ASSBLASTUSA "assblastusa"
@@ -144,6 +154,7 @@
#define TRAUMA_TRAIT "trauma"
#define SPECIES_TRAIT "species"
#define ORGAN_TRAIT "organ"
+#define JOB_TRAIT "job"
#define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention
// unique trait sources, still defines
diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm
index f05bf6f3e1..1f5b82f7bf 100644
--- a/code/__HELPERS/areas.dm
+++ b/code/__HELPERS/areas.dm
@@ -86,6 +86,8 @@
newA.contents += thing
thing.change_area(old_area, newA)
+ newA.reg_in_areas_in_z()
+
var/list/firedoors = oldA.firedoors
for(var/door in firedoors)
var/obj/machinery/door/firedoor/FD = door
diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm
index 8b77b170e0..d96ec76a7c 100644
--- a/code/__HELPERS/matrices.dm
+++ b/code/__HELPERS/matrices.dm
@@ -2,7 +2,7 @@
. = new_angle - old_angle
Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT
-/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3)
+/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE)
if(!segments)
return
var/segment = 360/segments
@@ -18,7 +18,11 @@
speed /= segments
- animate(src, transform = matrices[1], time = speed, loops)
+ if(parallel)
+ animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL)
+ else
+ animate(src, transform = matrices[1], time = speed, loops)
+
for(var/i in 2 to segments) //2 because 1 is covered above
animate(transform = matrices[i], time = speed)
//doesn't have an object argument because this is "Stacking" with the animate call above
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 51c814a5f9..9eb5400c52 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -170,7 +170,7 @@
"balls_amount" = 2,
"balls_sack_size" = BALLS_SACK_SIZE_DEF,
"balls_size" = BALLS_SIZE_DEF,
- "balls_shape" = "Pair",
+ "balls_shape" = "Single",
"balls_cum_rate" = CUM_RATE,
"balls_cum_mult" = CUM_RATE_MULT,
"balls_efficiency" = CUM_EFFICIENCY,
diff --git a/code/__HELPERS/reagents.dm b/code/__HELPERS/reagents.dm
new file mode 100644
index 0000000000..f1208abdd3
--- /dev/null
+++ b/code/__HELPERS/reagents.dm
@@ -0,0 +1,74 @@
+/proc/chem_recipes_do_conflict(datum/chemical_reaction/r1, datum/chemical_reaction/r2)
+ //do the non-list tests first, because they are cheaper
+ if(r1.required_container != r2.required_container)
+ return FALSE
+ if(r1.is_cold_recipe == r2.is_cold_recipe)
+ if(r1.required_temp != r2.required_temp)
+ //one reaction requires a more extreme temperature than the other, so there is no conflict
+ return FALSE
+ else
+ var/datum/chemical_reaction/cold_one = r1.is_cold_recipe ? r1 : r2
+ var/datum/chemical_reaction/warm_one = r1.is_cold_recipe ? r2 : r1
+ if(cold_one.required_temp < warm_one.required_temp)
+ //the range of temperatures does not overlap, so there is no conflict
+ return FALSE
+
+ //find the reactions with the shorter and longer required_reagents list
+ var/datum/chemical_reaction/long_req
+ var/datum/chemical_reaction/short_req
+ if(r1.required_reagents.len > r2.required_reagents.len)
+ long_req = r1
+ short_req = r2
+ else if(r1.required_reagents.len < r2.required_reagents.len)
+ long_req = r2
+ short_req = r1
+ else
+ //if they are the same length, sort instead by the length of the catalyst list
+ //this is important if the required_reagents lists are the same
+ if(r1.required_catalysts.len > r2.required_catalysts.len)
+ long_req = r1
+ short_req = r2
+ else
+ long_req = r2
+ short_req = r1
+
+
+ //check if the shorter reaction list is a subset of the longer one
+ var/list/overlap = r1.required_reagents & r2.required_reagents
+ if(overlap.len != short_req.required_reagents.len)
+ //there is at least one reagent in the short list that is not in the long list, so there is no conflict
+ return FALSE
+
+ //check to see if the shorter reaction's catalyst list is also a subset of the longer reaction's catalyst list
+ //if the longer reaction's catalyst list is a subset of the shorter ones, that is fine
+ //if the reaction lists are the same, the short reaction will have the shorter required_catalysts list, so it will register as a conflict
+ var/list/short_minus_long_catalysts = short_req.required_catalysts - long_req.required_catalysts
+ if(short_minus_long_catalysts.len)
+ //there is at least one unique catalyst for the short reaction, so there is no conflict
+ return FALSE
+
+ //if we got this far, the longer reaction will be impossible to create if the shorter one is earlier in GLOB.chemical_reactions_list, and will require the reagents to be added in a particular order otherwise
+ return TRUE
+
+/proc/get_chemical_reaction(id)
+ if(!GLOB.chemical_reactions_list)
+ return
+ for(var/reagent in GLOB.chemical_reactions_list)
+ for(var/datum/chemical_reaction/R in GLOB.chemical_reactions_list[reagent])
+ if(R.id == id)
+ return R
+
+/proc/remove_chemical_reaction(datum/chemical_reaction/R)
+ if(!GLOB.chemical_reactions_list || !R)
+ return
+ for(var/rid in R.required_reagents)
+ GLOB.chemical_reactions_list[rid] -= R
+
+//see build_chemical_reactions_list in holder.dm for explanations
+/proc/add_chemical_reaction(datum/chemical_reaction/R)
+ if(!GLOB.chemical_reactions_list || !R.id || !R.required_reagents || !R.required_reagents.len)
+ return
+ var/primary_reagent = R.required_reagents[1]
+ if(!GLOB.chemical_reactions_list[primary_reagent])
+ GLOB.chemical_reactions_list[primary_reagent] = list()
+ GLOB.chemical_reactions_list[primary_reagent] += R
diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm
index 200e1f907f..b28e7b5807 100644
--- a/code/__HELPERS/time.dm
+++ b/code/__HELPERS/time.dm
@@ -70,3 +70,6 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0)
if(hour)
hourT = " and [hour] hour[(hour != 1)? "s":""]"
return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]"
+
+/proc/daysSince(realtimev)
+ return round((world.realtime - realtimev) / (24 HOURS))
diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm
index efd405a4dc..7f9e0c6ca5 100644
--- a/code/_globalvars/lists/maintenance_loot.dm
+++ b/code/_globalvars/lists/maintenance_loot.dm
@@ -44,6 +44,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/flashlight = 4,
/obj/item/flashlight/pen = 1,
/obj/item/flashlight/glowstick/random = 4,
+ /obj/effect/spawner/lootdrop/mre = 3,
/obj/item/multitool = 2,
/obj/item/radio/off = 2,
/obj/item/t_scanner = 5,
@@ -107,10 +108,12 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/storage/toolbox/artistic = 2,
/obj/item/toy/eightball = 1,
/obj/item/reagent_containers/pill/floorpill = 1,
+ /obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 1,
/obj/item/storage/daki = 3, //VERY IMPORTANT CIT CHANGE - adds bodypillows to maint
/obj/item/storage/pill_bottle/penis_enlargement = 2,
/obj/item/clothing/shoes/wheelys = 1,
/obj/item/clothing/shoes/kindleKicks = 1,
/obj/item/autosurgeon/penis = 1,
+ /obj/item/autosurgeon/testicles = 1,
"" = 3
))
diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm
index fa0ecf117d..e7b2ae6cbe 100644
--- a/code/_globalvars/misc.dm
+++ b/code/_globalvars/misc.dm
@@ -18,3 +18,12 @@ GLOBAL_LIST_EMPTY(powernets)
GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes
GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details
+
+// All religion stuff
+GLOBAL_VAR(religion)
+GLOBAL_VAR(deity)
+GLOBAL_VAR(bible_name)
+GLOBAL_VAR(bible_icon_state)
+GLOBAL_VAR(bible_item_state)
+GLOBAL_VAR(holy_weapon_type)
+GLOBAL_VAR(holy_armor_type)
\ No newline at end of file
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index 0c01468712..7a495b95e7 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -23,6 +23,9 @@
return
next_click = world.time + 1
+ if(!can_interact_with(A))
+ return
+
if(multicam_on)
var/turf/T = get_turf(A)
if(T)
@@ -60,7 +63,6 @@
controlled_mech.click_action(A, src, params) //Override AI normal click behavior.
return
- return
if(modifiers["shift"])
ShiftClickOn(A)
return
diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm
index 73a207a457..2b5af9ddb8 100644
--- a/code/_onclick/hud/action_button.dm
+++ b/code/_onclick/hud/action_button.dm
@@ -20,10 +20,23 @@
else
return TRUE
-/obj/screen/movable/action_button/MouseDrop()
- if (!can_use(usr))
+/obj/screen/movable/action_button/MouseDrop(over_object)
+ if(!can_use(usr))
return
- return ..()
+ if((istype(over_object, /obj/screen/movable/action_button) && !istype(over_object, /obj/screen/movable/action_button/hide_toggle)))
+ if(locked)
+ to_chat(usr, "Action button \"[name]\" is locked, unlock it first.")
+ return
+ var/obj/screen/movable/action_button/B = over_object
+ var/list/actions = usr.actions
+ actions.Swap(actions.Find(src.linked_action), actions.Find(B.linked_action))
+ moved = FALSE
+ ordered = TRUE
+ B.moved = FALSE
+ B.ordered = TRUE
+ usr.update_action_buttons()
+ else
+ return ..()
/obj/screen/movable/action_button/Click(location,control,params)
if (!can_use(usr))
diff --git a/code/controllers/subsystem/augury.dm b/code/controllers/subsystem/augury.dm
index 875f1ee7d3..1b1c7bc3b7 100644
--- a/code/controllers/subsystem/augury.dm
+++ b/code/controllers/subsystem/augury.dm
@@ -50,7 +50,7 @@ SUBSYSTEM_DEF(augury)
watchers -= w
continue
var/mob/dead/observer/O = w
- if(biggest_doom && (!O.orbiting || O.orbiting.orbiting != biggest_doom))
+ if(biggest_doom && (!O.orbiting || O.orbiting.parent != biggest_doom))
O.ManualFollow(biggest_doom)
/datum/action/innate/augury
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index a2c60618ac..a365405ce6 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -256,10 +256,13 @@ GLOBAL_LIST_EMPTY(the_station_areas)
/datum/controller/subsystem/mapping/proc/generate_station_area_list()
var/list/station_areas_blacklist = typecacheof(list(/area/space, /area/mine, /area/ruin, /area/asteroid/nearstation))
for(var/area/A in world)
- var/turf/picked = safepick(get_area_turfs(A.type))
- if(picked && is_station_level(picked.z))
- if(!(A.type in GLOB.the_station_areas) && !is_type_in_typecache(A, station_areas_blacklist))
- GLOB.the_station_areas.Add(A.type)
+ if (is_type_in_typecache(A, station_areas_blacklist))
+ continue
+ if (!A.contents.len || !A.unique)
+ continue
+ var/turf/picked = A.contents[1]
+ if (is_station_level(picked.z))
+ GLOB.the_station_areas += A.type
if(!GLOB.the_station_areas.len)
log_world("ERROR: Station areas list failed to generate!")
@@ -495,4 +498,9 @@ GLOBAL_LIST_EMPTY(the_station_areas)
clearing |= used_turfs //used turfs is an associative list, BUT, reserve_turfs() can still handle it. If the code above works properly, this won't even be needed as the turfs would be freed already.
unused_turfs.Cut()
used_turfs.Cut()
- reserve_turfs(clearing)
\ No newline at end of file
+ reserve_turfs(clearing)
+
+/datum/controller/subsystem/mapping/proc/reg_in_areas_in_z(list/areas)
+ for(var/B in areas)
+ var/area/A = B
+ A.reg_in_areas_in_z()
diff --git a/code/controllers/subsystem/orbit.dm b/code/controllers/subsystem/orbit.dm
deleted file mode 100644
index 45d280b601..0000000000
--- a/code/controllers/subsystem/orbit.dm
+++ /dev/null
@@ -1,44 +0,0 @@
-SUBSYSTEM_DEF(orbit)
- name = "Orbits"
- priority = FIRE_PRIORITY_ORBIT
- wait = 2
- flags = SS_NO_INIT|SS_TICKER
-
- var/list/currentrun = list()
- var/list/processing = list()
-
-/datum/controller/subsystem/orbit/stat_entry()
- ..("P:[processing.len]")
-
-
-/datum/controller/subsystem/orbit/fire(resumed = 0)
- if (!resumed)
- src.currentrun = processing.Copy()
-
- //cache for sanic speed (lists are references anyways)
- var/list/currentrun = src.currentrun
-
- while (currentrun.len)
- var/datum/orbit/O = currentrun[currentrun.len]
- currentrun.len--
- if (!O)
- processing -= O
- if (MC_TICK_CHECK)
- return
- continue
- if (!O.orbiter)
- qdel(O)
- if (MC_TICK_CHECK)
- return
- continue
- if (O.lastprocess >= world.time) //we already checked recently
- if (MC_TICK_CHECK)
- return
- continue
- var/targetloc = get_turf(O.orbiting)
- if (targetloc != O.lastloc || O.orbiter.loc != targetloc)
- O.Check(targetloc)
- if (MC_TICK_CHECK)
- return
-
-
diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm
index 978eedb62f..455b53b1df 100644
--- a/code/controllers/subsystem/persistence.dm
+++ b/code/controllers/subsystem/persistence.dm
@@ -28,6 +28,7 @@ SUBSYSTEM_DEF(persistence)
LoadPhotoPersistence()
if(CONFIG_GET(flag/use_antag_rep))
LoadAntagReputation()
+ LoadRandomizedRecipes()
return ..()
/datum/controller/subsystem/persistence/proc/LoadSatchels()
@@ -206,6 +207,7 @@ SUBSYSTEM_DEF(persistence)
SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
if(CONFIG_GET(flag/use_antag_rep))
CollectAntagReputation()
+ SaveRandomizedRecipes()
/datum/controller/subsystem/persistence/proc/GetPhotoAlbums()
var/album_path = file("data/photo_albums.json")
@@ -371,3 +373,43 @@ SUBSYSTEM_DEF(persistence)
fdel(FILE_ANTAG_REP)
text2file(json_encode(antag_rep), FILE_ANTAG_REP)
+/datum/controller/subsystem/persistence/proc/LoadRandomizedRecipes()
+ var/json_file = file("data/RandomizedChemRecipes.json")
+ var/json
+ if(fexists(json_file))
+ json = json_decode(file2text(json_file))
+
+ for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized))
+ var/datum/chemical_reaction/randomized/R = new randomized_type
+ var/loaded = FALSE
+ if(R.persistent && json)
+ var/list/recipe_data = json[R.id]
+ if(recipe_data && R.LoadOldRecipe(recipe_data) && (daysSince(R.created) <= R.persistence_period))
+ loaded = TRUE
+ if(!loaded) //We do not have information for whatever reason, just generate new one
+ R.GenerateRecipe()
+
+ if(!R.HasConflicts()) //Might want to try again if conflicts happened in the future.
+ add_chemical_reaction(R)
+
+/datum/controller/subsystem/persistence/proc/SaveRandomizedRecipes()
+ var/json_file = file("data/RandomizedChemRecipes.json")
+ var/list/file_data = list()
+
+ //asert globchems done
+ for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized))
+ var/datum/chemical_reaction/randomized/R = randomized_type
+ R = get_chemical_reaction(initial(R.id)) //ew, would be nice to add some simple tracking
+ if(R && R.persistent && R.id)
+ var/recipe_data = list()
+ recipe_data["timestamp"] = R.created
+ recipe_data["required_reagents"] = R.required_reagents
+ recipe_data["required_catalysts"] = R.required_catalysts
+ recipe_data["required_temp"] = R.required_temp
+ recipe_data["is_cold_recipe"] = R.is_cold_recipe
+ recipe_data["results"] = R.results
+ recipe_data["required_container"] = "[R.required_container]"
+ file_data["[R.id]"] = recipe_data
+
+ fdel(json_file)
+ WRITE_FILE(json_file, json_encode(file_data))
diff --git a/code/controllers/subsystem/religion.dm b/code/controllers/subsystem/religion.dm
deleted file mode 100644
index 1c3cd76da4..0000000000
--- a/code/controllers/subsystem/religion.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-SUBSYSTEM_DEF(religion)
- name = "Religion"
- flags = SS_NO_FIRE|SS_NO_INIT
-
- var/religion
- var/deity
- var/bible_name
- var/bible_icon_state
- var/bible_item_state
- var/holy_weapon_type
- var/holy_armor_type
diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm
index d70493dedf..ee1f5b8c3d 100644
--- a/code/controllers/subsystem/traumas.dm
+++ b/code/controllers/subsystem/traumas.dm
@@ -72,7 +72,7 @@ SUBSYSTEM_DEF(traumas)
"security" = typecacheof(list(/obj/item/clothing/under/rank/security, /obj/item/clothing/under/rank/warden,
/obj/item/clothing/under/rank/head_of_security, /obj/item/clothing/under/rank/det,
/obj/item/melee/baton, /obj/item/gun/energy/taser, /obj/item/restraints/handcuffs,
- /obj/machinery/door/airlock/security)),
+ /obj/machinery/door/airlock/security, /obj/effect/hallucination/simple/securitron)),
"clowns" = typecacheof(list(/obj/item/clothing/under/rank/clown, /obj/item/clothing/shoes/clown_shoes,
/obj/item/clothing/mask/gas/clown_hat, /obj/item/instrument/bikehorn,
@@ -160,22 +160,22 @@ SUBSYSTEM_DEF(traumas)
/obj/item/grown/bananapeel/mimanapeel, /obj/item/cartridge/virus/mime, /obj/item/clothing/shoes/sneakers/mime,
/obj/item/bedsheet/mime, /obj/item/reagent_containers/food/snacks/burger/mime, /obj/item/clothing/head/beret, /obj/item/clothing/mask/gas/sexymime,
/obj/item/clothing/under/sexymime, /obj/item/toy/figure/mime, /obj/item/toy/crayon/mime, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced, /obj/mecha/combat/reticence)),
-
+
"cats" = typecacheof(list(/obj/item/organ/ears/cat, /obj/item/organ/tail/cat, /obj/item/laser_pointer, /obj/item/toy/cattoy, /obj/item/clothing/head/kitty,
/obj/item/clothing/head/collectable/kitty, /obj/item/melee/chainofcommand/tailwhip/kitty, /obj/item/stack/sheet/animalhide/cat)),
-
+
"syndicate" = typecacheof(list(/obj/item/stack/tile/mineral/plastitanium, /obj/machinery/computer/shuttle/syndicate, /obj/machinery/computer/shuttle/syndicate/recall, /obj/machinery/computer/shuttle/syndicate/drop_pod, /obj/machinery/computer/camera_advanced/shuttle_docker/syndicate, /obj/machinery/recharge_station,
/obj/machinery/porta_turret/syndicate, /obj/structure/closet/syndicate, /obj/machinery/suit_storage_unit/syndicate, /obj/item/clothing/under/syndicate, /obj/item/folder/syndicate, /obj/item/documents/syndicate, /obj/item/clothing/glasses/phantomthief/syndicate, /obj/item/antag_spawner/nuke_ops, /obj/item/storage/box/syndicate,
/obj/structure/fluff/empty_sleeper/syndicate, /obj/item/implant/radio/syndicate, /obj/item/clothing/head/helmet/space/syndicate, /obj/machinery/nuclearbomb/syndicate, /obj/item/grenade/syndieminibomb, /obj/item/storage/backpack/duffelbag/syndie, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver/syndie,
/obj/item/gun/ballistic/automatic/shotgun/bulldog, /obj/item/gun/ballistic/automatic/c20r, /obj/item/gun/ballistic/automatic/m90, /obj/item/gun/ballistic/automatic/l6_saw, /obj/item/storage/belt/grenade/full, /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate, /obj/item/gun/energy/kinetic_accelerator/crossbow,
- /obj/item/melee/transforming/energy/sword/saber, /obj/item/twohanded/dualsaber, /obj/item/melee/powerfist, /obj/item/storage/box/syndie_kit, /obj/item/grenade/spawnergrenade/manhacks, /obj/item/grenade/chem_grenade/bioterrorfoam, /obj/item/reagent_containers/spray/chemsprayer/bioterror, /obj/item/ammo_box/magazine/m10mm,
+ /obj/item/melee/transforming/energy/sword/saber, /obj/item/twohanded/dualsaber, /obj/item/melee/powerfist, /obj/item/storage/box/syndie_kit, /obj/item/grenade/spawnergrenade/manhacks, /obj/item/grenade/chem_grenade/bioterrorfoam, /obj/item/reagent_containers/spray/chemsprayer/bioterror, /obj/item/ammo_box/magazine/m10mm,
/obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/mecha/combat/gygax/dark, /obj/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate,
/obj/item/cartridge/virus/frame, /obj/item/chameleon, /obj/item/storage/box/syndie_kit/cutouts, /obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/card/emag, /obj/item/storage/toolbox/syndicate, /obj/item/storage/book/bible/syndicate, /obj/item/encryptionkey/binary, /obj/item/encryptionkey/syndicate, /obj/item/aiModule/syndicate,
- /obj/item/clothing/shoes/magboots/syndie, /obj/item/powersink, /obj/item/sbeacondrop, /obj/item/sbeacondrop/bomb, /obj/item/syndicatedetonator, /obj/item/shield/energy, /obj/item/assault_pod, /obj/item/slimepotion/slime/sentience/nuclear, /obj/item/stack/telecrystal, /obj/item/jammer, /obj/item/codespeak_manual/unlimited,
- /obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate,
- /obj/machinery/computer/pod/old/syndicate, /obj/machinery/vending/medical/syndicate_access, /obj/item/mmi/syndie, /obj/item/target/syndicate, /obj/machinery/vending/cigarette/syndicate, /obj/item/robot_module/syndicate, /obj/item/clothing/mask/gas/syndicate, /obj/machinery/power/singularity_beacon/syndicate, /obj/item/clothing/head/syndicatefake,
- /obj/item/radio/headset/syndicate, /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate, /obj/item/pda/syndicate, /obj/item/clothing/suit/armor/vest/capcarapace/syndicate, /obj/item/gun/ballistic/automatic/flechette, /obj/item/ammo_box/magazine/flechette, /obj/item/clothing/suit/toggle/lawyer/black/syndie, /obj/item/melee/transforming/energy/sword/cx/traitor,
- /obj/structure/sign/poster/contraband/syndicate_pistol, /obj/structure/sign/poster/contraband/syndicate_recruitment, /obj/item/bedsheet/syndie, /obj/item/borg/upgrade/syndicate, /obj/item/tank/jetpack/oxygen/harness, /obj/item/firing_pin/implant/pindicate, /obj/item/reagent_containers/glass/bottle/traitor, /obj/item/storage/belt/military,
+ /obj/item/clothing/shoes/magboots/syndie, /obj/item/powersink, /obj/item/sbeacondrop, /obj/item/sbeacondrop/bomb, /obj/item/syndicatedetonator, /obj/item/shield/energy, /obj/item/assault_pod, /obj/item/slimepotion/slime/sentience/nuclear, /obj/item/stack/telecrystal, /obj/item/jammer, /obj/item/codespeak_manual/unlimited,
+ /obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate,
+ /obj/machinery/computer/pod/old/syndicate, /obj/machinery/vending/medical/syndicate_access, /obj/item/mmi/syndie, /obj/item/target/syndicate, /obj/machinery/vending/cigarette/syndicate, /obj/item/robot_module/syndicate, /obj/item/clothing/mask/gas/syndicate, /obj/machinery/power/singularity_beacon/syndicate, /obj/item/clothing/head/syndicatefake,
+ /obj/item/radio/headset/syndicate, /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate, /obj/item/pda/syndicate, /obj/item/clothing/suit/armor/vest/capcarapace/syndicate, /obj/item/gun/ballistic/automatic/flechette, /obj/item/ammo_box/magazine/flechette, /obj/item/clothing/suit/toggle/lawyer/black/syndie, /obj/item/melee/transforming/energy/sword/cx/traitor,
+ /obj/structure/sign/poster/contraband/syndicate_pistol, /obj/structure/sign/poster/contraband/syndicate_recruitment, /obj/item/bedsheet/syndie, /obj/item/borg/upgrade/syndicate, /obj/item/tank/jetpack/oxygen/harness, /obj/item/firing_pin/implant/pindicate, /obj/item/reagent_containers/glass/bottle/traitor, /obj/item/storage/belt/military,
/obj/item/twohanded/shockpaddles/syndicate, /obj/item/clothing/mask/cigarette/syndicate, /obj/item/toy/plush/nukeplushie)),
"eye" = typecacheof(list(/obj/item/organ/eyes, /obj/item/reagent_containers/syringe))
@@ -199,7 +199,7 @@ SUBSYSTEM_DEF(traumas)
"anime" = typecacheof(list(/datum/species/human/felinid)),
"cats" = typecacheof(list(/datum/species/human/felinid)),
"syndicate" = typecacheof(list(/datum/species/corporate, /datum/species/zombie/infectious))
- )
+ )
return ..()
diff --git a/code/datums/brain_damage/brain_trauma.dm b/code/datums/brain_damage/brain_trauma.dm
index 941e7103c6..3731397170 100644
--- a/code/datums/brain_damage/brain_trauma.dm
+++ b/code/datums/brain_damage/brain_trauma.dm
@@ -9,7 +9,8 @@
var/obj/item/organ/brain/brain //the poor bastard's brain
var/gain_text = "You feel traumatized."
var/lose_text = "You no longer feel traumatized."
- var/can_gain = TRUE //can this be gained through random traumas?
+ var/can_gain = TRUE
+ var/random_gain = TRUE //can this be gained through random traumas?
var/resilience = TRAUMA_RESILIENCE_BASIC //how hard is this to cure?
/datum/brain_trauma/Destroy()
@@ -23,7 +24,7 @@
//Called on life ticks
/datum/brain_trauma/proc/on_life()
return
-
+
//Called on death
/datum/brain_trauma/proc/on_death()
return
diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm
index c6ccbee38c..71a5f21454 100644
--- a/code/datums/brain_damage/phobia.dm
+++ b/code/datums/brain_damage/phobia.dm
@@ -81,7 +81,7 @@
/datum/brain_trauma/mild/phobia/on_say(message)
for(var/word in trigger_words)
var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
-
+
if(findtext(message, reg))
to_chat(owner, "You can't bring yourself to say the word \"[word]\"!")
return ""
@@ -119,3 +119,7 @@
owner.confused += 10
owner.Jitter(10)
owner.stuttering += 10
+
+/datum/brain_trauma/mild/phobia/security
+ phobia_type = "security"
+ random_gain = FALSE
diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm
index e790e539c8..d094c162d7 100644
--- a/code/datums/brain_damage/severe.dm
+++ b/code/datums/brain_damage/severe.dm
@@ -60,18 +60,68 @@
/datum/brain_trauma/severe/paralysis
name = "Paralysis"
- desc = "Patient's brain can no longer control its motor functions."
+ desc = "Patient's brain can no longer control part of its motor functions."
scan_desc = "cerebral paralysis"
- gain_text = "You can't feel your body anymore!"
- lose_text = "You can feel your limbs again!"
+ gain_text = ""
+ lose_text = ""
+ var/paralysis_type
+ var/list/paralysis_traits = list()
+ //for descriptions
-/datum/brain_trauma/severe/paralysis/on_life()
- owner.Knockdown(200, ignore_canknockdown = TRUE)
+/datum/brain_trauma/severe/paralysis/New(specific_type)
+ if(specific_type)
+ paralysis_type = specific_type
+ if(!paralysis_type)
+ paralysis_type = pick("full","left","right","arms","legs","r_arm","l_arm","r_leg","l_leg")
+ var/subject
+ switch(paralysis_type)
+ if("full")
+ subject = "your body"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG)
+ if("left")
+ subject = "the left side of your body"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_L_LEG)
+ if("right")
+ subject = "the right side of your body"
+ paralysis_traits = list(TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_R_LEG)
+ if("arms")
+ subject = "your arms"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM)
+ if("legs")
+ subject = "your legs"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG)
+ if("r_arm")
+ subject = "your right arm"
+ paralysis_traits = list(TRAIT_PARALYSIS_R_ARM)
+ if("l_arm")
+ subject = "your left arm"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_ARM)
+ if("r_leg")
+ subject = "your right leg"
+ paralysis_traits = list(TRAIT_PARALYSIS_R_LEG)
+ if("l_leg")
+ subject = "your left leg"
+ paralysis_traits = list(TRAIT_PARALYSIS_L_LEG)
+
+ gain_text = "You can't feel [subject] anymore!"
+ lose_text = "You can feel [subject] again!"
+
+/datum/brain_trauma/severe/paralysis/on_gain()
..()
+ for(var/X in paralysis_traits)
+ ADD_TRAIT(owner, X, "trauma_paralysis")
+ owner.update_disabled_bodyparts()
/datum/brain_trauma/severe/paralysis/on_lose()
- owner.SetKnockdown(0)
..()
+ for(var/X in paralysis_traits)
+ REMOVE_TRAIT(owner, X, "trauma_paralysis")
+ owner.update_disabled_bodyparts()
+
+/datum/brain_trauma/severe/paralysis/paraplegic
+ //can_gain = FALSE maybe breaks.
+ paralysis_type = "legs"
+ resilience = TRAUMA_RESILIENCE_ABSOLUTE
/datum/brain_trauma/severe/narcolepsy
name = "Narcolepsy"
@@ -203,4 +253,4 @@
/datum/brain_trauma/severe/pacifism/on_lose()
REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT)
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm
index 0bbbf8de08..d9e6f00643 100644
--- a/code/datums/brain_damage/special.dm
+++ b/code/datums/brain_damage/special.dm
@@ -134,3 +134,71 @@
/datum/brain_trauma/special/psychotic_brawling/bath_salts
name = "Chemical Violent Psychosis"
+ random_gain = FALSE
+
+/datum/brain_trauma/special/beepsky
+ name = "Criminal"
+ desc = "Patient seems to be a criminal."
+ scan_desc = "criminal mind"
+ gain_text = "Justice is coming for you."
+ lose_text = "You were absolved for your crimes."
+ random_gain = FALSE
+ var/obj/effect/hallucination/simple/securitron/beepsky
+
+/datum/brain_trauma/special/beepsky/on_gain()
+ create_securitron()
+ ..()
+
+/datum/brain_trauma/special/beepsky/proc/create_securitron()
+ var/turf/where = locate(owner.x + pick(-12, 12), owner.y + pick(-12, 12), owner.z)
+ beepsky = new(where, owner)
+ beepsky.victim = owner
+
+/datum/brain_trauma/special/beepsky/on_lose()
+ QDEL_NULL(beepsky)
+ ..()
+
+/datum/brain_trauma/special/beepsky/on_life()
+ if(QDELETED(beepsky) || !beepsky.loc || beepsky.z != owner.z)
+ QDEL_NULL(beepsky)
+ if(prob(30))
+ create_securitron()
+ else
+ return
+ if(get_dist(owner, beepsky) >= 10 && prob(20))
+ QDEL_NULL(beepsky)
+ create_securitron()
+ if(owner.stat != CONSCIOUS)
+ if(prob(20))
+ owner.playsound_local(beepsky, 'sound/voice/beepsky/iamthelaw.ogg', 50)
+ return
+ if(get_dist(owner, beepsky) <= 1)
+ owner.playsound_local(owner, 'sound/weapons/egloves.ogg', 50)
+ owner.visible_message("[owner]'s body jerks as if it was shocked.", "You feel the fist of the LAW.")
+ owner.take_bodypart_damage(0,0,rand(40, 70))
+ QDEL_NULL(beepsky)
+ if(prob(20) && get_dist(owner, beepsky) <= 8)
+ owner.playsound_local(beepsky, 'sound/voice/beepsky/criminal.ogg', 40)
+ ..()
+
+/obj/effect/hallucination/simple/securitron
+ name = "Securitron"
+ desc = "The LAW is coming."
+ image_icon = 'icons/mob/aibots.dmi'
+ image_state = "secbot-c"
+ var/victim
+
+/obj/effect/hallucination/simple/securitron/New()
+ name = pick ( "officer Beepsky", "officer Johnson", "officer Pingsky")
+ START_PROCESSING(SSfastprocess,src)
+ ..()
+
+/obj/effect/hallucination/simple/securitron/process()
+ if(prob(60))
+ forceMove(get_step_towards(src, victim))
+ if(prob(5))
+ to_chat(victim, "[name] exclaims, \"Level 10 infraction alert!\"")
+
+/obj/effect/hallucination/simple/securitron/Destroy()
+ STOP_PROCESSING(SSfastprocess,src)
+ return ..()
\ No newline at end of file
diff --git a/code/datums/components/orbiter.dm b/code/datums/components/orbiter.dm
new file mode 100644
index 0000000000..301e50dc42
--- /dev/null
+++ b/code/datums/components/orbiter.dm
@@ -0,0 +1,156 @@
+/datum/component/orbiter
+ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+ var/list/orbiters
+ var/datum/callback/orbiter_spy
+ var/datum/callback/orbited_spy
+
+//radius: range to orbit at, radius of the circle formed by orbiting (in pixels)
+//clockwise: whether you orbit clockwise or anti clockwise
+//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete)
+//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default.
+//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts
+/datum/component/orbiter/Initialize(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
+ if(!istype(orbiter) || !isatom(parent) || isarea(parent))
+ return COMPONENT_INCOMPATIBLE
+
+ orbiters = list()
+ orbiter_spy = CALLBACK(src, .proc/orbiter_move_react)
+ orbited_spy = CALLBACK(src, .proc/move_react)
+
+ var/atom/master = parent
+ master.orbiters = src
+
+ begin_orbit(orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
+
+/datum/component/orbiter/RegisterWithParent()
+ var/atom/target = parent
+ while(ismovableatom(target))
+ RegisterSignal(target, COMSIG_MOVABLE_MOVED, orbited_spy)
+ target = target.loc
+
+/datum/component/orbiter/UnregisterFromParent()
+ var/atom/target = parent
+ while(ismovableatom(target))
+ UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
+ target = target.loc
+
+/datum/component/orbiter/Destroy()
+ var/atom/master = parent
+ master.orbiters = null
+ for(var/i in orbiters)
+ end_orbit(i)
+ orbiters = null
+ QDEL_NULL(orbiter_spy)
+ QDEL_NULL(orbited_spy)
+ return ..()
+
+/datum/component/orbiter/InheritComponent(datum/component/orbiter/newcomp, original, list/arguments)
+ if(arguments)
+ begin_orbit(arglist(arguments))
+ return
+ // The following only happens on component transfers
+ orbiters += newcomp.orbiters
+
+/datum/component/orbiter/PostTransfer()
+ if(!isatom(parent) || isarea(parent) || !get_turf(parent))
+ return COMPONENT_INCOMPATIBLE
+ move_react()
+
+/datum/component/orbiter/proc/begin_orbit(atom/movable/orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
+ if(orbiter.orbiting)
+ if(orbiter.orbiting == src)
+ orbiter.orbiting.end_orbit(orbiter, TRUE)
+ else
+ orbiter.orbiting.end_orbit(orbiter)
+ orbiters[orbiter] = TRUE
+ orbiter.orbiting = src
+ RegisterSignal(orbiter, COMSIG_MOVABLE_MOVED, orbiter_spy)
+ var/matrix/initial_transform = matrix(orbiter.transform)
+
+ // Head first!
+ if(pre_rotation)
+ var/matrix/M = matrix(orbiter.transform)
+ var/pre_rot = 90
+ if(!clockwise)
+ pre_rot = -90
+ M.Turn(pre_rot)
+ orbiter.transform = M
+
+ var/matrix/shift = matrix(orbiter.transform)
+ shift.Translate(0, radius)
+ orbiter.transform = shift
+
+ orbiter.SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE)
+
+ //we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
+ orbiter.transform = initial_transform
+ orbiter.forceMove(get_turf(parent))
+ to_chat(orbiter, "Now orbiting [parent].")
+
+/datum/component/orbiter/proc/end_orbit(atom/movable/orbiter, refreshing=FALSE)
+ if(!orbiters[orbiter])
+ return
+ UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED)
+ orbiter.SpinAnimation(0, 0)
+ orbiters -= orbiter
+ orbiter.stop_orbit(src)
+ orbiter.orbiting = null
+ if(!refreshing && !length(orbiters) && !QDELING(src))
+ qdel(src)
+
+// This proc can receive signals by either the thing being directly orbited or anything holding it
+/datum/component/orbiter/proc/move_react(atom/orbited, atom/oldloc, direction)
+ set waitfor = FALSE // Transfer calls this directly and it doesnt care if the ghosts arent done moving
+
+ var/atom/movable/master = parent
+ if(master.loc == oldloc)
+ return
+
+ var/turf/newturf = get_turf(master)
+ if(!newturf)
+ qdel(src)
+
+ // Handling the signals of stuff holding us (or not anymore)
+ // These are prety rarely activated, how often are you following something in a bag?
+ if(oldloc && !isturf(oldloc)) // We used to be registered to it, probably
+ var/atom/target = oldloc
+ while(ismovableatom(target))
+ UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
+ target = target.loc
+ if(orbited?.loc && orbited.loc != newturf) // We want to know when anything holding us moves too
+ var/atom/target = orbited.loc
+ while(ismovableatom(target))
+ RegisterSignal(target, COMSIG_MOVABLE_MOVED, orbited_spy, TRUE)
+ target = target.loc
+
+ var/atom/curloc = master.loc
+ for(var/i in orbiters)
+ var/atom/movable/thing = i
+ if(QDELETED(thing) || thing.loc == newturf)
+ continue
+ thing.forceMove(newturf)
+ if(CHECK_TICK && master.loc != curloc)
+ // We moved again during the checktick, cancel current operation
+ break
+
+
+/datum/component/orbiter/proc/orbiter_move_react(atom/movable/orbiter, atom/oldloc, direction)
+ if(orbiter.loc == get_turf(parent))
+ return
+ end_orbit(orbiter)
+
+/////////////////////
+
+/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE)
+ if(!istype(A) || !get_turf(A) || A == src)
+ return
+
+ return A.AddComponent(/datum/component/orbiter, src, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
+
+/atom/movable/proc/stop_orbit(datum/component/orbiter/orbits)
+ return // We're just a simple hook
+
+/atom/proc/transfer_observers_to(atom/target)
+ if(!orbiters || !istype(target) || !get_turf(target) || target == src)
+ return
+ target.TakeComponent(orbiters)
diff --git a/code/datums/components/storage/concrete/emergency.dm b/code/datums/components/storage/concrete/emergency.dm
index e5f9d83a17..48880ff605 100644
--- a/code/datums/components/storage/concrete/emergency.dm
+++ b/code/datums/components/storage/concrete/emergency.dm
@@ -7,12 +7,28 @@
. = ..()
RegisterSignal(parent, COMSIG_ATOM_EMAG_ACT, .proc/unlock_me)
+/datum/component/storage/concrete/emergency/on_attack_hand(datum/source, mob/user)
+ var/atom/A = parent
+ if(!attack_hand_interact)
+ return
+ if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item
+ user.active_storage.close(user)
+ close(user)
+ . = COMPONENT_NO_ATTACK_HAND
+ return
+ . = COMPONENT_NO_ATTACK_HAND
+ if(!check_locked(source, user, TRUE))
+ show_to(user)
+ A.do_jiggle()
+ if(rustle_sound)
+ playsound(A, "rustle", 50, 1, -5)
+
/datum/component/storage/concrete/emergency/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
if(!silent && istype(I, /obj/item/card/emag))
silent = TRUE // suppresses the message
return ..()
-/datum/component/storage/concrete/check_locked(datum/source, mob/user, message = FALSE)
+/datum/component/storage/concrete/emergency/check_locked(datum/source, mob/user, message = FALSE)
. = locked && GLOB.security_level < SEC_LEVEL_RED
if(message && . && user)
to_chat(user, "The storage unit will only unlock during a Red or Delta security alert.")
diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm
index 869fe59ae9..52d0036154 100644
--- a/code/datums/components/storage/storage.dm
+++ b/code/datums/components/storage/storage.dm
@@ -531,11 +531,9 @@
if(!istype(M))
return FALSE
A.add_fingerprint(M)
- if(locked && !force)
- to_chat(M, "[parent] seems to be locked!")
+ if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE)))
return FALSE
- if(force || M.CanReach(parent, view_only = TRUE))
- show_to(M)
+ show_to(M)
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
if(isitem(O))
@@ -749,7 +747,8 @@
if(!quickdraw)
A.add_fingerprint(user)
user_show_to_mob(user)
- playsound(A, "rustle", 50, 1, -5)
+ if(rustle_sound)
+ playsound(A, "rustle", 50, 1, -5)
return
if(!user.incapacitated())
diff --git a/code/datums/martial.dm b/code/datums/martial.dm
index 2bc01e0bf6..ae8f92a342 100644
--- a/code/datums/martial.dm
+++ b/code/datums/martial.dm
@@ -5,6 +5,7 @@
var/current_target
var/datum/martial_art/base // The permanent style. This will be null unless the martial art is temporary
var/deflection_chance = 0 //Chance to deflect projectiles
+ var/reroute_deflection = FALSE //Delete the bullet, or actually deflect it in some direction?
var/block_chance = 0 //Chance to block melee attacks using items while on throw mode.
var/restraining = 0 //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not
var/help_verb
diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm
index 035e5ac833..5f19c37b99 100644
--- a/code/datums/martial/sleeping_carp.dm
+++ b/code/datums/martial/sleeping_carp.dm
@@ -7,6 +7,7 @@
/datum/martial_art/the_sleeping_carp
name = "The Sleeping Carp"
deflection_chance = 100
+ reroute_deflection = TRUE
no_guns = TRUE
allow_temp_override = FALSE
help_verb = /mob/living/carbon/human/proc/sleeping_carp_help
diff --git a/code/datums/mood_events/drink_events.dm b/code/datums/mood_events/drink_events.dm
index db5a91009e..5d0eb0e0cb 100644
--- a/code/datums/mood_events/drink_events.dm
+++ b/code/datums/mood_events/drink_events.dm
@@ -22,3 +22,8 @@
description = "That drink was amazing!\n"
mood_change = 4
timeout = 1200
+
+/datum/mood_event/amazingtaste
+ description = "Amazing taste!\n"
+ mood_change = 50
+ timeout = 10 MINUTES
diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index 06857c0f55..b2b03fb56b 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -117,6 +117,16 @@
description = "I'm missing my family heirloom...\n"
mood_change = -4
+/datum/mood_event/loud_gong
+ description = "That loud gong noise really hurt my ears!\n"
+ mood_change = -3
+ timeout = 1200
+
+/datum/mood_event/spooked
+ description = "The rattling of those bones...It still haunts me.\n"
+ mood_change = -4
+ timeout = 2400
+
//These are unused so far but I want to remember them to use them later
/datum/mood_event/cloned_corpse
description = "I recently saw my own corpse...\n"
diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm
index 058c820f7a..22fca23902 100644
--- a/code/datums/ruins/space.dm
+++ b/code/datums/ruins/space.dm
@@ -281,3 +281,27 @@
suffix = "cloning_facility.dmm"
name = "Ancient Cloning Lab"
description = "An experimental cloning lab snapped off from an ancient ship. The cloner model inside lacks many modern functionalities and security measures."
+
+/datum/map_template/ruin/space/augmentation
+ id = "augmentationfacility"
+ suffix = "augmentationfacility.dmm"
+ name = "Roboticst Augmentation Facility"
+ description = "A mysterious lab in the depths of space containing robotics supplies and a one use autosurgeon."
+
+/datum/map_template/ruin/space/harambe
+ id = "bigape"
+ suffix = "bigape.dmm"
+ name = "Big Ape"
+ description = "A gorilla? Out here? But why."
+
+/datum/map_template/ruin/space/space_arcade
+ id = "arcade"
+ suffix = "arcade.dmm"
+ name = "Space Arcade"
+ description = "A lonely arcade in the depths of space."
+
+/datum/map_template/ruin/space/hermit
+ id = "spacehermit"
+ suffix = "spacehermit.dmm"
+ name = "Space Hermit"
+ description = "A late awakening cryo pod in a crashed escape pod wakes up to find what befell of his fellow survivors. Contains all the necessary resources to actually make it out alive. Good luck."
diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm
index 43be1fa2a7..36c6733cf7 100644
--- a/code/datums/traits/negative.dm
+++ b/code/datums/traits/negative.dm
@@ -38,13 +38,13 @@
var/obj/item/heirloom_type
switch(quirk_holder.mind.assigned_role)
if("Clown")
- heirloom_type = /obj/item/paint/anycolor
- heirloom_type = /obj/item/bikehorn/golden
+ heirloom_type = pick(/obj/item/paint/anycolor, /obj/item/bikehorn/golden)
if("Mime")
- heirloom_type = /obj/item/paint/anycolor
- heirloom_type = /obj/item/toy/dummy
+ heirloom_type = pick(/obj/item/paint/anycolor, /obj/item/toy/dummy)
if("Cook")
heirloom_type = /obj/item/kitchen/knife/scimitar
+ if("Botanist")
+ heirloom_type = pick(/obj/item/cultivator, /obj/item/reagent_containers/glass/bucket, /obj/item/storage/bag/plants, /obj/item/toy/plush/beeplushie)
if("Medical Doctor")
heirloom_type = /obj/item/healthanalyzer/advanced
if("Station Engineer")
@@ -187,6 +187,41 @@
to_chat(quirk_holder, "Your antagonistic nature has caused you to renounce your pacifism.")
qdel(src)
+/datum/quirk/paraplegic
+ name = "Paraplegic"
+ desc = "Your legs do not function. Nothing will ever fix this. But hey, free wheelchair!"
+ value = -3
+ mob_trait = TRAIT_PARA
+ human_only = TRUE
+ gain_text = null // Handled by trauma.
+ lose_text = null
+ medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities."
+
+/datum/quirk/paraplegic/add()
+ var/datum/brain_trauma/severe/paralysis/paraplegic/T = new()
+ var/mob/living/carbon/human/H = quirk_holder
+ H.gain_trauma(T, TRAUMA_RESILIENCE_ABSOLUTE)
+
+/datum/quirk/paraplegic/on_spawn()
+ if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs.
+ quirk_holder.buckled.unbuckle_mob(quirk_holder)
+
+ var/turf/T = get_turf(quirk_holder)
+ var/obj/structure/chair/spawn_chair = locate() in T
+
+ var/obj/vehicle/ridden/wheelchair/wheels = new(T)
+ if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
+ wheels.setDir(spawn_chair.dir)
+
+ wheels.buckle_mob(quirk_holder)
+
+ // During the spawning process, they may have dropped what they were holding, due to the paralysis
+ // So put the things back in their hands.
+
+ for(var/obj/item/I in T)
+ if(I.fingerprintslast == quirk_holder.ckey)
+ quirk_holder.put_in_hands(I)
+
/datum/quirk/poor_aim
name = "Poor Aim"
desc = "You're terrible with guns and can't line up a straight shot to save your life. Dual-wielding is right out."
@@ -208,8 +243,12 @@
var/slot_string = "limb"
/datum/quirk/prosthetic_limb/on_spawn()
- var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/mob/living/carbon/human/H = quirk_holder
+ var/limb_slot
+ if(HAS_TRAIT(H, TRAIT_PARA))//Prevent paraplegic legs being replaced
+ limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
+ else
+ limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot)
var/obj/item/bodypart/prosthetic
switch(limb_slot)
diff --git a/code/datums/wires/microwave.dm b/code/datums/wires/microwave.dm
new file mode 100644
index 0000000000..8c74abfa46
--- /dev/null
+++ b/code/datums/wires/microwave.dm
@@ -0,0 +1,27 @@
+/datum/wires/microwave
+ holder_type = /obj/machinery/microwave
+ proper_name = "Microwave"
+
+/datum/wires/microwave/New(atom/holder)
+ wires = list(
+ WIRE_ACTIVATE
+ )
+ ..()
+
+/datum/wires/microwave/interactable(mob/user)
+ . = FALSE
+ var/obj/machinery/microwave/M = holder
+ if(M.panel_open)
+ . = TRUE
+
+/datum/wires/microwave/on_pulse(wire)
+ var/obj/machinery/microwave/M = holder
+ switch(wire)
+ if(WIRE_ACTIVATE)
+ M.cook()
+
+/datum/wires/microwave/on_cut(wire, mend)
+ var/obj/machinery/microwave/M = holder
+ switch(wire)
+ if(WIRE_ACTIVATE)
+ M.wire_disabled = !mend
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 10650153d6..dfbb59811b 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -76,7 +76,9 @@ GLOBAL_LIST_EMPTY(teleportlocs)
continue
if(GLOB.teleportlocs[AR.name])
continue
- var/turf/picked = safepick(get_area_turfs(AR.type))
+ if (!AR.contents.len)
+ continue
+ var/turf/picked = AR.contents[1]
if (picked && is_station_level(picked.z))
GLOB.teleportlocs[AR.name] = AR
@@ -120,6 +122,14 @@ GLOBAL_LIST_EMPTY(teleportlocs)
if(!IS_DYNAMIC_LIGHTING(src))
add_overlay(/obj/effect/fullbright)
+ reg_in_areas_in_z()
+
+ return INITIALIZE_HINT_LATELOAD
+
+/area/LateInitialize()
+ power_change() // all machines set to current power level, also updates icon
+
+/area/proc/reg_in_areas_in_z()
if(contents.len)
var/list/areas_in_z = SSmapping.areas_in_z
var/z
@@ -137,11 +147,6 @@ GLOBAL_LIST_EMPTY(teleportlocs)
areas_in_z["[z]"] = list()
areas_in_z["[z]"] += src
- return INITIALIZE_HINT_LATELOAD
-
-/area/LateInitialize()
- power_change() // all machines set to current power level, also updates icon
-
/area/Destroy()
if(GLOB.areas_by_type[type] == src)
GLOB.areas_by_type[type] = null
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 81e2371f9a..f2eb23808e 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -31,6 +31,8 @@
var/list/filter_data //For handling persistent filters
+ var/datum/component/orbiter/orbiters
+
var/rad_flags = NONE // Will move to flags_1 when i can be arsed to
var/rad_insulation = RAD_NO_INSULATION
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index c37c120b93..f88f4f8e41 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -31,6 +31,7 @@
var/atom/movable/pulling
var/grab_state = 0
var/throwforce = 0
+ var/datum/component/orbiter/orbiting
var/can_be_z_moved = TRUE
/atom/movable/vv_edit_var(var_name, var_value)
@@ -296,14 +297,7 @@
if (length(client_mobs_in_contents))
update_parallax_contents()
- if (orbiters)
- for (var/thing in orbiters)
- var/datum/orbit/O = thing
- O.Check()
- if (orbiting)
- orbiting.Check()
-
- return 1
+ return TRUE
/atom/movable/Destroy(force)
QDEL_NULL(proximity_monitor)
@@ -325,6 +319,10 @@
if(pulledby)
pulledby.stop_pulling()
+ if(orbiting)
+ orbiting.end_orbit(src)
+ orbiting = null
+
// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly.
// You probably want CanPass()
/atom/movable/Cross(atom/movable/AM)
diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm
index 53aebc53dc..45a3b59661 100644
--- a/code/game/machinery/PDApainter.dm
+++ b/code/game/machinery/PDApainter.dm
@@ -35,15 +35,14 @@
/obj/item/pda/clear,
/obj/item/pda/syndicate,
/obj/item/pda/chameleon,
- /obj/item/pda/chameleon/broken)
+ /obj/item/pda/chameleon/broken,
+ /obj/item/pda/lieutenant)
- for(var/P in typesof(/obj/item/pda) - blocked)
- var/obj/item/pda/D = new P
-
- //D.name = "PDA Style [colorlist.len+1]" //Gotta set the name, otherwise it all comes up as "PDA"
- D.name = D.icon_state //PDAs don't have unique names, but using the sprite names works.
-
- src.colorlist += D
+ for(var/A in typesof(/obj/item/pda) - blocked)
+ var/obj/item/pda/P = A
+ var/PDA_name = initial(P.name)
+ colorlist += PDA_name
+ colorlist[PDA_name] = list(initial(P.icon_state), initial(P.desc), initial(P.overlays_offsets), initial(P.overlays_icons))
/obj/machinery/pdapainter/Destroy()
QDEL_NULL(storedpda)
@@ -108,22 +107,20 @@
if(.)
return
- if(storedpda)
- var/obj/item/pda/P
- P = input(user, "Select your color!", "PDA Painting") as null|anything in colorlist
- if(!P)
- return
- if(!in_range(src, user))
- return
- if(!storedpda)//is the pda still there?
- return
- storedpda.icon_state = P.icon_state
- storedpda.desc = P.desc
- ejectpda()
-
- else
+ if(!storedpda)
to_chat(user, "[src] is empty.")
-
+ return
+ var/choice = input(user, "Select the new skin!", "PDA Painting") as null|anything in colorlist
+ if(!choice || !storedpda || !in_range(src, user))
+ return
+ var/list/P = colorlist[choice]
+ storedpda.icon_state = P[1]
+ storedpda.desc = P[2]
+ storedpda.overlays_offsets = P[3]
+ storedpda.overlays_icons = P[4]
+ storedpda.set_new_overlays()
+ storedpda.update_icon()
+ ejectpda()
/obj/machinery/pdapainter/verb/ejectpda()
set name = "Eject PDA"
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 9b5aa96b0b..b0e4c699d7 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -168,9 +168,11 @@ Class Procs:
update_icon()
updateUsrDialog()
-/obj/machinery/proc/dropContents()
+/obj/machinery/proc/dropContents(list/subset = null)
var/turf/T = get_turf(src)
for(var/atom/movable/A in contents)
+ if(subset && !(A in subset))
+ continue
A.forceMove(T)
if(isliving(A))
var/mob/living/L = A
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index efbbe36228..8d0cfb95e8 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -1,7 +1,7 @@
#define ARCADE_WEIGHT_TRICK 4
#define ARCADE_WEIGHT_USELESS 2
#define ARCADE_WEIGHT_RARE 1
-#define ARCADE_WEIGHT_PLUSH 3
+#define ARCADE_WEIGHT_PLUSH 65
/obj/machinery/computer/arcade
@@ -32,7 +32,6 @@
/obj/item/toy/spinningtoy = ARCADE_WEIGHT_TRICK,
/obj/item/toy/sword = ARCADE_WEIGHT_TRICK,
/obj/item/toy/sword/cx = ARCADE_WEIGHT_TRICK,
- /obj/item/toy/sword/darksabre = ARCADE_WEIGHT_TRICK,
/obj/item/toy/talking/AI = ARCADE_WEIGHT_USELESS,
/obj/item/toy/talking/codex_gigas = ARCADE_WEIGHT_USELESS,
/obj/item/toy/talking/griffin = ARCADE_WEIGHT_USELESS,
@@ -41,7 +40,6 @@
/obj/item/toy/toy_xeno = ARCADE_WEIGHT_TRICK,
/obj/item/toy/windupToolbox = ARCADE_WEIGHT_TRICK,
- /obj/item/twohanded/dualsaber/toy = ARCADE_WEIGHT_RARE,
/mob/living/simple_animal/bot/secbot/grievous/toy = ARCADE_WEIGHT_RARE,
/obj/item/clothing/mask/facehugger/toy = ARCADE_WEIGHT_RARE,
/obj/item/gun/ballistic/automatic/toy/pistol/unrestricted = ARCADE_WEIGHT_TRICK,
@@ -83,13 +81,17 @@
// If it's a generic arcade machine, pick a random arcade
// circuit board for it and make the new machine
if(!circuit)
- var/choice = pick(subtypesof(/obj/item/circuitboard/computer/arcade))
- var/obj/item/circuitboard/CB = new choice()
+ var/list/gameodds = list(/obj/item/circuitboard/computer/arcade/battle = 33,
+ /obj/item/circuitboard/computer/arcade/orion_trail = 33,
+ /obj/item/circuitboard/computer/arcade/minesweeper = 33,
+ /obj/item/circuitboard/computer/arcade/amputation = 2)
+ var/thegame = pickweight(gameodds)
+ var/obj/item/circuitboard/CB = new thegame()
new CB.build_path(loc, CB)
return INITIALIZE_HINT_QDEL
Reset()
-/obj/machinery/computer/arcade/proc/prizevend(mob/user)
+/obj/machinery/computer/arcade/proc/prizevend(mob/user, list/rarity_classes)
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "arcade", /datum/mood_event/arcade)
if(prob(1) && prob(1) && prob(1)) //Proper 1 in a million
@@ -97,7 +99,14 @@
SSmedals.UnlockMedal(MEDAL_PULSE, usr.client)
if(!contents.len)
- var/prizeselect = pickweight(prizes)
+ var/list/toy_raffle
+ if(rarity_classes)
+ for(var/A in prizes)
+ if(prizes[A] in rarity_classes)
+ LAZYSET(toy_raffle, A, prizes[A])
+ if(!toy_raffle)
+ toy_raffle = prizes
+ var/prizeselect = pickweight(toy_raffle)
new prizeselect(src)
var/atom/movable/prize = pick(contents)
@@ -122,1022 +131,3 @@
empprize = pickweight(prizes)
new empprize(loc)
explosion(loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes)
-
-
-// ** BATTLE ** //
-
-
-/obj/machinery/computer/arcade/battle
- name = "arcade machine"
- desc = "Does not support Pinball."
- icon_state = "arcade"
- circuit = /obj/item/circuitboard/computer/arcade/battle
- var/enemy_name = "Space Villain"
- var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc
- var/player_hp = 30 //Player health/attack points
- var/player_mp = 10
- var/enemy_hp = 45 //Enemy health/attack points
- var/enemy_mp = 20
- var/gameover = FALSE
- var/blocked = FALSE //Player cannot attack/heal while set
- var/turtle = 0
-
- var/turn_speed = 5 //Measured in deciseconds.
-
-/obj/machinery/computer/arcade/battle/Reset()
- var/name_action
- var/name_part1
- var/name_part2
-
- name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "Ban ")
-
- name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ")
- name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers")
-
- enemy_name = replacetext((name_part1 + name_part2), "the ", "")
- name = (name_action + name_part1 + name_part2)
-
-/obj/machinery/computer/arcade/battle/ui_interact(mob/user)
- . = ..()
- var/dat = "Close"
- dat += "
Crew Management:
" - - //Buy crew - if(food >= 10 && fuel >= 10) - eventdat += "Hire a New Crewmember (-10FU, -10FO)
" - else - eventdat += "You cannot afford a new crewmember.
" - - //Sell crew - if(settlers.len > 1) - eventdat += "Sell Crew for Fuel and Food (+7FU, +7FO)
" - else - eventdat += "You have no other crew to sell.
" - - //BUY/SELL STUFF - eventdat += "Spare Parts:
" - - //Engine parts - if(fuel > 5) - eventdat += "" - else - eventdat += "You cannot afford engine parts." - - //Hull plates - if(fuel > 5) - eventdat += "
" - else - eventdat += "You cannot afford hull plates." - - //Electronics - if(fuel > 5) - eventdat += "
" - else - eventdat += "You cannot afford spare electronics." - - //Trade - if(fuel > 5) - eventdat += "
Trade Fuel for Food (-5FU,+5FO)
" - else - eventdat += "You don't have 5FU to trade.
5) - eventdat += "Trade Food for Fuel (+5FU,-5FO)
" - else - eventdat += "You don't have 5FO to trade.
!! Raid Spaceport !!" - - eventdat += "" - - -//Add Random/Specific crewmember -/obj/machinery/computer/arcade/orion_trail/proc/add_crewmember(var/specific = "") - var/newcrew = "" - if(specific) - newcrew = specific - else - if(prob(50)) - newcrew = pick(GLOB.first_names_male) - else - newcrew = pick(GLOB.first_names_female) - if(newcrew) - settlers += newcrew - alive++ - return newcrew - - -//Remove Random/Specific crewmember -/obj/machinery/computer/arcade/orion_trail/proc/remove_crewmember(var/specific = "", var/dont_remove = "") - var/list/safe2remove = settlers - var/removed = "" - if(dont_remove) - safe2remove -= dont_remove - if(specific && specific != dont_remove) - safe2remove = list(specific) - else - removed = pick(safe2remove) - - if(removed) - if(lings_aboard && prob(40*lings_aboard)) //if there are 2 lings you're twice as likely to get one, obviously - lings_aboard = max(0,--lings_aboard) - settlers -= removed - alive-- - return removed - - -/obj/machinery/computer/arcade/orion_trail/proc/win(mob/user) - gameStatus = ORION_STATUS_START - say("Congratulations, you made it to Orion!") - if(obj_flags & EMAGGED) - new /obj/item/orion_ship(loc) - message_admins("[ADMIN_LOOKUPFLW(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") - log_game("[key_name(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") - else - prizevend(user) - obj_flags &= ~EMAGGED - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - -/obj/machinery/computer/arcade/orion_trail/emag_act(mob/user) - if(obj_flags & EMAGGED) - return - to_chat(user, "You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.") - name = "The Orion Trail: Realism Edition" - desc = "Learn how our ancestors got to Orion, and try not to die in the process!" - newgame() - obj_flags |= EMAGGED - -/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion - name = "spaceport security" - desc = "Premier corporate security forces for all spaceports found along the Orion Trail." - faction = list("orion") - loot = list() - del_on_death = TRUE - -/obj/item/orion_ship - name = "model settler ship" - desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." - icon = 'icons/obj/toy.dmi' - icon_state = "ship" - w_class = WEIGHT_CLASS_SMALL - var/active = 0 //if the ship is on - -/obj/item/orion_ship/examine(mob/user) - ..() - if(!(in_range(user, src))) - return - if(!active) - to_chat(user, "There's a little switch on the bottom. It's flipped down.") - else - to_chat(user, "There's a little switch on the bottom. It's flipped up.") - -/obj/item/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse - if(active) - return - - message_admins("[ADMIN_LOOKUPFLW(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].") - log_game("[key_name(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].") - - to_chat(user, "You flip the switch on the underside of [src].") - active = 1 - visible_message("[src] softly beeps and whirs to life!") - playsound(loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1) - say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") - sleep(20) - visible_message("[src] begins to vibrate...") - say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") - sleep(30) - say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") - playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, 1) - sleep(3.6) - visible_message("[src] explodes!") - explosion(loc, 2,4,8, flame_range = 16) - qdel(src) - - -#undef ORION_TRAIL_WINTURN -#undef ORION_TRAIL_RAIDERS -#undef ORION_TRAIL_FLUX -#undef ORION_TRAIL_ILLNESS -#undef ORION_TRAIL_BREAKDOWN -#undef ORION_TRAIL_LING -#undef ORION_TRAIL_LING_ATTACK -#undef ORION_TRAIL_MALFUNCTION -#undef ORION_TRAIL_COLLISION -#undef ORION_TRAIL_SPACEPORT -#undef ORION_TRAIL_BLACKHOLE - -#undef ORION_STATUS_START -#undef ORION_STATUS_NORMAL -#undef ORION_STATUS_GAMEOVER -#undef ORION_STATUS_MARKET diff --git a/code/game/machinery/computer/arcade/battle.dm b/code/game/machinery/computer/arcade/battle.dm new file mode 100644 index 0000000000..ded9cf95f6 --- /dev/null +++ b/code/game/machinery/computer/arcade/battle.dm @@ -0,0 +1,206 @@ +// ** BATTLE ** // + + +/obj/machinery/computer/arcade/battle + name = "arcade machine" + desc = "Does not support Pinball." + icon_state = "arcade" + circuit = /obj/item/circuitboard/computer/arcade/battle + var/enemy_name = "Space Villain" + var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc + var/player_hp = 30 //Player health/attack points + var/player_mp = 10 + var/enemy_hp = 45 //Enemy health/attack points + var/enemy_mp = 20 + var/gameover = FALSE + var/blocked = FALSE //Player cannot attack/heal while set + var/turtle = 0 + + var/turn_speed = 5 //Measured in deciseconds. + +/obj/machinery/computer/arcade/battle/Reset() + var/name_action + var/name_part1 + var/name_part2 + + name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "Ban ") + + name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") + name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers") + + enemy_name = replacetext((name_part1 + name_part2), "the ", "") + name = (name_action + name_part1 + name_part2) + +/obj/machinery/computer/arcade/battle/ui_interact(mob/user) + . = ..() + var/dat = "Close" + dat += "| [MINESWEEPERIMG(flag)] | " + if(0) + if(game_status != MINESWEEPER_GAME_PLAYING) + web += "[MINESWEEPERIMG(mine)] | " + else + web += "[MINESWEEPERIMG(hidden)] | " //Make unique hrefs for every square + if(1 to 9) + if(game_status != MINESWEEPER_GAME_PLAYING) + web += "[MINESWEEPERIMG(hidden)] | " + else + web += "[MINESWEEPERIMG(hidden)] | " //Make unique hrefs for every square + if(10) + web += "[MINESWEEPERIMG(minehit)] | " + if(11) + web += "[MINESWEEPERIMG(empty)] | " + if(12) + web += "[MINESWEEPERIMG(1)] | " + if(13) + web += "[MINESWEEPERIMG(2)] | " + if(14) + web += "[MINESWEEPERIMG(3)] | " + if(15) + web += "[MINESWEEPERIMG(4)] | " + if(16) + web += "[MINESWEEPERIMG(5)] | " + if(17) + web += "[MINESWEEPERIMG(6)] | " + if(18) + web += "[MINESWEEPERIMG(7)] | " + if(19) + web += "[MINESWEEPERIMG(8)] | " + web += "" + web += "
Crew Management:
" + + //Buy crew + if(food >= 10 && fuel >= 10) + eventdat += "Hire a New Crewmember (-10FU, -10FO)
" + else + eventdat += "You cannot afford a new crewmember.
" + + //Sell crew + if(settlers.len > 1) + eventdat += "Sell Crew for Fuel and Food (+7FU, +7FO)
" + else + eventdat += "You have no other crew to sell.
" + + //BUY/SELL STUFF + eventdat += "Spare Parts:
" + + //Engine parts + if(fuel > 5) + eventdat += "" + else + eventdat += "You cannot afford engine parts." + + //Hull plates + if(fuel > 5) + eventdat += "
" + else + eventdat += "You cannot afford hull plates." + + //Electronics + if(fuel > 5) + eventdat += "
" + else + eventdat += "You cannot afford spare electronics." + + //Trade + if(fuel > 5) + eventdat += "
Trade Fuel for Food (-5FU,+5FO)
" + else + eventdat += "You don't have 5FU to trade.
5) + eventdat += "Trade Food for Fuel (+5FU,-5FO)
" + else + eventdat += "You don't have 5FO to trade.
!! Raid Spaceport !!" + + eventdat += "" + + +//Add Random/Specific crewmember +/obj/machinery/computer/arcade/orion_trail/proc/add_crewmember(var/specific = "") + var/newcrew = "" + if(specific) + newcrew = specific + else + if(prob(50)) + newcrew = pick(GLOB.first_names_male) + else + newcrew = pick(GLOB.first_names_female) + if(newcrew) + settlers += newcrew + alive++ + return newcrew + + +//Remove Random/Specific crewmember +/obj/machinery/computer/arcade/orion_trail/proc/remove_crewmember(var/specific = "", var/dont_remove = "") + var/list/safe2remove = settlers + var/removed = "" + if(dont_remove) + safe2remove -= dont_remove + if(specific && specific != dont_remove) + safe2remove = list(specific) + else + removed = pick(safe2remove) + + if(removed) + if(lings_aboard && prob(40*lings_aboard)) //if there are 2 lings you're twice as likely to get one, obviously + lings_aboard = max(0,--lings_aboard) + settlers -= removed + alive-- + return removed + + +/obj/machinery/computer/arcade/orion_trail/proc/win(mob/user) + gameStatus = ORION_STATUS_START + say("Congratulations, you made it to Orion!") + if(obj_flags & EMAGGED) + new /obj/item/orion_ship(loc) + message_admins("[ADMIN_LOOKUPFLW(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") + log_game("[key_name(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") + else + prizevend(user) + obj_flags &= ~EMAGGED + name = "The Orion Trail" + desc = "Learn how our ancestors got to Orion, and have fun in the process!" + +/obj/machinery/computer/arcade/orion_trail/emag_act(mob/user) + if(obj_flags & EMAGGED) + return + to_chat(user, "You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.") + name = "The Orion Trail: Realism Edition" + desc = "Learn how our ancestors got to Orion, and try not to die in the process!" + newgame() + obj_flags |= EMAGGED + +/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion + name = "spaceport security" + desc = "Premier corporate security forces for all spaceports found along the Orion Trail." + faction = list("orion") + loot = list() + del_on_death = TRUE + +/obj/item/orion_ship + name = "model settler ship" + desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." + icon = 'icons/obj/toy.dmi' + icon_state = "ship" + w_class = WEIGHT_CLASS_SMALL + var/active = 0 //if the ship is on + +/obj/item/orion_ship/examine(mob/user) + ..() + if(!(in_range(user, src))) + return + if(!active) + to_chat(user, "There's a little switch on the bottom. It's flipped down.") + else + to_chat(user, "There's a little switch on the bottom. It's flipped up.") + +/obj/item/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse + if(active) + return + + message_admins("[ADMIN_LOOKUPFLW(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].") + log_game("[key_name(usr)] primed an explosive Orion ship for detonation at [AREACOORD(usr)].") + + to_chat(user, "You flip the switch on the underside of [src].") + active = 1 + visible_message("[src] softly beeps and whirs to life!") + playsound(loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1) + say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") + sleep(20) + visible_message("[src] begins to vibrate...") + say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") + sleep(30) + say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") + playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, 1) + sleep(3.6) + visible_message("[src] explodes!") + explosion(loc, 2,4,8, flame_range = 16) + qdel(src) + +#undef ORION_TRAIL_WINTURN +#undef ORION_TRAIL_RAIDERS +#undef ORION_TRAIL_FLUX +#undef ORION_TRAIL_ILLNESS +#undef ORION_TRAIL_BREAKDOWN +#undef ORION_TRAIL_LING +#undef ORION_TRAIL_LING_ATTACK +#undef ORION_TRAIL_MALFUNCTION +#undef ORION_TRAIL_COLLISION +#undef ORION_TRAIL_SPACEPORT +#undef ORION_TRAIL_BLACKHOLE + +#undef ORION_STATUS_START +#undef ORION_STATUS_NORMAL +#undef ORION_STATUS_GAMEOVER +#undef ORION_STATUS_MARKET diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index ccc2121929..c11f7d9edc 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -31,7 +31,6 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) var/list/jobs = new/list() jobs["Captain"] = 00 - jobs["Head of Personnel"] = 50 jobs["Head of Security"] = 10 jobs["Warden"] = 11 jobs["Security Officer"] = 12 @@ -47,9 +46,10 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) jobs["Chief Engineer"] = 40 jobs["Station Engineer"] = 41 jobs["Atmospheric Technician"] = 42 - jobs["Quartermaster"] = 51 - jobs["Shaft Miner"] = 52 - jobs["Cargo Technician"] = 53 + jobs["Quartermaster"] = 50 + jobs["Shaft Miner"] = 51 + jobs["Cargo Technician"] = 52 + jobs["Head of Personnel"] = 60 jobs["Bartender"] = 61 jobs["Cook"] = 62 jobs["Botanist"] = 63 diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index 7beb32eebb..1c6d713437 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -214,11 +214,11 @@ sparkles += S switch(i) if(1 to 8) - S.orbit(src, 30, TRUE, 60, 36, TRUE, FALSE) + S.orbit(src, 30, TRUE, 60, 36, TRUE) if(9 to 16) - S.orbit(src, 62, TRUE, 60, 36, TRUE, FALSE) + S.orbit(src, 62, TRUE, 60, 36, TRUE) if(17 to 24) - S.orbit(src, 95, TRUE, 60, 36, TRUE, FALSE) + S.orbit(src, 95, TRUE, 60, 36, TRUE) if(25) S.pixel_y = 7 S.forceMove(get_turf(src)) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index b84db2ca8d..90166dacf0 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -51,6 +51,7 @@ /obj/machinery/suit_storage_unit/security suit_type = /obj/item/clothing/suit/space/hardsuit/security mask_type = /obj/item/clothing/mask/gas/sechailer + storage_type = /obj/item/tank/jetpack/oxygen/security /obj/machinery/suit_storage_unit/hos suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 4700dda60d..fc0665f51e 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -537,7 +537,7 @@ var/oldloc = loc if(internal_damage & MECHA_INT_CONTROL_LOST) move_result = mechsteprand() - else if(dir != direction && !strafe) + else if(dir != direction && (!strafe || occupant.client.keys_held["Alt"])) move_result = mechturn(direction) else move_result = mechstep(direction) diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm index 6d42c302e1..7b00e208cc 100644 --- a/code/game/mecha/mecha_actions.dm +++ b/code/game/mecha/mecha_actions.dm @@ -128,7 +128,7 @@ /datum/action/innate/mecha/strafe - name = "Toggle Strafing" + name = "Toggle Strafing. Disabled when Alt is held." button_icon_state = "strafe" /datum/action/innate/mecha/strafe/Activate() diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 4a77274d23..0e543a3642 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -214,6 +214,20 @@ /obj/item/aiModule/core/full/damaged ) +/obj/effect/spawner/lootdrop/mre + name = "random MRE" + icon = 'icons/obj/storage.dmi' + icon_state = "mre" + +/obj/effect/spawner/lootdrop/mre/Initialize() + for(var/A in subtypesof(/obj/item/storage/box/mre)) + var/obj/item/storage/box/mre/M = A + var/our_chance = initial(M.spawner_chance) + if(our_chance) + LAZYSET(loot, M, our_chance) + return ..() + + // Tech storage circuit board spawners // For these, make sure that lootcount equals the number of list items diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 3fbbab087f..2af7be2564 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -686,7 +686,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) ..() /obj/item/proc/microwave_act(obj/machinery/microwave/M) - if(M && M.dirty < 100) + if(istype(M) && M.dirty < 100) M.dirty++ /obj/item/proc/on_mob_death(mob/living/L, gibbed) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index d64f5b57b8..000c52ae43 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -707,9 +707,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = null w_class = WEIGHT_CLASS_TINY var/chem_volume = 100 - var/vapetime = 0 //this so it won't puff out clouds every tick - var/screw = 0 // kinky - var/super = 0 //for the fattest vapes dude. + var/vapetime = FALSE //this so it won't puff out clouds every tick + var/screw = FALSE // kinky + var/super = FALSE //for the fattest vapes dude. /obj/item/clothing/mask/vape/suicide_act(mob/user) user.visible_message("[user] is puffin hard on dat vape, [user.p_they()] trying to join the vape life on a whole notha plane!")//it doesn't give you cancer, it is cancer @@ -718,7 +718,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/vape/Initialize(mapload, param_color) . = ..() - DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) + create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it reagents.add_reagent("nicotine", 50) if(!icon_state) if(!param_color) @@ -727,52 +727,48 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = "[param_color]_vape" /obj/item/clothing/mask/vape/attackby(obj/item/O, mob/user, params) - if(O.is_drainable()) - if(reagents.total_volume < chem_volume) - if(O.reagents.total_volume > 0) - O.reagents.trans_to(src,25) - to_chat(user, "You add the contents of [O] to [src].") - else - to_chat(user, "[O] is empty!") - else - to_chat(user, "[src] can't hold anymore reagents!") - - if(istype(O, /obj/item/screwdriver)) + if(O.tool_behaviour == TOOL_SCREWDRIVER) if(!screw) - screw = 1 + screw = TRUE to_chat(user, "You open the cap on [src].") - if(super) + ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + if(obj_flags & EMAGGED) + add_overlay("vapeopen_high") + else if(super) add_overlay("vapeopen_med") else add_overlay("vapeopen_low") else - screw = 0 + screw = FALSE to_chat(user, "You close the cap on [src].") + DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) cut_overlays() - if(istype(O, /obj/item/multitool)) + if(O.tool_behaviour == TOOL_MULTITOOL) if(screw && !(obj_flags & EMAGGED))//also kinky if(!super) cut_overlays() - super = 1 + super = TRUE to_chat(user, "You increase the voltage of [src].") add_overlay("vapeopen_med") else cut_overlays() - super = 0 + super = FALSE to_chat(user, "You decrease the voltage of [src].") add_overlay("vapeopen_low") if(screw && (obj_flags & EMAGGED)) to_chat(user, "[src] can't be modified!") + else + ..() /obj/item/clothing/mask/vape/emag_act(mob/user)// I WON'T REGRET WRITTING THIS, SURLY. if(screw) if(!(obj_flags & EMAGGED)) cut_overlays() obj_flags |= EMAGGED - super = 0 + super = FALSE to_chat(user, "You maximize the voltage of [src].") add_overlay("vapeopen_high") var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread //for effect diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index 26f00c730e..a1ee62e2eb 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -123,6 +123,14 @@ name = "Orion Trail (Computer Board)" build_path = /obj/machinery/computer/arcade/orion_trail +/obj/item/circuitboard/computer/arcade/minesweeper + name = "Minesweeper (Computer Board)" + build_path = /obj/machinery/computer/arcade/minesweeper + +/obj/item/circuitboard/computer/arcade/amputation + name = "Mediborg's Amputation Adventure (Computer Board)" + build_path = /obj/machinery/computer/arcade/amputation + /obj/item/circuitboard/computer/turbine_control name = "Turbine control (Computer Board)" build_path = /obj/machinery/computer/turbine_computer diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 48b21d58bd..15c88d168f 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -10,11 +10,20 @@ GLOBAL_LIST_EMPTY(PDAs) #define PDA_SCANNER_HALOGEN 4 #define PDA_SCANNER_GAS 5 #define PDA_SPAM_DELAY 2 MINUTES +#define PDA_STANDARD_OVERLAYS list("pda-r", "blank", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay") + +//pda icon overlays list defines +#define PDA_OVERLAY_ALERT 1 +#define PDA_OVERLAY_SCREEN 2 +#define PDA_OVERLAY_ID 3 +#define PDA_OVERLAY_ITEM 4 +#define PDA_OVERLAY_LIGHT 5 +#define PDA_OVERLAY_PAI 6 /obj/item/pda name = "\improper PDA" desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge." - icon = 'icons/obj/pda.dmi' + icon = 'icons/obj/pda_alt.dmi' icon_state = "pda" item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' @@ -31,7 +40,8 @@ GLOBAL_LIST_EMPTY(PDAs) var/default_cartridge = 0 // Access level defined by cartridge var/obj/item/cartridge/cartridge = null //current cartridge var/mode = 0 //Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge. - var/icon_alert = "pda-r" //Icon to be overlayed for message alerts. Taken from the pda icon file. + var/list/overlays_icons = list('icons/obj/pda_alt.dmi' = list("pda-r", "screen_default", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay")) + var/current_overlays = PDA_STANDARD_OVERLAYS var/font_index = 0 //This int tells DM which font is currently selected and lets DM know when the last font has been selected so that it can cycle back to the first font when "toggle font" is pressed again. var/font_mode = "font-family:monospace;" //The currently selected font. var/background_color = "#808000" //The currently selected background color. @@ -78,7 +88,9 @@ GLOBAL_LIST_EMPTY(PDAs) var/list/contained_item = list(/obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/flashlight/pen, /obj/item/clothing/mask/cigarette) var/obj/item/inserted_item //Used for pen, crayon, and lipstick insertion or removal. Same as above. - var/overlays_x_offset = 0 //x offset to use for certain overlays + var/list/overlays_offsets // offsets to use for certain overlays + var/overlays_x_offset = 0 + var/overlays_y_offset = 0 var/underline_flag = TRUE //flag for underline @@ -91,15 +103,13 @@ GLOBAL_LIST_EMPTY(PDAs) return BRUTELOSS /obj/item/pda/examine(mob/user) - ..() - if(!id && !inserted_item) - return - - if(id) - to_chat(user, "Alt-click to remove the id.") - + . = ..() + var/dat = id ? "Alt-click to remove the id." : "" if(inserted_item && (!isturf(loc))) - to_chat(user, "Ctrl-click to remove [inserted_item].") + dat += "\nCtrl-click to remove [inserted_item]." + if(LAZYLEN(GLOB.pda_reskins)) + dat += "\nCtrl-shift-click it to reskin it." + to_chat(user, dat) /obj/item/pda/Initialize() . = ..() @@ -115,28 +125,71 @@ GLOBAL_LIST_EMPTY(PDAs) inserted_item = new /obj/item/pen(src) update_icon() +/obj/item/pda/CtrlShiftClick(mob/living/user) + . = ..() + if(GLOB.pda_reskins && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) + reskin_obj(user) + +/obj/item/pda/reskin_obj(mob/M) + if(!LAZYLEN(GLOB.pda_reskins)) + return + var/dat = "Reskin options for [name]:" + for(var/V in GLOB.pda_reskins) + var/output = icon2html(GLOB.pda_reskins[V], M, icon_state) + dat += "\n[V]: [output]" + to_chat(M, dat) + + var/choice = input(M, "Choose the a reskin for [src]","Reskin Object") as null|anything in GLOB.pda_reskins + var/new_icon = GLOB.pda_reskins[choice] + if(QDELETED(src) || isnull(new_icon) || new_icon == icon || M.incapacitated() || !in_range(M,src)) + return + icon = new_icon + set_new_overlays() + update_icon() + to_chat(M, "[src] is now skinned as '[choice]'.") + +/obj/item/pda/proc/set_new_overlays() + if(!overlays_offsets || !(icon in overlays_offsets)) + overlays_x_offset = 0 + overlays_y_offset = 0 + else + var/list/new_offsets = overlays_offsets[icon] + if(new_offsets) + overlays_x_offset = new_offsets[1] + overlays_y_offset = new_offsets[2] + if(!(icon in overlays_icons)) + current_overlays = PDA_STANDARD_OVERLAYS + return + current_overlays = overlays_icons[icon] + /obj/item/pda/equipped(mob/user, slot) . = ..() - if(!equipped) - if(user.client) - background_color = user.client.prefs.pda_color - switch(user.client.prefs.pda_style) - if(MONO) - font_index = MODE_MONO - font_mode = FONT_MONO - if(SHARE) - font_index = MODE_SHARE - font_mode = FONT_SHARE - if(ORBITRON) - font_index = MODE_ORBITRON - font_mode = FONT_ORBITRON - if(VT) - font_index = MODE_VT - font_mode = FONT_VT - else - font_index = MODE_MONO - font_mode = FONT_MONO - equipped = TRUE + if(equipped) + return + if(user.client) + background_color = user.client.prefs.pda_color + switch(user.client.prefs.pda_style) + if(MONO) + font_index = MODE_MONO + font_mode = FONT_MONO + if(SHARE) + font_index = MODE_SHARE + font_mode = FONT_SHARE + if(ORBITRON) + font_index = MODE_ORBITRON + font_mode = FONT_ORBITRON + if(VT) + font_index = MODE_VT + font_mode = FONT_VT + else + font_index = MODE_MONO + font_mode = FONT_MONO + var/pref_skin = GLOB.pda_reskins[user.client.prefs.pda_skin] + if(icon != pref_skin) + icon = pref_skin + set_new_overlays() + update_icon() + equipped = TRUE /obj/item/pda/proc/update_label() name = "PDA-[owner] ([ownjob])" //Name generalisation @@ -150,33 +203,34 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/GetID() return id -/obj/item/pda/update_icon() +/obj/item/pda/update_icon(alert = FALSE) cut_overlays() + add_overlay(alert ? current_overlays[PDA_OVERLAY_ALERT] : current_overlays[PDA_OVERLAY_SCREEN]) var/mutable_appearance/overlay = new() overlay.pixel_x = overlays_x_offset if(id) - overlay.icon_state = "id_overlay" + overlay.icon_state = current_overlays[PDA_OVERLAY_ID] add_overlay(new /mutable_appearance(overlay)) if(inserted_item) - overlay.icon_state = "insert_overlay" + overlay.icon_state = current_overlays[PDA_OVERLAY_ITEM] add_overlay(new /mutable_appearance(overlay)) if(fon) - overlay.icon_state = "light_overlay" + overlay.icon_state = current_overlays[PDA_OVERLAY_LIGHT] add_overlay(new /mutable_appearance(overlay)) if(pai) - if(pai.pai) - overlay.icon_state = "pai_overlay" - add_overlay(new /mutable_appearance(overlay)) - else - overlay.icon_state = "pai_off_overlay" - add_overlay(new /mutable_appearance(overlay)) + overlay.icon_state = "[current_overlays[PDA_OVERLAY_PAI]][pai.pai ? "" : "_off"]" + add_overlay(new /mutable_appearance(overlay)) -/obj/item/pda/MouseDrop(obj/over_object, src_location, over_location) +/obj/item/pda/MouseDrop(mob/over, src_location, over_location) var/mob/M = usr - if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src)) + if((M == over) && usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return attack_self(M) return ..() +/obj/item/pda/attack_self_tk(mob/user) + to_chat(user, "The PDA's capacitive touch screen doesn't seem to respond!") + return + /obj/item/pda/interact(mob/user) if(!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") @@ -382,7 +436,7 @@ GLOBAL_LIST_EMPTY(PDAs) var/mob/living/U = usr //Looking for master was kind of pointless since PDAs don't appear to have one. - if(usr.canUseTopic(src) && !href_list["close"]) + if(usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && !href_list["close"]) add_fingerprint(U) U.set_machine(src) @@ -636,7 +690,7 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/proc/remove_id() - if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE)) + if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if (id) @@ -736,8 +790,7 @@ GLOBAL_LIST_EMPTY(PDAs) to_chat(L, "[icon2html(src)] Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], [signal.format_message()] (Reply)") - update_icon() - add_overlay(icon_alert) + update_icon(TRUE) /obj/item/pda/proc/send_to_all(mob/living/U) if (last_everyone && world.time < last_everyone + PDA_SPAM_DELAY) @@ -802,7 +855,7 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/proc/remove_pen() - if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE)) + if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return if(inserted_item) @@ -1076,4 +1129,11 @@ GLOBAL_LIST_EMPTY(PDAs) #undef PDA_SCANNER_HALOGEN #undef PDA_SCANNER_GAS #undef PDA_SPAM_DELAY +#undef PDA_STANDARD_OVERLAYS +#undef PDA_OVERLAY_ALERT +#undef PDA_OVERLAY_SCREEN +#undef PDA_OVERLAY_ID +#undef PDA_OVERLAY_ITEM +#undef PDA_OVERLAY_LIGHT +#undef PDA_OVERLAY_PAI \ No newline at end of file diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm index 80d8cb5963..54b82d8e07 100644 --- a/code/game/objects/items/devices/PDA/PDA_types.dm +++ b/code/game/objects/items/devices/PDA/PDA_types.dm @@ -124,6 +124,16 @@ icon_state = "pda-captain" detonatable = FALSE +/obj/item/pda/lieutenant + name = "lieutenant PDA" + default_cartridge = /obj/item/cartridge/captain + inserted_item = /obj/item/pen/fountain/captain + icon_state = "pda-lieutenant" + ttone = "bwoink" + detonatable = FALSE + hidden = TRUE + note = "Congratulations, you have chosen the Thinktronic 5230-2 Personal Data Assistant Prestige Edition! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." + /obj/item/pda/cargo name = "cargo technician PDA" default_cartridge = /obj/item/cartridge/quartermaster @@ -171,25 +181,29 @@ /obj/item/pda/curator name = "curator PDA" icon_state = "pda-library" - icon_alert = "pda-r-library" + overlays_icons = list('icons/obj/pda.dmi' = list("pda-r-library","blank","id_overlay","insert_overlay", "light_overlay", "pai_overlay"), + 'icons/obj/pda_alt.dmi' = list("pda-r","screen_default","id_overlay","insert_overlay", "light_overlay", "pai_overlay")) + current_overlays = list("pda-r-library","blank","id_overlay","insert_overlay", "light_overlay", "pai_overlay") default_cartridge = /obj/item/cartridge/curator inserted_item = /obj/item/pen/fountain desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a WGW-11 series e-reader." - note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!" + note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." silent = TRUE //Quiet in the library! + overlays_offsets = list('icons/obj/pda.dmi' = list(-3,0)) overlays_x_offset = -3 /obj/item/pda/clear name = "clear PDA" icon_state = "pda-clear" desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special edition with a transparent case." - note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!" + note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." /obj/item/pda/neko name = "neko PDA" icon_state = "pda-neko" - desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special edition a feline fine case." - note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Mew Turbo Limited Edition NYA~!" + overlays_icons = list('icons/obj/pda_alt.dmi' = list("pda-r", "screen_neko", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay")) + desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special feline edition." + note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Mew Turbo Limited Edition NYA~! To help with navigation, we have provided the following definitions. North: Fore. South: Aft. West: Port. East: Starboard. Quarter is either side of aft." /obj/item/pda/cook name = "cook PDA" diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 1a733fbff2..bf352e8eb7 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -87,7 +87,7 @@ /obj/item/cartridge/detective name = "\improper D.E.T.E.C.T. cartridge" - icon_state = "cart-s" + icon_state = "cart-eye" access = CART_SECURITY | CART_MEDICAL | CART_MANIFEST bot_access_flags = SEC_BOT @@ -100,23 +100,25 @@ /obj/item/cartridge/lawyer name = "\improper P.R.O.V.E. cartridge" - icon_state = "cart-s" + icon_state = "cart-law" access = CART_SECURITY spam_enabled = 1 /obj/item/cartridge/curator name = "\improper Lib-Tweet cartridge" - icon_state = "cart-s" + icon_state = "cart-lib" access = CART_NEWSCASTER /obj/item/cartridge/roboticist name = "\improper B.O.O.P. Remote Control cartridge" desc = "Packed with heavy duty triple-bot interlink!" + icon_state = "cart-robo" bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT access = CART_DRONEPHONE /obj/item/cartridge/signal name = "generic signaler cartridge" + icon_state = "cart-sig" desc = "A data cartridge with an integrated radio signaler module." /obj/item/cartridge/signal/toxins diff --git a/code/game/objects/items/devices/PDA/virus_cart.dm b/code/game/objects/items/devices/PDA/virus_cart.dm index 13d653a4fe..d35b2b58cf 100644 --- a/code/game/objects/items/devices/PDA/virus_cart.dm +++ b/code/game/objects/items/devices/PDA/virus_cart.dm @@ -53,7 +53,6 @@ /obj/item/cartridge/virus/syndicate name = "\improper Detomatix cartridge" - icon_state = "cart" access = CART_REMOTE_DOOR remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing. charges = 4 @@ -85,7 +84,7 @@ /obj/item/cartridge/virus/frame name = "\improper F.R.A.M.E. cartridge" - icon_state = "cart" + icon_state = "cart-f" var/telecrystals = 0 /obj/item/cartridge/virus/frame/send_virus(obj/item/pda/target, mob/living/U) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 40f2059d25..d8b539ac27 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -13,7 +13,8 @@ actions_types = list(/datum/action/item_action/toggle_light) var/on = FALSE var/brightness_on = 4 //range of light when on - var/flashlight_power = 1 //strength of the light when on + var/flashlight_power = 0.8 //strength of the light when on + light_color = "#FFCC66" /obj/item/flashlight/Initialize() . = ..() @@ -63,7 +64,7 @@ to_chat(user, "[M] doesn't have a head!") return - if(flashlight_power < 1) + if(flashlight_power < 0.3) to_chat(user, "\The [src] isn't bright enough to see anything! ") return @@ -168,6 +169,8 @@ item_state = "" flags_1 = CONDUCT_1 brightness_on = 2 + light_color = "#FFDDCC" + flashlight_power = 0.3 var/holo_cooldown = 0 /obj/item/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag) @@ -204,6 +207,8 @@ righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' force = 9 // Not as good as a stun baton. brightness_on = 5 // A little better than the standard flashlight. + light_color = "#CDDDFF" + flashlight_power = 0.9 hitsound = 'sound/weapons/genhit1.ogg' // the desk lamps are a bit special @@ -216,6 +221,7 @@ righthand_file = 'icons/mob/inhands/items_righthand.dmi' force = 10 brightness_on = 5 + light_color = "#FFDDBB" w_class = WEIGHT_CLASS_BULKY flags_1 = CONDUCT_1 materials = list() @@ -252,6 +258,7 @@ desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'." w_class = WEIGHT_CLASS_SMALL brightness_on = 7 // Pretty bright. + light_color = "#FA421A" icon_state = "flare" item_state = "flare" actions_types = list() @@ -325,6 +332,7 @@ desc = "A torch fashioned from some leaves and a log." w_class = WEIGHT_CLASS_BULKY brightness_on = 4 + light_color = "#FAA44B" icon_state = "torch" item_state = "torch" lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' @@ -341,6 +349,8 @@ righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi' desc = "A mining lantern." brightness_on = 6 // luminosity when on + light_color = "#FFAA44" + flashlight_power = 0.75 /obj/item/flashlight/slime @@ -354,6 +364,8 @@ slot_flags = ITEM_SLOT_BELT materials = list() brightness_on = 6 //luminosity when on + light_color = "#FFEEAA" + flashlight_power = 0.6 /obj/item/flashlight/emp var/emp_max_charges = 4 @@ -517,6 +529,7 @@ icon_state = null light_color = null brightness_on = 0 + flashlight_power = 1 light_range = 0 light_power = 10 alpha = 0 @@ -538,7 +551,6 @@ name = "eyelight" desc = "This shouldn't exist outside of someone's head, how are you seeing this?" brightness_on = 15 - flashlight_power = 1 flags_1 = CONDUCT_1 item_flags = DROPDEL actions_types = list() diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index 882a50b3ba..9fb4206845 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -110,7 +110,7 @@ to_chat(user, "The safety is [safety ? "on" : "off"].") if(reagents.total_volume) - to_chat(user, "Alt-click to empty it.") + to_chat(user, "You can loose its screws to empty it.") /obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user) if(istype(target, tanktype) && target.Adjacent(user)) @@ -244,7 +244,7 @@ var/turf/open/theturf = T theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS) - user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "You quietly empty out \the [src] using its release valve.") + user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "You quietly empty out \the [src] by loosing the release valve's screws.") //firebot assembly /obj/item/extinguisher/attackby(obj/O, mob/user, params) diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 8d0d8d020e..34ce6bc521 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -87,6 +87,33 @@ active = FALSE UpdateButtonIcon() +/obj/item/book/granter/action/origami + granted_action = /datum/action/innate/origami + name = "The Art of Origami" + desc = "A meticulously in-depth manual explaining the art of paper folding." + icon_state = "origamibook" + actionname = "origami" + oneuse = TRUE + remarks = list("Dead-stick stability...", "Symmetry seems to play a rather large factor...", "Accounting for crosswinds... really?", "Drag coefficients of various paper types...", "Thrust to weight ratios?", "Positive dihedral angle?", "Center of gravity forward of the center of lift...") + +/datum/action/innate/origami + name = "Origami Folding" + desc = "Toggles your ability to fold and catch robust paper airplanes." + button_icon_state = "origami_off" + check_flags = NONE + +/datum/action/innate/origami/Activate() + to_chat(owner, "You will now fold origami planes.") + button_icon_state = "origami_on" + active = TRUE + UpdateButtonIcon() + +/datum/action/innate/origami/Deactivate() + to_chat(owner, "You will no longer fold origami planes.") + button_icon_state = "origami_off" + active = FALSE + UpdateButtonIcon() + ///SPELLS/// /obj/item/book/granter/spell diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index d1061a28a4..06aef0a22b 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -58,7 +58,7 @@ item_state = "radio" /obj/item/holybeacon/attack_self(mob/user) - if(user.mind && (user.mind.isholy) && !SSreligion.holy_armor_type) + if(user.mind && (user.mind.isholy) && !GLOB.holy_armor_type) beacon_armor(user) else playsound(src, 'sound/machines/buzz-sigh.ogg', 40, 1) @@ -71,13 +71,13 @@ display_names += list(initial(A.name) = A) var/choice = input(M,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names - if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || SSreligion.holy_armor_type) + if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type) return var/index = display_names.Find(choice) var/A = holy_armor_list[index] - SSreligion.holy_armor_type = A + GLOB.holy_armor_type = A var/holy_armor_box = new A SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]") @@ -245,7 +245,7 @@ reskin_holy_weapon(user) /obj/item/nullrod/proc/reskin_holy_weapon(mob/M) - if(SSreligion.holy_weapon_type) + if(GLOB.holy_weapon_type) return var/obj/item/nullrod/holy_weapon var/list/holy_weapons_list = typesof(/obj/item/nullrod) + list( @@ -264,7 +264,7 @@ var/A = display_names[choice] // This needs to be on a separate var as list member access is not allowed for new holy_weapon = new A - SSreligion.holy_weapon_type = holy_weapon.type + GLOB.holy_weapon_type = holy_weapon.type SSblackbox.record_feedback("tally", "chaplain_weapon", 1, "[choice]") diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm index 889f702ee7..3a4295c61e 100644 --- a/code/game/objects/items/implants/implant_misc.dm +++ b/code/game/objects/items/implants/implant_misc.dm @@ -33,7 +33,7 @@ /obj/item/implant/adrenalin/activate() . = ..() uses-- - imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "omnizine" = 10, "stimulants" = 10), "You feel a sudden surge of energy!") + imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10), "You feel a sudden surge of energy!") to_chat(imp_in, "You feel a sudden surge of energy!") if(!uses) qdel(src) diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 9528bf94ba..12de29c76e 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -613,6 +613,20 @@ icon_state = "plushie_awake" item_state = "plushie_awake" +/obj/item/toy/plush/awakenedplushie/ComponentInitialize() + . = ..() + AddComponent(/datum/component/edit_complainer) + + +/obj/item/toy/plush/beeplushie + name = "bee plushie" + desc = "A cute toy that resembles an even cuter bee." + icon_state = "plushie_h" + item_state = "plushie_h" + attack_verb = list("stung") + gender = FEMALE + squeak_override = list('modular_citadel/sound/voice/scream_moth.ogg' = 1) + /obj/item/toy/plush/mothplushie name = "insect plushie" desc = "An adorable stuffed toy that resembles some kind of insect" @@ -904,7 +918,3 @@ item_state = "fermis" attack_verb = list("cuddled", "petpatted", "wigglepurred") squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1) - -/obj/item/toy/plush/awakenedplushie/ComponentInitialize() - . = ..() - AddComponent(/datum/component/edit_complainer) diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index b641e15d90..a9f0e038df 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -20,7 +20,6 @@ attack_verb = list("shoved", "bashed") var/cooldown = 0 //shield bash cooldown. based on world.time - /obj/item/shield/riot/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/melee/baton)) if(cooldown < world.time - 25) @@ -166,3 +165,14 @@ block_chance = 25 force = 5 throwforce = 7 + +/obj/item/shield/riot/tower + name = "tower shield" + desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking." + armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user + item_state = "metal" + block_chance = 75 //1/4 shots will hit* + force = 10 + slowdown = 2 + throwforce = 15 //Massive pice of metal + w_class = WEIGHT_CLASS_HUGE diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 050e4f7b15..b17bc87ffd 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -409,8 +409,10 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ new/datum/stack_recipe("brass pinion airlock - windowed", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \ null, - new/datum/stack_recipe("directional brass window", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("brass reflector", /obj/structure/destructible/clockwork/reflector, 10, time = 100, one_per_turf = TRUE, on_floor = TRUE, window_checks = TRUE), \ + null, + new/datum/stack_recipe("brass window - directional", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("brass window - fulltile", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \ null, diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 34ae4cb5ef..4217a58f81 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -396,7 +396,7 @@ //TODO bloody overlay /obj/item/stack/microwave_act(obj/machinery/microwave/M) - if(M && M.dirty < 100) + if(istype(M) && M.dirty < 100) M.dirty += amount /* diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 8178f0390a..c2929dafbd 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -589,3 +589,16 @@ new /obj/item/clothing/mask/gas/clown_hat(src) new /obj/item/bikehorn(src) new /obj/item/implanter/sad_trombone(src) + +obj/item/storage/backpack/duffelbag/syndie/shredderbundle + desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig." + +/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents() + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/ammo_box/magazine/flechette/shredder(src) + new /obj/item/gun/ballistic/automatic/flechette/shredder(src) + new /obj/item/gun/ballistic/automatic/flechette/shredder(src) + new /obj/item/storage/belt/military(src) + new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 57c77e5983..e2d7fdf9d7 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -541,6 +541,25 @@ /obj/item/ammo_casing/shotgun )) +/obj/item/storage/belt/medolier + name = "medolier" + desc = "A medical bandolier for holding smartdarts." + icon_state = "medolier" + item_state = "medolier" + +/obj/item/storage/belt/medolier/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_items = 15 + STR.display_numerical_stacking = FALSE + STR.can_hold = typecacheof(list( + /obj/item/reagent_containers/syringe/dart + )) + +/obj/item/storage/belt/medolier/full/PopulateContents() + for(var/i in 1 to 16) + new /obj/item/reagent_containers/syringe/dart/(src) + /obj/item/storage/belt/holster name = "shoulder holster" desc = "A holster to carry a handgun and ammo. WARNING: Badasses only." @@ -557,6 +576,8 @@ /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/ammo_box, + /obj/item/toy/gun, + /obj/item/gun/energy/e_gun/mini )) /obj/item/storage/belt/holster/full/PopulateContents() diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index c2d5ca50be..830c3aea96 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -51,7 +51,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", if(!istype(H)) return // If H is the Chaplain, we can set the icon_state of the bible (but only once!) - if(!SSreligion.bible_icon_state && H.job == "Chaplain") + if(!GLOB.bible_icon_state && H.job == "Chaplain") var/dat = "| "
for(var/jobcat in categorizedJobs)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/socks.dm b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm
index 5a5d37d4e7..3384f3754b 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/socks.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm
@@ -11,6 +11,10 @@
// please make sure they're sorted alphabetically and categorized
+/datum/sprite_accessory/socks/bee_knee
+ name = "Knee-high (Bee)"
+ icon_state = "bee_knee"
+
/datum/sprite_accessory/socks/black_knee
name = "Knee-high (Black)"
icon_state = "black_knee"
@@ -63,6 +67,42 @@
name = "Short (White)"
icon_state = "white_short"
+/datum/sprite_accessory/socks/stockings_blue
+ name = "Stockings (Blue)"
+ icon_state = "stockings_blue"
+
+/datum/sprite_accessory/socks/stockings_cyan
+ name = "Stockings (Cyan)"
+ icon_state = "stockings_cyan"
+
+/datum/sprite_accessory/socks/stockings_dpink
+ name = "Stockings (Dark Pink)"
+ icon_state = "stockings_dpink"
+
+/datum/sprite_accessory/socks/stockings_green
+ name = "Stockings (Green)"
+ icon_state = "stockings_black"
+
+/datum/sprite_accessory/socks/stockings_orange
+ name = "Stockings (Orange)"
+ icon_state = "stockings_orange"
+
+/datum/sprite_accessory/socks/stockings_programmer
+ name = "Stockings (Programmer)"
+ icon_state = "stockings_lpink"
+
+/datum/sprite_accessory/socks/stockings_purple
+ name = "Stockings (Purple)"
+ icon_state = "stockings_purple"
+
+/datum/sprite_accessory/socks/stockings_yellow
+ name = "Stockings (Yellow)"
+ icon_state = "stockings_yellow"
+
+/datum/sprite_accessory/socks/bee_thigh
+ name = "Thigh-high (Bee)"
+ icon_state = "bee_thigh"
+
/datum/sprite_accessory/socks/black_thigh
name = "Thigh-high (Black)"
icon_state = "black_thigh"
@@ -93,4 +133,4 @@
/datum/sprite_accessory/socks/white_thigh
name = "Thigh-high (White)"
- icon_state = "white_thigh"
\ No newline at end of file
+ icon_state = "white_thigh"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm
index 7c66ef51e3..f5af9a3849 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm
@@ -248,9 +248,13 @@
icon_state = "bra_commie"
/datum/sprite_accessory/undershirt/female_babyblue
- name = "Bra, Baby Blue"
+ name = "Bra - Baby Blue"
icon_state = "bra_babyblue"
+/datum/sprite_accessory/undershirt/female_beekini
+ name = "Bra - Bee-kini"
+ icon_state = "bra_bee-kini"
+
/datum/sprite_accessory/undershirt/female_black
name = "Bra - Black"
icon_state = "bra_black"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm
index 6beed231aa..e7179eeb87 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm
@@ -90,6 +90,9 @@
name = "Boxer Briefs - Yellow"
icon_state = "boxer_briefs_yellow"
+/datum/sprite_accessory/underwear/female_beekini
+ name = "Panties - Bee-kini"
+ icon_state = "panties_bee-kini"
/datum/sprite_accessory/underwear/female_black
name = "Panties - Black"
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 55b8891534..fefa032e4f 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -429,9 +429,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/orbitsize = (I.Width()+I.Height())*0.5
orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25)
- if(orbiting && orbiting.orbiting != target)
- to_chat(src, "Now orbiting [target].")
-
var/rot_seg
switch(ghost_orbit)
@@ -450,10 +447,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/orbit()
setDir(2)//reset dir so the right directional sprites show up
- ..()
+ return ..()
-/mob/dead/observer/stop_orbit()
- ..()
+/mob/dead/observer/stop_orbit(datum/component/orbiter/orbits)
+ . = ..()
//restart our floating animation after orbit is done.
pixel_y = 0
animate(src, pixel_y = 2, time = 10, loop = -1)
@@ -753,7 +750,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)
+/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
return IsAdminGhost(usr)
/mob/dead/observer/is_literate()
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 2ced3054c4..dafc6cf5e0 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -265,7 +265,7 @@
var/list/datum/brain_trauma/possible_traumas = list()
for(var/T in subtypesof(brain_trauma_type))
var/datum/brain_trauma/BT = T
- if(can_gain_trauma(BT, resilience))
+ if(can_gain_trauma(BT, resilience) && initial(BT.random_gain))
possible_traumas += BT
if(!LAZYLEN(possible_traumas))
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index fb09de7ec2..92a993958a 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -496,9 +496,12 @@
add_splatter_floor(T)
if(stun)
adjustBruteLoss(3)
+ else if(src.reagents.has_reagent("blazaam"))
+ if(T)
+ T.add_vomit_floor(src, VOMIT_PURPLE)
else
if(T)
- T.add_vomit_floor(src, toxic)//toxic barf looks different
+ T.add_vomit_floor(src, VOMIT_TOXIC)//toxic barf looks different
T = get_step(T, dir)
if (is_blocked_turf(T))
break
@@ -895,6 +898,11 @@
var/obj/item/organ/I = X
I.Insert(src)
+/mob/living/carbon/proc/update_disabled_bodyparts()
+ for(var/B in bodyparts)
+ var/obj/item/bodypart/BP = B
+ BP.update_disabled()
+
/mob/living/carbon/vv_get_dropdown()
. = ..()
. += "---"
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index e96bb7f121..57483f64e7 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -48,18 +48,27 @@
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
affecting.dismember(P.damtype)
+/mob/living/carbon/proc/can_catch_item(skip_throw_mode_check)
+ . = FALSE
+ if(!skip_throw_mode_check && !in_throw_mode)
+ return
+ if(get_active_held_item())
+ return
+ if(restrained())
+ return
+ return TRUE
+
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE)
if(!skipcatch) //ugly, but easy
- if(in_throw_mode && !get_active_held_item()) //empty active hand and we're in throw mode
- if(canmove && !restrained())
- if(istype(AM, /obj/item))
- var/obj/item/I = AM
- if(isturf(I.loc))
- I.attack_hand(src)
- if(get_active_held_item() == I) //if our attack_hand() picks up the item...
- visible_message("[src] catches [I]!") //catch that sucker!
- throw_mode_off()
- return 1
+ if(can_catch_item())
+ if(istype(AM, /obj/item))
+ var/obj/item/I = AM
+ if(isturf(I.loc))
+ I.attack_hand(src)
+ if(get_active_held_item() == I) //if our attack_hand() picks up the item...
+ visible_message("[src] catches [I]!") //catch that sucker!
+ throw_mode_off()
+ return 1
..()
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index d814893053..8550a0887f 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -294,7 +294,7 @@
if(mood.sanity <= SANITY_DISTURBED)
msg += "[t_He] seem[p_s()] distressed.\n"
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empath", /datum/mood_event/sad_empath, src)
- if(mood.mood >= 5) //So roundstart people aren't all "happy"
+ if(mood.shown_mood >= 6) //So roundstart people aren't all "happy" and that antags don't show their true happiness.
msg += "[t_He] seem[p_s()] to have had something nice happen to them recently.\n"
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empathH", /datum/mood_event/happy_empath, src)
if (HAS_TRAIT(src, TRAIT_BLIND))
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 0f962d7b0f..a4fca9dd78 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -8,6 +8,7 @@
/mob/living/carbon/human/Initialize()
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
+ verbs += /mob/living/carbon/human/proc/underwear_toggle //fwee
//initialize limbs first
create_bodyparts()
@@ -724,12 +725,12 @@
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000")
cut_overlay(MA)
-/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
+/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(incapacitated() || lying )
to_chat(src, "You can't do that right now!")
return FALSE
if(!Adjacent(M) && (M.loc != src))
- if((be_close == 0) || (dna.check_mutation(TK) && tkMaxRangeCheck(src, M)))
+ if((be_close == 0) || (!no_tk && (dna.check_mutation(TK) && tkMaxRangeCheck(src, M))))
return TRUE
to_chat(src, "You are too far away!")
return FALSE
@@ -851,19 +852,24 @@
/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user)
//If they dragged themselves and we're currently aggressively grabbing them try to piggyback
- if(user == target && can_piggyback(target) && pulling == target && grab_state >= GRAB_AGGRESSIVE && stat == CONSCIOUS)
+ if(user == target && can_piggyback(target) && pulling == target && (HAS_TRAIT(src, TRAIT_PACIFISM) || grab_state >= GRAB_AGGRESSIVE) && stat == CONSCIOUS)
buckle_mob(target,TRUE,TRUE)
. = ..()
+/mob/living/carbon/human/proc/piggyback_instant(mob/living/M)
+ return buckle_mob(M, TRUE, TRUE, FALSE, TRUE)
+
//Can C try to piggyback at all.
/mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/C)
if(istype(C) && C.stat == CONSCIOUS)
return TRUE
return FALSE
-/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
+/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE, bypass_piggybacking = FALSE, no_delay = FALSE)
if(!force)//humans are only meant to be ridden through piggybacking and special cases
return
+ if(bypass_piggybacking)
+ return ..()
if(!is_type_in_typecache(M, can_ride_typecache))
M.visible_message("[M] really can't seem to mount [src]...")
return
@@ -876,7 +882,7 @@
if(can_piggyback(M))
riding_datum.ride_check_ridden_incapacitated = TRUE
visible_message("[M] starts to climb onto [src]...")
- if(do_after(M, 15, target = src))
+ if(no_delay || do_after(M, 15, target = src))
if(can_piggyback(M))
if(M.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
M.visible_message("[M] can't hang onto [src]!")
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 2a75119841..b42346382f 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -54,7 +54,12 @@
else
visible_message("[src] deflects the projectile!", "You deflect the projectile!")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
- return 0
+ if(!mind.martial_art.reroute_deflection)
+ return FALSE
+ else
+ P.firer = src
+ P.setAngle(rand(0, 360))//SHING
+ return FALSE
if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself
if(P.is_reflectable)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index d1ec7f3e4b..de976da40f 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -22,7 +22,7 @@
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
var/lip_color = "white"
- var/age = 30 //Player's age (pure fluff)
+ var/age = 30 //Player's age
var/underwear = "Nude" //Which underwear the player wants
var/undershirt = "Nude" //Which undershirt the player wants
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 62a4d42672..3324b07217 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -44,6 +44,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/siemens_coeff = 1 //base electrocution coefficient
var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded?
var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"]
+ var/list/special_step_sounds //Sounds to override barefeet walkng
+ var/grab_sound //Special sound for grabbing
// species-only traits. Can be found in DNA.dm
var/list/species_traits = list()
@@ -490,11 +492,19 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//Underwear, Undershirts & Socks
if(!(NO_UNDERWEAR in species_traits))
if(H.underwear)
+ if(H.hidden_underwear)
+ H.underwear = "Nude"
+ else
+ H.underwear = H.saved_underwear
var/datum/sprite_accessory/underwear/underwear = GLOB.underwear_list[H.underwear]
if(underwear)
standing += mutable_appearance(underwear.icon, underwear.icon_state, -BODY_LAYER)
if(H.undershirt)
+ if(H.hidden_undershirt)
+ H.undershirt = "Nude"
+ else
+ H.undershirt = H.saved_undershirt
var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[H.undershirt]
if(undershirt)
if(H.dna.species.sexes && H.gender == FEMALE)
@@ -503,6 +513,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER)
if(H.socks && H.get_num_legs(FALSE) >= 2)
+ if(H.hidden_socks)
+ H.socks = "Nude"
+ else
+ H.socks = H.saved_socks
var/datum/sprite_accessory/socks/socks = GLOB.socks_list[H.socks]
if(socks)
if(DIGITIGRADE in species_traits)
@@ -1288,7 +1302,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
. += H.physiology.speed_mod
if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP))
- . -= 1
+ . -= 1.5
if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN))
ignoreslow = 1
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 ff90929c4b..2907caff13 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -30,6 +30,7 @@
var/list/special_names = list("Tarkus")
var/human_surname_chance = 3
var/special_name_chance = 5
+ var/owner //dobby is a free golem
/datum/species/golem/random_name(gender,unique,lastname)
var/golem_surname = pick(GLOB.golem_names)
@@ -807,3 +808,196 @@
/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C)
. = ..()
C.ventcrawler = initial(C.ventcrawler)
+
+/datum/species/golem/bronze
+ name = "Bronze Golem"
+ id = "bronze golem"
+ prefix = "Bronze"
+ special_names = list("Bell")
+ fixed_mut_color = "cd7f32"
+ info_text = "As a Bronze Golem, you are very resistant to loud noises, and make loud noises if something hard hits you, however this ability does hurt your hearing."
+ special_step_sounds = list('sound/machines/clockcult/integration_cog_install.ogg', 'sound/magic/clockwork/fellowship_armory.ogg' )
+ attack_verb = "bonk"
+ mutantears = /obj/item/organ/ears/bronze
+ var/last_gong_time = 0
+ var/gong_cooldown = 150
+
+/datum/species/golem/bronze/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
+ if(!(world.time > last_gong_time + gong_cooldown))
+ return ..()
+ if(P.flag == "bullet" || P.flag == "bomb")
+ gong(H)
+ return ..()
+
+/datum/species/golem/bronze/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
+ ..()
+ if(world.time > last_gong_time + gong_cooldown)
+ gong(H)
+
+/datum/species/golem/bronze/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
+ ..()
+ if(world.time > last_gong_time + gong_cooldown && M.a_intent != INTENT_HELP)
+ gong(H)
+
+/datum/species/golem/bronze/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
+ ..()
+ if(world.time > last_gong_time + gong_cooldown)
+ gong(H)
+
+/datum/species/golem/bronze/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
+ ..()
+ if(world.time > last_gong_time + gong_cooldown)
+ gong(H)
+
+/datum/species/golem/bronze/proc/gong(mob/living/carbon/human/H)
+ last_gong_time = world.time
+ for(var/mob/living/M in get_hearers_in_view(7,H))
+ if(M.stat == DEAD) //F
+ return
+ if(M == H)
+ H.show_message("You cringe with pain as your body rings around you!", 2)
+ H.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE)
+ H.soundbang_act(2, 0, 100, 1)
+ H.jitteriness += 7
+ var/distance = max(0,get_dist(get_turf(H),get_turf(M)))
+ switch(distance)
+ if(0 to 1)
+ M.show_message("GONG!", 2)
+ M.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE)
+ M.soundbang_act(1, 0, 30, 3)
+ M.confused += 10
+ M.jitteriness += 4
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong)
+ if(2 to 3)
+ M.show_message("GONG!", 2)
+ M.playsound_local(H, 'sound/effects/gong.ogg', 75, TRUE)
+ M.soundbang_act(1, 0, 15, 2)
+ M.jitteriness += 3
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong)
+ else
+ M.show_message("GONG!", 2)
+ M.playsound_local(H, 'sound/effects/gong.ogg', 50, TRUE)
+
+
+/datum/species/golem/cardboard //Faster but weaker, can also make new shells on its own
+ name = "Cardboard Golem"
+ id = "cardboard golem"
+ prefix = "Cardboard"
+ special_names = list("Box")
+ info_text = "As a Cardboard Golem, you aren't very strong, but you are a bit quicker and can easily create more brethren by using cardboard on yourself."
+ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS)
+ inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ fixed_mut_color = "ffffff"
+ limbs_id = "c_golem" //special sprites
+ attack_verb = "bash"
+ armor = 25
+ burnmod = 1.25
+ heatmod = 2
+ speedmod = 1.5
+ punchdamagelow = 4
+ punchstunthreshold = 7
+ punchdamagehigh = 8
+ var/last_creation = 0
+ var/brother_creation_cooldown = 300
+
+/datum/species/golem/cardboard/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
+ . = ..()
+ if(user != H)
+ return FALSE //forced reproduction is rape.
+ if(istype(I, /obj/item/stack/sheet/cardboard))
+ var/obj/item/stack/sheet/cardboard/C = I
+ if(last_creation + brother_creation_cooldown > world.time) //no cheesing dork
+ return
+ if(C.amount < 10)
+ to_chat(H, "You do not have enough cardboard!")
+ return FALSE
+ to_chat(H, "You attempt to create a new cardboard brother.")
+ if(do_after(user, 30, target = user))
+ if(last_creation + brother_creation_cooldown > world.time) //no cheesing dork
+ return
+ if(!C.use(10))
+ to_chat(H, "You do not have enough cardboard!")
+ return FALSE
+ to_chat(H, "You create a new cardboard golem shell.")
+ create_brother(H.loc)
+
+/datum/species/golem/cardboard/proc/create_brother(var/location)
+ new /obj/effect/mob_spawn/human/golem/servant(location, /datum/species/golem/cardboard, owner)
+ last_creation = world.time
+
+/datum/species/golem/leather
+ name = "Leather Golem"
+ id = "leather golem"
+ special_names = list("Face", "Man", "Belt") //Ah dude 4 strength 4 stam leather belt AHHH
+ inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER, TRAIT_STRONG_GRABBER)
+ prefix = "Leather"
+ fixed_mut_color = "624a2e"
+ info_text = "As a Leather Golem, you are flammable, but you can grab things with incredible ease, allowing all your grabs to start at a strong level."
+ attack_verb = "whipp"
+ grab_sound = 'sound/weapons/whipgrab.ogg'
+ attack_sound = 'sound/weapons/whip.ogg'
+
+/datum/species/golem/bone
+ name = "Bone Golem"
+ id = "bone golem"
+ say_mod = "rattles"
+ prefix = "Bone"
+ limbs_id = "b_golem"
+ special_names = list("Head", "Broth", "Fracture", "Rattler", "Appetit")
+ liked_food = GROSS | MEAT | RAW
+ toxic_food = null
+ inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
+ mutanttongue = /obj/item/organ/tongue/bone
+ sexes = FALSE
+ fixed_mut_color = "ffffff"
+ attack_verb = "rattl"
+ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH,TRAIT_CALCIUM_HEALER)
+ info_text = "As a Bone Golem, You have a powerful spell that lets you chill your enemies with fear, and milk heals you! Just make sure to watch our for bone-hurting juice."
+ var/datum/action/innate/bonechill/bonechill
+
+/datum/species/golem/bone/on_species_gain(mob/living/carbon/C, datum/species/old_species)
+ ..()
+ if(ishuman(C))
+ bonechill = new
+ bonechill.Grant(C)
+
+/datum/species/golem/bone/on_species_loss(mob/living/carbon/C)
+ if(bonechill)
+ bonechill.Remove(C)
+ ..()
+
+/datum/action/innate/bonechill
+ name = "Bone Chill"
+ desc = "Rattle your bones and strike fear into your enemies!"
+ check_flags = AB_CHECK_CONSCIOUS
+ icon_icon = 'icons/mob/actions/actions_spells.dmi'
+ button_icon_state = "bonechill"
+ var/cooldown = 600
+ var/last_use
+ var/snas_chance = 3
+
+/datum/action/innate/bonechill/Activate()
+ if(world.time < last_use + cooldown)
+ to_chat("You aren't ready yet to rattle your bones again")
+ return
+ owner.visible_message("[owner] rattles [owner.p_their()] bones harrowingly.", "You rattle your bones")
+ last_use = world.time
+ if(prob(snas_chance))
+ playsound(get_turf(owner),'sound/magic/RATTLEMEBONES2.ogg', 100)
+ if(ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ var/mutable_appearance/badtime = mutable_appearance('icons/mob/human_parts.dmi', "b_golem_eyes", -FIRE_LAYER-0.5)
+ badtime.appearance_flags = RESET_COLOR
+ H.overlays_standing[FIRE_LAYER+0.5] = badtime
+ H.apply_overlay(FIRE_LAYER+0.5)
+ addtimer(CALLBACK(H, /mob/living/carbon/.proc/remove_overlay, FIRE_LAYER+0.5), 25)
+ 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))
+ return //Do not affect our brothers
+
+ to_chat(L, "A spine-chilling sound chills you to the bone!")
+ L.apply_status_effect(/datum/status_effect/bonechill)
+ SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "spooked", /datum/mood_event/spooked)
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 afd6e4e7f5..d7bb151ddc 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -5,7 +5,7 @@
sexes = 0
meat = /obj/item/stack/sheet/mineral/plasma
species_traits = list(NOBLOOD,NOTRANSSTING,NOGENITALS)
- inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER,TRAIT_CALCIUM_HEALER)
inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
mutantlungs = /obj/item/organ/lungs/plasmaman
mutanttongue = /obj/item/organ/tongue/bone/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 c3d1e1aedb..0da4073f1d 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -73,6 +73,9 @@
/datum/species/pod/pseudo_weak
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")
light_nutrition_gain_factor = 7.5
light_bruteheal = 0.2
light_burnheal = 0.2
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 5c2b01a179..135992f3a6 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -7,7 +7,7 @@
sexes = 0
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)
+ 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)
mutanttongue = /obj/item/organ/tongue/bone
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
@@ -21,4 +21,4 @@
/datum/species/skeleton/pirate
name = "Space Queen's Skeleton"
- inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 571775d541..b2eb83d668 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -654,6 +654,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
L.damage += d
/mob/living/carbon/proc/liver_failure()
+ reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE)
if(HAS_TRAIT(src, TRAIT_STABLEHEART))
return
diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm
index 4c1c235fe1..85436178fe 100644
--- a/code/modules/mob/living/carbon/monkey/combat.dm
+++ b/code/modules/mob/living/carbon/monkey/combat.dm
@@ -73,39 +73,21 @@
if(I.loc == src)
return TRUE
- if(I.anchored)
+ if(I.anchored || !put_in_hands(I))
blacklistItems[I] ++
return FALSE
- // WEAPONS
- if(istype(I, /obj/item))
- var/obj/item/W = I
- if(W.force >= best_force)
- put_in_hands(W)
- best_force = W.force
- return TRUE
-
- // CLOTHING
- else if(istype(I, /obj/item/clothing))
- var/obj/item/clothing/C = I
- monkeyDrop(C)
- addtimer(CALLBACK(src, .proc/pickup_and_wear, C), 5)
- return TRUE
-
- // EVERYTHING ELSE
+ if(I.force >= best_force)
+ best_force = I.force
else
- if(!get_item_for_held_index(1) || !get_item_for_held_index(2))
- put_in_hands(I)
- return TRUE
+ addtimer(CALLBACK(src, .proc/pickup_and_wear, I), 5)
- blacklistItems[I] ++
- return FALSE
+ return TRUE
-/mob/living/carbon/monkey/proc/pickup_and_wear(var/obj/item/clothing/C)
- if(!equip_to_appropriate_slot(C))
- monkeyDrop(get_item_by_slot(C)) // remove the existing item if worn
- sleep(5)
- equip_to_appropriate_slot(C)
+/mob/living/carbon/monkey/proc/pickup_and_wear(obj/item/I)
+ if(QDELETED(I) || I.loc != src)
+ return
+ equip_to_appropriate_slot(I)
/mob/living/carbon/monkey/resist_restraints()
var/obj/item/I = null
@@ -311,7 +293,8 @@
if(I == pickupTarget)
M.visible_message("[src] snatches [pickupTarget] from [M].", "[src] snatched [pickupTarget]!")
if(M.temporarilyRemoveItemFromInventory(pickupTarget) && !QDELETED(pickupTarget))
- equip_item(pickupTarget)
+ if(!equip_item(pickupTarget))
+ dropItemToGround(pickupTarget)
else
M.visible_message("[src] tried to snatch [pickupTarget] from [M], but failed!", "[src] tried to grab [pickupTarget]!")
pickpocketing = FALSE
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 65ed57a6f1..b844a294be 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -263,7 +263,7 @@
var/mob/M = AM
log_combat(src, M, "grabbed", addition="passive grab")
- if(!supress_message)
+ if(!supress_message && !(iscarbon(AM) && HAS_TRAIT(src, TRAIT_STRONG_GRABBER)))
visible_message("[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by their hands":" passively"]!") //Cit change - And they thought ERP was bad.
if(!iscarbon(src))
M.LAssailant = null
@@ -281,6 +281,11 @@
var/datum/disease/D = thing
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
ContactContractDisease(D)
+
+ if(iscarbon(L))
+ var/mob/living/carbon/C = L
+ if(HAS_TRAIT(src, TRAIT_STRONG_GRABBER))
+ C.grippedby(src)
//mob verbs are a lot faster than object verbs
//for more info on why this is not atom/pull, see examinate() in mob.dm
@@ -814,7 +819,7 @@
/mob/living/proc/harvest(mob/living/user) //used for extra objects etc. in butchering
return
-/mob/living/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
+/mob/living/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(incapacitated())
to_chat(src, "You can't do that right now!")
return FALSE
@@ -1189,9 +1194,13 @@
clamp_unconscious_to = 0,
clamp_immobility_to = 0,
reset_misc = TRUE,
- healing_chems = list("inaprovaline" = 3, "synaptizine" = 10, "omnizine" = 10, "stimulants" = 10),
- message = "You feel a surge of energy!"
+ healing_chems = list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10),
+ message = "You feel a surge of energy!",
+ stamina_buffer_boost = 0, //restores stamina buffer rather than just health
+ scale_stamina_loss_recovery, //defaults to null. if this is set, restores loss * this stamina. make sure it's a fraction.
+ stamina_loss_recovery_bypass = 0 //amount of stamina loss to ignore during calculation
)
+ to_chat(src, message)
if(AmountSleeping() > clamp_unconscious_to)
SetSleeping(clamp_unconscious_to)
if(AmountUnconscious() > clamp_unconscious_to)
@@ -1200,7 +1209,10 @@
SetStun(clamp_immobility_to)
if(AmountKnockdown() > clamp_immobility_to)
SetKnockdown(clamp_immobility_to)
- adjustStaminaLoss(max(0, -stamina_boost))
+ adjustStaminaLoss(min(0, -stamina_boost))
+ adjustStaminaLossBuffered(min(0, -stamina_buffer_boost))
+ if(scale_stamina_loss_recovery)
+ adjustStaminaLoss(min(-((getStaminaLoss() - stamina_loss_recovery_bypass) * scale_stamina_loss_recovery), 0))
if(put_on_feet)
resting = FALSE
lying = FALSE
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 46576a357f..1b1eb1a805 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -288,8 +288,17 @@
/mob/living/silicon/ai/can_interact_with(atom/A)
. = ..()
+ var/turf/ai = get_turf(src)
+ var/turf/target = get_turf(A)
if (.)
return
+
+ if(!target)
+ return
+
+ if ((ai.z != target.z) && !is_station_level(ai.z))
+ return FALSE
+
if (istype(loc, /obj/item/aicard))
var/turf/T0 = get_turf(src)
var/turf/T1 = get_turf(A)
@@ -779,7 +788,7 @@
return TRUE
return ..()
-/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
+/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(control_disabled || incapacitated())
to_chat(src, "You can't do that right now!")
return FALSE
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 896d8674be..7fd861bfeb 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -183,7 +183,7 @@
// See software.dm for Topic()
-/mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
+/mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(be_close && !in_range(M, src))
to_chat(src, "You are too far away!")
return FALSE
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 335645b17e..e71e269222 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -910,7 +910,7 @@
if(DISCONNECT) //Tampering with the wires
to_chat(connected_ai, " NOTICE - Remote telemetry lost with [name]. ") -/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(stat || lockcharge || low_power_mode) to_chat(src, "You can't do that right now!") return FALSE diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 9a08276999..5e5b486435 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -284,12 +284,8 @@ if(health < maxHealth) adjustBruteLoss(-8) //Fast life regen for(var/obj/item/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts! - if(D.icon_state != "donut2") - D.name = "frosted donut" - D.icon_state = "donut2" - D.reagents.add_reagent("sprinkles", 2) - D.bonus_reagents = list("sprinkles" = 2, "sugar" = 1) - D.filling_color = "#FF69B4" + if(!D.is_frosted) + D.frost_donut() /mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L) ..() diff --git a/code/modules/mob/living/simple_animal/friendly/panda.dm b/code/modules/mob/living/simple_animal/friendly/panda.dm new file mode 100644 index 0000000000..a7b6143ef5 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/panda.dm @@ -0,0 +1,20 @@ +/mob/living/simple_animal/pet/redpanda + name = "Red panda" + desc = "Wah't a dork." + icon = 'icons/mob/pets.dmi' + icon_state = "red_panda" + icon_living = "red_panda" + icon_dead = "dead_panda" + speak = list("Churip","Chuuriip","Cheep-cheep","Chiteurp","squueeaacipt") + speak_emote = list("chirps", "huff-quacks") + emote_hear = list("squeak-chrips.", "huff-squacks.") + emote_see = list("shakes its head.", "rolls about.") + speak_chance = 1 + turns_per_move = 5 + see_in_dark = 6 + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3) + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + gold_core_spawnable = FRIENDLY_SPAWN + do_footstep = TRUE diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 701e244f89..1a918766b6 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -596,6 +596,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians /obj/item/guardiancreator/tech/choose/traitor possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support") +/obj/item/guardiancreator/tech/choose/traitor/check_uplink_validity() + return !used + /obj/item/guardiancreator/tech/choose random = FALSE diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 2517d2438d..1f81899d8a 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -392,7 +392,7 @@ if(target) return new childspawn(target) -/mob/living/simple_animal/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/living/simple_animal/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) if(incapacitated()) to_chat(src, "You can't do that right now!") return FALSE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 7ff8fbc0b1..b098801da8 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -784,7 +784,7 @@ return 0 //Can the mob use Topic to interact with machines -/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) return /mob/proc/faction_check_mob(mob/target, exact_match) @@ -871,13 +871,7 @@ return /mob/proc/update_sight() - for(var/O in orbiters) - var/datum/orbit/orbit = O - var/obj/effect/wisp/wisp = orbit.orbiter - if (istype(wisp)) - sight |= wisp.sight_flags - if(!isnull(wisp.lighting_alpha)) - lighting_alpha = min(lighting_alpha, wisp.lighting_alpha) + SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT) sync_lighting_plane_alpha() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 33f1ec81c1..82e2b11f8e 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -148,7 +148,7 @@ if(INCORPOREAL_MOVE_BASIC) var/T = get_step(L,direct) if(T) - L.loc = T + L.forceMove(T) L.setDir(direct) if(INCORPOREAL_MOVE_SHADOW) if(prob(50)) @@ -190,7 +190,7 @@ new /obj/effect/temp_visual/dir_setting/ninja/shadow(mobloc, L.dir) var/T = get_step(L,direct) if(T) - L.loc = T + L.forceMove(T) L.setDir(direct) if(INCORPOREAL_MOVE_JAUNT) //Incorporeal move, but blocked by holy-watered tiles and salt piles. var/turf/open/floor/stepTurf = get_step(L, direct) @@ -209,7 +209,7 @@ to_chat(L, "Holy energies block your path!") return - L.loc = get_step(L, direct) + L.forceMove(stepTurf) L.setDir(direct) return TRUE diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm index 20ad2214cf..99d648d02b 100644 --- a/code/modules/modular_computers/computers/item/processor.dm +++ b/code/modules/modular_computers/computers/item/processor.dm @@ -44,7 +44,7 @@ return machinery_computer.update_icon() // This thing is not meant to be used on it's own, get topic data from our machinery owner. -//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) +//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) // if(!machinery_computer) // return 0 diff --git a/code/modules/orbit/orbit.dm b/code/modules/orbit/orbit.dm deleted file mode 100644 index 79685b9104..0000000000 --- a/code/modules/orbit/orbit.dm +++ /dev/null @@ -1,135 +0,0 @@ -/datum/orbit - var/atom/movable/orbiter - var/atom/orbiting - var/lock = TRUE - var/turf/lastloc - var/lastprocess - -/datum/orbit/New(_orbiter, _orbiting, _lock) - orbiter = _orbiter - orbiting = _orbiting - SSorbit.processing += src - if (!orbiting.orbiters) - orbiting.orbiters = list() - orbiting.orbiters += src - - if (orbiter.orbiting) - orbiter.stop_orbit() - orbiter.orbiting = src - Check() - lock = _lock - -//do not qdel directly, use stop_orbit on the orbiter. (This way the orbiter can bind to the orbit stopping) -/datum/orbit/Destroy(force = FALSE) - SSorbit.processing -= src - if (orbiter) - orbiter.orbiting = null - orbiter = null - if (orbiting) - if (orbiting.orbiters) - orbiting.orbiters -= src - if (!orbiting.orbiters.len)//we are the last orbit, delete the list - orbiting.orbiters = null - orbiting = null - return ..() - -/datum/orbit/proc/Check(turf/targetloc, list/checked_already = list()) - //Avoid infinite loops for people who end up orbiting themself through another orbiter - checked_already[src] = TRUE - if (!orbiter) - qdel(src) - return - if (!orbiting) - orbiter.stop_orbit() - return - if (!orbiter.orbiting) //admin wants to stop the orbit. - orbiter.orbiting = src //set it back to us first - orbiter.stop_orbit() - var/atom/movable/AM = orbiting - if(istype(AM) && AM.orbiting && AM.orbiting.orbiting == orbiter) - orbiter.stop_orbit() - return - lastprocess = world.time - if (!targetloc) - targetloc = get_turf(orbiting) - if (!targetloc || (!lock && orbiter.loc != lastloc && orbiter.loc != targetloc)) - orbiter.stop_orbit() - return - var/turf/old_turf = get_turf(orbiter) - var/turf/new_turf = get_turf(targetloc) - if (old_turf?.z != new_turf?.z) - orbiter.onTransitZ(old_turf?.z, new_turf?.z) - // DO NOT PORT TO FORCEMOVE - MEMECODE WILL KILL MC - orbiter.loc = targetloc - orbiter.update_parallax_contents() - orbiter.update_light() - lastloc = orbiter.loc - for(var/other_orbit in orbiter.orbiters) - var/datum/orbit/OO = other_orbit - //Skip if checked already - if(checked_already[OO]) - continue - OO.Check(targetloc, checked_already) - -/atom/movable/var/datum/orbit/orbiting = null -/atom/var/list/orbiters = null - -//A: atom to orbit -//radius: range to orbit at, radius of the circle formed by orbiting (in pixels) -//clockwise: whether you orbit clockwise or anti clockwise -//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete) -//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default. -//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts -//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts) - -/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE) - if (!istype(A)) - return - - new/datum/orbit(src, A, lockinorbit) - if (!orbiting) //something failed, and our orbit datum deleted itself - return - var/matrix/initial_transform = matrix(transform) - - //Head first! - if (pre_rotation) - var/matrix/M = matrix(transform) - var/pre_rot = 90 - if(!clockwise) - pre_rot = -90 - M.Turn(pre_rot) - transform = M - - var/matrix/shift = matrix(transform) - shift.Translate(0,radius) - transform = shift - - SpinAnimation(rotation_speed, -1, clockwise, rotation_segments) - - //we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit - transform = initial_transform - -/atom/movable/proc/stop_orbit() - SpinAnimation(0,0) - qdel(orbiting) - -/atom/Destroy(force = FALSE) - . = ..() - if (orbiters) - for (var/thing in orbiters) - var/datum/orbit/O = thing - if (O.orbiter) - O.orbiter.stop_orbit() - -/atom/movable/Destroy(force = FALSE) - . = ..() - if (orbiting) - stop_orbit() - -/atom/movable/proc/transfer_observers_to(atom/movable/target) - if(orbiters) - for(var/thing in orbiters) - var/datum/orbit/O = thing - if(O.orbiter && isobserver(O.orbiter)) - var/mob/dead/observer/D = O.orbiter - D.ManualFollow(target) diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index e3ce30066a..4b08ccf608 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -1,3 +1,4 @@ + /obj/item/paperplane name = "paper plane" desc = "Paper, folded in the shape of a plane." @@ -10,8 +11,14 @@ resistance_flags = FLAMMABLE max_integrity = 50 + var/hit_probability = 2//% var/obj/item/paper/internalPaper +/obj/item/paperplane/origami + desc = "Paper, masterfully folded in the shape of a plane." + throwforce = 20 //same as throwing stars, but no chance of embedding. + hit_probability = 100 //guaranteed to cause eye damage when it hits a mob. + /obj/item/paperplane/Initialize(mapload, obj/item/paper/newPaper) . = ..() pixel_y = rand(-8, 8) @@ -22,13 +29,18 @@ color = newPaper.color newPaper.forceMove(src) else - internalPaper = new /obj/item/paper(src) + internalPaper = new(src) update_icon() -/obj/item/paperplane/Destroy() - if(internalPaper) - qdel(internalPaper) +/obj/item/paperplane/handle_atom_del(atom/A) + if(A == internalPaper) internalPaper = null + if(!QDELETED(src)) + qdel(src) + return ..() + +/obj/item/paperplane/Destroy() + QDEL_NULL(internalPaper) return ..() /obj/item/paperplane/suicide_act(mob/living/user) @@ -48,7 +60,7 @@ /obj/item/paperplane/attack_self(mob/user) to_chat(user, "You unfold [src].") - var/atom/movable/internal_paper_tmp = internalPaper + var/obj/item/paper/internal_paper_tmp = internalPaper internal_paper_tmp.forceMove(loc) internalPaper = null qdel(src) @@ -86,11 +98,18 @@ . = ..(target, range, speed, thrower, FALSE, diagonals_first, callback) /obj/item/paperplane/throw_impact(atom/hit_atom) + if(iscarbon(hit_atom)) + var/mob/living/carbon/C = hit_atom + if(C.can_catch_item(TRUE)) + var/datum/action/innate/origami/origami_action = locate() in C.actions + if(origami_action?.active) //if they're a master of origami and have the ability turned on, force throwmode on so they'll automatically catch the plane. + C.throw_mode_on() + if(..() || !ishuman(hit_atom))//if the plane is caught or it hits a nonhuman return var/mob/living/carbon/human/H = hit_atom - if(prob(2)) - if((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)) + if(prob(hit_probability)) + if(H.is_eyes_covered()) return visible_message("\The [src] hits [H] in the eye!") H.adjust_blurriness(6) @@ -103,9 +122,15 @@ to_chat(user, "Alt-click [src] to fold it into a paper plane.") /obj/item/paper/AltClick(mob/living/carbon/user, obj/item/I) - if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user), NO_TK)) return to_chat(user, "You fold [src] into the shape of a plane!") user.temporarilyRemoveItemFromInventory(src) - I = new /obj/item/paperplane(user, src) + var/obj/item/paperplane/plane_type = /obj/item/paperplane + //Origami Master + var/datum/action/innate/origami/origami_action = locate() in user.actions + if(origami_action?.active) + plane_type = /obj/item/paperplane/origami + + I = new plane_type(user, src) user.put_in_hands(I) diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index a04ed08611..40f71b81d4 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -90,7 +90,7 @@ /obj/machinery/power/emitter/ComponentInitialize() . = ..() - AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_FLIP ,null,CALLBACK(src, .proc/can_be_rotated)) + AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS, null, CALLBACK(src, .proc/can_be_rotated)) /obj/machinery/power/emitter/proc/can_be_rotated(mob/user,rotation_type) if (anchored) @@ -495,4 +495,4 @@ #undef EMITTER_UNWRENCHED #undef EMITTER_WRENCHED -#undef EMITTER_WELDED \ No newline at end of file +#undef EMITTER_WELDED diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 0a54bcab33..bbad3e08b0 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -33,8 +33,8 @@ return /obj/singularity/energy_ball/Destroy() - if(orbiting && istype(orbiting.orbiting, /obj/singularity/energy_ball)) - var/obj/singularity/energy_ball/EB = orbiting.orbiting + if(orbiting && istype(orbiting.parent, /obj/singularity/energy_ball)) + var/obj/singularity/energy_ball/EB = orbiting.parent EB.orbiting_balls -= src for(var/ball in orbiting_balls) @@ -146,12 +146,12 @@ . = ..() /obj/singularity/energy_ball/stop_orbit() - if (orbiting && istype(orbiting.orbiting, /obj/singularity/energy_ball)) - var/obj/singularity/energy_ball/orbitingball = orbiting.orbiting + if (orbiting && istype(orbiting.parent, /obj/singularity/energy_ball)) + var/obj/singularity/energy_ball/orbitingball = orbiting.parent orbitingball.orbiting_balls -= src orbitingball.dissipate_strength = orbitingball.orbiting_balls.len - ..() - if (!loc && !QDELETED(src)) + . = ..() + if (!QDELETED(src)) qdel(src) diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm index 3f033ac904..c9e60ddc1d 100644 --- a/code/modules/projectiles/ammunition/energy/stun.dm +++ b/code/modules/projectiles/ammunition/energy/stun.dm @@ -24,4 +24,4 @@ e_cost = 40 fire_sound = 'sound/weapons/taser2.ogg' harmful = FALSE - click_cooldown_override = 3 + click_cooldown_override = 3.5 diff --git a/code/modules/projectiles/ammunition/special/syringe.dm b/code/modules/projectiles/ammunition/special/syringe.dm index 4a2a354ca6..d5cba6936f 100644 --- a/code/modules/projectiles/ammunition/special/syringe.dm +++ b/code/modules/projectiles/ammunition/special/syringe.dm @@ -59,3 +59,20 @@ S.forceMove(D) D.injector = S ..() + +/obj/item/ammo_casing/syringegun/dart + name = "used air canister" + desc = "A small canister of compressed gas." + projectile_type = /obj/item/projectile/bullet/dart/syringe/dart + firing_effect_type = null + harmful = FALSE + +/obj/item/ammo_casing/syringegun/dart/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + ..() + var/obj/item/gun/syringe/SG = loc + if(!SG.syringes.len) + return + var/obj/item/reagent_containers/syringe/dart/S = SG.syringes[1] + if(S.emptrig == TRUE) + var/obj/item/projectile/bullet/dart/syringe/dart/D = BB + D.emptrig = TRUE diff --git a/code/modules/projectiles/guns/misc/medbeam.dm b/code/modules/projectiles/guns/misc/medbeam.dm index 17c0f63955..7bdefe5e91 100644 --- a/code/modules/projectiles/guns/misc/medbeam.dm +++ b/code/modules/projectiles/guns/misc/medbeam.dm @@ -116,7 +116,7 @@ new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF") target.adjustBruteLoss(-4) target.adjustFireLoss(-4) - target.adjustToxLoss(-1) + target.adjustToxLoss(-1, forced = TRUE) target.adjustOxyLoss(-1) return diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm index cc1b321e3a..26e66b1987 100644 --- a/code/modules/projectiles/guns/misc/syringe_gun.dm +++ b/code/modules/projectiles/guns/misc/syringe_gun.dm @@ -102,3 +102,23 @@ else to_chat(user, "[src] cannot hold more syringes!") return FALSE + +/obj/item/gun/syringe/dart + name = "dart gun" + desc = "A compressed air gun, designed to fit medicinal darts for application of medicine for those patients just out of reach." + icon_state = "dartgun" + item_state = "dartgun" + materials = list(MAT_METAL=2000, MAT_GLASS=500) + suppressed = TRUE //Softer fire sound + can_unsuppress = FALSE + +/obj/item/gun/syringe/dart/Initialize() + ..() + chambered = new /obj/item/ammo_casing/syringegun/dart(src) + +/obj/item/gun/syringe/dart/attackby(obj/item/A, mob/user, params, show_msg = TRUE) + if(istype(A, /obj/item/reagent_containers/syringe/dart)) + ..() + else + to_chat(user, "You can't put the [A] into \the [src]!") + return FALSE diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm index 94d075c789..bdbf706448 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -8,12 +8,14 @@ . = ..() create_reagents(50, NO_REACT) -/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE) +/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE, skip = FALSE) if(iscarbon(target)) var/mob/living/carbon/M = target if(blocked != 100) // not completely blocked if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. ..() + if(skip == TRUE) + return reagents.reaction(M, INJECT) reagents.trans_to(M, reagents.total_volume) return TRUE @@ -36,3 +38,44 @@ /obj/item/projectile/bullet/dart/syringe name = "syringe" icon_state = "syringeproj" + +//I am in a mess of my own making +/obj/item/projectile/bullet/dart/syringe/dart + name = "Smartdart" + icon_state = "dartproj" + damage = 0 + var/emptrig = FALSE + +/obj/item/projectile/bullet/dart/syringe/dart/on_hit(atom/target, blocked = FALSE) + if(iscarbon(target)) + var/mob/living/carbon/M = target + if(blocked != 100) + if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. + ..(target, blocked, TRUE) + for(var/datum/reagent/R in reagents.reagent_list) //OD prevention time! + if(istype(R, /datum/reagent/medicine)) //Is this a medicine? + if(M.reagents.has_reagent(R.id)) + if(R.overdose_threshold == 0 || emptrig == TRUE) //Is there a possible OD? + M.reagents.add_reagent(R.id, R.volume) + else + var/transVol = CLAMP(R.volume, 0, (R.overdose_threshold - M.reagents.get_reagent_amount(R.id)) -1) + M.reagents.add_reagent(R.id, transVol) + else + if(!R.overdose_threshold == 0) + var/transVol = CLAMP(R.volume, 0, R.overdose_threshold-1) + M.reagents.add_reagent(R.id, transVol) + else + M.reagents.add_reagent(R.id, R.volume) + + + + target.visible_message("\The [src] beeps!") + to_chat("You feel a tiny prick as a smartdart embeds itself in you with a beep.") + return TRUE + else + blocked = 100 + target.visible_message("\The [src] was deflected!", \ + "You see a [src] bounce off you, booping sadly!") + + target.visible_message("\The [src] fails to land on target!") + return TRUE diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 58c29f351b..dc86ab4e6c 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -21,7 +21,9 @@ if(GLOB.chemical_reactions_list) return - var/paths = subtypesof(/datum/chemical_reaction) + + //Randomized need to go last since they need to check against conflicts with normal recipes + var/paths = subtypesof(/datum/chemical_reaction) - typesof(/datum/chemical_reaction/randomized) + subtypesof(/datum/chemical_reaction/randomized) GLOB.chemical_reactions_list = list() for(var/path in paths) @@ -29,6 +31,9 @@ var/datum/chemical_reaction/D = new path() var/list/reaction_ids = list() + if(!D.id) + continue + if(D.required_reagents && D.required_reagents.len) for(var/reaction in D.required_reagents) reaction_ids += reaction @@ -267,6 +272,9 @@ continue if(!C) C = R.holder.my_atom + if(!R.metabolizing) + R.metabolizing = TRUE + R.on_mob_metabolize(C) if(C && R) if(C.reagent_check(R) != 1) if(can_overdose) @@ -313,6 +321,21 @@ C.update_stamina() update_total() +//Signals that metabolization has stopped, triggering the end of trait-based effects +/datum/reagents/proc/end_metabolization(mob/living/carbon/C, keep_liverless = TRUE) + var/list/cached_reagents = reagent_list + for(var/reagent in cached_reagents) + var/datum/reagent/R = reagent + if(QDELETED(R.holder)) + continue + if(keep_liverless && R.self_consuming) //Will keep working without a liver + continue + if(!C) + C = R.holder.my_atom + if(R.metabolizing) + R.metabolizing = FALSE + R.on_mob_end_metabolize(C) + /datum/reagents/proc/conditional_update_move(atom/A, Running = 0) var/list/cached_reagents = reagent_list for(var/reagent in cached_reagents) @@ -466,6 +489,9 @@ if(R.id == reagent) if(my_atom && isliving(my_atom)) var/mob/living/M = my_atom + if(R.metabolizing) + R.metabolizing = FALSE + R.on_mob_end_metabolize(M) R.on_mob_delete(M) qdel(R) reagent_list -= R diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 10282e5e0a..fa9d60a219 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -9,7 +9,6 @@ interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE resistance_flags = FIRE_PROOF | ACID_PROOF circuit = /obj/item/circuitboard/machine/chem_dispenser - var/cell_type = /obj/item/stock_parts/cell/high var/obj/item/stock_parts/cell/cell var/powerefficiency = 0.1 var/amount = 30 @@ -52,7 +51,8 @@ //these become available once upgraded. var/list/upgrade_reagents = list( "oil", - "ammonia" + "ammonia", + "ash" ) var/list/upgrade_reagents2 = list( @@ -79,7 +79,6 @@ /obj/machinery/chem_dispenser/Initialize() . = ..() - cell = new cell_type dispensable_reagents = sortList(dispensable_reagents) update_icon() @@ -250,13 +249,8 @@ work_animation() . = TRUE if("eject") - if(beaker) - beaker.forceMove(drop_location()) - if(Adjacent(usr) && !issilicon(usr)) - usr.put_in_hands(beaker) - beaker = null - update_icon() - . = TRUE + replace_beaker(usr) + . = TRUE //no afterattack if("dispense_recipe") if(!is_operational() || QDELETED(cell)) return @@ -269,7 +263,7 @@ if(beaker && dispensable_reagents.Find(r_id)) // but since we verify we have the reagent, it'll be fine var/datum/reagents/R = beaker.reagents var/free = R.maximum_volume - R.total_volume - var/actual = min(round(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free) + var/actual = min(max(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free) if(actual) if(!cell.use(actual / powerefficiency)) say("Not enough energy to complete operation!") @@ -322,14 +316,12 @@ return if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) var/obj/item/reagent_containers/B = I - . = 1 //no afterattack - if(beaker) - to_chat(user, "A container is already loaded into [src]!") - return + . = TRUE //no afterattack if(!user.transferItemToLoc(B, src)) return - beaker = B + replace_beaker(user, B) to_chat(user, "You add [B] to [src].") + updateUsrDialog() update_icon() else if(user.a_intent != INTENT_HARM && !istype(I, /obj/item/card/emag)) to_chat(user, "You can't load [I] into [src]!") @@ -381,7 +373,17 @@ dispensable_reagents |= upgrade_reagents3 powerefficiency = round(newpowereff, 0.01) - +/obj/machinery/chem_dispenser/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) + if(beaker) + beaker.forceMove(drop_location()) + if(user && Adjacent(user) && !issiliconoradminghost(user)) + user.put_in_hands(beaker) + if(new_beaker) + beaker = new_beaker + else + beaker = null + update_icon() + return TRUE /obj/machinery/chem_dispenser/on_deconstruction() cell = null @@ -417,6 +419,12 @@ final_list += list(avoid_assoc_duplicate_keys(fuck[1],key_list) = text2num(fuck[2])) return final_list +/obj/machinery/chem_dispenser/AltClick(mob/living/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + replace_beaker(user) + return + /obj/machinery/chem_dispenser/drinks/Initialize() . = ..() AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE) @@ -480,9 +488,16 @@ "tomatojuice", "lemonjuice", "menthol" - ) //prevents the soda machine from obtaining chemical upgrades. . - upgrade_reagents = null - upgrade_reagents2 = null + ) + upgrade_reagents = list( + "mushroomhallucinogen", + "nothing", + "cryoxadone" + ) + upgrade_reagents2 = list( + "banana", + "berryjuice" + ) upgrade_reagents3 = null emagged_reagents = list( "thirteenloko", @@ -534,19 +549,21 @@ "creme_de_menthe", "creme_de_cacao", "triple_sec", - "sake" - )//prevents the booze machine from obtaining chemical upgrades. - upgrade_reagents = null + "sake", + "applejack" + ) + upgrade_reagents = list( + "ethanol", + "fernet" + ) upgrade_reagents2 = null upgrade_reagents3 = null emagged_reagents = list( - "ethanol", "iron", "alexander", "clownstears", "minttoxin", "atomicbomb", - "fernet", "aphro", "aphro+" ) diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index e4c6966cff..a17b1e8190 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -28,13 +28,23 @@ else icon_state = "mixer0b" -/obj/machinery/chem_heater/proc/eject_beaker(mob/user) +/obj/machinery/chem_heater/AltClick(mob/living/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + replace_beaker(user) + return + +/obj/machinery/chem_heater/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) if(beaker) beaker.forceMove(drop_location()) - if(Adjacent(user) && !issilicon(user)) + if(user && Adjacent(user) && !issiliconoradminghost(user)) user.put_in_hands(beaker) + if(new_beaker) + beaker = new_beaker + else beaker = null update_icon() + return TRUE /obj/machinery/chem_heater/RefreshParts() heater_coefficient = 0.1 @@ -58,21 +68,19 @@ return if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) - . = 1 //no afterattack - if(beaker) - to_chat(user, "A container is already loaded into [src]!") + . = TRUE //no afterattack + var/obj/item/reagent_containers/B = I + if(!user.transferItemToLoc(B, src)) return - - if(!user.transferItemToLoc(I, src)) - return - beaker = I - to_chat(user, "You add [I] to [src].") + replace_beaker(user, B) + to_chat(user, "You add [B] to [src].") + updateUsrDialog() update_icon() return return ..() /obj/machinery/chem_heater/on_deconstruction() - eject_beaker() + replace_beaker() return ..() /obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ @@ -122,5 +130,5 @@ target_temperature = CLAMP(target, 0, 1000) if("eject") on = FALSE - eject_beaker(usr) + replace_beaker(usr) . = TRUE diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 6327c5ba3a..aeed5ffc37 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -60,16 +60,6 @@ else icon_state = "mixer0" -/obj/machinery/chem_master/proc/eject_beaker(mob/user) - if(beaker) - beaker.forceMove(drop_location()) - if(Adjacent(user) && !issilicon(user)) - user.put_in_hands(beaker) - else - adjust_item_drop_location(beaker) - beaker = null - update_icon() - /obj/machinery/chem_master/blob_act(obj/structure/blob/B) if (prob(50)) qdel(src) @@ -85,36 +75,49 @@ return if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) - . = 1 // no afterattack + . = TRUE // no afterattack if(panel_open) to_chat(user, "You can't use the [src.name] while its panel is opened!") return - if(beaker) - to_chat(user, "A container is already loaded into [src]!") + var/obj/item/reagent_containers/B = I + if(!user.transferItemToLoc(B, src)) return - if(!user.transferItemToLoc(I, src)) - return - - beaker = I - to_chat(user, "You add [I] to [src].") - src.updateUsrDialog() + replace_beaker(user, B) + to_chat(user, "You add [B] to [src].") + updateUsrDialog() update_icon() - else if(!condi && istype(I, /obj/item/storage/pill_bottle)) if(bottle) to_chat(user, "A pill bottle is already loaded into [src]!") return if(!user.transferItemToLoc(I, src)) return - bottle = I to_chat(user, "You add [I] into the dispenser slot.") - src.updateUsrDialog() + updateUsrDialog() else return ..() +/obj/machinery/chem_master/AltClick(mob/living/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + replace_beaker(user) + return + +/obj/machinery/chem_master/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) + if(beaker) + beaker.forceMove(drop_location()) + if(user && Adjacent(user) && !issiliconoradminghost(user)) + user.put_in_hands(beaker) + if(new_beaker) + beaker = new_beaker + else + beaker = null + update_icon() + return TRUE + /obj/machinery/chem_master/on_deconstruction() - eject_beaker() + replace_beaker(usr) if(bottle) bottle.forceMove(drop_location()) adjust_item_drop_location(bottle) @@ -164,7 +167,7 @@ return switch(action) if("eject") - eject_beaker(usr) + replace_beaker(usr) . = TRUE if("ejectp") diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 5c39cd9db2..1847f1f722 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -19,6 +19,12 @@ var/speed = 1 var/list/holdingitems + var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine") + var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject") + var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind") + var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice") + var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix") + /obj/machinery/reagentgrinder/Initialize() . = ..() holdingitems = list() @@ -51,7 +57,6 @@ if(A == beaker) beaker = null update_icon() - updateUsrDialog() if(holdingitems[A]) holdingitems -= A @@ -67,6 +72,18 @@ else icon_state = "juicer0" +/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) + if(beaker) + beaker.forceMove(drop_location()) + if(user && Adjacent(user) && !issiliconoradminghost(user)) + user.put_in_hands(beaker) + if(new_beaker) + beaker = new_beaker + else + beaker = null + update_icon() + return TRUE + /obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params) //You can only screw open empty grinder if(!beaker && !length(holdingitems) && default_deconstruction_screwdriver(user, icon_state, icon_state, I)) @@ -82,17 +99,14 @@ return TRUE if (istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) - if (!beaker) - if(!user.transferItemToLoc(I, src)) - to_chat(user, "[I] is stuck to your hand!") - return TRUE - to_chat(user, "You slide [I] into [src].") - beaker = I - update_icon() - updateUsrDialog() - else - to_chat(user, "There's already a container inside [src].") - return TRUE //no afterattack + var/obj/item/reagent_containers/B = I + . = TRUE + if(!user.transferItemToLoc(B, src)) + return + replace_beaker(user, B) + to_chat(user, "You add [B] to [src].") + update_icon() + return if(holdingitems.len >= limit) to_chat(user, "[src] is filled to capacity!") @@ -108,8 +122,6 @@ to_chat(user, "You empty [I] into [src].") else to_chat(user, "You fill [src] to the brim.") - - updateUsrDialog() return TRUE if(!I.grind_results && !I.juice_results) @@ -125,104 +137,89 @@ if(user.transferItemToLoc(I, src)) to_chat(user, "You add [I] to [src].") holdingitems[I] = TRUE - updateUsrDialog() return FALSE /obj/machinery/reagentgrinder/ui_interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave . = ..() - var/is_chamber_empty = FALSE - var/is_beaker_ready = FALSE - var/processing_chamber = "" - var/beaker_contents = "" - var/dat = "" - if(!operating) - for (var/i in holdingitems) - var/obj/item/O = i - processing_chamber += "\A [O.name] " + if(operating || !user.canUseTopic(src, !issilicon(user))) + return - if (!processing_chamber) - is_chamber_empty = TRUE - processing_chamber = "Nothing." - if (!beaker) - beaker_contents = "No beaker attached. " - else - is_beaker_ready = TRUE - beaker_contents = "The beaker contains: " - var/anything = FALSE - for(var/datum/reagent/R in beaker.reagents.reagent_list) - anything = TRUE - beaker_contents += "[R.volume] - [R.name] " - if(!anything) - beaker_contents += "Nothing " + var/list/options = list() - dat = {" - Processing chamber contains: - [processing_chamber] - [beaker_contents] - "} - if (is_beaker_ready) - if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Grind the reagents " - dat += "Juice the reagents " - else if (beaker.reagents.total_volume) - dat += "Mix the reagents " - if(length(holdingitems)) - dat += "Eject the reagents " - if(beaker) - dat += "Detach the beaker " + if(beaker || length(holdingitems)) + options["eject"] = radial_eject + + if(isAI(user)) + if(stat & NOPOWER) + return + options["examine"] = radial_examine + + // if there is no power or it's broken, the procs will fail but the buttons will still show + if(length(holdingitems)) + options["grind"] = radial_grind + options["juice"] = radial_juice + else if(beaker?.reagents.total_volume) + options["mix"] = radial_mix + + var/choice + + if(length(options) < 1) + return + if(length(options) == 1) + for(var/key in options) + choice = key else - dat += "Please wait..." + choice = show_radial_menu(user, src, options, require_near = !issilicon(user)) - var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder") - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) - popup.open(1) - return + // post choice verification + if(operating || (isAI(user) && stat & NOPOWER) || !user.canUseTopic(src, !issilicon(user))) + return -/obj/machinery/reagentgrinder/Topic(href, href_list) - if(..()) - return - var/mob/user = usr - if(!user.canUseTopic(src)) - return - if(stat & (NOPOWER|BROKEN)) - return - user.set_machine(src) - if(operating) - updateUsrDialog() - return - switch(href_list["action"]) - if ("grind") + switch(choice) + if("eject") + eject(user) + if("grind") grind(user) if("juice") juice(user) if("mix") mix(user) - if("eject") - eject(user) - if("detach") - detach(user) - updateUsrDialog() + if("examine") + examine(user) -/obj/machinery/reagentgrinder/proc/detach(mob/user) - if(!beaker) +/obj/machinery/reagentgrinder/examine(mob/user) + . = ..() + if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) + to_chat(user, "You're too far away to examine [src]'s contents and display!") return - beaker.forceMove(drop_location()) - if(Adjacent(user) && !issilicon(user)) - user.put_in_hands(beaker) - beaker = null - update_icon() - updateUsrDialog() + + if(operating) + to_chat(user, "\The [src] is operating.") + return + + if(beaker || length(holdingitems)) + to_chat(user, "\The [src] contains:") + if(beaker) + to_chat(user, "- \A [beaker].") + for(var/i in holdingitems) + var/obj/item/O = i + to_chat(user, "- \A [O.name].") + + if(!(stat & (NOPOWER|BROKEN))) + to_chat(user, "The status display reads:") + to_chat(user, "- Grinding reagents at [speed*100]%.") + if(beaker) + for(var/datum/reagent/R in beaker.reagents.reagent_list) + to_chat(user, "- [R.volume] units of [R.name].") /obj/machinery/reagentgrinder/proc/eject(mob/user) - if(!length(holdingitems)) - return for(var/i in holdingitems) var/obj/item/O = i O.forceMove(drop_location()) holdingitems -= O - updateUsrDialog() + if(beaker) + replace_beaker(user) /obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) holdingitems -= O @@ -240,7 +237,6 @@ /obj/machinery/reagentgrinder/proc/operate_for(time, silent = FALSE, juicing = FALSE) shake_for(time / speed) - updateUsrDialog() operating = TRUE if(!silent) if(!juicing) @@ -251,11 +247,10 @@ /obj/machinery/reagentgrinder/proc/stop_operating() operating = FALSE - updateUsrDialog() /obj/machinery/reagentgrinder/proc/juice() power_change() - if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) + if(!beaker || stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume) return operate_for(50, juicing = TRUE) for(var/obj/item/i in holdingitems) @@ -274,7 +269,7 @@ /obj/machinery/reagentgrinder/proc/grind() power_change() - if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) + if(!beaker || stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume) return operate_for(60) for(var/i in holdingitems) @@ -296,13 +291,13 @@ /obj/machinery/reagentgrinder/proc/mix(mob/user) //For butter and other things that would change upon shaking or mixing power_change() - if(!beaker) + if(!beaker || stat & (NOPOWER|BROKEN)) return operate_for(50, juicing = TRUE) addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50) /obj/machinery/reagentgrinder/proc/mix_complete() - if(beaker && beaker.reagents.total_volume) + if(beaker?.reagents.total_volume) //Recipe to make Butter var/butter_amt = FLOOR(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF, 1) beaker.reagents.remove_reagent("milk", MILK_TO_BUTTER_COEFF * butter_amt) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index a52bb1ecfe..9bfbffd330 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -33,6 +33,10 @@ var/addiction_stage4_end = 40 var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick. var/self_consuming = FALSE + var/metabolizing = FALSE + + + /datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references . = ..() @@ -68,6 +72,14 @@ /datum/reagent/proc/on_mob_delete(mob/living/L) return +// Called when this reagent first starts being metabolized by a liver +/datum/reagent/proc/on_mob_metabolize(mob/living/L) + return + +// Called when this reagent stops being metabolized by a liver +/datum/reagent/proc/on_mob_end_metabolize(mob/living/L) + return + /datum/reagent/proc/on_move(mob/M) return diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 14963a6689..211fddca26 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -111,7 +111,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY) return ..() -/datum/reagent/consumable/ethanol/beer/green/on_mob_delete(mob/living/M) +/datum/reagent/consumable/ethanol/beer/green/on_mob_end_metabolize(mob/living/M) M.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, color) /datum/reagent/consumable/ethanol/kahlua @@ -333,7 +333,7 @@ All effects don't start immediately, but rather get worse over time; the rate is id = "grappa" description = "A fine Italian brandy, for when regular wine just isn't alcoholic enough for you." color = "#F8EBF1" - boozepwr = 45 + boozepwr = 60 taste_description = "classy bitter sweetness" glass_icon_state = "grappa" glass_name = "glass of grappa" @@ -379,6 +379,11 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Hooch" glass_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." +/datum/reagent/consumable/ethanol/hooch/on_mob_life(mob/living/carbon/M) + if(M.mind && M.mind.assigned_role == "Assistant") + M.heal_bodypart_damage(1,1) + . = TRUE + return ..() || . /datum/reagent/consumable/ethanol/ale name = "Ale" @@ -569,13 +574,13 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Tequila and Coffee liqueur, brought together in a mouthwatering mixture. Drink up." var/tough_text -/datum/reagent/consumable/ethanol/brave_bull/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/brave_bull/on_mob_metabolize(mob/living/M) tough_text = pick("brawny", "tenacious", "tough", "hardy", "sturdy") //Tuff stuff to_chat(M, "You feel [tough_text]!") M.maxHealth += 10 //Brave Bull makes you sturdier, and thus capable of withstanding a tiny bit more punishment. M.health += 10 -/datum/reagent/consumable/ethanol/brave_bull/on_mob_delete(mob/living/M) +/datum/reagent/consumable/ethanol/brave_bull/on_mob_end_metabolize(mob/living/M) to_chat(M, "You no longer feel [tough_text].") M.maxHealth -= 10 M.health = min(M.health - 10, M.maxHealth) //This can indeed crit you if you're alive solely based on alchol ingestion @@ -593,7 +598,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Oh great, now you feel nostalgic about sunrises back on Terra..." var/obj/effect/light_holder -/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_metabolize(mob/living/M) to_chat(M, "You feel gentle warmth spread through your body!") light_holder = new(M) light_holder.set_light(3, 0.7, "#FFCC00") //Tequila Sunrise makes you radiate dim light, like a sunrise! @@ -605,7 +610,7 @@ All effects don't start immediately, but rather get worse over time; the rate is light_holder.forceMove(M) return ..() -/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_delete(mob/living/M) +/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_end_metabolize(mob/living/M) to_chat(M, "The warmth in your body fades.") QDEL_NULL(light_holder) @@ -633,25 +638,48 @@ All effects don't start immediately, but rather get worse over time; the rate is color = "#664300" // rgb: 102, 67, 0 boozepwr = 90 //THE FIST OF THE LAW IS STRONG AND HARD quality = DRINK_GOOD - metabolization_rate = 0.8 + metabolization_rate = 0.5 taste_description = "JUSTICE" glass_icon_state = "beepskysmashglass" glass_name = "Beepsky Smash" glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW." + overdose_threshold = 40 + var/datum/brain_trauma/special/beepsky/B + +/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_metabolize(mob/living/carbon/M) + if(HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE)) + metabolization_rate = 0.8 + if(!HAS_TRAIT(M, TRAIT_LAW_ENFORCEMENT_METABOLISM)) + B = new() + M.gain_trauma(B, TRAUMA_RESILIENCE_ABSOLUTE) + ..() /datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/carbon/M) - if(HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE)) - M.Stun(30, 0) //this realistically does nothing to prevent chainstunning but will cause them to recover faster once it's out of their system - else - M.Stun(40, 0) + M.Jitter(2) + if(HAS_TRAIT(M, TRAIT_LAW_ENFORCEMENT_METABOLISM)) + M.adjustStaminaLoss(-10, 0) + if(prob(20)) + new /datum/hallucination/items_other(M) + if(prob(10)) + new /datum/hallucination/stray_bullet(M) + ..() + . = TRUE + +/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_end_metabolize(mob/living/carbon/M) + if(B) + QDEL_NULL(B) return ..() +/datum/reagent/consumable/ethanol/beepsky_smash/overdose_start(mob/living/carbon/M) + if(!HAS_TRAIT(M, TRAIT_LAW_ENFORCEMENT_METABOLISM)) + M.gain_trauma(/datum/brain_trauma/mild/phobia/security, TRAUMA_RESILIENCE_BASIC) + /datum/reagent/consumable/ethanol/irish_cream name = "Irish Cream" id = "irishcream" description = "Whiskey-imbued cream, what else would you expect from the Irish?" color = "#664300" // rgb: 102, 67, 0 - boozepwr = 70 + boozepwr = 50 quality = DRINK_NICE taste_description = "creamy alcohol" glass_icon_state = "irishcreamglass" @@ -671,7 +699,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A manly concoction made from Ale and Beer. Intended for true men only." var/dorf_mode -/datum/reagent/consumable/ethanol/manly_dorf/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/manly_dorf/on_mob_metabolize(mob/living/M) if(ishuman(M)) var/mob/living/carbon/human/H = M if(H.dna.check_mutation(DWARFISM) || HAS_TRAIT(H, TRAIT_ALCOHOL_TOLERANCE)) @@ -722,7 +750,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Kahlua, Irish Cream, and cognac. You will get bombed." shot_glass_icon_state = "b52glass" -/datum/reagent/consumable/ethanol/b52/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/b52/on_mob_metabolize(mob/living/M) playsound(M, 'sound/effects/explosion_distant.ogg', 100, FALSE) /datum/reagent/consumable/ethanol/irishcoffee @@ -947,7 +975,7 @@ All effects don't start immediately, but rather get worse over time; the rate is id = "red_mead" description = "The true Viking drink! Even though it has a strange red color." color = "#C73C00" // rgb: 199, 60, 0 - boozepwr = 51 //Red drinks are stronger + boozepwr = 31 //Red drinks are stronger quality = DRINK_GOOD taste_description = "sweet and salty alcohol" glass_icon_state = "red_meadglass" @@ -960,7 +988,7 @@ All effects don't start immediately, but rather get worse over time; the rate is description = "A Viking drink, though a cheap one." color = "#664300" // rgb: 102, 67, 0 nutriment_factor = 1 * REAGENTS_METABOLISM - boozepwr = 50 + boozepwr = 30 quality = DRINK_NICE taste_description = "sweet, sweet alcohol" glass_icon_state = "meadglass" @@ -1319,32 +1347,49 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/neurotoxin name = "Neurotoxin" - id = "neurotoxin" description = "A strong neurotoxin that puts the subject into a death-like state." color = "#2E2E61" // rgb: 46, 46, 97 - boozepwr = 0 //custom drunk effect + boozepwr = 50 quality = DRINK_VERYGOOD taste_description = "a numbing sensation" + metabolization_rate = 1 * REAGENTS_METABOLISM glass_icon_state = "neurotoxinglass" glass_name = "Neurotoxin" glass_desc = "A drink that is guaranteed to knock you silly." +/datum/reagent/consumable/ethanol/neurotoxin/proc/pickt() + return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG)) + /datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/M) - M.Knockdown(60, 1, 0) + M.set_drugginess(50) M.dizziness +=2 - switch(current_cycle) - if(15 to 45) - M.slurring = max(M.slurring,50) - M.slurring += 3 - if(45 to 55) - if(prob(50)) - M.confused = max(M.confused+3,0) - if(55 to 200) - M.set_drugginess(55) - if(200 to INFINITY) - M.adjustToxLoss(2, 0) + M.adjustBrainLoss(1*REM, 150) + if(prob(20)) + M.adjustStaminaLoss(10) + M.drop_all_held_items() + to_chat(M, "You cant feel your hands!") + if(current_cycle > 5) + if(prob(20)) + var/t = pickt() + ADD_TRAIT(M, t, type) + M.adjustStaminaLoss(10) + if(current_cycle > 30) + M.adjustBrainLoss(2*REM) + if(current_cycle > 50 && prob(15)) + if(!M.undergoing_cardiac_arrest() && M.can_heartattack()) + M.set_heartattack(TRUE) + if(M.stat == CONSCIOUS) + M.visible_message("[M] clutches at [M.p_their()] chest as if [M.p_their()] heart stopped!") + . = TRUE + ..() + +/datum/reagent/consumable/ethanol/neurotoxin/on_mob_end_metabolize(mob/living/carbon/M) + REMOVE_TRAIT(M, TRAIT_PARALYSIS_L_ARM, type) + REMOVE_TRAIT(M, TRAIT_PARALYSIS_R_ARM, type) + REMOVE_TRAIT(M, TRAIT_PARALYSIS_R_LEG, type) + REMOVE_TRAIT(M, TRAIT_PARALYSIS_L_LEG, type) + M.adjustStaminaLoss(10) ..() - . = 1 /datum/reagent/consumable/ethanol/hippies_delight name = "Hippie's Delight" @@ -1468,7 +1513,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "An intimidating and lawful beverage dares you to violate the law and make its day. Still can't drink it on duty, though." /datum/reagent/consumable/ethanol/quadruple_sec/on_mob_life(mob/living/carbon/M) - if(M.mind && M.mind.assigned_role in list("Security Officer", "Detective", "Head of Security", "Warden", "Lawyer")) //Securidrink in line with the screwderiver for engineers or nothing for mimes. + if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) //Securidrink in line with the screwderiver for engineers or nothing for mimes. M.heal_bodypart_damage(1, 1) M.adjustBruteLoss(-2,0) . = 1 @@ -1487,7 +1532,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Now you are become law, destroyer of clowns." /datum/reagent/consumable/ethanol/quintuple_sec/on_mob_life(mob/living/carbon/M) - if(M.mind && M.mind.assigned_role in list("Security Officer", "Detective", "Head of Security", "Warden", "Lawyer")) //Securidrink in line with the screwderiver for engineers or nothing for mimes but STRONG.. + if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) //Securidrink in line with the screwderiver for engineers or nothing for mimes but STRONG.. M.heal_bodypart_damage(2,2,2) M.adjustBruteLoss(-5,0) M.adjustOxyLoss(-5,0) @@ -1534,7 +1579,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "If you're feeling low, count on the buttery flavor of our own bastion bourbon." shot_glass_icon_state = "shotglassgreen" -/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_add(mob/living/L) +/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_metabolize(mob/living/L) var/heal_points = 10 if(L.health <= 0) heal_points = 20 //heal more if we're in softcrit @@ -1618,7 +1663,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Crevice Spike" glass_desc = "It'll either knock the drunkenness out of you or knock you out cold. Both, probably." -/datum/reagent/consumable/ethanol/crevice_spike/on_mob_add(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out +/datum/reagent/consumable/ethanol/crevice_spike/on_mob_metabolize(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out L.adjustBruteLoss(3 * min(5,volume)) //minimum 3 brute damage on ingestion to limit non-drink means of injury - a full 5 unit gulp of the drink trucks you for the full 15 /datum/reagent/consumable/ethanol/sake @@ -1661,7 +1706,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A creamy, indulgent delight that is stronger than it seems." var/obj/item/shield/mighty_shield -/datum/reagent/consumable/ethanol/alexander/on_mob_add(mob/living/L) +/datum/reagent/consumable/ethanol/alexander/on_mob_metabolize(mob/living/L) if(ishuman(L)) var/mob/living/carbon/human/thehuman = L for(var/obj/item/shield/theshield in thehuman.contents) @@ -1675,7 +1720,7 @@ All effects don't start immediately, but rather get worse over time; the rate is if(mighty_shield && !(mighty_shield in L.contents)) //If you had a shield and lose it, you lose the reagent as well. Otherwise this is just a normal drink. L.reagents.del_reagent("alexander") -/datum/reagent/consumable/ethanol/alexander/on_mob_delete(mob/living/L) +/datum/reagent/consumable/ethanol/alexander/on_mob_end_metabolize(mob/living/L) if(mighty_shield) mighty_shield.block_chance -= 10 to_chat(L,"You notice [mighty_shield] looks worn again. Weird.") @@ -1796,7 +1841,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.overeatduration = 0 return ..() -/datum/reagent/consumable/ethanol/fanciulli/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/fanciulli/on_mob_metabolize(mob/living/M) if(M.health > 0) M.adjustStaminaLoss(20) . = TRUE @@ -1820,12 +1865,236 @@ All effects don't start immediately, but rather get worse over time; the rate is M.adjust_bodytemperature(-20 * TEMPERATURE_DAMAGE_COEFFICIENT, T0C) return ..() -/datum/reagent/consumable/ethanol/branca_menta/on_mob_add(mob/living/M) +/datum/reagent/consumable/ethanol/branca_menta/on_mob_metabolize(mob/living/M) if(M.health > 0) M.adjustStaminaLoss(35) . = TRUE ..() +/datum/reagent/consumable/ethanol/blank_paper + name = "Blank Paper" + id = "blank_paper" + description = "A bubbling glass of blank paper. Just looking at it makes you feel fresh." + nutriment_factor = 1 * REAGENTS_METABOLISM + color = "#DCDCDC" // rgb: 220, 220, 220 + boozepwr = 20 + quality = DRINK_GOOD + taste_description = "bubbling possibility" + glass_icon_state = "blank_paper" + glass_name = "glass of blank paper" + glass_desc = "A fizzy cocktail for those looking to start fresh." + +/datum/reagent/consumable/ethanol/blank_paper/on_mob_life(mob/living/carbon/M) + if(ishuman(M) && M.job == "Mime") + M.heal_bodypart_damage(1,1) + . = 1 + return ..() + +/datum/reagent/consumable/ethanol/champagne //How the hell did we not have champagne already!? + name = "Champagne" + id = "champagne" + description = "A sparkling wine known for its ability to strike fast and hard." + color = "#ffffc1" + boozepwr = 40 + taste_description = "auspicious occasions and bad decisions" + glass_icon_state = "champagne_glass" + glass_name = "Champagne" + glass_desc = "The flute clearly displays the slowly rising bubbles." + +/datum/reagent/consumable/ethanol/wizz_fizz + name = "Wizz Fizz" + id = "wizz_fizz" + description = "A magical potion, fizzy and wild! However the taste, you will find, is quite mild." + color = "#4235d0" //Just pretend that the triple-sec was blue curacao. + boozepwr = 50 + quality = DRINK_GOOD + taste_description = "friendship! It is magic, after all" + glass_icon_state = "wizz_fizz" + glass_name = "Wizz Fizz" + glass_desc = "The glass bubbles and froths with an almost magical intensity." + +/datum/reagent/consumable/ethanol/wizz_fizz/on_mob_life(mob/living/carbon/M) + //A healing drink similar to Quadruple Sec, Ling Stings, and Screwdrivers for the Wizznerds; the check is consistent with the changeling sting + if(M?.mind?.has_antag_datum(/datum/antagonist/wizard)) + M.heal_bodypart_damage(1,1,1) + M.adjustOxyLoss(-1,0) + M.adjustToxLoss(-1,0) + return ..() + +/datum/reagent/consumable/ethanol/bug_spray + name = "Bug Spray" + id = "bug_spray" + description = "A harsh, acrid, bitter drink, for those who need something to brace themselves." + color = "#33ff33" + boozepwr = 50 + quality = DRINK_GOOD + taste_description = "the pain of ten thousand slain mosquitos" + glass_icon_state = "bug_spray" + glass_name = "Bug Spray" + glass_desc = "Your eyes begin to water as the sting of alcohol reaches them." + +/datum/reagent/consumable/ethanol/bug_spray/on_mob_life(mob/living/carbon/M) +//Bugs should not drink Bug spray. + if(ismoth(M) || isflyperson(M)) + M.adjustToxLoss(1,0) + return ..() + +/datum/reagent/consumable/ethanol/bug_spray/on_mob_add(mob/living/carbon/M) + if(ismoth(M) || isflyperson(M)) + M.emote("scream") + return ..() + +/datum/reagent/consumable/ethanol/applejack + name = "Applejack" + id = "applejack" + description = "The perfect beverage for when you feel the need to horse around." + color = "#ff6633" + boozepwr = 20 + taste_description = "an honest day's work at the orchard" + glass_icon_state = "applejack_glass" + glass_name = "Applejack" + glass_desc = "You feel like you could drink this all neight." + +/datum/reagent/consumable/ethanol/jack_rose + name = "Jack Rose" + id = "jack_rose" + description = "A light cocktail perfect for sipping with a slice of pie." + color = "#ff6633" + boozepwr = 15 + quality = DRINK_NICE + taste_description = "a sweet and sour slice of apple" + glass_icon_state = "jack_rose" + glass_name = "Jack Rose" + glass_desc = "Enough of these, and you really will start to suppose your toeses are roses." + +/datum/reagent/consumable/ethanol/turbo + name = "Turbo" + id = "turbo" + description = "A turbulent cocktail associated with outlaw hoverbike racing. Not for the faint of heart." + color = "#e94c3a" + boozepwr = 85 + quality = DRINK_VERYGOOD + taste_description = "the outlaw spirit" + glass_icon_state = "turbo" + glass_name = "Turbo" + glass_desc = "A turbulent cocktail for outlaw hoverbikers." + +/datum/reagent/consumable/ethanol/turbo/on_mob_life(mob/living/carbon/M) + if(prob(4)) + to_chat(M, "[pick("You feel disregard for the rule of law.", "You feel pumped!", "Your head is pounding.", "Your thoughts are racing..")]") + M.adjustStaminaLoss(-M.drunkenness * 0.25) + return ..() + +/datum/reagent/consumable/ethanol/old_timer + name = "Old Timer" + id = "old_timer" + description = "An archaic potation enjoyed by old coots of all ages." + color = "#996835" + boozepwr = 35 + quality = DRINK_NICE + taste_description = "simpler times" + glass_icon_state = "old_timer" + glass_name = "Old Timer" + glass_desc = "WARNING! May cause premature aging!" + +/datum/reagent/consumable/ethanol/old_timer/on_mob_life(mob/living/carbon/M) + if(prob(20)) + if(ishuman(M)) + var/mob/living/carbon/human/N = M + N.age += 1 + if(N.age > 70) + N.facial_hair_color = "ccc" + N.hair_color = "ccc" + N.update_hair() + if(N.age > 100) + N.become_nearsighted(id) + if(N.gender == MALE) + N.facial_hair_style = "Beard (Very Long)" + N.update_hair() + + if(N.age > 969) //Best not let people get older than this or i might incur G-ds wrath + M.visible_message("[M] becomes older than any man should be.. and crumbles into dust!") + M.dust(0,1,0) + + return ..() + +/datum/reagent/consumable/ethanol/rubberneck + name = "Rubberneck" + id = "rubberneck" + description = "A quality rubberneck should not contain any gross natural ingredients." + color = "#ffe65b" + boozepwr = 60 + quality = DRINK_GOOD + taste_description = "artifical fruityness" + glass_icon_state = "rubberneck" + glass_name = "Rubberneck" + glass_desc = "A popular drink amongst those adhering to an all synthetic diet." + +/datum/reagent/consumable/ethanol/duplex + name = "Duplex" + id = "duplex" + description = "An inseparable combination of two fruity drinks." + color = "#50e5cf" + boozepwr = 25 + quality = DRINK_NICE + taste_description = "green apples and blue raspberries" + glass_icon_state = "duplex" + glass_name = "Duplex" + glass_desc = "To imbibe one component separately from the other is consider a great faux pas." + +/datum/reagent/consumable/ethanol/trappist + name = "Trappist Beer" + id = "trappist" + description = "A strong dark ale brewed by space-monks." + color = "#390c00" + boozepwr = 40 + quality = DRINK_VERYGOOD + taste_description = "dried plums and malt" + glass_icon_state = "trappistglass" + glass_name = "Trappist Beer" + glass_desc = "boozy Catholicism in a glass." + +/datum/reagent/consumable/ethanol/trappist/on_mob_life(mob/living/carbon/M) + if(M.mind.isholy) + M.adjustFireLoss(-2.5, 0) + M.jitteriness = max(0, M.jitteriness-1) + M.stuttering = max(0, M.stuttering-1) + return ..() + +/datum/reagent/consumable/ethanol/blazaam + name = "Blazaam" + id = "blazaam" + description = "A strange drink that few people seem to remember existing. Doubles as a Berenstain remover." + boozepwr = 70 + quality = DRINK_FANTASTIC + taste_description = "alternate realities" + glass_icon_state = "blazaamglass" + glass_name = "Blazaam" + glass_desc = "The glass seems to be sliding between realities. Doubles as a Berenstain remover." + var/stored_teleports = 0 + +/datum/reagent/consumable/ethanol/blazaam/on_mob_life(mob/living/carbon/M) + if(M.drunkenness > 40) + if(stored_teleports) + do_teleport(M, get_turf(M), rand(1,3)) + stored_teleports-- + if(prob(10)) + stored_teleports += rand(2,6) + if(prob(70)) + M.vomit() + return ..() + +/datum/reagent/consumable/ethanol/planet_cracker + name = "Planet Cracker" + id = "planet_cracker" + description = "This jubilant drink celebrates humanity's triumph over the alien menace. May be offensive to non-human crewmembers." + boozepwr = 50 + quality = DRINK_FANTASTIC + taste_description = "triumph with a hint of bitterness" + glass_icon_state = "planet_cracker" + glass_name = "Planet Cracker" + glass_desc = "Although historians believe the drink was originally created to commemorate the end of an important conflict in man's past, its origins have largely been forgotten and it is today seen more as a general symbol of human supremacy." + /datum/reagent/consumable/ethanol/fruit_wine name = "Fruit Wine" id = "fruit_wine" diff --git a/code/modules/reagents/chemistry/reagents/blob_reagents.dm b/code/modules/reagents/chemistry/reagents/blob_reagents.dm index 8ee9449468..af85b6b35f 100644 --- a/code/modules/reagents/chemistry/reagents/blob_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/blob_reagents.dm @@ -204,7 +204,7 @@ C.hal_screwyhud = SCREWYHUD_HEALTHY //fully healed, honest ..() -/datum/reagent/blob/regenerative_materia/on_mob_delete(mob/living/M) +/datum/reagent/blob/regenerative_materia/on_mob_end_metabolize(mob/living/M) if(iscarbon(M)) var/mob/living/carbon/N = M N.hal_screwyhud = 0 diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index ac15eb6b01..4e40233713 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -213,15 +213,15 @@ glass_desc = "White and nutritious goodness!" /datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/M) - if(M.getBruteLoss() && prob(20)) - M.heal_bodypart_damage(1,0, 0) + if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER)) + M.heal_bodypart_damage(1.5,0, 0) . = 1 + else + if(M.getBruteLoss() && prob(20)) + M.heal_bodypart_damage(1,0, 0) + . = 1 if(holder.has_reagent("capsaicin")) holder.remove_reagent("capsaicin", 2) - var/datum/dna/Mdna = M.has_dna() - if(Mdna && Mdna.species && (Mdna.species.id == "plasmaman" || Mdna.species.id == "skeleton")) - M.heal_bodypart_damage(1,0, 0) - . = 1 ..() /datum/reagent/consumable/soymilk @@ -305,6 +305,16 @@ ..() . = 1 +/datum/reagent/consumable/lemonade + name = "Lemonade" + id = "lemonade" + description = "Sweet, tangy lemonade. Good for the soul." + quality = DRINK_NICE + taste_description = "sunshine and summertime" + glass_icon_state = "lemonpitcher" + glass_name = "pitcher of lemonade" + glass_desc = "This drink leaves you feeling nostalgic for some reason." + /datum/reagent/consumable/tea/arnold_palmer name = "Arnold Palmer" id = "arnold_palmer" @@ -390,11 +400,11 @@ glass_name = "glass of Nuka Cola" glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland." -/datum/reagent/consumable/nuka_cola/on_mob_add(mob/living/L) +/datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) -/datum/reagent/consumable/nuka_cola/on_mob_delete(mob/living/L) +/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() @@ -498,6 +508,34 @@ /datum/reagent/consumable/shamblers/on_mob_life(mob/living/carbon/M) M.adjust_bodytemperature(-8 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) ..() + +/datum/reagent/consumable/grey_bull + name = "Grey Bull" + id = "grey_bull" + description = "Grey Bull, it gives you gloves!" + color = "#EEFF00" // rgb: 238, 255, 0 + quality = DRINK_VERYGOOD + taste_description = "carbonated oil" + glass_icon_state = "grey_bull_glass" + glass_name = "glass of Grey Bull" + glass_desc = "Surprisingly it isnt grey." + +/datum/reagent/consumable/grey_bull/on_mob_metabolize(mob/living/L) + ..() + ADD_TRAIT(L, TRAIT_SHOCKIMMUNE, id) + +/datum/reagent/consumable/grey_bull/on_mob_end_metabolize(mob/living/L) + REMOVE_TRAIT(L, TRAIT_SHOCKIMMUNE, id) + ..() + +/datum/reagent/consumable/grey_bull/on_mob_life(mob/living/carbon/M) + M.Jitter(20) + M.dizziness +=1 + M.drowsyness = 0 + M.AdjustSleeping(-40, FALSE) + M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) + ..() + /datum/reagent/consumable/sodawater name = "Soda Water" id = "sodawater" @@ -719,6 +757,11 @@ glass_name = "glass of grape juice" glass_desc = "It's grape (soda)!" +/datum/reagent/consumable/grape_soda/on_mob_life(mob/living/carbon/M) + M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) + ..() + + /datum/reagent/consumable/milk/chocolate_milk name = "Chocolate Milk" id = "chocolate_milk" @@ -746,6 +789,65 @@ glass_name = "glass of grenadine" glass_desc = "Delicious flavored syrup." +/datum/reagent/consumable/parsnipjuice + name = "Parsnip Juice" + id = "parsnipjuice" + description = "Why..." + color = "#FFA500" + taste_description = "parsnip" + glass_name = "glass of parsnip juice" + +/datum/reagent/consumable/peachjuice //Intended to be extremely rare due to being the limiting ingredients in the blazaam drink + name = "Peach Juice" + id = "peachjuice" + description = "Just peachy." + color = "#E78108" + taste_description = "peaches" + glass_name = "glass of peach juice" + +/datum/reagent/consumable/cream_soda + name = "Cream Soda" + id = "cream_soda" + description = "A classic space-American vanilla flavored soft drink." + color = "#dcb137" + quality = DRINK_VERYGOOD + taste_description = "fizzy vanilla" + glass_icon_state = "cream_soda" + glass_name = "Cream Soda" + glass_desc = "A classic space-American vanilla flavored soft drink." + +/datum/reagent/consumable/cream_soda/on_mob_life(mob/living/carbon/M) + M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) + ..() + +/datum/reagent/consumable/red_queen + name = "Red Queen" + id = "red_queen" + description = "DRINK ME." + color = "#e6ddc3" + quality = DRINK_GOOD + taste_description = "wonder" + glass_icon_state = "red_queen" + glass_name = "Red Queen" + glass_desc = "DRINK ME." + var/current_size = 1 + +/datum/reagent/consumable/red_queen/on_mob_life(mob/living/carbon/H) + if(prob(75)) + return ..() + var/newsize = pick(0.5, 0.75, 1, 1.50, 2) + H.resize = newsize/current_size + current_size = newsize + H.update_transform() + if(prob(40)) + H.emote("sneeze") + ..() + +/datum/reagent/consumable/red_queen/on_mob_end_metabolize(mob/living/M) + M.resize = 1/current_size + M.update_transform() + ..() + /datum/reagent/consumable/pinkmilk name = "Strawberry Milk" id = "pinkmilk" diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 04dad3a065..a4586dd997 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -5,7 +5,7 @@ taste_description = "bitterness" var/trippy = TRUE //Does this drug make you trip? -/datum/reagent/drug/on_mob_delete(mob/living/M) +/datum/reagent/drug/on_mob_end_metabolize(mob/living/M) if(trippy) SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "[id]_high") @@ -168,11 +168,11 @@ var/jitter = TRUE var/confusion = TRUE -/datum/reagent/drug/methamphetamine/on_mob_add(mob/living/L) +/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L) ..() L.ignore_slowdown(id) -/datum/reagent/drug/methamphetamine/on_mob_delete(mob/living/L) +/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/L) L.unignore_slowdown(id) ..() @@ -262,7 +262,7 @@ taste_description = "salt" // because they're bathsalts? var/datum/brain_trauma/special/psychotic_brawling/bath_salts/rage -/datum/reagent/drug/bath_salts/on_mob_add(mob/living/L) +/datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_STUNIMMUNE, id) ADD_TRAIT(L, TRAIT_SLEEPIMMUNE, id) @@ -271,7 +271,7 @@ rage = new() C.gain_trauma(rage, TRAUMA_RESILIENCE_ABSOLUTE) -/datum/reagent/drug/bath_salts/on_mob_delete(mob/living/L) +/datum/reagent/drug/bath_salts/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id) REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id) if(rage) @@ -381,7 +381,7 @@ addiction_stage3_end = 40 addiction_stage4_end = 240 -/datum/reagent/drug/skooma/on_mob_add(mob/living/L) +/datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L) . = ..() ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) L.next_move_modifier *= 2 @@ -392,7 +392,7 @@ if(H.dna && H.dna.species) H.dna.species.punchdamagehigh *= 5 -/datum/reagent/drug/skooma/on_mob_delete(mob/living/L) +/datum/reagent/drug/skooma/on_mob_end_metabolize(mob/living/L) . = ..() REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) L.next_move_modifier *= 0.5 diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index afa469706a..d0c08d9534 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -32,6 +32,8 @@ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_verygood) if (DRINK_FANTASTIC) SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_fantastic) + if (FOOD_AMAZING) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_food", /datum/mood_event/amazingtaste) return ..() /datum/reagent/consumable/nutriment @@ -401,7 +403,7 @@ metabolization_rate = 0.2 * REAGENTS_METABOLISM taste_description = "mushroom" -/datum/reagent/mushroomhallucinogen/on_mob_life(mob/living/carbon/M) +/datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/M) M.slurring = max(M.slurring,50) switch(current_cycle) if(1 to 5) @@ -431,7 +433,7 @@ taste_description = "childhood whimsy" /datum/reagent/consumable/sprinkles/on_mob_life(mob/living/carbon/M) - if(ishuman(M) && M.job in list("Security Officer", "Head of Security", "Detective", "Warden")) + if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) M.heal_bodypart_damage(1,1, 0) . = 1 ..() @@ -686,7 +688,7 @@ /datum/reagent/consumable/tinlux/reaction_mob(mob/living/M) M.set_light(2) -/datum/reagent/consumable/tinlux/on_mob_delete(mob/living/M) +/datum/reagent/consumable/tinlux/on_mob_end_metabolize(mob/living/M) M.set_light(-2) /datum/reagent/consumable/vitfro @@ -711,3 +713,32 @@ nutriment_factor = 5 * REAGENTS_METABOLISM color = "#eef442" // rgb: 238, 244, 66 taste_description = "mournful honking" + +/datum/reagent/consumable/astrotame + name = "Astrotame" + id = "astrotame" + description = "A space age artifical sweetener." + nutriment_factor = 0 + metabolization_rate = 2 * REAGENTS_METABOLISM + reagent_state = SOLID + color = "#FFFFFF" // rgb: 255, 255, 255 + taste_mult = 8 + taste_description = "sweetness" + overdose_threshold = 17 + +/datum/reagent/consumable/astrotame/overdose_process(mob/living/carbon/M) + if(M.disgust < 80) + M.adjust_disgust(10) + ..() + . = TRUE + +/datum/reagent/consumable/secretsauce + name = "secret sauce" + id = "secret_sauce" + description = "What could it be." + nutriment_factor = 2 * REAGENTS_METABOLISM + color = "#792300" + taste_description = "indescribable" + quality = FOOD_AMAZING + taste_mult = 100 + can_synth = FALSE diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 07a2a9c02a..ed441504a5 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -366,7 +366,7 @@ to_chat(M, "You feel your wounds fade away to nothing!" ) ..() -/datum/reagent/medicine/mine_salve/on_mob_delete(mob/living/M) +/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M) if(iscarbon(M)) var/mob/living/carbon/N = M N.hal_screwyhud = SCREWYHUD_NONE @@ -483,16 +483,24 @@ reagent_state = LIQUID color = "#E6FFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM + var/healtoxinlover = FALSE /datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/M) M.radiation -= max(M.radiation-RAD_MOB_SAFE, 0)/50 - M.adjustToxLoss(-2*REM, 0) + M.adjustToxLoss(-2*REM, 0, healtoxinlover) for(var/datum/reagent/R in M.reagents.reagent_list) if(R != src) M.reagents.remove_reagent(R.id,2) ..() . = 1 +/datum/reagent/medicine/pen_acid/pen_jelly + name = "Pentetic Jelly" + id = "pen_jelly" + description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body. Slimepeople friendly!" + color = "#91D865" + healtoxinlover = TRUE + /datum/reagent/medicine/sal_acid name = "Salicyclic Acid" id = "sal_acid" @@ -630,11 +638,11 @@ overdose_threshold = 30 addiction_threshold = 25 -/datum/reagent/medicine/morphine/on_mob_add(mob/living/L) +/datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/L) ..() L.ignore_slowdown(id) -/datum/reagent/medicine/morphine/on_mob_delete(mob/living/L) +/datum/reagent/medicine/morphine/on_mob_end_metabolize(mob/living/L) L.unignore_slowdown(id) ..() @@ -875,11 +883,11 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 60 -/datum/reagent/medicine/stimulants/on_mob_add(mob/living/L) +/datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) -/datum/reagent/medicine/stimulants/on_mob_delete(mob/living/L) +/datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() @@ -1102,7 +1110,7 @@ M.adjustBruteLoss(-3 * REM, 0) M.adjustFireLoss(-3 * REM, 0) M.adjustOxyLoss(-15 * REM, 0) - M.adjustToxLoss(-3 * REM, 0) + M.adjustToxLoss(-3 * REM, 0, TRUE) //Heals TOXINLOVERS M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! M.adjustCloneLoss(-1 * REM, 0) M.adjustStaminaLoss(-30 * REM, 0) @@ -1113,7 +1121,7 @@ /datum/reagent/medicine/earthsblood/overdose_process(mob/living/M) M.hallucination = min(max(0, M.hallucination + 5), 60) - M.adjustToxLoss(5 * REM, 0) + M.adjustToxLoss(8 * REM, 0, TRUE) //Hurts TOXINLOVERS ..() . = 1 @@ -1188,11 +1196,11 @@ color = "#C8A5DC" metabolization_rate = 1 -/datum/reagent/medicine/changelinghaste/on_mob_add(mob/living/L) +/datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id) -/datum/reagent/medicine/changelinghaste/on_mob_delete(mob/living/L) +/datum/reagent/medicine/changelinghaste/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id) ..() @@ -1210,11 +1218,11 @@ color = "#F5F5F5" self_consuming = TRUE -/datum/reagent/medicine/corazone/on_mob_add(mob/living/M) +/datum/reagent/medicine/corazone/on_mob_metabolize(mob/living/M) ..() ADD_TRAIT(M, TRAIT_STABLEHEART, id) -/datum/reagent/medicine/corazone/on_mob_delete(mob/living/M) +/datum/reagent/medicine/corazone/on_mob_end_metabolize(mob/living/M) REMOVE_TRAIT(M, TRAIT_STABLEHEART, id) ..() @@ -1223,11 +1231,11 @@ id = "muscle_stimulant" description = "A potent chemical that allows someone under its influence to be at full physical ability even when under massive amounts of pain." -/datum/reagent/medicine/muscle_stimulant/on_mob_add(mob/living/M) +/datum/reagent/medicine/muscle_stimulant/on_mob_metabolize(mob/living/M) . = ..() M.ignore_slowdown(id) -/datum/reagent/medicine/muscle_stimulant/on_mob_delete(mob/living/M) +/datum/reagent/medicine/muscle_stimulant/on_mob_end_metabolize(mob/living/M) . = ..() M.unignore_slowdown(id) @@ -1242,11 +1250,11 @@ taste_description = "salt" // it actually does taste salty var/overdose_progress = 0 // to track overdose progress -/datum/reagent/medicine/modafinil/on_mob_add(mob/living/M) +/datum/reagent/medicine/modafinil/on_mob_metabolize(mob/living/M) ADD_TRAIT(M, TRAIT_SLEEPIMMUNE, id) ..() -/datum/reagent/medicine/modafinil/on_mob_delete(mob/living/M) +/datum/reagent/medicine/modafinil/on_mob_end_metabolize(mob/living/M) REMOVE_TRAIT(M, TRAIT_SLEEPIMMUNE, id) ..() diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 40242909de..890403691e 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -196,11 +196,11 @@ glass_name = "glass of holy water" glass_desc = "A glass of holy water." -/datum/reagent/water/holywater/on_mob_add(mob/living/L) +/datum/reagent/water/holywater/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_HOLY, id) -/datum/reagent/water/holywater/on_mob_delete(mob/living/L) +/datum/reagent/water/holywater/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_HOLY, id) ..() @@ -1241,12 +1241,12 @@ color = "E1A116" taste_description = "sourness" -/datum/reagent/stimulum/on_mob_add(mob/living/L) +/datum/reagent/stimulum/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_STUNIMMUNE, id) ADD_TRAIT(L, TRAIT_SLEEPIMMUNE, id) -/datum/reagent/stimulum/on_mob_delete(mob/living/L) +/datum/reagent/stimulum/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id) REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id) ..() @@ -1266,11 +1266,11 @@ color = "90560B" taste_description = "burning" -/datum/reagent/nitryl/on_mob_add(mob/living/L) +/datum/reagent/nitryl/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) -/datum/reagent/nitryl/on_mob_delete(mob/living/L) +/datum/reagent/nitryl/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() @@ -1723,7 +1723,7 @@ H.update_transform() ..() -/datum/reagent/growthserum/on_mob_delete(mob/living/M) +/datum/reagent/growthserum/on_mob_end_metabolize(mob/living/M) M.resize = 1/current_size M.update_transform() ..() @@ -1777,11 +1777,11 @@ taste_description = "water" metabolization_rate = 0.25 * REAGENTS_METABOLISM -/datum/reagent/pax/on_mob_add(mob/living/L) +/datum/reagent/pax/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_PACIFISM, id) -/datum/reagent/pax/on_mob_delete(mob/living/L) +/datum/reagent/pax/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_PACIFISM, id) ..() @@ -1793,11 +1793,11 @@ taste_description = "acrid cinnamon" metabolization_rate = 0.2 * REAGENTS_METABOLISM -/datum/reagent/bz_metabolites/on_mob_add(mob/living/L) +/datum/reagent/bz_metabolites/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, CHANGELING_HIVEMIND_MUTE, id) -/datum/reagent/bz_metabolites/on_mob_delete(mob/living/L) +/datum/reagent/bz_metabolites/on_mob_end_metabolize(mob/living/L) ..() REMOVE_TRAIT(L, CHANGELING_HIVEMIND_MUTE, id) @@ -1814,14 +1814,14 @@ description = "A colorless liquid that suppresses violence on the subjects. Cheaper to synthetize, but wears out faster than normal Pax." metabolization_rate = 1.5 * REAGENTS_METABOLISM -/datum/reagent/peaceborg/confuse +/datum/reagent/peaceborg_confuse name = "Dizzying Solution" id = "dizzysolution" description = "Makes the target off balance and dizzy" metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "dizziness" -/datum/reagent/peaceborg/confuse/on_mob_life(mob/living/carbon/M) +/datum/reagent/peaceborg_confuse/on_mob_life(mob/living/carbon/M) if(M.confused < 6) M.confused = CLAMP(M.confused + 3, 0, 5) if(M.dizziness < 6) @@ -1830,14 +1830,14 @@ to_chat(M, "You feel confused and disorientated.") ..() -/datum/reagent/peaceborg/tire +/datum/reagent/peaceborg_tire name = "Tiring Solution" id = "tiresolution" description = "An extremely weak stamina-toxin that tires out the target. Completely harmless." metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "tiredness" -/datum/reagent/peaceborg/tire/on_mob_life(mob/living/carbon/M) +/datum/reagent/peaceborg_tire/on_mob_life(mob/living/carbon/M) var/healthcomp = (100 - M.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS. if(M.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.) M.adjustStaminaLoss(10) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 8be95efb83..6bd165f23e 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -156,11 +156,11 @@ toxpwr = 0.5 taste_description = "death" -/datum/reagent/toxin/zombiepowder/on_mob_add(mob/living/L) +/datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L) ..() L.fakedeath(id) -/datum/reagent/toxin/zombiepowder/on_mob_delete(mob/living/L) +/datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/L) L.cure_fakedeath(id) ..() @@ -178,11 +178,11 @@ toxpwr = 0.8 taste_description = "death" -/datum/reagent/toxin/ghoulpowder/on_mob_add(mob/living/L) +/datum/reagent/toxin/ghoulpowder/on_mob_metabolize(mob/living/L) ..() ADD_TRAIT(L, TRAIT_FAKEDEATH, id) -/datum/reagent/toxin/ghoulpowder/on_mob_delete(mob/living/L) +/datum/reagent/toxin/ghoulpowder/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_FAKEDEATH, id) ..() @@ -626,7 +626,7 @@ toxpwr = 0 metabolization_rate = 0.5 * REAGENTS_METABOLISM -/datum/reagent/toxin/amanitin/on_mob_delete(mob/living/M) +/datum/reagent/toxin/amanitin/on_mob_end_metabolize(mob/living/M) var/toxdamage = current_cycle*3*REM M.log_message("has taken [toxdamage] toxin damage from amanitin toxin", LOG_ATTACK) M.adjustToxLoss(toxdamage) @@ -742,7 +742,7 @@ animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING) return ..() -/datum/reagent/toxin/rotatium/on_mob_delete(mob/living/M) +/datum/reagent/toxin/rotatium/on_mob_end_metabolize(mob/living/M) if(M && M.hud_used) var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) for(var/whole_screen in screens) @@ -779,7 +779,7 @@ */ return ..() -/datum/reagent/toxin/skewium/on_mob_delete(mob/living/M) +/datum/reagent/toxin/skewium/on_mob_end_metabolize(mob/living/M) if(M && M.hud_used) var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) for(var/whole_screen in screens) @@ -798,7 +798,7 @@ /datum/reagent/toxin/anacea/on_mob_life(mob/living/carbon/M) var/remove_amt = 5 - if(holder.has_reagent("calomel") || holder.has_reagent("pen_acid")) + if(holder.has_reagent("calomel") || holder.has_reagent("pen_acid") || holder.has_reagent("pen_jelly")) remove_amt = 0.5 for(var/datum/reagent/medicine/R in M.reagents.reagent_list) M.reagents.remove_reagent(R.id,remove_amt) @@ -882,8 +882,69 @@ toxpwr = 0 taste_description = "stillness" -/datum/reagent/toxin/mimesbane/on_mob_add(mob/living/L) +/datum/reagent/toxin/mimesbane/on_mob_metabolize(mob/living/L) ADD_TRAIT(L, TRAIT_EMOTEMUTE, id) -/datum/reagent/toxin/mimesbane/on_mob_delete(mob/living/L) +/datum/reagent/toxin/mimesbane/on_mob_end_metabolize(mob/living/L) REMOVE_TRAIT(L, TRAIT_EMOTEMUTE, id) + +/datum/reagent/toxin/bonehurtingjuice //oof ouch + name = "Bone Hurting Juice" + id = "bonehurtingjuice" + description = "A strange substance that looks a lot like water. Drinking it is oddly tempting. Oof ouch." + color = "#AAAAAA77" //RGBA: 170, 170, 170, 77 + toxpwr = 0 + taste_description = "bone hurting" + overdose_threshold = 20 + +/datum/reagent/toxin/bonehurtingjuice/on_mob_add(mob/living/carbon/M) + M.say("oof ouch my bones", forced = /datum/reagent/toxin/bonehurtingjuice) + +/datum/reagent/toxin/bonehurtingjuice/on_mob_life(mob/living/carbon/M) + M.adjustStaminaLoss(7.5, 0) + if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER)) + M.adjustBruteLoss(3.5, 0) + if(prob(12)) + switch(rand(1, 3)) + if(1) + var/list/possible_says = list("oof.", "ouch!", "my bones.", "oof ouch.", "oof ouch my bones.") + M.say(pick(possible_says), forced = /datum/reagent/toxin/bonehurtingjuice) + if(2) + var/list/possible_mes = list("oofs softly.", "looks like their bones hurt.", "grimaces, as though their bones hurt.") + M.say("*custom " + pick(possible_mes), forced = /datum/reagent/toxin/bonehurtingjuice) + if(3) + to_chat(M, "Your bones hurt!") + return ..() + +/datum/reagent/toxin/bonehurtingjuice/overdose_process(mob/living/carbon/M) + if(prob(6) && iscarbon(M)) //big oof + var/selected_part + switch(rand(1, 4)) //God help you if the same limb gets picked twice quickly. + if(1) + selected_part = BODY_ZONE_L_ARM + if(2) + selected_part = BODY_ZONE_R_ARM + if(3) + selected_part = BODY_ZONE_L_LEG + if(4) + selected_part = BODY_ZONE_R_LEG + var/obj/item/bodypart/bp = M.get_bodypart(selected_part) + if(M.dna.species.type != /datum/species/skeleton || M.dna.species.type != /datum/species/plasmaman || M.dna.species.type != /datum/species/golem/bone) //We're so sorry skeletons, you're so misunderstood + if(bp) + bp.receive_damage(0, 0, 200) + playsound(M, get_sfx("desceration"), 50, TRUE, -1) + M.visible_message("[M]'s bones hurt too much!!", "Your bones hurt too much!!") + M.say("OOF!!", forced = /datum/reagent/toxin/bonehurtingjuice) + else //SUCH A LUST FOR REVENGE!!! + to_chat(M, "A phantom limb hurts!") + M.say("Why are we still here, just to suffer?", forced = /datum/reagent/toxin/bonehurtingjuice) + else //you just want to socialize + if(bp) + playsound(M, get_sfx("desceration"), 50, TRUE, -1) + M.visible_message("[M] rattles loudly and flails around!!", "Your bones hurt so much that your missing muscles spasm!!") + M.say("OOF!!", forced=/datum/reagent/toxin/bonehurtingjuice) + bp.receive_damage(200, 0, 0) //But I don't think we should + else + to_chat(M, "Your missing arm aches from wherever you left it.") + M.emote("sigh") + return ..() diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index dc7c32d925..727048a12c 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -94,6 +94,12 @@ results = list("pen_acid" = 6) required_reagents = list("welding_fuel" = 1, "chlorine" = 1, "ammonia" = 1, "formaldehyde" = 1, "sodium" = 1, "cyanide" = 1) +/datum/chemical_reaction/pen_jelly + name = "Pentetic Jelly" + id = "pen_jelly" + results = list("pen_jelly" = 2) + required_reagents = list("pen_acid" = 1, "slimejelly" = 1) + /datum/chemical_reaction/sal_acid name = "Salicyclic Acid" id = "sal_acid" diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 29863c2b90..b29a1c6809 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -64,8 +64,8 @@ strengthdiv = 8 for(var/mob/living/simple_animal/revenant/R in get_hearers_in_view(7,get_turf(holder.my_atom))) var/deity - if(SSreligion.deity) - deity = SSreligion.deity + if(GLOB.deity) + deity = GLOB.deity else deity = "Christ" to_chat(R, "The power of [deity] compels you!") diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special.dm new file mode 100644 index 0000000000..153372101e --- /dev/null +++ b/code/modules/reagents/chemistry/recipes/special.dm @@ -0,0 +1,212 @@ +GLOBAL_LIST_INIT(food_reagents, build_reagents_to_food()) //reagentid = related food types + +/proc/build_reagents_to_food() + . = list() + for (var/type in subtypesof(/obj/item/reagent_containers/food)) + var/obj/item/reagent_containers/food/item = new type() + for(var/r in item.list_reagents) + if (!.[r]) + .[r] = list() + .[r] += type + qdel(item) + //dang plant snowflake + for (var/type in subtypesof(/obj/item/seeds)) + var/obj/item/seeds/item = new type() + for(var/r in item.reagents_add) + if (!.[r]) + .[r] = list() + .[r] += type + qdel(item) + + +#define RNGCHEM_INPUT "input" +#define RNGCHEM_CATALYSTS "catalysts" +#define RNGCHEM_OUTPUT "output" + +/datum/chemical_reaction/randomized + name = "semi randomized reaction" + + var/persistent = FALSE + var/persistence_period = 7 //Will reset every x days + var/created //creation timestamp + + var/randomize_container = FALSE + var/list/possible_containers = list() + + var/randomize_req_temperature = TRUE + var/min_temp = 1 + var/max_temp = 600 + + var/randomize_inputs = TRUE + var/min_input_reagent_amount = 1 + var/max_input_reagent_amount = 10 + var/min_input_reagents = 2 + var/max_input_reagents = 5 + var/list/possible_reagents = list() + var/min_catalysts = 0 + var/max_catalysts = 2 + var/list/possible_catalysts = list() + + var/randomize_results = FALSE + var/min_output_reagent_amount = 1 + var/max_output_reagent_amount = 5 + var/min_result_reagents = 1 + var/max_result_reagents = 1 + var/list/possible_results = list() + +/datum/chemical_reaction/randomized/proc/GenerateRecipe() + created = world.time + if(randomize_container) + required_container = pick(possible_containers) + if(randomize_req_temperature) + required_temp = rand(min_temp,max_temp) + is_cold_recipe = pick(TRUE,FALSE) + + if(randomize_results) + results = list() + var/list/remaining_possible_results = GetPossibleReagents(RNGCHEM_OUTPUT) + var/out_reagent_count = min(rand(min_result_reagents,max_result_reagents),remaining_possible_results.len) + for(var/i in 1 to out_reagent_count) + var/r_id = pick_n_take(remaining_possible_results) + results[r_id] = rand(min_output_reagent_amount,max_output_reagent_amount) + + if(randomize_inputs) + var/list/remaining_possible_reagents = GetPossibleReagents(RNGCHEM_INPUT) + var/list/remaining_possible_catalysts = GetPossibleReagents(RNGCHEM_CATALYSTS) + + //We're going to assume we're not doing any weird partial reactions for now. + for(var/reagent_type in results) + remaining_possible_catalysts -= reagent_type + remaining_possible_reagents -= reagent_type + + var/in_reagent_count = min(rand(min_input_reagents,max_input_reagents),remaining_possible_reagents.len) + if(in_reagent_count <= 0) + return FALSE + + required_reagents = list() + for(var/i in 1 to in_reagent_count) + var/r_id = pick_n_take(remaining_possible_reagents) + required_reagents[r_id] = rand(min_input_reagent_amount,max_input_reagent_amount) + remaining_possible_catalysts -= r_id //Can't have same reagents both as catalyst and reagent. Or can we ? + + required_catalysts = list() + var/in_catalyst_count = min(rand(min_catalysts,max_catalysts),remaining_possible_catalysts.len) + for(var/i in 1 to in_catalyst_count) + var/r_id = pick_n_take(remaining_possible_catalysts) + required_catalysts[r_id] = rand(min_input_reagent_amount,max_input_reagent_amount) + + return TRUE + +/datum/chemical_reaction/randomized/proc/GetPossibleReagents(kind) + switch(kind) + if(RNGCHEM_INPUT) + return possible_reagents.Copy() + if(RNGCHEM_CATALYSTS) + return possible_catalysts.Copy() + if(RNGCHEM_OUTPUT) + return possible_results.Copy() + +/datum/chemical_reaction/randomized/proc/HasConflicts() + for(var/x in required_reagents) + for(var/datum/chemical_reaction/R in GLOB.chemical_reactions_list[x]) + if(chem_recipes_do_conflict(R,src)) + return TRUE + return FALSE + +/datum/chemical_reaction/randomized/proc/unwrap_reagent_list(list/textreagents) + . = list() + for(var/R in textreagents) + var/pathR = text2path(R) + if(!pathR) + return null + .[pathR] = textreagents[R] + +/datum/chemical_reaction/randomized/proc/LoadOldRecipe(recipe_data) + created = text2num(recipe_data["timestamp"]) + + var/req_reag = unwrap_reagent_list(recipe_data["required_reagents"]) + if(!req_reag) + return FALSE + required_reagents = req_reag + + var/req_catalysts = unwrap_reagent_list(recipe_data["required_catalysts"]) + if(!req_catalysts) + return FALSE + required_catalysts = req_catalysts + + required_temp = recipe_data["required_temp"] + is_cold_recipe = recipe_data["is_cold_recipe"] + + var/temp_results = unwrap_reagent_list(recipe_data["results"]) + if(!temp_results) + return FALSE + results = temp_results + var/containerpath = text2path(recipe_data["required_container"]) + if(!containerpath) + return FALSE + required_container = containerpath + return TRUE + +/datum/chemical_reaction/randomized/secret_sauce + name = "secret sauce creation" + id = "secretsauce" + persistent = TRUE + persistence_period = 7 //Reset every week + randomize_container = TRUE + possible_containers = list(/obj/item/reagent_containers/glass/bucket) //easy way to ensure no common conflicts + randomize_req_temperature = TRUE + results = list("secret_sauce" =1) + +/datum/chemical_reaction/randomized/secret_sauce/GetPossibleReagents(kind) + switch(kind) + if(RNGCHEM_INPUT,RNGCHEM_CATALYSTS) + var/food_reagent_ids = list() + for(var/key in GLOB.food_reagents) + food_reagent_ids += key + return food_reagent_ids + return ..() + + +/obj/item/paper/secretrecipe + name = "old recipe" + var/recipe_id = "secretsauce" + +/obj/item/paper/secretrecipe/examine(mob/user) //Extra secret + if(isobserver(user)) + return + . = ..() + +/obj/item/paper/secretrecipe/Initialize() + . = ..() + if(SSpersistence.initialized) + UpdateInfo() + else + SSticker.OnRoundstart(CALLBACK(src,.proc/UpdateInfo)) + +/obj/item/paper/secretrecipe/proc/UpdateInfo() + var/datum/chemical_reaction/recipe = get_chemical_reaction(recipe_id) + if(!recipe) + info = "This recipe is illegible." + var/list/dat = list("
-
-
-
- Loading...
- - If this takes longer than 30 seconds, it will automatically reload a maximum of 5 times. - If it still doesn't work, use the bug report button at the top right of the window. -
-
-
-
-
-
-
\ No newline at end of file
diff --git a/goon/browserassets/js/browserOutput.js b/goon/browserassets/js/browserOutput.js
deleted file mode 100644
index 0fb7386dd8..0000000000
--- a/goon/browserassets/js/browserOutput.js
+++ /dev/null
@@ -1,908 +0,0 @@
-/*****************************************
-*
-* FUNCTION AND VAR DECLARATIONS
-*
-******************************************/
-
-//DEBUG STUFF
-var escaper = encodeURIComponent || escape;
-var decoder = decodeURIComponent || unescape;
-window.onerror = function(msg, url, line, col, error) {
- if (document.location.href.indexOf("proc=debug") <= 0) {
- var extra = !col ? '' : ' | column: ' + col;
- extra += !error ? '' : ' | error: ' + error;
- extra += !navigator.userAgent ? '' : ' | user agent: ' + navigator.userAgent;
- var debugLine = 'Error: ' + msg + ' | url: ' + url + ' | line: ' + line + extra;
- window.location = '?_src_=chat&proc=debug¶m[error]='+escaper(debugLine);
- }
- return true;
-};
-
-//Globals
-window.status = 'Output';
-var $messages, $subOptions, $contextMenu, $filterMessages;
-var opts = {
- //General
- 'messageCount': 0, //A count...of messages...
- 'messageLimit': 2053, //A limit...for the messages...
- 'scrollSnapTolerance': 5, //If within x pixels of bottom
- 'clickTolerance': 10, //Keep focus if outside x pixels of mousedown position on mouseup
- 'popups': 0, //Amount of popups opened ever
- 'wasd': false, //Is the user in wasd mode?
- 'chatMode': 'default', //The mode the chat is in
- 'priorChatHeight': 0, //Thing for height-resizing detection
- 'restarting': false, //Is the round restarting?
-
- //Options menu
- 'subOptionsLoop': null, //Contains the interval loop for closing the options menu
- 'suppressOptionsClose': false, //Whether or not we should be hiding the suboptions menu
- 'highlightTerms': [],
- 'highlightLimit': 5,
- 'highlightColor': '#FFFF00', //The color of the highlighted message
- 'pingDisabled': false, //Has the user disabled the ping counter
-
- //Ping display
- 'lastPang': 0, //Timestamp of the last response from the server.
- 'pangLimit': 35000,
- 'pingTime': 0, //Timestamp of when ping sent
- 'pongTime': 0, //Timestamp of when ping received
- 'noResponse': false, //Tracks the state of the previous ping request
- 'noResponseCount': 0, //How many failed pings?
-
- //Clicks
- 'mouseDownX': null,
- 'mouseDownY': null,
- 'preventFocus': false, //Prevents switching focus to the game window
-
- //Client Connection Data
- 'clientDataLimit': 5,
- 'clientData': [],
-
-};
-
-function outerHTML(el) {
- var wrap = document.createElement('div');
- wrap.appendChild(el.cloneNode(true));
- return wrap.innerHTML;
-}
-
-//Polyfill for fucking date now because of course IE8 and below don't support it
-if (!Date.now) {
- Date.now = function now() {
- return new Date().getTime();
- };
-}
-//Polyfill for trim() (IE8 and below)
-if (typeof String.prototype.trim !== 'function') {
- String.prototype.trim = function () {
- return this.replace(/^\s+|\s+$/g, '');
- };
-}
-
-//Shit fucking piece of crap that doesn't work god fuckin damn it
-function linkify(text) {
- var rex = /((?:'+$0+'';
- }
- else {
- return $1 ? $0: ''+$0+'';
- }
- });
-}
-
-//Actually turns the highlight term match into appropriate html
-function addHighlightMarkup(match) {
- var extra = '';
- if (opts.highlightColor) {
- extra += ' style="background-color: '+opts.highlightColor+'"';
- }
- return ''+match+'';
-}
-
-//Highlights words based on user settings
-function highlightTerms(el) {
- if (el.children.length > 0) {
- for(var h = 0; h < el.children.length; h++){
- highlightTerms(el.children[h]);
- }
- }
-
- var hasTextNode = false;
- for (var node = 0; node < el.childNodes.length; node++)
- {
- if (el.childNodes[node].nodeType === 3)
- {
- hasTextNode = true;
- break;
- }
- }
-
- if (hasTextNode) { //If element actually has text
- var newText = '';
- for (var c = 0; c < el.childNodes.length; c++) { //Each child element
- if (el.childNodes[c].nodeType === 3) { //Is it text only?
- var words = el.childNodes[c].data.split(' ');
- for (var w = 0; w < words.length; w++) { //Each word in the text
- var newWord = null;
- for (var i = 0; i < opts.highlightTerms.length; i++) { //Each highlight term
- if (opts.highlightTerms[i] && words[w].toLowerCase().indexOf(opts.highlightTerms[i].toLowerCase()) > -1) { //If a match is found
- newWord = words[w].replace("<", "<").replace(new RegExp(opts.highlightTerms[i], 'gi'), addHighlightMarkup);
- break;
- }
- console.log(newWord)
- }
- newText += newWord || words[w].replace("<", "<");
- newText += w >= words.length ? '' : ' ';
- }
- } else { //Every other type of element
- newText += outerHTML(el.childNodes[c]);
- }
- }
- el.innerHTML = newText;
- }
-}
-//Send a message to the client
-function output(message, flag) {
- if (typeof message === 'undefined') {
- return;
- }
- if (typeof flag === 'undefined') {
- flag = '';
- }
-
- if (flag !== 'internal')
- opts.lastPang = Date.now();
-
- // Basically we url_encode twice server side so we can manually read the encoded version and actually do UTF-8.
- // The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b.
- // Marvelous.
- message = message.replace(/\+/g, "%20")
- message = decoder(message)
-
- //The behemoth of filter-code (for Admin message filters)
- //Note: This is proooobably hella inefficient
- var filteredOut = false;
- if (opts.hasOwnProperty('showMessagesFilters') && !opts.showMessagesFilters['All'].show) {
- //Get this filter type (defined by class on message)
- var messageHtml = $.parseHTML(message),
- messageClasses;
- if (opts.hasOwnProperty('filterHideAll') && opts.filterHideAll) {
- var internal = false;
- messageClasses = (!!$(messageHtml).attr('class') ? $(messageHtml).attr('class').split(/\s+/) : false);
- if (messageClasses) {
- for (var i = 0; i < messageClasses.length; i++) { //Every class
- if (messageClasses[i] == 'internal') {
- internal = true;
- break;
- }
- }
- }
- if (!internal) {
- filteredOut = 'All';
- }
- } else {
- //If the element or it's child have any classes
- if (!!$(messageHtml).attr('class') || !!$(messageHtml).children().attr('class')) {
- messageClasses = $(messageHtml).attr('class').split(/\s+/);
- if (!!$(messageHtml).children().attr('class')) {
- messageClasses = messageClasses.concat($(messageHtml).children().attr('class').split(/\s+/));
- }
- var tempCount = 0;
- for (var i = 0; i < messageClasses.length; i++) { //Every class
- var thisClass = messageClasses[i];
- $.each(opts.showMessagesFilters, function(key, val) { //Every filter
- if (key !== 'All' && val.show === false && typeof val.match != 'undefined') {
- for (var i = 0; i < val.match.length; i++) {
- var matchClass = val.match[i];
- if (matchClass == thisClass) {
- filteredOut = key;
- break;
- }
- }
- }
- if (filteredOut) return false;
- });
- if (filteredOut) break;
- tempCount++;
- }
- } else {
- if (!opts.showMessagesFilters['Misc'].show) {
- filteredOut = 'Misc';
- }
- }
- }
- }
-
- //Stuff we do along with appending a message
- var atBottom = false;
- if (!filteredOut) {
- var bodyHeight = $('body').height();
- var messagesHeight = $messages.outerHeight();
- var scrollPos = $('body,html').scrollTop();
-
- //Should we snap the output to the bottom?
- if (bodyHeight + scrollPos >= messagesHeight - opts.scrollSnapTolerance) {
- atBottom = true;
- if ($('#newMessages').length) {
- $('#newMessages').remove();
- }
- //If not, put the new messages box in
- } else {
- if ($('#newMessages').length) {
- var messages = $('#newMessages .number').text();
- messages = parseInt(messages);
- messages++;
- $('#newMessages .number').text(messages);
- if (messages == 2) {
- $('#newMessages .messageWord').append('s');
- }
- } else {
- $messages.after('1 new ');
- }
- }
- }
-
- //Url stuff
- if (message.length && flag != 'preventLink') {
- message = linkify(message);
- }
-
- opts.messageCount++;
-
- //Pop the top message off if history limit reached
- if (opts.messageCount >= opts.messageLimit) {
- $messages.children('div.entry:first-child').remove();
- opts.messageCount--; //I guess the count should only ever equal the limit
- }
-
- //Actually append the message
- var entry = document.createElement('div');
- entry.className = 'entry';
-
- if (filteredOut) {
- entry.className += ' hidden';
- entry.setAttribute('data-filter', filteredOut);
- }
-
- entry.innerHTML = message.trim();
- $messages[0].appendChild(entry);
-
- //Actually do the snap
- if (!filteredOut && atBottom) {
- $('body,html').scrollTop($messages.outerHeight());
- }
-
- //Stuff we can do after the message shows can go here, in the interests of responsiveness
- if (opts.highlightTerms && opts.highlightTerms.length > 0) {
- highlightTerms(entry);
- }
-}
-
-function internalOutput(message, flag)
-{
- output(escaper(message), flag)
-}
-
-//Runs a route within byond, client or server side. Consider this "ehjax" for byond.
-function runByond(uri) {
- window.location = uri;
-}
-
-function setCookie(cname, cvalue, exdays) {
- cvalue = escaper(cvalue);
- var d = new Date();
- d.setTime(d.getTime() + (exdays*24*60*60*1000));
- var expires = 'expires='+d.toUTCString();
- document.cookie = cname + '=' + cvalue + '; ' + expires;
-}
-
-function getCookie(cname) {
- var name = cname + '=';
- var ca = document.cookie.split(';');
- for(var i=0; i < ca.length; i++) {
- var c = ca[i];
- while (c.charAt(0)==' ') c = c.substring(1);
- if (c.indexOf(name) === 0) {
- return decoder(c.substring(name.length,c.length));
- }
- }
- return '';
-}
-
-function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B);}
-function toHex(n) {
- n = parseInt(n,10);
- if (isNaN(n)) return "00";
- n = Math.max(0,Math.min(n,255));
- return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16);
-}
-
-function changeMode(mode) {
- switch (mode) {
- case 'geocities':
- //switch in stylesheet
- opts.chatMode = mode;
- break;
- case 'console':
-
- opts.chatMode = mode;
- break;
- case 'default':
- default:
- //remove loaded stylesheet/s
- opts.chatMode = 'default';
- }
-}
-
-function handleClientData(ckey, ip, compid) {
- //byond sends player info to here
- var currentData = {'ckey': ckey, 'ip': ip, 'compid': compid};
- if (opts.clientData && !$.isEmptyObject(opts.clientData)) {
- runByond('?_src_=chat&proc=analyzeClientData¶m[cookie]='+JSON.stringify({'connData': opts.clientData}));
-
- for (var i = 0; i < opts.clientData.length; i++) {
- var saved = opts.clientData[i];
- if (currentData.ckey == saved.ckey && currentData.ip == saved.ip && currentData.compid == saved.compid) {
- return; //Record already exists
- }
- }
-
- if (opts.clientData.length >= opts.clientDataLimit) {
- opts.clientData.shift();
- }
- } else {
- runByond('?_src_=chat&proc=analyzeClientData¶m[cookie]=none');
- }
-
- //Update the cookie with current details
- opts.clientData.push(currentData);
- setCookie('connData', JSON.stringify(opts.clientData), 365);
-}
-
-//Server calls this on ehjax response
-//Or, y'know, whenever really
-function ehjaxCallback(data) {
- opts.lastPang = Date.now();
- if (data == 'softPang') {
- return;
- } else if (data == 'pang') {
- opts.pingCounter = 0; //reset
- opts.pingTime = Date.now();
- runByond('?_src_=chat&proc=ping');
-
- } else if (data == 'pong') {
- if (opts.pingDisabled) {return;}
- opts.pongTime = Date.now();
- var pingDuration = Math.ceil((opts.pongTime - opts.pingTime) / 2);
- $('#pingMs').text(pingDuration+'ms');
- pingDuration = Math.min(pingDuration, 255);
- var red = pingDuration;
- var green = 255 - pingDuration;
- var blue = 0;
- var hex = rgbToHex(red, green, blue);
- $('#pingDot').css('color', '#'+hex);
-
- } else if (data == 'roundrestart') {
- opts.restarting = true;
- internalOutput('The connection has been closed because the server is restarting. Please wait while you automatically reconnect. ', 'internal');
- } else if (data == 'stopaudio') {
- $('.dectalk').remove();
- } else {
- //Oh we're actually being sent data instead of an instruction
- var dataJ;
- try {
- dataJ = $.parseJSON(data);
- } catch (e) {
- //But...incorrect :sadtrombone:
- window.onerror('JSON: '+e+'. '+data, 'browserOutput.html', 327);
- return;
- }
- data = dataJ;
-
- if (data.clientData) {
- if (opts.restarting) {
- opts.restarting = false;
- $('.connectionClosed.restarting:not(.restored)').addClass('restored').text('The round restarted and you successfully reconnected!');
- }
- if (!data.clientData.ckey && !data.clientData.ip && !data.clientData.compid) {
- //TODO: Call shutdown perhaps
- return;
- } else {
- handleClientData(data.clientData.ckey, data.clientData.ip, data.clientData.compid);
- }
- } else if (data.modeChange) {
- changeMode(data.modeChange);
- } else if (data.firebug) {
- if (data.trigger) {
- internalOutput('Loading firebug console, triggered by '+data.trigger+'...', 'internal');
- } else {
- internalOutput('Loading firebug console...', 'internal');
- }
- var firebugEl = document.createElement('script');
- firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js';
- document.body.appendChild(firebugEl);
- } else if (data.dectalk) {
- var message = '';
- if (data.decTalkTrigger) {
- message = ' '+
- 'You hear a strange robotic voice...' + message;
- }
- internalOutput(message, 'preventLink');
- }
- }
-}
-
-function createPopup(contents, width) {
- opts.popups++;
- $('body').append('');
-
- //Attach close popup event
- var $popup = $('#popup'+opts.popups);
- var height = $popup.outerHeight();
- $popup.css({'height': height+'px', 'margin': '-'+(height/2)+'px 0 0 -'+(width/2)+'px'});
-
- $popup.on('click', '.close', function(e) {
- e.preventDefault();
- $popup.remove();
- });
-}
-
-function toggleWasd(state) {
- opts.wasd = (state == 'on' ? true : false);
-}
-
-/*****************************************
-*
-* DOM READY
-*
-******************************************/
-
-if (typeof $ === 'undefined') {
- var div = document.getElementById('loading').childNodes[1];
- div += 'ERROR: Jquery did not load.'; -} - -$(function() { - $messages = $('#messages'); - $subOptions = $('#subOptions'); - - //Hey look it's a controller loop! - setInterval(function() { - if (opts.lastPang + opts.pangLimit < Date.now() && !opts.restarting) { //Every pingLimit - if (!opts.noResponse) { //Only actually append a message if the previous ping didn't also fail (to prevent spam) - opts.noResponse = true; - opts.noResponseCount++; - internalOutput(' You are either AFK, experiencing lag or the connection has closed. ', 'internal');
- }
- } else if (opts.noResponse) { //Previous ping attempt failed ohno
- $('.connectionClosed[data-count="'+opts.noResponseCount+'"]:not(.restored)').addClass('restored').text('Your connection has been restored (probably)!');
- opts.noResponse = false;
- }
- }, 2000); //2 seconds
-
-
- /*****************************************
- *
- * LOAD SAVED CONFIG
- *
- ******************************************/
- var savedConfig = {
- 'sfontSize': getCookie('fontsize'),
- 'sfontType': getCookie('fonttype'),
- 'spingDisabled': getCookie('pingdisabled'),
- 'shighlightTerms': getCookie('highlightterms'),
- 'shighlightColor': getCookie('highlightcolor'),
- };
-
- if (savedConfig.sfontSize) {
- $messages.css('font-size', savedConfig.sfontSize);
- internalOutput('Loaded font size setting of: '+savedConfig.sfontSize+'', 'internal');
- }
- if (savedConfig.sfontType) {
- $messages.css('font-family', savedConfig.sfontType);
- internalOutput('Loaded font type setting of: '+savedConfig.sfontType+'', 'internal');
- }
- if (savedConfig.spingDisabled) {
- if (savedConfig.spingDisabled == 'true') {
- opts.pingDisabled = true;
- $('#ping').hide();
- }
- internalOutput('Loaded ping display of: '+(opts.pingDisabled ? 'hidden' : 'visible')+'', 'internal');
- }
- if (savedConfig.shighlightTerms) {
- var savedTerms = $.parseJSON(savedConfig.shighlightTerms);
- var actualTerms = '';
- for (var i = 0; i < savedTerms.length; i++) {
- if (savedTerms[i]) {
- actualTerms += savedTerms[i] + ', ';
- }
- }
- if (actualTerms) {
- actualTerms = actualTerms.substring(0, actualTerms.length - 2);
- internalOutput('Loaded highlight strings of: ' + actualTerms+'', 'internal');
- opts.highlightTerms = savedTerms;
- }
- }
- if (savedConfig.shighlightColor) {
- opts.highlightColor = savedConfig.shighlightColor;
- internalOutput('Loaded highlight color of: '+savedConfig.shighlightColor+'', 'internal');
- }
-
- (function() {
- var dataCookie = getCookie('connData');
- if (dataCookie) {
- var dataJ;
- try {
- dataJ = $.parseJSON(dataCookie);
- } catch (e) {
- window.onerror('JSON '+e+'. '+dataCookie, 'browserOutput.html', 434);
- return;
- }
- opts.clientData = dataJ;
- }
- })();
-
-
- /*****************************************
- *
- * BASE CHAT OUTPUT EVENTS
- *
- ******************************************/
-
- $('body').on('click', 'a', function(e) {
- e.preventDefault();
- });
-
- $('body').on('mousedown', function(e) {
- var $target = $(e.target);
-
- if ($contextMenu && opts.hasOwnProperty('contextMenuTarget') && opts.contextMenuTarget) {
- hideContextMenu();
- return false;
- }
-
- if ($target.is('a') || $target.parent('a').length || $target.is('input') || $target.is('textarea')) {
- opts.preventFocus = true;
- } else {
- opts.preventFocus = false;
- opts.mouseDownX = e.pageX;
- opts.mouseDownY = e.pageY;
- }
- });
-
- $messages.on('mousedown', function(e) {
- if ($subOptions && $subOptions.is(':visible')) {
- $subOptions.slideUp('fast', function() {
- $(this).removeClass('scroll');
- $(this).css('height', '');
- });
- clearInterval(opts.subOptionsLoop);
- }
- });
-
- $('body').on('mouseup', function(e) {
- if (!opts.preventFocus &&
- (e.pageX >= opts.mouseDownX - opts.clickTolerance && e.pageX <= opts.mouseDownX + opts.clickTolerance) &&
- (e.pageY >= opts.mouseDownY - opts.clickTolerance && e.pageY <= opts.mouseDownY + opts.clickTolerance)
- ) {
- opts.mouseDownX = null;
- opts.mouseDownY = null;
- runByond('byond://winset?mapwindow.map.focus=true');
- }
- });
-
- $messages.on('click', 'a', function(e) {
- var href = $(this).attr('href');
- $(this).addClass('visited');
- if (href[0] == '?' || (href.length >= 8 && href.substring(0,8) == 'byond://')) {
- runByond(href);
- } else {
- href = escaper(href);
- runByond('?action=openLink&link='+href);
- }
- });
-
- //Fuck everything about this event. Will look into alternatives.
- $('body').on('keydown', function(e) {
- if (e.target.nodeName == 'INPUT' || e.target.nodeName == 'TEXTAREA') {
- return;
- }
-
- if (e.ctrlKey || e.altKey || e.shiftKey) { //Band-aid "fix" for allowing ctrl+c copy paste etc. Needs a proper fix.
- return;
- }
-
- e.preventDefault()
-
- var k = e.which;
- var command; // Command to execute through winset.
-
- // Hardcoded because else there would be no feedback message.
- if (k == 113) { // F2
- runByond('byond://winset?screenshot=auto');
- internalOutput('Screenshot taken', 'internal');
- }
-
- var c = "";
- switch (k) {
- case 8:
- c = 'BACK';
- case 9:
- c = 'TAB';
- case 13:
- c = 'ENTER';
- case 19:
- c = 'PAUSE';
- case 27:
- c = 'ESCAPE';
- case 33: // Page up
- c = 'NORTHEAST';
- case 34: // Page down
- c = 'SOUTHEAST';
- case 35: // End
- c = 'SOUTHWEST';
- case 36: // Home
- c = 'NORTHWEST';
- case 37:
- c = 'WEST';
- case 38:
- c = 'NORTH';
- case 39:
- c = 'EAST';
- case 40:
- c = 'SOUTH';
- case 45:
- c = 'INSERT';
- case 46:
- c = 'DELETE';
- case 93: // That weird thing to the right of alt gr.
- c = 'APPS';
-
- default:
- c = String.fromCharCode(k);
- }
-
-// if(opts.macros.hasOwnProperty(c.toUpperCase()))
- // command = opts.macros[c];
-
- if (command) {
- runByond('byond://winset?mapwindow.map.focus=true;command='+command);
- return false;
- }
- else if (c.length == 0) {
- if (!e.shiftKey) {
- c = c.toLowerCase();
- }
- runByond('byond://winset?mapwindow.map.focus=true;mainwindow.input.text='+c);
- return false;
- } else {
- runByond('byond://winset?mapwindow.map.focus=true');
- return false;
- }
- });
-
- //Mildly hacky fix for scroll issues on mob change (interface gets resized sometimes, messing up snap-scroll)
- $(window).on('resize', function(e) {
- if ($(this).height() !== opts.priorChatHeight) {
- $('body,html').scrollTop($messages.outerHeight());
- opts.priorChatHeight = $(this).height();
- }
- });
-
- //Audio sound prevention
- $messages.on('click', '.stopAudio', function() {
- var $audio = $(this).parent().children('audio');
- if ($audio) {
- $audio.remove();
- }
- });
-
-
- /*****************************************
- *
- * OPTIONS INTERFACE EVENTS
- *
- ******************************************/
-
- $('body').on('click', '#newMessages', function(e) {
- var messagesHeight = $messages.outerHeight();
- $('body,html').scrollTop(messagesHeight);
- $('#newMessages').remove();
- runByond('byond://winset?mapwindow.map.focus=true');
- });
-
- $('#toggleOptions').click(function(e) {
- if ($subOptions.is(':visible')) {
- $subOptions.slideUp('fast', function() {
- $(this).removeClass('scroll');
- $(this).css('height', '');
- });
- clearInterval(opts.subOptionsLoop);
- } else {
- $subOptions.slideDown('fast', function() {
- var windowHeight = $(window).height();
- var toggleHeight = $('#toggleOptions').outerHeight();
- var priorSubHeight = $subOptions.outerHeight();
- var newSubHeight = windowHeight - toggleHeight;
- $(this).height(newSubHeight);
- if (priorSubHeight > (windowHeight - toggleHeight)) {
- $(this).addClass('scroll');
- }
- });
- opts.subOptionsLoop = setInterval(function() {
- if (!opts.suppressOptionsClose && $('#subOptions').is(':visible')) {
- $subOptions.slideUp('fast', function() {
- $(this).removeClass('scroll');
- $(this).css('height', '');
- });
- clearInterval(opts.subOptionsLoop);
- }
- }, 5000); //Every 5 seconds
- }
- });
-
- $('#subOptions, #toggleOptions').mouseenter(function() {
- opts.suppressOptionsClose = true;
- });
-
- $('#subOptions, #toggleOptions').mouseleave(function() {
- opts.suppressOptionsClose = false;
- });
-
- $('#decreaseFont').click(function(e) {
- var fontSize = parseInt($messages.css('font-size'));
- fontSize = fontSize - 1 + 'px';
- $messages.css({'font-size': fontSize});
- setCookie('fontsize', fontSize, 365);
- internalOutput('Font size set to '+fontSize+'', 'internal');
- });
-
- $('#increaseFont').click(function(e) {
- var fontSize = parseInt($messages.css('font-size'));
- fontSize = fontSize + 1 + 'px';
- $messages.css({'font-size': fontSize});
- setCookie('fontsize', fontSize, 365);
- internalOutput('Font size set to '+fontSize+'', 'internal');
- });
-
- $('#chooseFont').click(function(e) {
- if ($('.popup .changeFont').is(':visible')) {return;}
- var popupContent = 'Change Font ' +
- ''+
- 'Verdana (Default)'+
- 'Arial / Helvetica'+
- 'Times New Roman'+
- 'Georgia'+
- 'Courier New'+
- 'Lucida Console'+
- 'Wingdings'+
- 'Comic Sans MS'+
- ' ';
- createPopup(popupContent, 200);
- });
-
- $('body').on('click', '#changeFont a', function(e) {
- var font = $(this).attr('data-font');
- $messages.css('font-family', font);
- setCookie('fonttype', font, 365);
- });
-
- $('#togglePing').click(function(e) {
- if (opts.pingDisabled) {
- $('#ping').slideDown('fast');
- opts.pingDisabled = false;
- } else {
- $('#ping').slideUp('fast');
- opts.pingDisabled = true;
- }
- setCookie('pingdisabled', (opts.pingDisabled ? 'true' : 'false'), 365);
- });
-
- $('#saveLog').click(function(e) {
- var saved = '';
-
- if (window.XMLHtpRequest) {
- xmlHttp = new XMLHttpRequest();
- } else {
- xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
- }
- xmlHttp.open('GET', 'browserOutput.css', false);
- xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
- xmlHttp.send();
- saved += '';
-
- saved += $messages.html();
- saved = saved.replace(/&/g, '&');
- saved = saved.replace(/';
- }
- var popupContent = 'String Highlighting ' +
- '' +
- ' ';
- createPopup(popupContent, 250);
- });
-
- $('body').on('keyup', '#highlightColor', function() {
- var color = $('#highlightColor').val();
- color = color.trim();
- if (!color || color.charAt(0) != '#') return;
- $('#highlightColor').css('background-color', color);
- });
-
- $('body').on('submit', '#highlightTermForm', function(e) {
- e.preventDefault();
-
- var count = 0;
- while (count < opts.highlightLimit) {
- var term = $('#highlightTermInput'+count).val();
- if (term) {
- term = term.trim();
- if (term === '') {
- opts.highlightTerms[count] = null;
- } else {
- opts.highlightTerms[count] = term.toLowerCase();
- }
- } else {
- opts.highlightTerms[count] = null;
- }
- count++;
- }
-
- var color = $('#highlightColor').val();
- color = color.trim();
- if (color == '' || color.charAt(0) != '#') {
- opts.highlightColor = '#FFFF00';
- } else {
- opts.highlightColor = color;
- }
- var $popup = $('#highlightPopup').closest('.popup');
- $popup.remove();
-
- setCookie('highlightterms', JSON.stringify(opts.highlightTerms), 365);
- setCookie('highlightcolor', opts.highlightColor, 365);
- });
-
- $('#clearMessages').click(function() {
- $messages.empty();
- opts.messageCount = 0;
- });
-
-
- /*****************************************
- *
- * KICK EVERYTHING OFF
- *
- ******************************************/
-
- runByond('?_src_=chat&proc=doneLoading');
- if ($('#loading').is(':visible')) {
- $('#loading').remove();
- }
- $('#userBar').show();
- opts.priorChatHeight = $(window).height();
-});
\ No newline at end of file
diff --git a/goon/browserassets/js/json2.min.js b/goon/browserassets/js/json2.min.js
deleted file mode 100644
index d867407f26..0000000000
--- a/goon/browserassets/js/json2.min.js
+++ /dev/null
@@ -1 +0,0 @@
-"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function this_value(){return this.valueOf()}function quote(t){return rx_escapable.lastIndex=0,rx_escapable.test(t)?'"'+t.replace(rx_escapable,function(t){var e=meta[t];return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}function str(t,e){var r,n,o,u,f,a=gap,i=e[t];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(t)),"function"==typeof rep&&(i=rep.call(e,t,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,f=[],"[object Array]"===Object.prototype.toString.apply(i)){for(u=i.length,r=0;u>r;r+=1)f[r]=str(r,i)||"null";return o=0===f.length?"[]":gap?"[\n"+gap+f.join(",\n"+gap)+"\n"+a+"]":"["+f.join(",")+"]",gap=a,o}if(rep&&"object"==typeof rep)for(u=rep.length,r=0;u>r;r+=1)"string"==typeof rep[r]&&(n=rep[r],o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));else for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));return o=0===f.length?"{}":gap?"{\n"+gap+f.join(",\n"+gap)+"\n"+a+"}":"{"+f.join(",")+"}",gap=a,o}}var rx_one=/^[\],:{}\s]*$/,rx_two=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,rx_three=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,rx_four=/(?:^|:|,)(?:\s*\[)+/g,rx_escapable=/[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,rx_dangerous=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},Boolean.prototype.toJSON=this_value,Number.prototype.toJSON=this_value,String.prototype.toJSON=this_value);var gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,r){var n;if(gap="",indent="","number"==typeof r)for(n=0;r>n;n+=1)indent+=" ";else"string"==typeof r&&(indent=r);if(rep=e,e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(t,e){var r,n,o=t[e];if(o&&"object"==typeof o)for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(n=walk(o,r),void 0!==n?o[r]=n:delete o[r]);return reviver.call(t,e,o)}var j;if(text=String(text),rx_dangerous.lastIndex=0,rx_dangerous.test(text)&&(text=text.replace(rx_dangerous,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),rx_one.test(text.replace(rx_two,"@").replace(rx_three,"]").replace(rx_four,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}();
\ No newline at end of file
diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm
deleted file mode 100644
index d928397728..0000000000
--- a/goon/code/datums/browserOutput.dm
+++ /dev/null
@@ -1,289 +0,0 @@
-/*********************************
-For the main html chat area
-*********************************/
-
-//Precaching a bunch of shit
-GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of icons for the browser output
-
-//On client, created on login
-/datum/chatOutput
- var/client/owner //client ref
- var/loaded = FALSE // Has the client loaded the browser output area?
- var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do
- var/cookieSent = FALSE // Has the client sent a cookie for analysis
- var/list/connectionHistory //Contains the connection history passed from chat cookie
- var/broken = FALSE
-
-/datum/chatOutput/New(client/C)
- owner = C
- messageQueue = list()
- connectionHistory = list()
- // log_world("chatOutput: New()")
-
-/datum/chatOutput/proc/start()
- //Check for existing chat
- if(!owner)
- return FALSE
-
- if(!winexists(owner, "browseroutput")) // Oh goddamnit.
- alert(owner.mob, "Updated chat window does not exist. If you are using a custom skin file please allow the game to update.")
- broken = TRUE
- return FALSE
-
- if(winget(owner, "browseroutput", "is-disabled") == "false") //Already setup
- doneLoading()
-
- else //Not setup
- load()
-
- return TRUE
-
-/datum/chatOutput/proc/load()
- set waitfor = FALSE
- if(!owner)
- return
-
- var/static/list/chatResources = list(
- "code/modules/html_interface/js/jquery.min.js",
- "goon/browserassets/js/json2.min.js",
- "goon/browserassets/js/browserOutput.js",
- "tgui/assets/fonts/fontawesome-webfont.eot",
- "tgui/assets/fonts/fontawesome-webfont.svg",
- "tgui/assets/fonts/fontawesome-webfont.ttf",
- "tgui/assets/fonts/fontawesome-webfont.woff",
- "goon/browserassets/css/font-awesome.css",
- "goon/browserassets/css/browserOutput.css"
- )
-
- // to_chat(world.log, "chatOutput: load()")
- for(var/attempts in 1 to 5)
- for(var/asset in chatResources)
- owner << browse_rsc(file(asset))
-
- //log_world("Sending main chat window to client [owner.ckey]")
- owner << browse(file("goon/browserassets/html/browserOutput.html"), "window=browseroutput")
- sleep(14 + (chatResources.len * 7))
- if(!owner || loaded)
- break
-
- if(owner && !loaded)
- doneLoading() // try doing this manually
- CRASH("[owner] failed to load chat. Attempting doneLoading() manually")
- // log_world("chatOutput: [owner.ckey] load() completed")
-
-/datum/chatOutput/Topic(href, list/href_list)
- if(usr.client != owner)
- return TRUE
-
- // Build arguments.
- // Arguments are in the form "param[paramname]=thing"
- var/list/params = list()
- for(var/key in href_list)
- if(length(key) > 7 && findtext(key, "param")) // 7 is the amount of characters in the basic param key template.
- var/param_name = copytext(key, 7, -1)
- var/item = href_list[key]
-
- params[param_name] = item
-
- var/data // Data to be sent back to the chat.
- switch(href_list["proc"])
- if("doneLoading")
- data = doneLoading(arglist(params))
-
- if("debug")
- data = debug(arglist(params))
-
- if("ping")
- data = ping(arglist(params))
-
- if("analyzeClientData")
- data = analyzeClientData(arglist(params))
-
- if(data)
- ehjax_send(data = data)
-
-//Called on chat output done-loading by JS.
-/datum/chatOutput/proc/doneLoading()
- if(loaded)
- return
-
- loaded = TRUE
- winset(owner, "browseroutput", "is-disabled=false")
- for(var/message in messageQueue)
- to_chat(owner, message)
-
- messageQueue = null
- sendClientData()
-
- pingLoop()
-
-/datum/chatOutput/proc/pingLoop()
- set waitfor = FALSE
-
- while (owner)
- ehjax_send(data = owner.is_afk(29) ? "softPang" : "pang") // SoftPang isn't handled anywhere but it'll always reset the opts.lastPang.
- sleep(30)
-
-/datum/chatOutput/proc/ehjax_send(client/C = owner, window = "browseroutput", data)
- if(islist(data))
- data = json_encode(data)
- C << output("[data]", "[window]:ehjaxCallback")
-
-//Sends client connection details to the chat to handle and save
-/datum/chatOutput/proc/sendClientData()
- //Get dem deets
- var/list/deets = list("clientData" = list())
- deets["clientData"]["ckey"] = owner.ckey
- deets["clientData"]["ip"] = owner.address
- deets["clientData"]["compid"] = owner.computer_id
- var/data = json_encode(deets)
- ehjax_send(data = data)
-
-//Called by client, sent data to investigate (cookie history so far)
-/datum/chatOutput/proc/analyzeClientData(cookie = "")
- if(!cookie)
- return
-
- if(cookie != "none")
- var/list/connData = json_decode(cookie)
- if (connData && islist(connData) && connData.len > 0 && connData["connData"])
- connectionHistory = connData["connData"] //lol fuck
- var/list/found = new()
- for(var/i in connectionHistory.len to 1 step -1)
- var/list/row = src.connectionHistory[i]
- if (!row || row.len < 3 || (!row["ckey"] && !row["compid"] && !row["ip"])) //Passed malformed history object
- return
- if (world.IsBanned(row["ckey"], row["compid"], row["ip"]))
- found = row
- break
-
- //Uh oh this fucker has a history of playing on a banned account!!
- if (found.len > 0)
- //TODO: add a new evasion ban for the CURRENT client details, using the matched row details
- message_admins("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])")
- log_admin("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])")
-
- cookieSent = TRUE
-
-//Called by js client every 60 seconds
-/datum/chatOutput/proc/ping()
- return "pong"
-
-//Called by js client on js error
-/datum/chatOutput/proc/debug(error)
- log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]")
-
-#ifdef TESTING
-/client/verb/debug_chat()
- set hidden = TRUE
- chatOutput.ehjax_send(data = list("firebug" = TRUE))
-#endif
-//Global chat procs
-
-GLOBAL_LIST_EMPTY(bicon_cache)
-
-//Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
-// exporting it as text, and then parsing the base64 from that.
-// (This relies on byond automatically storing icons in savefiles as base64)
-/proc/icon2base64(icon/icon, iconKey = "misc")
- if (!isicon(icon))
- return FALSE
- GLOB.iconCache[iconKey] << icon
- var/iconData = GLOB.iconCache.ExportText(iconKey)
- var/list/partial = splittext(iconData, "{")
- return replacetext(copytext(partial[2], 3, -5), "\n", "")
-
-/proc/bicon(obj)
- if (!obj)
- return
-
- if (isicon(obj))
- //Icons get pooled constantly, references are no good here.
- /*if (!bicon_cache["\ref[obj]"]) // Doesn't exist yet, make it.
- bicon_cache["\ref[obj]"] = icon2base64(obj)
- return "Choose up to '+opts.highlightLimit+' strings that will highlight the line when they appear in chat. ' +
- '' +
- '") - message = replacetext(message, "\t", " ") - - // url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. - target << output(url_encode(url_encode(message)), "browseroutput:output") - -/proc/grab_client(target) - if(istype(target, /client)) - return target - else if(istype(target, /mob)) - var/mob/M = target - if(M.client) - return M.client - else if(istype(target, /datum/mind)) - var/datum/mind/M = target - if(M.current && M.current.client) - return M.current.client - -/datum/log //exists purely to capture to_chat() output - var/log = "" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-8416.yml b/html/changelogs/AutoChangeLog-pr-8416.yml new file mode 100644 index 0000000000..34bac362be --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8416.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "adds the sec jetpack to sec hardsuit storge" diff --git a/html/changelogs/AutoChangeLog-pr-8497.yml b/html/changelogs/AutoChangeLog-pr-8497.yml new file mode 100644 index 0000000000..4c42899313 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8497.yml @@ -0,0 +1,5 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds clockwork reflectors, a fragile anti-laser reflection shield object that can be constructed for 10 brass sheets. Upon firing on the object in the direction where it is shielded, it ricochets the bullet off of it relative to the shooting angle." + - tweak: "Renames some windows in the build menu for consistency." diff --git a/html/changelogs/AutoChangeLog-pr-8505.yml b/html/changelogs/AutoChangeLog-pr-8505.yml new file mode 100644 index 0000000000..57d6399680 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8505.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Clockwork Cult walls can no longer be deconstructed by RCDs when heated." diff --git a/html/changelogs/AutoChangeLog-pr-8561.yml b/html/changelogs/AutoChangeLog-pr-8561.yml new file mode 100644 index 0000000000..dca2bff2ff --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8561.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by JJRcop)" +delete-after: True +changes: + - rscadd: "Ports in more emojis, including : flushed :" diff --git a/html/changelogs/AutoChangeLog-pr-8570.yml b/html/changelogs/AutoChangeLog-pr-8570.yml new file mode 100644 index 0000000000..787b486685 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8570.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "origami" diff --git a/html/changelogs/AutoChangeLog-pr-8578.yml b/html/changelogs/AutoChangeLog-pr-8578.yml new file mode 100644 index 0000000000..39ded33f2d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8578.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - spellcheck: "Properly rewords the extinguisher's instructions on how to empty it on the floor since it was changed to be a screwdriver action instead of Alt Click a while ago." diff --git a/html/changelogs/AutoChangeLog-pr-8579.yml b/html/changelogs/AutoChangeLog-pr-8579.yml new file mode 100644 index 0000000000..56ecea119f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8579.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "gang tower shield" + - tweak: "costs of boots" diff --git a/html/changelogs/AutoChangeLog-pr-8581.yml b/html/changelogs/AutoChangeLog-pr-8581.yml new file mode 100644 index 0000000000..90433ecb88 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8581.yml @@ -0,0 +1,6 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Reskinnable PDAs. A related game preference." + - refactor: "Refactoring the pda, pda painter, obj reskinning and chameleon pda a bit to support this feature." + - imageadd: "more PDA sprites and ported reskins." diff --git a/html/changelogs/AutoChangeLog-pr-8584.yml b/html/changelogs/AutoChangeLog-pr-8584.yml new file mode 100644 index 0000000000..2621812d64 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8584.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "organ box" diff --git a/html/changelogs/AutoChangeLog-pr-8602.yml b/html/changelogs/AutoChangeLog-pr-8602.yml new file mode 100644 index 0000000000..4974c1ae79 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8602.yml @@ -0,0 +1,5 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Added an underwear toggle button under 'Object' tab" + - tweak: "Genitals now layer under underwear. Hide these if they're too obnoxious." diff --git a/html/changelogs/AutoChangeLog-pr-8614.yml b/html/changelogs/AutoChangeLog-pr-8614.yml new file mode 100644 index 0000000000..e9473181fb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8614.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by SpaceManiac)" +delete-after: True +changes: + - bugfix: "Disassembling a chem dispenser for the first time will no longer always yield a fully-charged cell." diff --git a/html/changelogs/AutoChangeLog-pr-8618.yml b/html/changelogs/AutoChangeLog-pr-8618.yml new file mode 100644 index 0000000000..77ba2439a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8618.yml @@ -0,0 +1,7 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "New cargo crate for tech-slugs!" + - rscadd: "Ammo to each fitting crate" + - bugfix: "Cat-code" + - spellcheck: "fixed a few typos - Again my bad" diff --git a/html/changelogs/AutoChangeLog-pr-8643.yml b/html/changelogs/AutoChangeLog-pr-8643.yml new file mode 100644 index 0000000000..b172071e2e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8643.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "The sacrificial target icon will now display onto the cult objective ui alert once again." diff --git a/html/changelogs/AutoChangeLog-pr-8648.yml b/html/changelogs/AutoChangeLog-pr-8648.yml new file mode 100644 index 0000000000..8d0f9d20c8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8648.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "makes uplink kits more usefull for the risk" diff --git a/html/changelogs/AutoChangeLog-pr-8652.yml b/html/changelogs/AutoChangeLog-pr-8652.yml new file mode 100644 index 0000000000..b788c5785c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8652.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by Dennok)" +delete-after: True +changes: + - bugfix: "Now areas_in_z get areas spawned by templates and blueprints." diff --git a/html/changelogs/AutoChangeLog-pr-8658.yml b/html/changelogs/AutoChangeLog-pr-8658.yml new file mode 100644 index 0000000000..ad35118c3f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8658.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Moving some tablecrafting recipes to the appropriate categories: Kitty ears and lizard cloche hats to \"clothing\"; Hot dogs to \"Sandwichs\"; Cuban carb, fish and chips and fish fingers to \"Fish\"." + - bugfix: "Fixes the not-a-sandwich recipe being M.I.A." diff --git a/html/changelogs/AutoChangeLog-pr-8659.yml b/html/changelogs/AutoChangeLog-pr-8659.yml new file mode 100644 index 0000000000..6287f1307f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8659.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by ninjanomnom)" +delete-after: True +changes: + - bugfix: "Orbiting is a little more aggressive about staying in orbit. The wisp as a result now correctly follows you over shuttle moves." diff --git a/html/changelogs/AutoChangeLog-pr-8665.yml b/html/changelogs/AutoChangeLog-pr-8665.yml new file mode 100644 index 0000000000..fc34f9ac3e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8665.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "Buffed wizard and artificier's Magic Missile, wizard and xeno queen's Repulse and juggernaut's Gauntlet Echo." diff --git a/html/changelogs/AutoChangeLog-pr-8666.yml b/html/changelogs/AutoChangeLog-pr-8666.yml new file mode 100644 index 0000000000..df2e2e3af0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8666.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by YPOQ)" +delete-after: True +changes: + - bugfix: "Fixing roffle waffle, mushroom halluginogen and some invalid reagents." diff --git a/html/changelogs/AutoChangeLog-pr-8667.yml b/html/changelogs/AutoChangeLog-pr-8667.yml new file mode 100644 index 0000000000..1f80a2917d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8667.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Anturk)" +delete-after: True +changes: + - rscadd: "Recipe for fabled secret sauce can now be found in the deepest reaches of space." diff --git a/html/changelogs/AutoChangeLog-pr-8669.yml b/html/changelogs/AutoChangeLog-pr-8669.yml new file mode 100644 index 0000000000..20770e8cc2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8669.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PRs by Denton and Skoglol)" +delete-after: True +changes: + - tweak: "Reorganized the syndicate uplinks. Items are now mostly alphabetical, some misplaced items moved to more fitting categories. Bundles, random item and TC have been moved into a new category called \"Bundles and Telecrystals\". Gloves of the North Star and Box of Throwing Weapons have been moved to Conspicuous and Dangerous Weapons. Combat Gloves Plus have been moved to Stealthy and Inconspicuous Weapons. Moved all implants into the Implants category." + - tweak: "Added a new category to the uplink: Grenades and Explosives." diff --git a/html/changelogs/AutoChangeLog-pr-8671.yml b/html/changelogs/AutoChangeLog-pr-8671.yml new file mode 100644 index 0000000000..bb01481d5c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8671.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by wesoda25)" +delete-after: True +changes: + - balance: "disembowelment no longer works on mobs that aren't dead or in critical condition" diff --git a/html/changelogs/AutoChangeLog-pr-8674.yml b/html/changelogs/AutoChangeLog-pr-8674.yml new file mode 100644 index 0000000000..3277946844 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8674.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "fixing cat code that dosnt work, my bad" diff --git a/html/changelogs/AutoChangeLog-pr-8675.yml b/html/changelogs/AutoChangeLog-pr-8675.yml new file mode 100644 index 0000000000..170a44ca25 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8675.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "Arcades stealing from noodles" diff --git a/html/changelogs/AutoChangeLog-pr-8677.yml b/html/changelogs/AutoChangeLog-pr-8677.yml new file mode 100644 index 0000000000..181f6d2932 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8677.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "speedy quirk" diff --git a/html/changelogs/AutoChangeLog-pr-8681.yml b/html/changelogs/AutoChangeLog-pr-8681.yml new file mode 100644 index 0000000000..1cd5f04124 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8681.yml @@ -0,0 +1,6 @@ +author: "Ghommie (Original PRs by Tortellini Tony and BuffEngineering)" +delete-after: True +changes: + - bugfix: "E-cigs will continue to display their setting after being emagged." + - bugfix: "Vapes now come out of the mouth. +fix Fixes an E-cig initialize() runtime." diff --git a/html/changelogs/AutoChangeLog-pr-8687.yml b/html/changelogs/AutoChangeLog-pr-8687.yml new file mode 100644 index 0000000000..65347093ef --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8687.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by monster860)" +delete-after: True +changes: + - bugfix: "fixes advanced proccall" diff --git a/html/changelogs/AutoChangeLog-pr-8688.yml b/html/changelogs/AutoChangeLog-pr-8688.yml new file mode 100644 index 0000000000..b22c2c52fd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8688.yml @@ -0,0 +1,5 @@ +author: "Ghommie (Original PR by nemvar)" +delete-after: True +changes: + - rscadd: "Botanists can now get beeplushies (or cultivator and bucket) as an heirloom." + - bugfix: "Clowns and mimes will now properly pick either a can of paint or their brand as heirloom now." diff --git a/html/changelogs/AutoChangeLog-pr-8689.yml b/html/changelogs/AutoChangeLog-pr-8689.yml new file mode 100644 index 0000000000..bf44770c76 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8689.yml @@ -0,0 +1,4 @@ +author: "Fermis" +delete-after: True +changes: + - rscadd: "Added a panda simplemob" diff --git a/html/changelogs/AutoChangeLog-pr-8690.yml b/html/changelogs/AutoChangeLog-pr-8690.yml new file mode 100644 index 0000000000..3ac76333a2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8690.yml @@ -0,0 +1,4 @@ +author: "Fermis" +delete-after: True +changes: + - bugfix: "fixes empathy exploit." diff --git a/html/changelogs/AutoChangeLog-pr-8691.yml b/html/changelogs/AutoChangeLog-pr-8691.yml new file mode 100644 index 0000000000..680904cc5c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8691.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PRs by nemvar and Rowell)" +delete-after: True +changes: + - rscadd: "Added beekini bras and panties, thigh-high and knee-high bee socks." diff --git a/html/changelogs/AutoChangeLog-pr-8692.yml b/html/changelogs/AutoChangeLog-pr-8692.yml new file mode 100644 index 0000000000..f1d87676ab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8692.yml @@ -0,0 +1,7 @@ +author: "Ghommie (original PRs by ShizCalev)" +delete-after: True +changes: + - bugfix: "Fixed a bug that allowed you to teleport an ID in your possession to a PDA anywhere ingame." + - bugfix: "Fixed an exploit allowing you to steal ID's/pens from PDA's not in your possession." + - bugfix: "Fixed an exploit allowing you unlimited control of a PDA's interface even if it wasn't near you/in your possession." + - bugfix: "Fixed Pride Mirror exploits." diff --git a/html/changelogs/AutoChangeLog-pr-8695.yml b/html/changelogs/AutoChangeLog-pr-8695.yml new file mode 100644 index 0000000000..671eaa519e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8695.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by grandpawalton and Mickyan)" +delete-after: True +changes: + - tweak: "the contents on the smartfridge icon now change depending on how many items it contains" + - bugfix: "opening the maintenance panel of smartfridges now correctly updates the icon" + - bugfix: "Screwing a disk compartmentalizer no longer makes it look like a smartfridge." diff --git a/html/changelogs/AutoChangeLog-pr-8698.yml b/html/changelogs/AutoChangeLog-pr-8698.yml new file mode 100644 index 0000000000..464f74427e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8698.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes flashlights being unable to be used for rudimentary eyes and mouth exams." diff --git a/html/changelogs/AutoChangeLog-pr-8708.yml b/html/changelogs/AutoChangeLog-pr-8708.yml new file mode 100644 index 0000000000..0929c2ee6c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8708.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - spellcheck: "Ironic" diff --git a/html/changelogs/AutoChangeLog-pr-8711.yml b/html/changelogs/AutoChangeLog-pr-8711.yml new file mode 100644 index 0000000000..f836783659 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8711.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Adds in a grey jumpsuit to the loadout choices, restricted to Assistants." diff --git a/html/changelogs/AutoChangeLog-pr-8715.yml b/html/changelogs/AutoChangeLog-pr-8715.yml new file mode 100644 index 0000000000..b99309cdd9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8715.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Pentetic Jelly, new chemical made through mixing 1:1 slime jelly and pentetic acid." + - tweak: "Anatomic panacea now gives pent jelly instead of pent acid. Medbeams now have TRUE tox healing to heal TOXINLOVER as well." diff --git a/html/changelogs/AutoChangeLog-pr-8718.yml b/html/changelogs/AutoChangeLog-pr-8718.yml new file mode 100644 index 0000000000..102fbd4f23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8718.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - rscadd: "ability to quickly max sensors" diff --git a/html/changelogs/AutoChangeLog-pr-8720.yml b/html/changelogs/AutoChangeLog-pr-8720.yml new file mode 100644 index 0000000000..81684baeac --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8720.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Credits to Kmc2000 for the original PR)" +delete-after: True +changes: + - rscadd: "Porting in MRE boxes from Yogstation. But be careful, eating possibly expired MREs found in maintenance comes with an unrealistically large (actually small) chance of food poisoning. Otherwise just bail out and order actually safe-to-eat MREs from cargo for 2000 credits." diff --git a/html/changelogs/AutoChangeLog-pr-8721.yml b/html/changelogs/AutoChangeLog-pr-8721.yml new file mode 100644 index 0000000000..4b616e9923 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8721.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by XDTM)" +delete-after: True +changes: + - bugfix: "Reagents now stop their passive effects (for example, stun immunity) if the liver stops working while they're active." diff --git a/html/changelogs/AutoChangeLog-pr-8722.yml b/html/changelogs/AutoChangeLog-pr-8722.yml new file mode 100644 index 0000000000..fe858768af --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8722.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "I didn't code it right it in the first place" diff --git a/html/changelogs/AutoChangeLog-pr-8726.yml b/html/changelogs/AutoChangeLog-pr-8726.yml new file mode 100644 index 0000000000..49da4299ce --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8726.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "Changed bible heal proc, halving the healed damage and increasing brain damage 5x in exchange for a much wider array of items to protect you from it." diff --git a/html/changelogs/AutoChangeLog-pr-8727.yml b/html/changelogs/AutoChangeLog-pr-8727.yml new file mode 100644 index 0000000000..b1ca5f0d51 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8727.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PRs by Jujumatic and PKPenguin321, respectively)" +delete-after: True +changes: + - rscadd: "Minesweeper Arcade machines. The higher the difficulty setting, the better the prizes will be." + - rscadd: "Also keep your eye out for another new (and rare) arcade game!" diff --git a/html/changelogs/AutoChangeLog-pr-8728.yml b/html/changelogs/AutoChangeLog-pr-8728.yml new file mode 100644 index 0000000000..2e860e737f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8728.yml @@ -0,0 +1,6 @@ +author: "Sishen1542" +delete-after: True +changes: + - tweak: "Moved around some chems from emag list into upgrades." + - balance: "Added some fun chems to dispensers." + - bugfix: "Gave dispensers old tg functionality." diff --git a/html/changelogs/AutoChangeLog-pr-8729.yml b/html/changelogs/AutoChangeLog-pr-8729.yml new file mode 100644 index 0000000000..a72f624352 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8729.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by AffectedArc07)" +delete-after: True +changes: + - tweak: "Religion is now a globalvar instead of being a subsystem for some reason" diff --git a/html/changelogs/AutoChangeLog-pr-8730.yml b/html/changelogs/AutoChangeLog-pr-8730.yml new file mode 100644 index 0000000000..d0204f2830 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8730.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by Tlaltecuhtli and nicbn)" +delete-after: True +changes: + - rscadd: "alt click to eject beakers from chem masters + chem dispensers + grinders + chem heaters" + - rscadd: "hit chem master + chem dispenser + chem heaters with a beaker and if its loaded with another it swaps em" + - rscadd: "All-In-One Blender UI uses a radial menu now. You can see the contents and reagents by examining." diff --git a/html/changelogs/AutoChangeLog-pr-8731.yml b/html/changelogs/AutoChangeLog-pr-8731.yml new file mode 100644 index 0000000000..0728c12124 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8731.yml @@ -0,0 +1,9 @@ +author: "Ghommie (original PRs by nicbn and coiax)" +delete-after: True +changes: + - rscadd: "Microwave UI uses a radial menu now. You can see the contents by examining." + - rscadd: "Microwaves have a single wire accessible when open, the activation wire. +When cut, the microwave will no longer function, when pulsed, the microwave +will turn on." + - rscadd: "Stabilized dark purple extracts now cook items in your hands, rather than dropping +the cooked item on the floor." diff --git a/html/changelogs/AutoChangeLog-pr-8732.yml b/html/changelogs/AutoChangeLog-pr-8732.yml new file mode 100644 index 0000000000..69a79b93ac --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8732.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Nicjh)" +delete-after: True +changes: + - rscadd: "Abductor console's select disguise option now uses a radial" diff --git a/html/changelogs/AutoChangeLog-pr-8733.yml b/html/changelogs/AutoChangeLog-pr-8733.yml new file mode 100644 index 0000000000..593c06bd90 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8733.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Swindly)" +delete-after: True +changes: + - rscadd: "Arm-mounted implants that contain more than one item use a radial menu instead of a list menu." diff --git a/html/changelogs/AutoChangeLog-pr-8736.yml b/html/changelogs/AutoChangeLog-pr-8736.yml new file mode 100644 index 0000000000..68d64e2410 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8736.yml @@ -0,0 +1,6 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "gear harness and a conflict merg" + - rscdel: "Nudity permits" + - bugfix: "nothing" diff --git a/html/changelogs/AutoChangeLog-pr-8737.yml b/html/changelogs/AutoChangeLog-pr-8737.yml new file mode 100644 index 0000000000..d8e868df33 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8737.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes CWC construct shells being visible as ghost role to latejoiners." diff --git a/html/changelogs/AutoChangeLog-pr-8738.yml b/html/changelogs/AutoChangeLog-pr-8738.yml new file mode 100644 index 0000000000..f0e48a77b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8738.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by ShizCalev)" +delete-after: True +changes: + - bugfix: "Pineapple haters/lovers will get/no longer get pineapple pizzas respectively from infinite pizza boxes." diff --git a/html/changelogs/AutoChangeLog-pr-8739.yml b/html/changelogs/AutoChangeLog-pr-8739.yml new file mode 100644 index 0000000000..0c25a1a649 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8739.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Leather, cardboard, bronze & bone golems!" + - rscadd: "Bone hurting juice and interactions with plasmamen, skeletons & bone golems!" diff --git a/html/changelogs/AutoChangeLog-pr-8741.yml b/html/changelogs/AutoChangeLog-pr-8741.yml new file mode 100644 index 0000000000..be803933ae --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8741.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by AffectedArc07 and Shazbot)" +delete-after: True +changes: + - imageadd: "Added 8 new sock styles" diff --git a/html/changelogs/AutoChangeLog-pr-8742.yml b/html/changelogs/AutoChangeLog-pr-8742.yml new file mode 100644 index 0000000000..03428fc8d1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8742.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Donner item" diff --git a/html/changelogs/AutoChangeLog-pr-8744.yml b/html/changelogs/AutoChangeLog-pr-8744.yml new file mode 100644 index 0000000000..2979a4a842 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8744.yml @@ -0,0 +1,4 @@ +author: "Linzolle" +delete-after: True +changes: + - bugfix: "atmos helmet visual bug" diff --git a/html/changelogs/AutoChangeLog-pr-8745.yml b/html/changelogs/AutoChangeLog-pr-8745.yml new file mode 100644 index 0000000000..6feaa2eadd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8745.yml @@ -0,0 +1,5 @@ +author: "Sishen1542" +delete-after: True +changes: + - rscadd: "Ported addition of new CAS cards." + - bugfix: "Ported a fix for CAS." diff --git a/html/changelogs/AutoChangeLog-pr-8747.yml b/html/changelogs/AutoChangeLog-pr-8747.yml new file mode 100644 index 0000000000..c8a4689c60 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8747.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Luna's Gauntlets" diff --git a/html/changelogs/AutoChangeLog-pr-8753.yml b/html/changelogs/AutoChangeLog-pr-8753.yml new file mode 100644 index 0000000000..04fd009e2f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8753.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "Ported the inability for non-station AI to interact with station z-level." diff --git a/html/changelogs/AutoChangeLog-pr-8755.yml b/html/changelogs/AutoChangeLog-pr-8755.yml new file mode 100644 index 0000000000..a1c4742802 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8755.yml @@ -0,0 +1,6 @@ +author: "Poojawa" +delete-after: True +changes: + - tweak: "tweaked the Genital character creation layout to look better" + - bugfix: "fixed having balls/womb when you don't have the linked organ at character creation" + - bugfix: "fixed being able to squeeze semen directly from your balls. Probably." diff --git a/html/changelogs/AutoChangeLog-pr-8756.yml b/html/changelogs/AutoChangeLog-pr-8756.yml new file mode 100644 index 0000000000..8d78c6d5e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8756.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "HoS mains can now peacefully sleep in their office." diff --git a/html/changelogs/AutoChangeLog-pr-8760.yml b/html/changelogs/AutoChangeLog-pr-8760.yml new file mode 100644 index 0000000000..78812c5c05 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8760.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "rebalanced lingy dingy powery gamey" diff --git a/html/changelogs/AutoChangeLog-pr-8762.yml b/html/changelogs/AutoChangeLog-pr-8762.yml new file mode 100644 index 0000000000..e248589b1b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8762.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - imageadd: "new sprites for the flechette gun, its magazines and the toy ray gun" diff --git a/html/changelogs/AutoChangeLog-pr-8764.yml b/html/changelogs/AutoChangeLog-pr-8764.yml new file mode 100644 index 0000000000..ad5b82505a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8764.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "holster doing holster things" diff --git a/html/changelogs/AutoChangeLog-pr-8766.yml b/html/changelogs/AutoChangeLog-pr-8766.yml new file mode 100644 index 0000000000..33c2a47a71 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8766.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes being able to teleport papers to your location with TK." diff --git a/html/changelogs/AutoChangeLog-pr-8767.yml b/html/changelogs/AutoChangeLog-pr-8767.yml new file mode 100644 index 0000000000..ce01bf471b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8767.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed some monkey-code shenanigeans making items sometimes disappear from pickpocketing." diff --git a/html/changelogs/AutoChangeLog-pr-8768.yml b/html/changelogs/AutoChangeLog-pr-8768.yml new file mode 100644 index 0000000000..de8338b545 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8768.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - imageadd: "New sprites for the some pda cartridges." diff --git a/html/changelogs/AutoChangeLog-pr-8773.yml b/html/changelogs/AutoChangeLog-pr-8773.yml new file mode 100644 index 0000000000..6cc39f8184 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8773.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - tweak: "Podpeople now have customization options." diff --git a/html/changelogs/AutoChangeLog-pr-8775.yml b/html/changelogs/AutoChangeLog-pr-8775.yml new file mode 100644 index 0000000000..51e8a15b13 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8775.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "The crew monitor's entry for the Quartermaster will now appear bolded, while HoP's will be of the same color of the service/unknown/other jobs." diff --git a/html/changelogs/AutoChangeLog-pr-8776.yml b/html/changelogs/AutoChangeLog-pr-8776.yml new file mode 100644 index 0000000000..bd3d30677a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8776.yml @@ -0,0 +1,11 @@ +author: "Ghommie (original PRs by ShizCalev, coiax and Tlaltecuhtli)" +delete-after: True +changes: + - bugfix: "Caks will no longer override the bonus reagents provided in a donut when frosting them." + - bugfix: "Caks can no longer create frosted frosted jelly donuts." + - bugfix: "Jelly donuts will no longer lose their vitamins when they're frosted." + - bugfix: "Fixed chaos donuts potentially doubling the amount of reagents added when microwaved with something else." + - bugfix: "Donuts now always contain 1 sprinkles as was stated on the wiki. Frosted donuts have a chance at adding an extra sprinkle." + - code_imp: "Improved the code for ensuring that security members enjoy donuts and security-themed alcoholic drinks." + - balance: "neurotoxin doesnt insta stun but gives you limb paralysis overtime and heart attacks if it stays in for too long and it is also alcholic" + - balance: "beepsky smash now summons imaginary beepskys that deal stamina damage instead of outright stunning" diff --git a/html/changelogs/AutoChangeLog-pr-8778.yml b/html/changelogs/AutoChangeLog-pr-8778.yml new file mode 100644 index 0000000000..1fa8446e6a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8778.yml @@ -0,0 +1,16 @@ +author: "Ghommie (original PRs by carshalash, GranpaWalton, BebeYoshi & Hexmaniacosanna, Fire Chance, Ordonis, Krysonism and OnlineGirlfriend)" +delete-after: True +changes: + - tweak: "Reduced booze power of Mead, Red Mead, and Irish Cream." + - tweak: "Increased booze power of Grappa." + - rscadd: "Added a new premium drink to the soda machine called \"Grey Bull\" which gives temporary shock resistance" + - rscadd: "A new drink called Blank Paper was added to the bar menu, it was made by a mime and it represents a new start." + - rscadd: "Adds a variety of fine alcoholic beverages for discerning patrons of the bar: Wizz Fizz, Bug Spray, Champagne, Applejack, Jack Rose, Turbo, Old Timer, Rubberneck, Duplex, Trappist Beer, Blazaam and Planet Cracker!" + - rscadd: "Also more nonalcoholic drinks: Cream Soda, Lemonade and Red Queen." + - rscadd: "Packs of a novel artificial sweetener have been added to the kitchen vendor." + - rscadd: "Bottles of trappist beer and champagne are now available in the premium seection of the booze-o-mat." + - rscadd: "Juicing parsnips now yields parsnip juice." + - rscadd: "Maintenance peaches." + - bugfix: "Grape soda now cools you down like other sodas." + - tweak: "tweaked the Arnold Palmer recipe, it now uses lemonade." + - imageadd: "Added new drink, bottle, vomit and peach can sprites." diff --git a/html/changelogs/AutoChangeLog-pr-8779.yml b/html/changelogs/AutoChangeLog-pr-8779.yml new file mode 100644 index 0000000000..b5e90f7ecb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8779.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - balance: "Roundstart carbon jetpacks now have full_speed FALSE." diff --git a/html/changelogs/AutoChangeLog-pr-8781.yml b/html/changelogs/AutoChangeLog-pr-8781.yml new file mode 100644 index 0000000000..12bd5ccdf0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8781.yml @@ -0,0 +1,4 @@ +author: "Sishen1542" +delete-after: True +changes: + - tweak: "Adds plasteel to medical and security techfabs." diff --git a/html/changelogs/AutoChangeLog-pr-8783.yml b/html/changelogs/AutoChangeLog-pr-8783.yml new file mode 100644 index 0000000000..5b283b9b21 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8783.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "emergency pods' storage will now properly work." diff --git a/html/changelogs/AutoChangeLog-pr-8784.yml b/html/changelogs/AutoChangeLog-pr-8784.yml new file mode 100644 index 0000000000..7d6d9d4739 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8784.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Donor item" diff --git a/html/changelogs/AutoChangeLog-pr-8793.yml b/html/changelogs/AutoChangeLog-pr-8793.yml new file mode 100644 index 0000000000..82a113c94d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8793.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "The PDA skin preference will now properly save up." + - tweak: "Changed the default PDA icon var to match the default PDA skin preference." diff --git a/html/changelogs/AutoChangeLog-pr-8797.yml b/html/changelogs/AutoChangeLog-pr-8797.yml new file mode 100644 index 0000000000..40c7afc570 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8797.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by @Tlaltecuhtli" +delete-after: True +changes: + - bugfix: "alt clicking the emitter now rotates it instead of only flipping" diff --git a/html/changelogs/AutoChangeLog-pr-8798.yml b/html/changelogs/AutoChangeLog-pr-8798.yml new file mode 100644 index 0000000000..367aadad80 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8798.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by Arkatos" +delete-after: True +changes: + - rscadd: "Action buttons can now be dragged onto each other to swap places" diff --git a/html/changelogs/AutoChangeLog-pr-8799.yml b/html/changelogs/AutoChangeLog-pr-8799.yml new file mode 100644 index 0000000000..73d3f590ba --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8799.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Promiscuous Organs crate, pills to lewd crate and testicles to maints" diff --git a/html/changelogs/AutoChangeLog-pr-8801.yml b/html/changelogs/AutoChangeLog-pr-8801.yml new file mode 100644 index 0000000000..e1089f2f1d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8801.yml @@ -0,0 +1,4 @@ +author: "Sishen1542, original by NewSta" +delete-after: True +changes: + - tweak: "updated the miasma canister sprites" diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi index dce76f58b5..6a1a35f326 100644 Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ diff --git a/icons/emoji.dmi b/icons/emoji.dmi index f0286dd33c..128a3b243c 100644 Binary files a/icons/emoji.dmi and b/icons/emoji.dmi differ diff --git a/icons/misc/minesweeper_tiles/eight.png b/icons/misc/minesweeper_tiles/eight.png new file mode 100644 index 0000000000..3a5c4179ef Binary files /dev/null and b/icons/misc/minesweeper_tiles/eight.png differ diff --git a/icons/misc/minesweeper_tiles/empty.png b/icons/misc/minesweeper_tiles/empty.png new file mode 100644 index 0000000000..8a4fb536bb Binary files /dev/null and b/icons/misc/minesweeper_tiles/empty.png differ diff --git a/icons/misc/minesweeper_tiles/five.png b/icons/misc/minesweeper_tiles/five.png new file mode 100644 index 0000000000..dacf837f9b Binary files /dev/null and b/icons/misc/minesweeper_tiles/five.png differ diff --git a/icons/misc/minesweeper_tiles/flag.png b/icons/misc/minesweeper_tiles/flag.png new file mode 100644 index 0000000000..e71d8685ed Binary files /dev/null and b/icons/misc/minesweeper_tiles/flag.png differ diff --git a/icons/misc/minesweeper_tiles/four.png b/icons/misc/minesweeper_tiles/four.png new file mode 100644 index 0000000000..17a2bdfeb4 Binary files /dev/null and b/icons/misc/minesweeper_tiles/four.png differ diff --git a/icons/misc/minesweeper_tiles/hidden.png b/icons/misc/minesweeper_tiles/hidden.png new file mode 100644 index 0000000000..8d34a2a7f3 Binary files /dev/null and b/icons/misc/minesweeper_tiles/hidden.png differ diff --git a/icons/misc/minesweeper_tiles/mine.png b/icons/misc/minesweeper_tiles/mine.png new file mode 100644 index 0000000000..e16c89c2a8 Binary files /dev/null and b/icons/misc/minesweeper_tiles/mine.png differ diff --git a/icons/misc/minesweeper_tiles/minehit.png b/icons/misc/minesweeper_tiles/minehit.png new file mode 100644 index 0000000000..f0c9699d97 Binary files /dev/null and b/icons/misc/minesweeper_tiles/minehit.png differ diff --git a/icons/misc/minesweeper_tiles/one.png b/icons/misc/minesweeper_tiles/one.png new file mode 100644 index 0000000000..a84e6010a3 Binary files /dev/null and b/icons/misc/minesweeper_tiles/one.png differ diff --git a/icons/misc/minesweeper_tiles/seven.png b/icons/misc/minesweeper_tiles/seven.png new file mode 100644 index 0000000000..10d71c427e Binary files /dev/null and b/icons/misc/minesweeper_tiles/seven.png differ diff --git a/icons/misc/minesweeper_tiles/six.png b/icons/misc/minesweeper_tiles/six.png new file mode 100644 index 0000000000..fe2ba800f4 Binary files /dev/null and b/icons/misc/minesweeper_tiles/six.png differ diff --git a/icons/misc/minesweeper_tiles/three.png b/icons/misc/minesweeper_tiles/three.png new file mode 100644 index 0000000000..1c128d88ee Binary files /dev/null and b/icons/misc/minesweeper_tiles/three.png differ diff --git a/icons/misc/minesweeper_tiles/two.png b/icons/misc/minesweeper_tiles/two.png new file mode 100644 index 0000000000..ff74af5c82 Binary files /dev/null and b/icons/misc/minesweeper_tiles/two.png differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 0ef4996b07..65b5733ffe 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/actions/actions_spells.dmi b/icons/mob/actions/actions_spells.dmi index dd8a6fb869..30927d3608 100644 Binary files a/icons/mob/actions/actions_spells.dmi and b/icons/mob/actions/actions_spells.dmi differ diff --git a/icons/mob/custom_w.dmi b/icons/mob/custom_w.dmi index e9bbbc4d45..d974d0ca6c 100644 Binary files a/icons/mob/custom_w.dmi and b/icons/mob/custom_w.dmi differ diff --git a/icons/mob/human_parts_greyscale.dmi b/icons/mob/human_parts_greyscale.dmi index f49a27fda4..3bb3874d35 100644 Binary files a/icons/mob/human_parts_greyscale.dmi and b/icons/mob/human_parts_greyscale.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index fbfa039451..5f0b665ff4 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi index 3c126daba6..3463065bc7 100644 Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi index 45b0ab1f04..fe0146ccc4 100644 Binary files a/icons/mob/pets.dmi and b/icons/mob/pets.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index b3b2f7703c..42c32f134a 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/underwear.dmi b/icons/mob/underwear.dmi index cf16eb9e32..5e6725cec7 100644 Binary files a/icons/mob/underwear.dmi and b/icons/mob/underwear.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 2ed1783941..3d281606de 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/atmos.dmi b/icons/obj/atmos.dmi index 9a51635b81..ee42e95dd2 100644 Binary files a/icons/obj/atmos.dmi and b/icons/obj/atmos.dmi differ diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi index 56cfdf468b..1948bb605c 100644 Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index dc5dde9cb6..3e56574fbf 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 2970de757b..568adb69b3 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 84155bfe43..3e3a1cefcb 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi index 0a426f2d79..eb4f5813c8 100644 Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ diff --git a/icons/obj/dart.dmi b/icons/obj/dart.dmi new file mode 100644 index 0000000000..50ba4fc1ab Binary files /dev/null and b/icons/obj/dart.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index a32d0234d6..dc3aca6b19 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/food/containers.dmi b/icons/obj/food/containers.dmi index c348fb4f8f..ad3073a140 100644 Binary files a/icons/obj/food/containers.dmi and b/icons/obj/food/containers.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 9861a2e618..6292f7e21a 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index e4a39903b3..7d44d35f55 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index fbb55434d1..140f6a4d9e 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi index 241bb46b98..7d184c6459 100644 Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ diff --git a/icons/obj/pda_alt.dmi b/icons/obj/pda_alt.dmi new file mode 100644 index 0000000000..4f03d2c574 Binary files /dev/null and b/icons/obj/pda_alt.dmi differ diff --git a/icons/obj/pda_modern.dmi b/icons/obj/pda_modern.dmi new file mode 100644 index 0000000000..26c3b9ce16 Binary files /dev/null and b/icons/obj/pda_modern.dmi differ diff --git a/icons/obj/pda_rugged.dmi b/icons/obj/pda_rugged.dmi new file mode 100644 index 0000000000..84c8ffd1f9 Binary files /dev/null and b/icons/obj/pda_rugged.dmi differ diff --git a/icons/obj/plushes.dmi b/icons/obj/plushes.dmi index 8e845d9710..586bca61aa 100644 Binary files a/icons/obj/plushes.dmi and b/icons/obj/plushes.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index d276655ae8..bff1b631c3 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 9467e8f818..9037bfc0d0 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi index f77735fc3e..80e681399a 100644 Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi index 5e3757cedd..67079de3e2 100644 Binary files a/icons/obj/vehicles.dmi and b/icons/obj/vehicles.dmi differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index e5d474f01d..553336115b 100644 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/modular_citadel/code/datums/uplink_items_cit.dm b/modular_citadel/code/datums/uplink_items_cit.dm deleted file mode 100644 index 16130de96d..0000000000 --- a/modular_citadel/code/datums/uplink_items_cit.dm +++ /dev/null @@ -1,177 +0,0 @@ -/*/datum/uplink_item/stealthy_tools/syndi_borer - name = "Syndicate Brain Slug" - desc = "A small cortical borer, modified to be completely loyal to the owner. \ - Genetically infertile, these brain slugs can assist medically in a support role, or take direct action \ - to assist their host." - item = /obj/item/antag_spawner/syndi_borer - refundable = TRUE - cost = 10 - surplus = 20 //Let's not have this be too common - exclude_modes = list(/datum/game_mode/nuclear) */ - -/datum/uplink_item/stealthy_tools/holoparasite - name="Holoparasite Injector" - desc="An injector containing a swarm of holographic parasites. \ - They mimic the function of the guardians employed by the Space Wizard Federation, and their form can be selected upon application \ - NOTE: The precise nature of the symbiosis required by the parasites renders them incompatible with changelings" //updated to actually describe what they do and warn traitorchans not to buy it - item = /obj/item/storage/box/syndie_kit/holoparasite - refundable = TRUE - cant_discount = TRUE - cost = 15 - surplus = 20 //Nobody needs a ton of parasites - exclude_modes = list(/datum/game_mode/nuclear) - refund_path = /obj/item/guardiancreator/tech/choose/traitor - - -/obj/item/storage/box/syndie_kit/holoparasite - name = "box" - -/obj/item/storage/box/syndie_kit/holoparasite/PopulateContents() - new /obj/item/guardiancreator/tech/choose/traitor(src) - new /obj/item/paper/guides/antag/guardian(src) - -/datum/uplink_item/dangerous/antitank - name = "Anti Tank Pistol" - desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all), \ - this extremely dubious pistol is guaranteed to dislocate your wrists and hit the broad side of a barn! \ - Uses sniper ammo. \ - Bullets tend to veer off-course. We are not responsible for any unintentional damage or injury resulting from inaacuracy." - item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate - cost = 14 - surplus = 25 - include_modes = list(/datum/game_mode/nuclear) - -/* Commented out due to introduction of reskinnable stetchkins. May still have a niche if people decide it somehow has value. -/datum/uplink_item/dangerous/stealthpistol - name = "Stealth Pistol" - desc = "A compact, easily concealable bullpup pistol that fires 10mm auto rounds in 8 round magazines. \ - Has an integrated suppressor." - item = /obj/item/gun/ballistic/automatic/pistol/stealth - cost = 10 - surplus = 30 -*/ - -///Soporific 10mm mags/// - -/datum/uplink_item/ammo/pistolzzz - name = "10mm Soporific Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \ - NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require three shots to take effect." - item = /obj/item/ammo_box/magazine/m10mm/soporific - cost = 2 - -///flechette memes/// - -/datum/uplink_item/dangerous/flechettegun - name = "Flechette Launcher" - desc = "A compact bullpup that fires micro-flechettes.\ - Flechettes have very poor performance idividually, but can be very deadly in numbers. \ - Pre-loaded with armor piercing flechettes that are capable of puncturing most kinds of armor." - item = /obj/item/gun/ballistic/automatic/flechette - cost = 12 - surplus = 30 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/flechetteap - name = "Armor Piercing Flechette Magazine" - desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ - Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective agaisnt flesh." - item = /obj/item/ammo_box/magazine/flechette - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/flechettes - name = "Serrated Flechette Magazine" - desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ - Loaded with serrated flechettes that shreds flesh, but is stopped dead in its tracks by armor. \ - These flechettes are highly likely to sever arteries, and even limbs." - item = /obj/item/ammo_box/magazine/flechette/s - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -///shredder/// - -/datum/uplink_item/nukeoffer/shredder - name = "Shredder bundle" - desc = "A truly horrific weapon designed simply to maim its victim, the CX Shredder is banned by several intergalactic treaties. \ - You'll get two of them with this. And spare ammo to boot. And we'll throw in an extra elite hardsuit and chest rig to hold them all!" - item = /obj/item/storage/backpack/duffelbag/syndie/shredderbundle - cost = 30 // normally 41 - -///Modular Pistols/// - -/datum/uplink_item/bundle/modular - name="Modular Pistol Kit" - desc="A heavy briefcase containing one modular pistol (chambered in 10mm), one supressor, and spare ammunition, including a box of soporific ammo. \ - Includes a suit jacket that is padded with a robust liner." - item = /obj/item/storage/briefcase/modularbundle - cost = 12 - -//////Bundle stuff////// - -///bundle category/// - -/datum/uplink_item/bundle - category = "Bundles" - surplus = 0 - cant_discount = TRUE - -///place bundle storage items here I guess/// - -/obj/item/storage/briefcase/modularbundle - name = "briefcase" - desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding." - icon_state = "briefcase" - flags_1 = CONDUCT_1 - force = 10 - hitsound = "swing_hit" - throw_speed = 2 - throw_range = 4 - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") - resistance_flags = FLAMMABLE - max_integrity = 150 - -/obj/item/storage/briefcase/modularbundle/PopulateContents() - new /obj/item/gun/ballistic/automatic/pistol/modular(src) - new /obj/item/suppressor(src) - new /obj/item/ammo_box/magazine/m10mm(src) - new /obj/item/ammo_box/magazine/m10mm/soporific(src) - new /obj/item/ammo_box/c10mm/soporific(src) - new /obj/item/clothing/under/lawyer/blacksuit(src) - new /obj/item/clothing/accessory/waistcoat(src) - new /obj/item/clothing/suit/toggle/lawyer/black/syndie(src) - -/obj/item/clothing/suit/toggle/lawyer/black/syndie - desc = "A snappy dress jacket. Suspiciously has no tags or branding." - armor = list(melee = 10, bullet = 10, laser = 10, energy = 10, bomb = 10) - -/obj/item/storage/backpack/duffelbag/syndie/shredderbundle - desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig." - -/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents() - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/ammo_box/magazine/flechette/shredder(src) - new /obj/item/gun/ballistic/automatic/flechette/shredder(src) - new /obj/item/gun/ballistic/automatic/flechette/shredder(src) - new /obj/item/storage/belt/military(src) - new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src) - -///End of Bundle stuff/// - - -/*///////////////////////////////////////////////////////////////////////// -///////////// The TRUE Energy Sword /////////////////////////// -*////////////////////////////////////////////////////////////////////////// - -/datum/uplink_item/dangerous/cxneb - name = "Dragon's Tooth Non-Eutactic Blade" - desc = "An illegal modification of a weapon that is functionally identical to the energy sword, \ - the Non-Eutactic Blade (NEB) forges a hardlight blade on-demand, \ - generating an extremely sharp, unbreakable edge that is guaranteed to satisfy your every need. \ - This particular model has a polychromic hardlight generator, allowing you to murder in style! \ - The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds." - item = /obj/item/melee/transforming/energy/sword/cx/traitor - cost = 8 \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_items.dm b/modular_citadel/code/game/gamemodes/gangs/gang_items.dm index 0f16b6462b..2e9ca4dcc0 100644 --- a/modular_citadel/code/game/gamemodes/gangs/gang_items.dm +++ b/modular_citadel/code/game/gamemodes/gangs/gang_items.dm @@ -83,14 +83,12 @@ return return TRUE - /datum/gang_item/clothing/hat name = "Pimp Hat" id = "hat" cost = 16 item_path = /obj/item/clothing/head/collectable/petehat/gang - /obj/item/clothing/head/collectable/petehat/gang name = "pimpin' hat" desc = "The undisputed king of style." @@ -109,7 +107,7 @@ /datum/gang_item/clothing/shoes name = "Bling Boots" id = "boots" - cost = 22 + cost = 20 item_path = /obj/item/clothing/shoes/gang /obj/item/clothing/shoes/gang @@ -258,7 +256,6 @@ datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang m /datum/gang_item/equipment category = "Purchase Equipment:" - /datum/gang_item/equipment/spraycan name = "Territory Spraycan" id = "spraycan" @@ -275,7 +272,6 @@ datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang m cost = 3 item_path = /obj/item/sharpener - /datum/gang_item/equipment/emp name = "EMP Grenade" id = "EMP" @@ -329,6 +325,12 @@ datum/gang_item/equipment/shield cost = 25 item_path = /obj/item/shield/riot +datum/gang_item/equipment/gangsheild + name = "Tower Shield" + id = "metal" + cost = 45 //High block of melee and even higher for bullets + item_path = /obj/item/shield/riot/tower + /datum/gang_item/equipment/pen name = "Recruitment Pen" id = "pen" @@ -352,7 +354,6 @@ datum/gang_item/equipment/shield return "(GET ONE FREE)" return ..() - /datum/gang_item/equipment/gangtool id = "gangtool" cost = 5 @@ -413,4 +414,4 @@ datum/gang_item/equipment/shield /datum/gang_item/equipment/dominator/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) new item_path(user.loc) - to_chat(user, spawn_msg) \ No newline at end of file + to_chat(user, spawn_msg) diff --git a/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm b/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm deleted file mode 100644 index d26cf28778..0000000000 --- a/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm +++ /dev/null @@ -1,4 +0,0 @@ -//Overrides TG's PDA sprites with Cit's PDA sprites. Remind me to turn this into a pref somewhere down the line. - -/obj/item/pda - icon = 'modular_citadel/icons/obj/pda.dmi' diff --git a/modular_citadel/code/game/objects/items/devices/flashlight.dm b/modular_citadel/code/game/objects/items/devices/flashlight.dm deleted file mode 100644 index 3a373c9277..0000000000 --- a/modular_citadel/code/game/objects/items/devices/flashlight.dm +++ /dev/null @@ -1,31 +0,0 @@ -/obj/item/flashlight - light_color = "#FFCC66" - flashlight_power = 0.8 - -/obj/item/flashlight/pen - light_color = "#FFDDCC" - flashlight_power = 0.3 - -/obj/item/flashlight/seclite - light_color = "#CDDDFF" - flashlight_power = 0.9 - -/obj/item/flashlight/lamp - light_color = "#FFDDBB" - flashlight_power = 0.8 - -/obj/item/flashlight/flare - light_color = "#FA421A" - flashlight_power = 0.8 - -/obj/item/flashlight/flare/torch - light_color = "#FAA44B" - flashlight_power = 0.8 - -/obj/item/flashlight/lantern - light_color = "#FFAA44" - flashlight_power = 0.75 - -/obj/item/flashlight/slime - light_color = "#FFEEAA" - flashlight_power = 0.6 diff --git a/modular_citadel/code/game/objects/items/holy_weapons.dm b/modular_citadel/code/game/objects/items/holy_weapons.dm index 204a27f3fa..3ecc6cc31b 100644 --- a/modular_citadel/code/game/objects/items/holy_weapons.dm +++ b/modular_citadel/code/game/objects/items/holy_weapons.dm @@ -11,8 +11,8 @@ /obj/item/nullrod/rosary/Initialize() .=..() - if(SSreligion.religion) - deity_name = SSreligion.deity + if(GLOB.religion) + deity_name = GLOB.deity /obj/item/nullrod/rosary/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(!istype(M)) diff --git a/modular_citadel/code/modules/arousal/arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm index 846a8cff62..27f7576e7f 100644 --- a/modular_citadel/code/modules/arousal/arousal.dm +++ b/modular_citadel/code/modules/arousal/arousal.dm @@ -14,6 +14,10 @@ var/saved_underwear = ""//saves their underwear so it can be toggled later var/saved_undershirt = "" + var/saved_socks = "" + var/hidden_underwear = FALSE + var/hidden_undershirt = FALSE + var/hidden_socks = FALSE /mob/living/carbon/human/New() ..() @@ -29,6 +33,33 @@ var/list/femcum_fluids = list("femcum") //Mob procs +/mob/living/carbon/human/proc/underwear_toggle() + set name = "Toggle undergarments" + set category = "Object" + if(ishuman(src)) + var/mob/living/carbon/human/humz = src + var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling", "Cancel") in list("Top", "Bottom", "Socks", "All", "Cancel") + if(confirm == "Top") + humz.hidden_undershirt = !humz.hidden_undershirt + + if(confirm == "Bottom") + humz.hidden_underwear = !humz.hidden_underwear + + if(confirm == "Socks") + humz.hidden_socks = !humz.hidden_socks + + if(confirm == "All") + humz.hidden_undershirt = !humz.hidden_undershirt + humz.hidden_underwear = !humz.hidden_underwear + humz.hidden_socks = !humz.hidden_socks + + if(confirm == "Cancel") + return + src.update_body() + + else + to_chat(src, "Humans only. How the fuck did you get this verb anyway.") + /mob/living/proc/handle_arousal() diff --git a/modular_citadel/code/modules/arousal/organs/genitals.dm b/modular_citadel/code/modules/arousal/organs/genitals.dm index 52508d7803..63d6834409 100644 --- a/modular_citadel/code/modules/arousal/organs/genitals.dm +++ b/modular_citadel/code/modules/arousal/organs/genitals.dm @@ -73,7 +73,7 @@ owner.exposed_genitals += src if("Hidden by clothes") through_clothes = FALSE - hidden = FALSE + hidden = TRUE if(src in owner.exposed_genitals) owner.exposed_genitals -= src if("Always hidden") @@ -303,6 +303,8 @@ for(var/obj/item/organ/O in H.internal_organs) if(isgenital(O)) var/obj/item/organ/genital/G = O + if(G.hidden) + return //we're gunna just hijack this for updates. if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes genitals_to_add += H.getorganslot(G.slot) //Now we added all genitals that aren't internal and should be rendered diff --git a/modular_citadel/code/modules/arousal/organs/testicles.dm b/modular_citadel/code/modules/arousal/organs/testicles.dm index 0b86d58208..1e6b4d62d4 100644 --- a/modular_citadel/code/modules/arousal/organs/testicles.dm +++ b/modular_citadel/code/modules/arousal/organs/testicles.dm @@ -11,7 +11,7 @@ var/sack_size = BALLS_SACK_SIZE_DEF fluid_id = "semen" producing = TRUE - can_masturbate_with = TRUE + can_masturbate_with = FALSE masturbation_verb = "massage" can_climax = TRUE var/sent_full_message = TRUE //defaults to 1 since they're full to start diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index 1e17736380..ab03e83b44 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -397,4 +397,34 @@ datum/gear/darksabresheath name = "Kimono" category = SLOT_WEAR_SUIT path = /obj/item/clothing/suit/kimono - ckeywhitelist = list("sfox63") \ No newline at end of file + ckeywhitelist = list("sfox63") + +/datum/gear/commjacket + name = "Dusty Commisar's Cloak" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/commjacket + ckeywhitelist = list("sadisticbatter") + +/datum/gear/mw2_russian_para + name = "Russian Paratrooper Jumper" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/mw2_russian_para + ckeywhitelist = list("investigator77") + +/datum/gear/longblackgloves + name = "Luna's Gauntlets" + category = SLOT_GLOVES + path = /obj/item/clothing/gloves/longblackgloves + ckeywhitelist = list("bigmanclancy") + +/datum/gear/trendy_fit + name = "Trendy Fit" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/trendy_fit + ckeywhitelist = list("midgetdragon") + +/datum/gear/csheet + name = "NT Bedsheet" + category = SLOT_NECK + path = /obj/item/bedsheet/captain + ckeywhitelist = list("tikibomb") \ No newline at end of file diff --git a/modular_citadel/code/modules/client/loadout/_service.dm b/modular_citadel/code/modules/client/loadout/_service.dm index 9b508bb93f..062e22f966 100644 --- a/modular_citadel/code/modules/client/loadout/_service.dm +++ b/modular_citadel/code/modules/client/loadout/_service.dm @@ -1,3 +1,9 @@ +/datum/gear/greytidestationwide + name = "Grey jumpsuit" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/color/grey + restricted_roles = list("Assistant") + /datum/gear/plushvar name = "Ratvar Plushie" category = SLOT_IN_BACKPACK diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 4172230dbf..abdf8e3a24 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -309,8 +309,8 @@ restricted_desc = "Engineering and Security" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") -//memes -/datum/gear/nudepermit - name = "Nudity Permit" +//Memes +/datum/gear/gear_harnesses + name = "Gear Harness" category = SLOT_W_UNIFORM - path = /obj/item/clothing/under/permit \ No newline at end of file + path = /obj/item/clothing/under/gear_harness \ No newline at end of file diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index c43b8f3ce1..4fd628f9d3 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -417,7 +417,6 @@ icon_state = "flagcape" item_state = "flagcape" - /obj/item/clothing/shoes/lucky name = "Lucky Jackboots" icon = 'icons/obj/custom.dmi' @@ -494,3 +493,38 @@ icon = 'icons/obj/custom.dmi' alternate_worn_icon = 'icons/mob/custom_w.dmi' mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/suit/commjacket + name = "Dusty Commisar's Cloak" + desc = "An Imperial Commisar's Coat, straight from the frontline of battle, filled with dirt, bulletholes, and dozens of little pockets. Alongside a curious golden eagle sitting on it's left breast, the marking '200th Venoland' is clearly visible on the inner workings of the coat. It certainly holds an imposing flair, however." + icon_state = "commjacket" + item_state = "commjacket" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/suit/mw2_russian_para + name = "Russian Paratrooper Jumper" + desc = "A Russian made old paratrooper jumpsuit, has many pockets for easy storage of gear from a by gone era. As bulky as it looks, its shockingly light!" + icon_state = "mw2_russian_para" + item_state = "mw2_russian_para" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/gloves/longblackgloves + name = "Luna's Gauntlets" + desc = "These gloves seem to have a coating of slime fluid on them, you should possibly return them to their rightful owner." + icon_state = "longblackgloves" + item_state = "longblackgloves" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + +/obj/item/clothing/under/trendy_fit + name = "Trendy Fitting Clothing" + desc = "An outfit straight from the boredom of space, its the type of thing only someone trying to entertain themselves on the way to their next destination would wear." + icon_state = "trendy_fit" + item_state = "trendy_fit" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + mutantrace_variation = NO_MUTANTRACE_VARIATION \ No newline at end of file diff --git a/modular_citadel/code/modules/mob/cit_emotes.dm b/modular_citadel/code/modules/mob/cit_emotes.dm index a314baa852..aff1739ae4 100644 --- a/modular_citadel/code/modules/mob/cit_emotes.dm +++ b/modular_citadel/code/modules/mob/cit_emotes.dm @@ -183,6 +183,7 @@ key_third_person = "suddenly hits a dab" message = "suddenly hits a dab!" emote_type = EMOTE_AUDIBLE + restraint_check = TRUE diff --git a/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm b/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm index e552c2cbdd..bf811b777c 100644 --- a/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm +++ b/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm @@ -191,6 +191,32 @@ icon = 'modular_citadel/icons/mob/mam_ears.dmi' color_src = MATRIXED +/datum/sprite_accessory/ears/human/bigwolf + name = "Big Wolf" + icon_state = "bigwolf" + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/ears/human/bigwolfinner + name = "Big Wolf (ALT)" + icon_state = "bigwolfinner" + hasinner = 1 + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/ears/human/bigwolfdark + name = "Dark Big Wolf" + icon_state = "bigwolfdark" + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + +/datum/sprite_accessory/ears/human/bigwolfinnerdark + name = "Dark Big Wolf (ALT)" + icon_state = "bigwolfinnerdark" + hasinner = 1 + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = MATRIXED + /datum/sprite_accessory/ears/human/cow name = "Cow" icon_state = "cow" diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm index 0f71a71add..00063c22d4 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -17,13 +17,13 @@ M.adjustStaminaLoss(-5*REM) . = ..() -/datum/reagent/syndicateadrenals/on_mob_add(mob/living/M) +/datum/reagent/syndicateadrenals/on_mob_metabolize(mob/living/M) . = ..() if(istype(M)) M.next_move_modifier *= 0.5 to_chat(M, "You feel an intense surge of energy rushing through your veins.") -/datum/reagent/syndicateadrenals/on_mob_delete(mob/living/M) +/datum/reagent/syndicateadrenals/on_mob_end_metabolize(mob/living/M) . = ..() if(istype(M)) M.next_move_modifier *= 2 diff --git a/modular_citadel/code/modules/reagents/reagent container/hypovial.dm b/modular_citadel/code/modules/reagents/reagent container/hypovial.dm index a58a7fc825..4b7972d0a7 100755 --- a/modular_citadel/code/modules/reagents/reagent container/hypovial.dm +++ b/modular_citadel/code/modules/reagents/reagent container/hypovial.dm @@ -16,6 +16,7 @@ "purple hypovial" = "hypovial-p", "black hypovial" = "hypovial-t" ) + always_reskinnable = TRUE /obj/item/reagent_containers/glass/bottle/vial/Initialize() . = ..() @@ -29,17 +30,6 @@ /obj/item/reagent_containers/glass/bottle/vial/on_reagent_change() update_icon() -/obj/item/reagent_containers/glass/bottle/vial/reskin_obj(mob/M) //Makes the vials completely reskinnable, and renames them - overrides /obj/proc/reskin_obj - if(!LAZYLEN(unique_reskin)) - return - var/choice = input(M,"Do you wish to recolour your [src]?","Vial Recolour") as null|anything in unique_reskin - if(!QDELETED(src) && choice && !current_skin && !M.incapacitated() && in_range(M,src)) - if(!unique_reskin[choice]) - return - icon_state = unique_reskin[choice] - name = choice - to_chat(M, "[src] is now skinned as '[choice].'") - /obj/item/reagent_containers/glass/bottle/vial/update_icon() cut_overlays() if(reagents.total_volume) diff --git a/modular_citadel/code/modules/research/techweb/all_nodes.dm b/modular_citadel/code/modules/research/techweb/all_nodes.dm index e561b106d8..c0ddaceaf7 100644 --- a/modular_citadel/code/modules/research/techweb/all_nodes.dm +++ b/modular_citadel/code/modules/research/techweb/all_nodes.dm @@ -19,7 +19,7 @@ display_name = "Games and Toys" description = "For the slackers on the station." prereq_ids = list("comptech") - design_ids = list("arcade_battle", "arcade_orion", "slotmachine", "autoylathe") + design_ids = list("arcade_battle", "arcade_orion", "arcade_minesweeper", "slotmachine", "autoylathe") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) export_price = 5000 diff --git a/modular_citadel/code/modules/uplink/uplink_items.dm b/modular_citadel/code/modules/uplink/uplink_items.dm deleted file mode 100644 index df076c3994..0000000000 --- a/modular_citadel/code/modules/uplink/uplink_items.dm +++ /dev/null @@ -1,18 +0,0 @@ -/* -// PUT ALL YOUR NEW UPLINK STUFF HERE, OVERRIDES GO IN HERE TOO -*/ - -/datum/uplink_item/device_tools/emagrecharge - name = "Electromagnet Charging Device" - desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer." - item = /obj/item/emagrecharge - cost = 2 - -/datum/uplink_item/dangerous/revolver - item = /obj/item/gun/ballistic/revolver/syndie - -/datum/uplink_item/dangerous/phantomthief - name = "Syndicate Mask" - desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles" - item = /obj/item/clothing/glasses/phantomthief/syndicate - cost = 2 diff --git a/modular_citadel/icons/mob/clothing/trek_item_icon.dmi b/modular_citadel/icons/mob/clothing/trek_item_icon.dmi deleted file mode 100644 index ed3286615b..0000000000 Binary files a/modular_citadel/icons/mob/clothing/trek_item_icon.dmi and /dev/null differ diff --git a/modular_citadel/icons/mob/muzzled_helmet.dmi b/modular_citadel/icons/mob/muzzled_helmet.dmi index a96f18c3ce..e321f8ae47 100644 Binary files a/modular_citadel/icons/mob/muzzled_helmet.dmi and b/modular_citadel/icons/mob/muzzled_helmet.dmi differ diff --git a/modular_citadel/icons/mob/uniform_digi.dmi b/modular_citadel/icons/mob/uniform_digi.dmi index 9513f82c9c..5ff291f400 100644 Binary files a/modular_citadel/icons/mob/uniform_digi.dmi and b/modular_citadel/icons/mob/uniform_digi.dmi differ diff --git a/modular_citadel/icons/obj/clothing/trek_item_icon.dmi b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi index 86afe16b03..ed3286615b 100644 Binary files a/modular_citadel/icons/obj/clothing/trek_item_icon.dmi and b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi differ diff --git a/modular_citadel/icons/obj/genitals/breasts_onmob.dmi b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi index 69a531bd11..c4b75b1172 100644 Binary files a/modular_citadel/icons/obj/genitals/breasts_onmob.dmi and b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi index 2457759b73..434f171e22 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/genitals/testicles_onmob.dmi b/modular_citadel/icons/obj/genitals/testicles_onmob.dmi index 581bcb0583..33659cf13c 100644 Binary files a/modular_citadel/icons/obj/genitals/testicles_onmob.dmi and b/modular_citadel/icons/obj/genitals/testicles_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/vagina_onmob.dmi b/modular_citadel/icons/obj/genitals/vagina_onmob.dmi index f5daa3fea1..c4cf891eac 100644 Binary files a/modular_citadel/icons/obj/genitals/vagina_onmob.dmi and b/modular_citadel/icons/obj/genitals/vagina_onmob.dmi differ diff --git a/modular_citadel/icons/obj/guns/cit_guns.dmi b/modular_citadel/icons/obj/guns/cit_guns.dmi index 8154a753e0..cc04fbcb14 100644 Binary files a/modular_citadel/icons/obj/guns/cit_guns.dmi and b/modular_citadel/icons/obj/guns/cit_guns.dmi differ diff --git a/modular_citadel/icons/obj/pda.dmi b/modular_citadel/icons/obj/pda.dmi deleted file mode 100644 index 5404b908c6..0000000000 Binary files a/modular_citadel/icons/obj/pda.dmi and /dev/null differ diff --git a/sound/arcade/minesweeper_boardpress.ogg b/sound/arcade/minesweeper_boardpress.ogg new file mode 100644 index 0000000000..a928a7498d Binary files /dev/null and b/sound/arcade/minesweeper_boardpress.ogg differ diff --git a/sound/arcade/minesweeper_emag1.ogg b/sound/arcade/minesweeper_emag1.ogg new file mode 100644 index 0000000000..4601f8df89 Binary files /dev/null and b/sound/arcade/minesweeper_emag1.ogg differ diff --git a/sound/arcade/minesweeper_emag2.ogg b/sound/arcade/minesweeper_emag2.ogg new file mode 100644 index 0000000000..84cb5c2e25 Binary files /dev/null and b/sound/arcade/minesweeper_emag2.ogg differ diff --git a/sound/arcade/minesweeper_explosion1.ogg b/sound/arcade/minesweeper_explosion1.ogg new file mode 100644 index 0000000000..f8272722fd Binary files /dev/null and b/sound/arcade/minesweeper_explosion1.ogg differ diff --git a/sound/arcade/minesweeper_explosion2.ogg b/sound/arcade/minesweeper_explosion2.ogg new file mode 100644 index 0000000000..aabd43851d Binary files /dev/null and b/sound/arcade/minesweeper_explosion2.ogg differ diff --git a/sound/arcade/minesweeper_explosion3.ogg b/sound/arcade/minesweeper_explosion3.ogg new file mode 100644 index 0000000000..22aa309d9d Binary files /dev/null and b/sound/arcade/minesweeper_explosion3.ogg differ diff --git a/sound/arcade/minesweeper_menuselect.ogg b/sound/arcade/minesweeper_menuselect.ogg new file mode 100644 index 0000000000..b9e0b765dc Binary files /dev/null and b/sound/arcade/minesweeper_menuselect.ogg differ diff --git a/sound/arcade/minesweeper_startup.ogg b/sound/arcade/minesweeper_startup.ogg new file mode 100644 index 0000000000..c51d473d60 Binary files /dev/null and b/sound/arcade/minesweeper_startup.ogg differ diff --git a/sound/arcade/minesweeper_win.ogg b/sound/arcade/minesweeper_win.ogg new file mode 100644 index 0000000000..214f1925b0 Binary files /dev/null and b/sound/arcade/minesweeper_win.ogg differ diff --git a/sound/arcade/minesweeper_winfail.ogg b/sound/arcade/minesweeper_winfail.ogg new file mode 100644 index 0000000000..878f153063 Binary files /dev/null and b/sound/arcade/minesweeper_winfail.ogg differ diff --git a/sound/effects/gong.ogg b/sound/effects/gong.ogg new file mode 100644 index 0000000000..4d12f5d0d2 Binary files /dev/null and b/sound/effects/gong.ogg differ diff --git a/sound/magic/RATTLEMEBONES.ogg b/sound/magic/RATTLEMEBONES.ogg new file mode 100644 index 0000000000..d42cf51253 Binary files /dev/null and b/sound/magic/RATTLEMEBONES.ogg differ diff --git a/sound/magic/RATTLEMEBONES2.ogg b/sound/magic/RATTLEMEBONES2.ogg new file mode 100644 index 0000000000..7265a06aab Binary files /dev/null and b/sound/magic/RATTLEMEBONES2.ogg differ diff --git a/sound/weapons/whipgrab.ogg b/sound/weapons/whipgrab.ogg new file mode 100644 index 0000000000..3b17632056 Binary files /dev/null and b/sound/weapons/whipgrab.ogg differ diff --git a/strings/cas_black.txt b/strings/cas_black.txt index b63e33cdf2..734222d1fd 100644 --- a/strings/cas_black.txt +++ b/strings/cas_black.txt @@ -1,13 +1,13 @@ Today, Security killed ____. Security, the clown's breaking into ____. -The Chaplain is worshiping the Church of _____. +Our last Chaplain believed in nothing but _____. What angered the gods this time? Why didn't engineering set up the singularity? What does the traitor steal this time? Cargo: There's a galaxy-wide shortage of _______. I don't care what they called me back on the station, I'm not a traitor. I'm a man of _________. The Syndicate is offering crew members _________ to defect. -Cargo ordered a crate full of _____. +What is Nanotrasen's highest-priority bounty? What is the gray tide protesting this time? If the Space Gods didn't want _________ they wouldn't have given us __________. Why was the death squad sent in? @@ -30,11 +30,10 @@ What made the nuclear operatives fluke? Why did the Chief Engineer disable comms? Every spaceman receives an internals box and ________. What brought the space orgy to a grinding halt? -Scientists are no longer allowed to make _____. +Scientists are no longer allowed to make ______. What was the clown's best joke? The HoP is now hiring assistants for __________. What happens when you emag an emag? -Our gang doesn't wear uniforms. Our gang wears ___________. No matter how many lizards you have, _____ is never acceptable. No, the AI's second law is NOT to serve _____. First CentCom came for the ________. Now they're coming for the __________. @@ -109,5 +108,12 @@ The auxiliary base was disabled after landing in the middle of _______. Xenobiologists have found slimes to be exceptionally responsive to _______. Why did the captain give me a medal? The curator's new exhibit is devoted solely to _________. -There's no ______ on the new escape shuttle, but there is plenty of _________! -What made me sell my soul to the devil? \ No newline at end of file +What made me sell my soul to the devil? +The engineers are testing an experimental supermatter setup involving _________. +I'm __________ in the streets, __________ in the sheets. +What's my family heirloom? +The Lawyer was fired for messaging the entire station a picture of ___________. +On Lavaland, it is rumored that ashwalkers roam, worshipping _________. +How did the traitor die a glorious death? +Nanotrasen's new state-of-the-art emergency shuttle was repurposed from _________ and _________. +What caused my brain trauma? \ No newline at end of file diff --git a/strings/cas_white.txt b/strings/cas_white.txt index 8cf224d1db..3e229862a2 100644 --- a/strings/cas_white.txt +++ b/strings/cas_white.txt @@ -2,6 +2,7 @@ Those motherfucking carp. Having sex in the maintenance tunnels. Space 'Nam. Space lesbians. +Space NEETs. Space Hitler. Space Asshole. Ragin' mages. @@ -57,7 +58,6 @@ Defusing a syndicate bomb with another bomb. Going braindead mid-murder. A petsplosion. Meat spikes. -Collecting the crew's brains. Lopping off the Captain's johnson and shooting it out a pneumatic cannon. The secret monkey technique. Putting the pAI's doorjack where it don't belong. @@ -84,7 +84,6 @@ Paranoia. Putting the boots to him, medium style. ERP-seeking meteors. Paperwork HoPs. -A sexy clown. Rampant vending machines. The prisoner transfer center. Nations. @@ -186,7 +185,6 @@ A big, black shadowling dick. Emagging. Dead lizard storage. Dermal armor. -Energy balls. Fisting somebody until they gib. Alternate uses for defibrillator paddles. Breaking spacetime with thousands of bluespace tomatoes. @@ -197,7 +195,7 @@ Plasmaman strippers. A Quartermaster who WON'T STOP ordering guns. Space lag. Polishing the captain's laser rifle. -That one asshole double agent. +That one asshole nuke op. A surprise visit from Nanotrasen's CEO. The bleeding, dismembered, beautiful corpse of the clown. A glass of ...what? @@ -220,20 +218,18 @@ Welderbombing. Validhunting. Nar'Sie making love to Lord Singulo. Fun. -Crashing the stock market. HONK! -Enough morphine to put the entire station down. +Enough morphine to make the entire station comatose. A defective comdom. Cleanbot. A beaker of dried space carp penis. An Ian storm. -voxtest2. Nuking it from orbit. My senpAI. Harmbatonning. A Nanotrasen D-Notice. TALKING MIMES. -The lusty xenomorph maid, +The lusty xenomorph maid. Using assistants as human shields. Sentient securitrons. Piloting the station into the nearest sun. @@ -247,11 +243,11 @@ Medbay stutterwhores. The scrubbers uncontrollably spewing cum. The lawyer's job. Emoting slowly drawing a gun, then slowly cocking the trigger, then slowly preparing to shoot... -NAR-SIE HAS RISEN. +NAR'SIE HAS RISEN. Pierrot's Throat. A clown bomb. Space bees? -The entire engineering team having unprotected group sex. +Driving the clown car full speed into the engine. IC in OOC. The best cookie. The wizard with his staff inserted into his anus. @@ -276,9 +272,8 @@ Draconic. Riding borgs, cowgirl style. The Voice of God. Overpowered stuns. -Unironically reading library smut. +Unironically enjoying library smut. Spiritual journeys with BZ. -Freon. Deep-fried body parts. Suit sensor unit gas chambers. Moonlighting. @@ -294,4 +289,14 @@ Mindswap. Potassium in the toilet bowls. Giving head to the heads. A lizard wearing cat ears. -DOOR STUCK!! +Precious clown gold. +Dabbing on a pile of corpses. +Tactical chairs. +The sweet, forbidden meat of the gondola. +Turning tricks for holocredits. +A captain that doesn't secure the disk. +A positive moodlet. +A sexy clown. +Razoring the wings off the moths. +Wiring the ethereals into the powernet. +Well-aged miasma. \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 341497cb5c..99447ea789 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -130,6 +130,7 @@ #include "code\__HELPERS\qdel.dm" #include "code\__HELPERS\radiation.dm" #include "code\__HELPERS\radio.dm" +#include "code\__HELPERS\reagents.dm" #include "code\__HELPERS\roundend.dm" #include "code\__HELPERS\sanitize_values.dm" #include "code\__HELPERS\shell.dm" @@ -247,7 +248,6 @@ #include "code\controllers\subsystem\moods.dm" #include "code\controllers\subsystem\nightshift.dm" #include "code\controllers\subsystem\npcpool.dm" -#include "code\controllers\subsystem\orbit.dm" #include "code\controllers\subsystem\overlays.dm" #include "code\controllers\subsystem\pai.dm" #include "code\controllers\subsystem\parallax.dm" @@ -256,7 +256,6 @@ #include "code\controllers\subsystem\ping.dm" #include "code\controllers\subsystem\radiation.dm" #include "code\controllers\subsystem\radio.dm" -#include "code\controllers\subsystem\religion.dm" #include "code\controllers\subsystem\research.dm" #include "code\controllers\subsystem\server_maint.dm" #include "code\controllers\subsystem\shuttle.dm" @@ -360,6 +359,7 @@ #include "code\datums\components\mood.dm" #include "code\datums\components\nanites.dm" #include "code\datums\components\ntnet_interface.dm" +#include "code\datums\components\orbiter.dm" #include "code\datums\components\paintable.dm" #include "code\datums\components\rad_insulation.dm" #include "code\datums\components\radioactive.dm" @@ -494,6 +494,7 @@ #include "code\datums\wires\autolathe.dm" #include "code\datums\wires\emitter.dm" #include "code\datums\wires\explosive.dm" +#include "code\datums\wires\microwave.dm" #include "code\datums\wires\mulebot.dm" #include "code\datums\wires\particle_accelerator.dm" #include "code\datums\wires\r_n_d.dm" @@ -638,6 +639,10 @@ #include "code\game\machinery\computer\station_alert.dm" #include "code\game\machinery\computer\telecrystalconsoles.dm" #include "code\game\machinery\computer\teleporter.dm" +#include "code\game\machinery\computer\arcade\battle.dm" +#include "code\game\machinery\computer\arcade\minesweeper.dm" +#include "code\game\machinery\computer\arcade\misc_arcade.dm" +#include "code\game\machinery\computer\arcade\orion_trail.dm" #include "code\game\machinery\doors\airlock.dm" #include "code\game\machinery\doors\airlock_electronics.dm" #include "code\game\machinery\doors\airlock_types.dm" @@ -1236,6 +1241,7 @@ #include "code\modules\antagonists\clockcult\clock_structures\mania_motor.dm" #include "code\modules\antagonists\clockcult\clock_structures\ocular_warden.dm" #include "code\modules\antagonists\clockcult\clock_structures\ratvar_the_clockwork_justicar.dm" +#include "code\modules\antagonists\clockcult\clock_structures\reflector.dm" #include "code\modules\antagonists\clockcult\clock_structures\stargazer.dm" #include "code\modules\antagonists\clockcult\clock_structures\taunting_trail.dm" #include "code\modules\antagonists\clockcult\clock_structures\wall_gear.dm" @@ -2124,6 +2130,7 @@ #include "code\modules\mob\living\simple_animal\friendly\gondola.dm" #include "code\modules\mob\living\simple_animal\friendly\lizard.dm" #include "code\modules\mob\living\simple_animal\friendly\mouse.dm" +#include "code\modules\mob\living\simple_animal\friendly\panda.dm" #include "code\modules\mob\living\simple_animal\friendly\penguin.dm" #include "code\modules\mob\living\simple_animal\friendly\pet.dm" #include "code\modules\mob\living\simple_animal\friendly\sloth.dm" @@ -2285,7 +2292,6 @@ #include "code\modules\NTNet\network.dm" #include "code\modules\NTNet\relays.dm" #include "code\modules\NTNet\services\_service.dm" -#include "code\modules\orbit\orbit.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\contract.dm" #include "code\modules\paperwork\filingcabinet.dm" @@ -2501,6 +2507,7 @@ #include "code\modules\reagents\chemistry\recipes\others.dm" #include "code\modules\reagents\chemistry\recipes\pyrotechnics.dm" #include "code\modules\reagents\chemistry\recipes\slime_extracts.dm" +#include "code\modules\reagents\chemistry\recipes\special.dm" #include "code\modules\reagents\chemistry\recipes\toxins.dm" #include "code\modules\reagents\reagent_containers\blood_pack.dm" #include "code\modules\reagents\reagent_containers\borghydro.dm" @@ -2794,6 +2801,7 @@ #include "code\modules\vehicles\speedbike.dm" #include "code\modules\vehicles\vehicle_actions.dm" #include "code\modules\vehicles\vehicle_key.dm" +#include "code\modules\vehicles\wheelchair.dm" #include "code\modules\vehicles\cars\car.dm" #include "code\modules\vehicles\cars\clowncar.dm" #include "code\modules\vending\_vending.dm" @@ -2845,7 +2853,6 @@ #include "modular_citadel\code\controllers\configuration\entries\general.dm" #include "modular_citadel\code\controllers\subsystem\job.dm" #include "modular_citadel\code\controllers\subsystem\shuttle.dm" -#include "modular_citadel\code\datums\uplink_items_cit.dm" #include "modular_citadel\code\datums\components\material_container.dm" #include "modular_citadel\code\datums\components\phantomthief.dm" #include "modular_citadel\code\datums\components\souldeath.dm" @@ -2900,8 +2907,6 @@ #include "modular_citadel\code\game\objects\items\vending_items.dm" #include "modular_citadel\code\game\objects\items\circuitboards\machine_circuitboards.dm" #include "modular_citadel\code\game\objects\items\devices\aicard.dm" -#include "modular_citadel\code\game\objects\items\devices\flashlight.dm" -#include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" #include "modular_citadel\code\game\objects\items\devices\radio\encryptionkey.dm" #include "modular_citadel\code\game\objects\items\devices\radio\headset.dm" #include "modular_citadel\code\game\objects\items\devices\radio\shockcollar.dm" @@ -3056,7 +3061,6 @@ #include "modular_citadel\code\modules\research\techweb\_techweb.dm" #include "modular_citadel\code\modules\research\techweb\all_nodes.dm" #include "modular_citadel\code\modules\research\xenobiology\xenobio_camera.dm" -#include "modular_citadel\code\modules\uplink\uplink_items.dm" #include "modular_citadel\code\modules\vehicles\secway.dm" #include "modular_citadel\code\modules\vore\hook-defs_vr.dm" #include "modular_citadel\code\modules\vore\persistence.dm" |