diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm
index 6feb378515..eab08815f3 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm
@@ -227,7 +227,7 @@
/area/ruin/unpowered/xenonest)
"ba" = (
/obj/structure/stone_tile/slab,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bb" = (
/obj/structure/stone_tile/cracked{
@@ -241,7 +241,7 @@
dir = 8
},
/obj/item/flashlight/lantern,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bc" = (
/obj/structure/stone_tile/block,
@@ -251,7 +251,7 @@
/obj/structure/stone_tile{
dir = 4
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bd" = (
/obj/structure/stone_tile/block,
@@ -262,7 +262,7 @@
dir = 1
},
/obj/effect/decal/cleanable/blood/xeno,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"be" = (
/obj/structure/stone_tile/block,
@@ -272,7 +272,7 @@
/obj/structure/stone_tile{
dir = 1
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bf" = (
/obj/structure/stone_tile,
@@ -286,7 +286,7 @@
dir = 4
},
/obj/item/flashlight/lantern,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bg" = (
/obj/structure/alien/weeds,
@@ -303,7 +303,7 @@
/obj/structure/stone_tile{
dir = 8
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bi" = (
/obj/structure/alien/weeds,
@@ -336,11 +336,11 @@
dir = 1
},
/obj/structure/stone_tile,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bm" = (
/obj/structure/stone_tile/slab/cracked,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bn" = (
/obj/structure/stone_tile/block{
@@ -352,7 +352,7 @@
/obj/structure/stone_tile{
dir = 4
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bo" = (
/obj/structure/stone_tile/surrounding_tile{
@@ -383,7 +383,7 @@
dir = 1
},
/obj/effect/decal/cleanable/blood/xeno,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bs" = (
/obj/structure/stone_tile/block{
@@ -416,7 +416,7 @@
dir = 1
},
/obj/structure/stone_tile/cracked,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bw" = (
/obj/structure/stone_tile/cracked{
@@ -430,7 +430,7 @@
dir = 8
},
/obj/item/flashlight/lantern,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bx" = (
/obj/structure/stone_tile/block{
@@ -441,7 +441,7 @@
dir = 8
},
/obj/effect/decal/cleanable/blood/xeno,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"by" = (
/obj/structure/stone_tile/block{
@@ -451,7 +451,7 @@
/obj/structure/stone_tile/cracked{
dir = 8
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bz" = (
/obj/structure/stone_tile/block/cracked{
@@ -461,7 +461,7 @@
/obj/structure/stone_tile{
dir = 8
},
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bA" = (
/obj/structure/stone_tile/cracked{
@@ -475,7 +475,7 @@
},
/obj/structure/stone_tile,
/obj/item/flashlight/lantern,
-/turf/open/indestructible/boss/air,
+/turf/open/indestructible/boss,
/area/ruin/unpowered/xenonest)
"bB" = (
/obj/structure/alien/weeds,
diff --git a/_maps/RandomRuins/SpaceRuins/arcade.dmm b/_maps/RandomRuins/SpaceRuins/arcade.dmm
index 74bdc9a7b8..c68d3b224e 100644
--- a/_maps/RandomRuins/SpaceRuins/arcade.dmm
+++ b/_maps/RandomRuins/SpaceRuins/arcade.dmm
@@ -3,7 +3,7 @@
/turf/template_noop,
/area/template_noop)
"b" = (
-/turf/open/floor/plating/asteroid,
+/turf/open/floor/plating/asteroid/airless,
/area/ruin/powered)
"c" = (
/turf/closed/mineral/random/high_chance,
@@ -135,7 +135,7 @@
/area/ruin/powered)
"F" = (
/obj/structure/closet/crate/trashcart,
-/turf/open/floor/plating/asteroid,
+/turf/open/floor/plating/asteroid/airless,
/area/ruin/powered)
"G" = (
/obj/structure/chair/sofa/right,
diff --git a/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm b/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm
index e23beb3407..2a25a3b6e7 100644
--- a/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm
+++ b/_maps/RandomRuins/SpaceRuins/augmentationfacility.dmm
@@ -3,7 +3,7 @@
/turf/template_noop,
/area/template_noop)
"b" = (
-/turf/open/floor/plating/asteroid,
+/turf/open/floor/plating/asteroid/airless,
/area/ruin/powered)
"c" = (
/turf/closed/mineral/random/high_chance,
@@ -176,8 +176,8 @@
/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....";
+ name = "rusted autosurgeon";
uses = 1
},
/turf/open/floor/plasteel,
@@ -205,7 +205,7 @@
/obj/machinery/atmospherics/components/unary/outlet_injector/on/layer1{
dir = 4
},
-/turf/open/floor/plating/asteroid,
+/turf/open/floor/plating/asteroid/airless,
/area/ruin/powered)
"K" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{
diff --git a/_maps/RandomRuins/SpaceRuinsStation/roid6.dmm b/_maps/RandomRuins/SpaceRuinsStation/roid6.dmm
index 56967b0c37..1bc497d4f9 100644
--- a/_maps/RandomRuins/SpaceRuinsStation/roid6.dmm
+++ b/_maps/RandomRuins/SpaceRuinsStation/roid6.dmm
@@ -80,7 +80,7 @@
/obj/item/shard{
icon_state = "medium"
},
-/turf/open/floor/plating/airless{
+/turf/open/floor/plating{
icon_state = "platingdmg2"
},
/area/ruin/space/has_grav)
diff --git a/_maps/RandomZLevels/VR/murderdome.dmm b/_maps/RandomZLevels/VR/murderdome.dmm
index 740f9fd09f..5b5cbbfcfe 100644
--- a/_maps/RandomZLevels/VR/murderdome.dmm
+++ b/_maps/RandomZLevels/VR/murderdome.dmm
@@ -232,7 +232,9 @@
/area/awaymission/vr/murderdome)
"H" = (
/obj/machinery/telecomms/allinone,
-/turf/open/indestructible,
+/turf/open/indestructible{
+ initial_gas_mix = "TEMP=2.7"
+ },
/area/awaymission/vr/murderdome)
"R" = (
/obj/effect/spawner/structure/window/reinforced/indestructable,
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 9877f5b259..f9ff2a594c 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -5103,7 +5103,7 @@
/area/security/main)
"ajv" = (
/obj/machinery/computer/med_data{
- dir = 3
+ dir = 4
},
/obj/structure/sign/poster/official/medical_green_cross{
pixel_x = -32
@@ -30888,7 +30888,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"bvH" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
@@ -53679,9 +53679,6 @@
},
/turf/open/floor/mineral/titanium/blue,
/area/crew_quarters/toilet)
-"dVU" = (
-/turf/open/floor/plating,
-/area/space/nearstation)
"dXq" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
@@ -53734,7 +53731,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 6
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"egt" = (
/obj/effect/turf_decal/tile/bar,
@@ -54363,7 +54360,7 @@
"fIs" = (
/obj/structure/grille,
/obj/structure/lattice,
-/turf/open/floor/plating,
+/turf/open/space/basic,
/area/space/nearstation)
"fJY" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
@@ -54521,19 +54518,6 @@
},
/turf/open/floor/carpet,
/area/crew_quarters/cryopod)
-"ghq" = (
-/obj/structure/lattice/catwalk,
-/obj/item/stack/marker_beacon{
- anchored = 1;
- icon_state = "markerburgundy-on";
- light_color = "#FA644B";
- light_power = 3;
- light_range = 3;
- name = "Docking Beacon";
- picked_color = "Burgundy"
- },
-/turf/open/floor/plating,
-/area/space/nearstation)
"ghD" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel,
@@ -54690,7 +54674,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 9
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"gJi" = (
/obj/structure/lattice/catwalk,
@@ -54926,7 +54910,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 10
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"hxn" = (
/obj/effect/spawner/structure/window/reinforced,
@@ -57288,7 +57272,7 @@
/area/crew_quarters/theatre)
"oyN" = (
/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"oyX" = (
/obj/machinery/atmospherics/components/binary/pump/on{
@@ -58127,7 +58111,7 @@
dir = 5
},
/obj/machinery/camera{
- c_tag = "Bar Backroom"
+ c_tag = "Gravity Generator - Fore"
},
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
@@ -58410,7 +58394,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 8
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"slk" = (
/obj/machinery/door/airlock/maintenance{
@@ -58667,9 +58651,6 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/closed/wall/r_wall,
/area/engine/engine_smes)
-"sQX" = (
-/turf/open/floor/plating,
-/area/space)
"sRH" = (
/obj/machinery/autolathe/secure{
name = "public autolathe"
@@ -58786,7 +58767,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 5
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"trb" = (
/obj/machinery/light{
@@ -59009,7 +58990,7 @@
/area/hallway/primary/central)
"uaw" = (
/obj/machinery/power/apc{
- areastring = "/area/storage/art";
+ areastring = "/area/maintenance/bar";
dir = 1;
name = "Maint bar";
pixel_y = 24
@@ -59422,7 +59403,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 4
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"vbi" = (
/obj/structure/table,
@@ -60521,7 +60502,7 @@
name = "Docking Beacon";
picked_color = "Burgundy"
},
-/turf/open/space/basic,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"xOx" = (
/obj/structure/chair/comfy/brown{
@@ -66754,11 +66735,11 @@ aaa
aaa
aaa
aaa
-ghq
+xLX
aaa
aaa
aaa
-ghq
+xLX
aaa
aaa
aaa
@@ -67005,9 +66986,9 @@ aaa
aaa
aaa
aaa
-ghq
+xLX
aaa
-ghq
+xLX
aaa
aaa
aaa
@@ -67019,9 +67000,9 @@ gXs
aaa
aaa
aaa
-ghq
+xLX
aaa
-ghq
+xLX
aaa
aaa
aaa
@@ -76570,7 +76551,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -76827,7 +76808,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -77084,7 +77065,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -77341,7 +77322,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -77598,7 +77579,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -77855,7 +77836,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aaa
aaa
@@ -78112,7 +78093,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aoV
bZm
@@ -78369,13 +78350,13 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aoV
bVz
aaf
aaf
-sQX
+aoV
aaa
aaS
aaf
@@ -78626,7 +78607,7 @@ aaa
aaa
aaa
aaa
-aag
+aaa
aaa
aag
bVz
@@ -78883,7 +78864,7 @@ aaa
aaa
aaa
aaa
-aag
+gJi
aaa
aaf
bVz
@@ -79140,7 +79121,7 @@ aaa
aaa
aaa
aaa
-aag
+gJi
aaa
aaf
bVz
@@ -84190,7 +84171,7 @@ aaa
aaa
gXs
gXs
-dVU
+aaH
abc
abu
abu
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index fbd4c1bf39..6415c984bf 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -32681,6 +32681,10 @@
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
+/obj/machinery/light{
+ dir = 1;
+ light_color = "#cee5d2"
+ },
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat/foyer)
"blC" = (
@@ -36118,13 +36122,9 @@
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
"bsf" = (
-/obj/machinery/light,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat/foyer)
"bsg" = (
@@ -37682,16 +37682,10 @@
/turf/closed/wall,
/area/aisat)
"bvu" = (
-/obj/structure/table/wood,
/obj/machinery/light/small{
dir = 8
},
-/obj/item/radio/off{
- pixel_y = 4
- },
-/obj/item/screwdriver{
- pixel_y = 10
- },
+/obj/machinery/announcement_system,
/turf/open/floor/plasteel/grimy,
/area/tcommsat/computer)
"bvv" = (
@@ -40188,12 +40182,15 @@
/area/tcommsat/computer)
"bAW" = (
/obj/structure/table/wood,
-/obj/item/folder/blue,
/obj/machinery/status_display/evac{
pixel_y = 31
},
-/obj/item/folder/blue,
-/obj/item/pen,
+/obj/item/radio/off{
+ pixel_y = 4
+ },
+/obj/item/screwdriver{
+ pixel_y = 10
+ },
/turf/open/floor/plasteel/grimy,
/area/tcommsat/computer)
"bAX" = (
@@ -42716,9 +42713,12 @@
/turf/open/floor/carpet,
/area/crew_quarters/theatre)
"bGh" = (
-/obj/machinery/announcement_system,
-/turf/open/floor/plasteel/grimy,
-/area/tcommsat/computer)
+/obj/effect/turf_decal/tile/blue,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/plasteel/dark,
+/area/ai_monitored/turret_protected/aisat/foyer)
"bGj" = (
/obj/machinery/vending/cola/random,
/obj/machinery/newscaster{
@@ -81595,6 +81595,10 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/port)
+"jQK" = (
+/obj/structure/lattice,
+/turf/closed/wall/r_wall,
+/area/aisat)
"jRo" = (
/obj/structure/table/wood,
/obj/machinery/newscaster{
@@ -81912,6 +81916,16 @@
/obj/machinery/door/firedoor,
/turf/open/floor/plasteel,
/area/hallway/primary/port)
+"nix" = (
+/obj/machinery/light/small{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/blue,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/turf/open/floor/plasteel/dark,
+/area/ai_monitored/turret_protected/aisat/foyer)
"njd" = (
/obj/machinery/atmospherics/components/binary/pump{
dir = 8;
@@ -82580,6 +82594,13 @@
},
/turf/open/floor/plating,
/area/maintenance/starboard)
+"txh" = (
+/obj/machinery/door/airlock/hatch{
+ name = "Telecomms Control Room";
+ req_one_access_txt = "19; 61"
+ },
+/turf/open/floor/plasteel/dark,
+/area/tcommsat/computer)
"txj" = (
/obj/structure/chair/office/light{
dir = 1
@@ -136361,9 +136382,9 @@ bnw
bpJ
brW
aRy
-bvt
-aaa
-aTU
+aRy
+aRy
+jQK
aaa
aaa
aaa
@@ -136617,9 +136638,9 @@ blC
bnx
bpK
bsf
-aRy
-aRy
-aRy
+bGh
+nix
+bGh
aRy
aRy
aRy
@@ -136876,7 +136897,7 @@ bpL
brY
btL
btL
-btL
+txh
btL
btL
bCD
@@ -137133,7 +137154,7 @@ bpM
brZ
btL
bvu
-bGh
+bxq
bzn
bAU
bCD
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index f11815b537..29be428d66 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -334,8 +334,8 @@
/area/crew_quarters/fitness/pool)
"aaM" = (
/turf/open/floor/plasteel/yellowsiding/corner{
- icon_state = "yellowcornersiding";
- dir = 8
+ dir = 8;
+ icon_state = "yellowcornersiding"
},
/area/crew_quarters/fitness/pool)
"aaN" = (
@@ -354,8 +354,8 @@
/area/crew_quarters/fitness/pool)
"aaP" = (
/turf/open/floor/plasteel/yellowsiding{
- icon_state = "yellowsiding";
- dir = 8
+ dir = 8;
+ icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"aaQ" = (
@@ -433,8 +433,8 @@
/area/crew_quarters/fitness/pool)
"aaW" = (
/turf/open/floor/plasteel/yellowsiding{
- icon_state = "yellowsiding";
- dir = 1
+ dir = 1;
+ icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"aaX" = (
@@ -550,8 +550,8 @@
"abm" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel/yellowsiding{
- icon_state = "yellowsiding";
- dir = 4
+ dir = 4;
+ icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abn" = (
@@ -580,8 +580,8 @@
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel/yellowsiding{
- icon_state = "yellowsiding";
- dir = 4
+ dir = 4;
+ icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abr" = (
@@ -595,8 +595,8 @@
"abt" = (
/obj/structure/pool/Rboard,
/turf/open/floor/plasteel/yellowsiding{
- icon_state = "yellowsiding";
- dir = 8
+ dir = 8;
+ icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abu" = (
@@ -659,8 +659,8 @@
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel/yellowsiding/corner{
- icon_state = "yellowcornersiding";
- dir = 4
+ dir = 4;
+ icon_state = "yellowcornersiding"
},
/area/crew_quarters/fitness/pool)
"abB" = (
@@ -670,21 +670,21 @@
pixel_y = -27
},
/turf/open/floor/plasteel/yellowsiding{
- icon_state = "yellowsiding";
- dir = 1
+ dir = 1;
+ icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abC" = (
/obj/machinery/light,
/turf/open/floor/plasteel/yellowsiding{
- icon_state = "yellowsiding";
- dir = 1
+ dir = 1;
+ icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abD" = (
/turf/open/floor/plasteel/yellowsiding/corner{
- icon_state = "yellowcornersiding";
- dir = 1
+ dir = 1;
+ icon_state = "yellowcornersiding"
},
/area/crew_quarters/fitness/pool)
"abE" = (
@@ -6313,27 +6313,7 @@
"aoz" = (
/turf/closed/wall,
/area/maintenance/fore)
-"aoA" = (
-/obj/machinery/gateway{
- dir = 9
- },
-/obj/effect/turf_decal/bot_white/right,
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/turf/open/floor/plasteel/dark,
-/area/gateway)
"aoB" = (
-/obj/machinery/gateway{
- dir = 1
- },
/obj/machinery/light{
dir = 1
},
@@ -6350,23 +6330,6 @@
},
/turf/open/floor/plasteel/dark,
/area/gateway)
-"aoC" = (
-/obj/machinery/gateway{
- dir = 5
- },
-/obj/effect/turf_decal/bot_white/left,
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/turf/open/floor/plasteel/dark,
-/area/gateway)
"aoH" = (
/obj/structure/lattice,
/obj/structure/grille,
@@ -6692,44 +6655,10 @@
},
/turf/open/space,
/area/space/nearstation)
-"apq" = (
-/obj/machinery/gateway{
- dir = 8
- },
-/obj/effect/turf_decal/bot_white,
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/turf/open/floor/plasteel/dark,
-/area/gateway)
"apr" = (
/obj/machinery/gateway/centerstation,
/turf/open/floor/plasteel/dark,
/area/gateway)
-"aps" = (
-/obj/machinery/gateway{
- dir = 4
- },
-/obj/effect/turf_decal/bot_white,
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/turf/open/floor/plasteel/dark,
-/area/gateway)
"apt" = (
/obj/structure/chair{
dir = 4
@@ -6916,9 +6845,6 @@
/turf/closed/wall/r_wall,
/area/ai_monitored/nuke_storage)
"apU" = (
-/obj/machinery/gateway{
- dir = 10
- },
/obj/effect/turf_decal/bot_white/left,
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -6933,7 +6859,6 @@
/turf/open/floor/plasteel/dark,
/area/gateway)
"apV" = (
-/obj/machinery/gateway,
/obj/effect/turf_decal/bot_white,
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -6948,9 +6873,6 @@
/turf/open/floor/plasteel/dark,
/area/gateway)
"apW" = (
-/obj/machinery/gateway{
- dir = 6
- },
/obj/effect/turf_decal/bot_white/right,
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -7876,32 +7798,7 @@
/turf/open/floor/plasteel,
/area/gateway)
"arY" = (
-/obj/structure/closet/crate/internals,
-/obj/item/clothing/suit/hazardvest{
- desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
- name = "emergency lifejacket"
- },
-/obj/item/clothing/suit/hazardvest{
- desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
- name = "emergency lifejacket"
- },
-/obj/item/clothing/suit/hazardvest{
- desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
- name = "emergency lifejacket"
- },
-/obj/item/clothing/suit/hazardvest{
- desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
- name = "emergency lifejacket"
- },
-/obj/item/clothing/suit/hazardvest{
- desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
- name = "emergency lifejacket"
- },
-/obj/item/flashlight,
-/obj/item/flashlight,
-/obj/item/flashlight,
-/obj/item/flashlight,
-/obj/item/flashlight,
+/obj/machinery/computer/gateway_control,
/turf/open/floor/plasteel,
/area/gateway)
"arZ" = (
@@ -8904,6 +8801,32 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
},
+/obj/structure/closet/crate/internals,
+/obj/item/clothing/suit/hazardvest{
+ desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
+ name = "emergency lifejacket"
+ },
+/obj/item/clothing/suit/hazardvest{
+ desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
+ name = "emergency lifejacket"
+ },
+/obj/item/clothing/suit/hazardvest{
+ desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
+ name = "emergency lifejacket"
+ },
+/obj/item/clothing/suit/hazardvest{
+ desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
+ name = "emergency lifejacket"
+ },
+/obj/item/clothing/suit/hazardvest{
+ desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks.";
+ name = "emergency lifejacket"
+ },
+/obj/item/flashlight,
+/obj/item/flashlight,
+/obj/item/flashlight,
+/obj/item/flashlight,
+/obj/item/flashlight,
/turf/open/floor/plasteel,
/area/gateway)
"auh" = (
@@ -39042,7 +38965,6 @@
/area/chapel/dock)
"bKe" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on,
-/obj/structure/closet/emcloset,
/turf/open/floor/plasteel/white{
heat_capacity = 1e+006
},
@@ -40077,12 +39999,6 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 8
},
-/obj/machinery/light/small{
- dir = 4
- },
-/obj/structure/chair{
- dir = 1
- },
/turf/open/floor/plasteel/white{
heat_capacity = 1e+006
},
@@ -47273,7 +47189,7 @@
"ceT" = (
/obj/effect/turf_decal/stripes/line,
/obj/structure/closet/emcloset,
-/turf/open/floor/plating/airless,
+/turf/open/floor/plating,
/area/engine/engineering)
"ceU" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
@@ -50404,9 +50320,11 @@
/turf/open/floor/plasteel,
/area/crew_quarters/heads/chief)
"cqW" = (
-/obj/effect/spawner/structure/window/reinforced,
-/turf/closed/mineral,
-/area/chapel/asteroid/monastery)
+/obj/structure/chair,
+/turf/open/floor/plasteel/white{
+ heat_capacity = 1e+006
+ },
+/area/chapel/dock)
"cqX" = (
/obj/structure/disposalpipe/segment,
/obj/structure/lattice,
@@ -52993,7 +52911,7 @@
/turf/open/floor/plasteel/dark,
/area/security/main)
"cCT" = (
-/obj/machinery/rnd/production/protolathe/department/cargo,
+/obj/machinery/rnd/production/techfab/department/cargo,
/turf/open/floor/plasteel,
/area/quartermaster/storage)
"cCU" = (
@@ -55664,11 +55582,11 @@
/turf/open/floor/plating,
/area/crew_quarters/dorms)
"izF" = (
-/turf/open/floor/plating{
- initial_gas_mix = "o2=0.01;n2=0.01";
- luminosity = 2
+/obj/structure/closet/emcloset,
+/turf/open/floor/plasteel/white{
+ heat_capacity = 1e+006
},
-/area/maintenance/department/science)
+/area/chapel/dock)
"iAx" = (
/obj/structure/cable{
icon_state = "4-8"
@@ -57738,10 +57656,7 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 6
},
-/turf/open/floor/plating{
- initial_gas_mix = "o2=0.01;n2=0.01";
- luminosity = 2
- },
+/turf/open/floor/plating,
/area/maintenance/department/science)
"nAs" = (
/obj/machinery/door/airlock/engineering/glass{
@@ -57904,7 +57819,7 @@
/obj/structure/disposalpipe/trunk{
dir = 8
},
-/turf/open/floor/plating,
+/turf/open/floor/plating/airless,
/area/space/nearstation)
"nOY" = (
/obj/effect/turf_decal/stripes/line{
@@ -58007,10 +57922,7 @@
/obj/structure/table,
/obj/item/paper_bin,
/obj/item/pen,
-/turf/open/floor/plating{
- initial_gas_mix = "o2=0.01;n2=0.01";
- luminosity = 2
- },
+/turf/open/floor/plating,
/area/maintenance/department/science)
"odM" = (
/obj/effect/landmark/barthpot,
@@ -59532,14 +59444,13 @@
/turf/open/floor/plating/airless,
/area/space/nearstation)
"ros" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+/obj/machinery/light/small{
dir = 4
},
-/turf/open/floor/plating{
- initial_gas_mix = "o2=0.01;n2=0.01";
- luminosity = 2
+/turf/open/floor/plasteel/white{
+ heat_capacity = 1e+006
},
-/area/maintenance/department/science)
+/area/chapel/dock)
"rrb" = (
/obj/structure/cable{
icon_state = "1-2"
@@ -60667,10 +60578,7 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 9
},
-/turf/open/floor/plating{
- initial_gas_mix = "o2=0.01;n2=0.01";
- luminosity = 2
- },
+/turf/open/floor/plating,
/area/maintenance/department/science)
"uos" = (
/obj/machinery/computer/camera_advanced/base_construction,
@@ -61099,13 +61007,6 @@
/obj/structure/lattice,
/turf/open/space/basic,
/area/space/nearstation)
-"vpz" = (
-/obj/structure/girder,
-/turf/open/floor/plating{
- initial_gas_mix = "o2=0.01;n2=0.01";
- luminosity = 2
- },
-/area/maintenance/department/science)
"vsk" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -61620,12 +61521,6 @@
},
/turf/open/floor/plating,
/area/maintenance/department/crew_quarters/bar)
-"wDe" = (
-/obj/effect/spawner/structure/window/reinforced,
-/turf/open/floor/plasteel/white{
- heat_capacity = 1e+006
- },
-/area/chapel/dock)
"wDl" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/turf_decal/stripes/corner,
@@ -62038,10 +61933,7 @@
/area/maintenance/department/science)
"xsO" = (
/obj/item/ectoplasm,
-/turf/open/floor/plating{
- initial_gas_mix = "o2=0.01;n2=0.01";
- luminosity = 2
- },
+/turf/open/floor/plating,
/area/maintenance/department/science)
"xuv" = (
/obj/item/broken_bottle,
@@ -75866,8 +75758,8 @@ aaa
bGI
bNs
cfN
-cqW
-cqW
+cfN
+cfN
cfN
cfN
bZY
@@ -76379,7 +76271,7 @@ aaa
aaa
bGI
bNs
-cqW
+cfN
bOw
cfN
bOw
@@ -80477,7 +80369,7 @@ aaa
aht
aqG
bGE
-bKf
+cqW
bKf
bMw
bNy
@@ -80734,8 +80626,8 @@ aht
aht
aqG
bGE
-bKf
-bKf
+izF
+ros
bMx
bNz
bHM
@@ -80991,7 +80883,7 @@ aaa
aaa
aqG
bGE
-wDe
+bGE
bHM
bHM
bNA
@@ -97884,8 +97776,8 @@ aaa
aaa
aaa
lcZ
-aoA
-apq
+apW
+apV
apU
aqQ
arX
@@ -98398,8 +98290,8 @@ aiT
aiS
aaa
lcZ
-aoC
-aps
+apU
+apV
apW
aqS
arZ
@@ -107723,7 +107615,7 @@ aht
bwm
ikB
iVJ
-izF
+lWy
typ
bwm
aht
@@ -108233,7 +108125,7 @@ bwm
svN
bIQ
uek
-izF
+lWy
bwm
qnT
lJr
@@ -108488,9 +108380,9 @@ dMO
lWy
rxQ
lWy
-ros
-izF
-izF
+bIQ
+lWy
+lWy
mES
lWy
lWy
@@ -108747,7 +108639,7 @@ bwm
nzD
uoj
bwm
-izF
+lWy
bwm
dMI
lWy
@@ -109001,7 +108893,7 @@ bkF
bwm
bwm
bwm
-ros
+bIQ
bwm
bwm
bwm
@@ -109258,8 +109150,8 @@ bkF
qIO
jXA
bwm
-ros
-vpz
+bIQ
+hXt
bwm
aht
bwm
diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index d1c1d309cd..035563627f 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -144,6 +144,10 @@
#define WINGCOLOR 26
#define CAN_SCAR 27 // If this species can be scarred (fleshy)
+/// Used for determining which wounds are applicable to this species.
+#define HAS_FLESH 28 /// if we have flesh (can suffer slash/piercing/burn wounds, requires they don't have NOBLOOD)
+#define HAS_BONE 29 /// if we have bones (can suffer bone wounds)
+
//organ slots
#define ORGAN_SLOT_BRAIN "brain"
#define ORGAN_SLOT_APPENDIX "appendix"
diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm
index 198356f804..97f07acc05 100644
--- a/code/__DEFINES/admin.dm
+++ b/code/__DEFINES/admin.dm
@@ -80,6 +80,7 @@
#define ADMIN_PUNISHMENT_SCARIFY "Scarify"
#define ADMIN_PUNISHMENT_PICKLE "Pickle-ify"
#define ADMIN_PUNISHMENT_FRY "Fry"
+#define ADMIN_PUNISHMENT_PERFORATE ":B:erforate"
#define AHELP_ACTIVE 1
#define AHELP_CLOSED 2
diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm
index 07f24fd8a3..585e8da7d7 100644
--- a/code/__DEFINES/citadel_defines.dm
+++ b/code/__DEFINES/citadel_defines.dm
@@ -98,6 +98,7 @@
#define NO_APHRO (1<<9)
#define NO_ASS_SLAP (1<<10)
#define BIMBOFICATION (1<<11)
+#define NO_AUTO_WAG (1<<12)
#define TOGGLES_CITADEL 0
diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm
index f597eb4ae7..5f4317060d 100644
--- a/code/__DEFINES/clockcult.dm
+++ b/code/__DEFINES/clockcult.dm
@@ -23,6 +23,7 @@ GLOBAL_VAR_INIT(script_scripture_unlocked, FALSE) //If script scripture is avail
GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE) //If application scripture is available
GLOBAL_VAR_INIT(judgement_scripture_unlocked, FALSE) //If judgement scripture is available
GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not used to track existing scripture
+GLOBAL_LIST_EMPTY(all_clockwork_rites) //a list containing all clockwork rites. Filled the first time any cultist interacts with a sigil of rites.
//Scripture tiers and requirements; peripherals should never be used
#define SCRIPTURE_PERIPHERAL "Peripheral"
diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 1bf9b01403..14d62f7978 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -154,9 +154,10 @@
#define SHOVE_KNOCKDOWN_HUMAN 30
#define SHOVE_KNOCKDOWN_TABLE 30
#define SHOVE_KNOCKDOWN_COLLATERAL 10
-//for the shove slowdown, see __DEFINES/movespeed_modification.dm
-#define SHOVE_SLOWDOWN_LENGTH 30
-#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier
+/// how long they're staggered for
+#define SHOVE_STAGGER_DURATION 35
+/// how long they're off balance for
+#define SHOVE_OFFBALANCE_DURATION 30
//Shove disarming item list
GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/obj/item/gun)))
@@ -208,9 +209,9 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define GUN_AIMING_TIME (2 SECONDS)
//Object/Item sharpness
-#define IS_BLUNT 0
-#define IS_SHARP 1
-#define IS_SHARP_ACCURATE 2
+#define SHARP_NONE 0
+#define SHARP_EDGED 1
+#define SHARP_POINTY 2
//His Grace.
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 5b8a4d5fc3..7e1a83486d 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -356,8 +356,8 @@
#define COMSIG_PEN_ROTATED "pen_rotated" //called after rotation in /obj/item/pen/attack_self(): (rotation, mob/living/carbon/user)
// /obj/item/projectile signals (sent to the firer)
-#define COMSIG_PROJECTILE_SELF_ON_HIT "projectile_self_on_hit" // from base of /obj/item/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle)
-#define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit" // from base of /obj/item/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle)
+#define COMSIG_PROJECTILE_SELF_ON_HIT "projectile_self_on_hit" ///from base of /obj/item/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle, hit_limb)
+#define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit" ///from base of /obj/item/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle, hit_limb)
#define COMSIG_PROJECTILE_BEFORE_FIRE "projectile_before_fire" // from base of /obj/item/projectile/proc/fire(): (obj/item/projectile, atom/original_target)
#define COMSIG_PROJECTILE_FIRE "projectile_fire" ///from the base of /obj/item/projectile/proc/fire(): ()
#define COMSIG_PROJECTILE_RANGE_OUT "projectile_range_out" // sent to targets during the process_hit proc of projectiles
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 964c4e911e..3aa5a07480 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -199,14 +199,6 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
#define isclothing(A) (istype(A, /obj/item/clothing))
-GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
- /obj/item/pen,
- /obj/item/screwdriver,
- /obj/item/reagent_containers/syringe,
- /obj/item/kitchen/fork)))
-
-#define is_pointed(W) (is_type_in_typecache(W, GLOB.pointed_types))
-
#define isbodypart(A) (istype(A, /obj/item/bodypart))
#define isprojectile(A) (istype(A, /obj/item/projectile))
diff --git a/code/__DEFINES/loadout.dm b/code/__DEFINES/loadout.dm
new file mode 100644
index 0000000000..332095e049
--- /dev/null
+++ b/code/__DEFINES/loadout.dm
@@ -0,0 +1,56 @@
+//defines for loadout categories
+//no category defines
+#define NOCATEGORY list("NOCATEGORY")
+#define NOSUBCATEGORY list("NOSUBCATEGORY")
+
+
+//backpack
+#define CATEGORY_BACKPACK "In backpack"
+#define SUBCATEGORY_BACKPACK_GENERAL "General" //basically anything that there's not enough of to have its own subcategory
+#define SUBCATEGORY_BACKPACK_TOYS "Toys"
+//neck
+#define CATEGORY_NECK "Neck"
+#define SUBCATEGORY_NECK_GENERAL "General"
+#define SUBCATEGORY_NECK_TIE "Ties"
+#define SUBCATEGORY_NECK_SCARVES "Scarves"
+
+//mask
+#define CATEGORY_MASK "Mask"
+
+//hands
+#define CATEGORY_HANDS "Hands"
+
+//uniform
+#define CATEGORY_UNIFORM "Uniform" //there's so many types of uniform it's best to have lots of categories
+#define SUBCATEGORY_UNIFORM_GENERAL "General"
+#define SUBCATEGORY_UNIFORM_JOBS "Jobs"
+#define SUBCATEGORY_UNIFORM_SUITS "Suits"
+#define SUBCATEGORY_UNIFORM_SKIRTS "Skirts"
+#define SUBCATEGORY_UNIFORM_DRESSES "Dresses"
+#define SUBCATEGORY_UNIFORM_SWEATERS "Sweaters"
+#define SUBCATEGORY_UNIFORM_PANTS "Pants"
+#define SUBCATEGORY_UNIFORM_SHORTS "Shorts"
+
+//suit
+#define CATEGORY_SUIT "Suit"
+#define SUBCATEGORY_SUIT_GENERAL "General"
+#define SUBCATEGORY_SUIT_COATS "Coats"
+#define SUBCATEGORY_SUIT_JACKETS "Jackets"
+#define SUBCATEGORY_SUIT_JOBS "Jobs"
+
+//head
+#define CATEGORY_HEAD "Head"
+#define SUBCATEGORY_HEAD_GENERAL "General"
+#define SUBCATEGORY_HEAD_JOBS "Jobs"
+
+//shoes
+#define CATEGORY_SHOES "Shoes"
+
+//gloves
+#define CATEGORY_GLOVES "Gloves"
+
+//glasses
+#define CATEGORY_GLASSES "Glasses"
+
+//donator items
+#define CATEGORY_DONATOR "Donator"
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 120fdcb72d..d294c69972 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -434,6 +434,9 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define ION_FILE "ion_laws.json"
#define REDPILL_FILE "redpill.json"
#define PIRATE_NAMES_FILE "pirates.json"
+#define FLESH_SCAR_FILE "wounds/flesh_scar_desc.json"
+#define BONE_SCAR_FILE "wounds/bone_scar_desc.json"
+#define SCAR_LOC_FILE "wounds/scar_loc.json"
//Fullscreen overlay resolution in tiles.
diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
index 699f39e79f..5e7d0a2cca 100644
--- a/code/__DEFINES/movespeed_modification.dm
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -63,7 +63,6 @@
#define MOVESPEED_ID_TASED_STATUS "TASED"
#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
-#define MOVESPEED_ID_SHOVE "SHOVE"
#define MOVESPEED_ID_FAT "FAT"
#define MOVESPEED_ID_COLD "COLD"
#define MOVESPEED_ID_HUNGRY "HUNGRY"
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 14cc7c9e5e..9a3b5d55f4 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -111,6 +111,9 @@
#define STATUS_EFFECT_LIMP /datum/status_effect/limp //For when you have a busted leg (or two!) and want additional slowdown when walking on that leg
+/// shoves inflict this to indicate the next shove while this is in effect should disarm guns
+#define STATUS_EFFECT_OFF_BALANCE /datum/status_effect/off_balance
+
/////////////
// NEUTRAL //
/////////////
diff --git a/code/__DEFINES/storage/_storage.dm b/code/__DEFINES/storage/_storage.dm
index 3a05293d2d..6eb613b423 100644
--- a/code/__DEFINES/storage/_storage.dm
+++ b/code/__DEFINES/storage/_storage.dm
@@ -19,7 +19,7 @@
/// Size of EACH left/right border icon for volumetric boxes
#define VOLUMETRIC_STORAGE_BOX_BORDER_SIZE 1
/// Minimum pixels an item must have in volumetric scaled storage UI
-#define MINIMUM_PIXELS_PER_ITEM 8
+#define MINIMUM_PIXELS_PER_ITEM 16
/// Maximum number of objects that will be allowed to be displayed using the volumetric display system. Arbitrary number to prevent server lockups.
#define MAXIMUM_VOLUMETRIC_ITEMS 256
/// How much padding to give between items
diff --git a/code/__DEFINES/wounds.dm b/code/__DEFINES/wounds.dm
index b993429961..73ada71423 100644
--- a/code/__DEFINES/wounds.dm
+++ b/code/__DEFINES/wounds.dm
@@ -1,4 +1,13 @@
-#define WOUND_DAMAGE_EXPONENT 1.4
+
+#define WOUND_DAMAGE_EXPONENT 1.225
+
+/// an attack must do this much damage after armor in order to roll for being a wound (incremental pressure damage need not apply)
+#define WOUND_MINIMUM_DAMAGE 5
+/// an attack must do this much damage after armor in order to be eliigible to dismember a suitably mushed bodypart
+#define DISMEMBER_MINIMUM_DAMAGE 10
+/// any damage dealt over this is ignored for damage rolls unless the target has the frail quirk (35^1.4=145)
+#define WOUND_MAX_CONSIDERED_DAMAGE 35
+
#define WOUND_SEVERITY_TRIVIAL 0 // for jokey/meme wounds like stubbed toe, no standard messages/sounds or second winds
#define WOUND_SEVERITY_MODERATE 1
@@ -6,38 +15,105 @@
#define WOUND_SEVERITY_CRITICAL 3
#define WOUND_SEVERITY_LOSS 4 // theoretical total limb loss, like dismemberment for cuts
-#define WOUND_BRUTE 0
-#define WOUND_SHARP 1
-#define WOUND_BURN 2
+/// any brute weapon/attack that doesn't have sharpness. rolls for blunt bone wounds
+#define WOUND_BLUNT 1
+/// any brute weapon/attack with sharpness = SHARP_EDGED. rolls for slash wounds
+#define WOUND_SLASH 2
+/// any brute weapon/attack with sharpness = SHARP_POINTY. rolls for piercing wounds
+#define WOUND_PIERCE 3
+/// any concentrated burn attack (lasers really). rolls for burning wounds
+#define WOUND_BURN 4
// How much determination reagent to add each time someone gains a new wound in [/datum/wound/proc/second_wind()]
#define WOUND_DETERMINATION_MODERATE 1
#define WOUND_DETERMINATION_SEVERE 2.5
#define WOUND_DETERMINATION_CRITICAL 5
+#define WOUND_DETERMINATION_LOSS 7.5
+/// the max amount of determination you can have
#define WOUND_DETERMINATION_MAX 10
-// set wound_bonus on an item or attack to this to disable checking wounding for the attack
+/// set wound_bonus on an item or attack to this to disable checking wounding for the attack
#define CANT_WOUND -100
// list in order of highest severity to lowest
-#define WOUND_LIST_BONE list(/datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/moderate)
-#define WOUND_LIST_CUT list(/datum/wound/brute/cut/loss, /datum/wound/brute/cut/critical, /datum/wound/brute/cut/severe, /datum/wound/brute/cut/moderate)
-#define WOUND_LIST_BURN list(/datum/wound/burn/critical, /datum/wound/burn/severe, /datum/wound/burn/moderate)
+GLOBAL_LIST_INIT(global_wound_types, list(WOUND_BLUNT = list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate),
+ WOUND_SLASH = list(/datum/wound/slash/critical, /datum/wound/slash/severe, /datum/wound/slash/moderate),
+ WOUND_PIERCE = list(/datum/wound/pierce/critical, /datum/wound/pierce/severe, /datum/wound/pierce/moderate),
+ WOUND_BURN = list(/datum/wound/burn/critical, /datum/wound/burn/severe, /datum/wound/burn/moderate)
+ ))
+
+GLOBAL_LIST_INIT(global_all_wound_types, list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate,
+ /datum/wound/slash/critical, /datum/wound/slash/severe, /datum/wound/slash/moderate,
+ /datum/wound/pierce/critical, /datum/wound/pierce/severe, /datum/wound/pierce/moderate,
+ /datum/wound/burn/critical, /datum/wound/burn/severe, /datum/wound/burn/moderate))
// Thresholds for infection for burn wounds, once infestation hits each threshold, things get steadily worse
-#define WOUND_INFECTION_MODERATE 4 // below this has no ill effects from infection
-#define WOUND_INFECTION_SEVERE 8 // then below here, you ooze some pus and suffer minor tox damage, but nothing serious
-#define WOUND_INFECTION_CRITICAL 12 // then below here, your limb occasionally locks up from damage and infection and briefly becomes disabled. Things are getting really bad
-#define WOUND_INFECTION_SEPTIC 20 // below here, your skin is almost entirely falling off and your limb locks up more frequently. You are within a stone's throw of septic paralysis and losing the limb
+/// below this has no ill effects from infection
+#define WOUND_INFECTION_MODERATE 4
+/// then below here, you ooze some pus and suffer minor tox damage, but nothing serious
+#define WOUND_INFECTION_SEVERE 8
+/// then below here, your limb occasionally locks up from damage and infection and briefly becomes disabled. Things are getting really bad
+#define WOUND_INFECTION_CRITICAL 12
+/// below here, your skin is almost entirely falling off and your limb locks up more frequently. You are within a stone's throw of septic paralysis and losing the limb
+#define WOUND_INFECTION_SEPTIC 20
// above WOUND_INFECTION_SEPTIC, your limb is completely putrid and you start rolling to lose the entire limb by way of paralyzation. After 3 failed rolls (~4-5% each probably), the limb is paralyzed
-#define WOUND_BURN_SANITIZATION_RATE 0.15 // how quickly sanitization removes infestation and decays per tick
-#define WOUND_CUT_MAX_BLOODFLOW 8 // how much blood you can lose per tick per cut max. 8 is a LOT of blood for one cut so don't worry about hitting it easily
-#define WOUND_BONE_HEAD_TIME_VARIANCE 20 // if we suffer a bone wound to the head that creates brain traumas, the timer for the trauma cycle is +/- by this percent (0-100)
+
+/// how quickly sanitization removes infestation and decays per tick
+#define WOUND_BURN_SANITIZATION_RATE 0.15
+/// how much blood you can lose per tick per slash max. 8 is a LOT of blood for one cut so don't worry about hitting it easily
+#define WOUND_SLASH_MAX_BLOODFLOW 8
+/// dead people don't bleed, but they can clot! this is the minimum amount of clotting per tick on dead people, so even critical cuts will slowly clot in dead people
+#define WOUND_SLASH_DEAD_CLOT_MIN 0.05
+/// if we suffer a bone wound to the head that creates brain traumas, the timer for the trauma cycle is +/- by this percent (0-100)
+#define WOUND_BONE_HEAD_TIME_VARIANCE 20
// The following are for persistent scar save formats
-#define SCAR_SAVE_ZONE 1 // The body_zone we're applying to on granting
-#define SCAR_SAVE_DESC 2 // The description we're loading
-#define SCAR_SAVE_PRECISE_LOCATION 3 // The precise location we're loading
-#define SCAR_SAVE_SEVERITY 4 // The severity the scar had
+/// The version number of the scar we're saving
+#define SCAR_SAVE_VERS 1
+/// The body_zone we're applying to on granting
+#define SCAR_SAVE_ZONE 2
+/// The description we're loading
+#define SCAR_SAVE_DESC 3
+/// The precise location we're loading
+#define SCAR_SAVE_PRECISE_LOCATION 4
+/// The severity the scar had
+#define SCAR_SAVE_SEVERITY 5
+///how many fields there are above (NOT INCLUDING THIS OBVIOUSLY)
+#define SCAR_SAVE_LENGTH 5
+
+// increment this number when you update the persistent scarring format in a way that invalidates previous saved scars (new fields, reordering, etc)
+/// saved scars with a version lower than this will be discarded
+#define SCAR_CURRENT_VERSION 1
+
+
+// With the wounds pt. 2 update, general dismemberment now requires 2 things for a limb to be dismemberable (bone only creatures just need the second):
+// 1. Skin is mangled: A critical slash or pierce wound on that limb
+// 2. Bone is mangled: At least a severe bone wound on that limb
+// see [/obj/item/bodypart/proc/get_mangled_state] for more information
+#define BODYPART_MANGLED_NONE 0
+#define BODYPART_MANGLED_BONE 1
+#define BODYPART_MANGLED_FLESH 2
+#define BODYPART_MANGLED_BOTH 3
+
+// What kind of biology we have, and what wounds we can suffer, mostly relies on the HAS_FLESH and HAS_BONE species traits on human species
+/// golems and androids, cannot suffer any wounds
+#define BIO_INORGANIC 0
+/// skeletons and plasmemes, can only suffer bone wounds, only needs mangled bone to be able to dismember
+#define BIO_JUST_BONE 1
+/// nothing right now, maybe slimepeople in the future, can only suffer slashing, piercing, and burn wounds
+#define BIO_JUST_FLESH 2
+/// standard humanoids, can suffer all wounds, needs mangled bone and flesh to dismember
+#define BIO_FLESH_BONE 3
+
+/// If this wound requires having the HAS_FLESH flag for humanoids
+#define FLESH_WOUND (1<<0)
+/// If this wound requires having the HAS_BONE flag for humanaoids
+#define BONE_WOUND (1<<1)
+/// If having this wound counts as mangled flesh for dismemberment
+#define MANGLES_FLESH (1<<2)
+/// If having this wound counts as mangled bone for dismemberment
+#define MANGLES_BONE (1<<3)
+/// If this wound marks the limb as being allowed to have gauze applied
+#define ACCEPTS_GAUZE (1<<4)
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 9c71cfeb69..6dfb685331 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -113,6 +113,22 @@
else
return trim(html_encode(name), max_length)
+/**
+ * stripped_multiline_input but reflects to the user instead if it's too big and returns null.
+ */
+/proc/stripped_multiline_input_or_reflect(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE)
+ var/name = input(user, message, title, default) as message|null
+ if(isnull(name)) // Return null if canceled.
+ return null
+ if(length(name) > max_length)
+ to_chat(user, name)
+ to_chat(user, "^^^----- The preceeding message has been DISCARDED for being over the maximum length of [max_length]. It has NOT been sent! -----^^^")
+ return null
+ if(no_trim)
+ return copytext(html_encode(name), 1, max_length)
+ else
+ return trim(html_encode(name), max_length)
+
#define NO_CHARS_DETECTED 0
#define SPACES_DETECTED 1
#define SYMBOLS_DETECTED 2
@@ -811,4 +827,4 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
corrupted_text += pick(corruption_options)
if(prob(15))
corrupted_text += pick(corruption_options)
- return corrupted_text
\ No newline at end of file
+ return corrupted_text
diff --git a/code/_globalvars/lists/loadout_categories.dm b/code/_globalvars/lists/loadout_categories.dm
new file mode 100644
index 0000000000..2a44bf60f4
--- /dev/null
+++ b/code/_globalvars/lists/loadout_categories.dm
@@ -0,0 +1,13 @@
+GLOBAL_LIST_INIT(loadout_categories, list(
+ CATEGORY_BACKPACK = list(SUBCATEGORY_BACKPACK_GENERAL, SUBCATEGORY_BACKPACK_TOYS),
+ CATEGORY_NECK = list(SUBCATEGORY_NECK_GENERAL, SUBCATEGORY_NECK_TIE, SUBCATEGORY_NECK_SCARVES),
+ CATEGORY_MASK = NOSUBCATEGORY,
+ CATEGORY_HANDS = NOSUBCATEGORY,
+ CATEGORY_UNIFORM = list(SUBCATEGORY_UNIFORM_GENERAL, SUBCATEGORY_UNIFORM_JOBS, SUBCATEGORY_UNIFORM_SUITS, SUBCATEGORY_UNIFORM_SKIRTS, SUBCATEGORY_UNIFORM_DRESSES, SUBCATEGORY_UNIFORM_SWEATERS, SUBCATEGORY_UNIFORM_PANTS, SUBCATEGORY_UNIFORM_SHORTS),
+ CATEGORY_SUIT = list(SUBCATEGORY_SUIT_GENERAL, SUBCATEGORY_SUIT_COATS, SUBCATEGORY_SUIT_JACKETS, SUBCATEGORY_SUIT_JOBS),
+ CATEGORY_HEAD = list(SUBCATEGORY_HEAD_GENERAL, SUBCATEGORY_HEAD_JOBS),
+ CATEGORY_SHOES = NOSUBCATEGORY,
+ CATEGORY_GLOVES = NOSUBCATEGORY,
+ CATEGORY_GLASSES = NOSUBCATEGORY,
+ CATEGORY_DONATOR = NOSUBCATEGORY
+))
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 6a26a6f116..9e88476513 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -238,25 +238,24 @@
else
return clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100
-/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area, current_force)
+/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area, obj/item/bodypart/hit_bodypart)
var/message_verb = "attacked"
- if(I.attack_verb && I.attack_verb.len)
+ if(length(I.attack_verb))
message_verb = "[pick(I.attack_verb)]"
- if(current_force < I.force * FEEBLE_ATTACK_MSG_THRESHOLD)
- message_verb = "[pick("feebly", "limply", "saplessly")] [message_verb]"
else if(!I.force)
return
var/message_hit_area = ""
if(hit_area)
message_hit_area = " in the [hit_area]"
- var/attack_message = "[src] has been [message_verb][message_hit_area] with [I]."
+ var/attack_message = "[src] is [message_verb][message_hit_area] with [I]!"
+ var/attack_message_local = "You're [message_verb][message_hit_area] with [I]!"
if(user in viewers(src, null))
- attack_message = "[user] has [message_verb] [src][message_hit_area] with [I]!"
+ attack_message = "[user] [message_verb] [src][message_hit_area] with [I]!"
+ attack_message_local = "[user] [message_verb] you[message_hit_area] with [I]!"
+ if(user == src)
+ attack_message_local = "You [message_verb] yourself[message_hit_area] with [I]"
visible_message("[attack_message]",\
- "[attack_message]", null, COMBAT_MESSAGE_RANGE)
- if(hit_area == BODY_ZONE_HEAD)
- if(prob(2))
- playsound(src, 'sound/weapons/dink.ogg', 30, 1)
+ "[attack_message_local]", null, COMBAT_MESSAGE_RANGE)
return 1
/// How much stamina this takes to swing this is not for realism purposes hecc off.
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 4b2cf24f1e..4f59992ace 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -674,7 +674,7 @@ SUBSYSTEM_DEF(job)
return
for(var/i in the_mob.client.prefs.chosen_gear)
var/datum/gear/G = i
- G = GLOB.loadout_items[slot_to_string(initial(G.category))][initial(G.name)]
+ G = GLOB.loadout_items[initial(G.category)][initial(G.subcategory)][initial(G.name)]
if(!G)
continue
var/permitted = TRUE
@@ -682,14 +682,14 @@ SUBSYSTEM_DEF(job)
permitted = FALSE
if(G.donoritem && !G.donator_ckey_check(the_mob.client.ckey))
permitted = FALSE
- if(!equipbackpackstuff && G.category == SLOT_IN_BACKPACK)//snowflake check since plopping stuff in the backpack doesnt work for pre-job equip loadout stuffs
+ if(!equipbackpackstuff && G.slot == SLOT_IN_BACKPACK)//snowflake check since plopping stuff in the backpack doesnt work for pre-job equip loadout stuffs
permitted = FALSE
- if(equipbackpackstuff && G.category != SLOT_IN_BACKPACK)//ditto
+ if(equipbackpackstuff && G.slot != SLOT_IN_BACKPACK)//ditto
permitted = FALSE
if(!permitted)
continue
var/obj/item/I = new G.path
- if(!M.equip_to_slot_if_possible(I, G.category, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // If the job's dresscode compliant, try to put it in its slot, first
+ if(!M.equip_to_slot_if_possible(I, G.slot, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // If the job's dresscode compliant, try to put it in its slot, first
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/storage/backpack/B = C.back
diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm
index b4a162c982..5b60747725 100644
--- a/code/controllers/subsystem/persistence.dm
+++ b/code/controllers/subsystem/persistence.dm
@@ -561,8 +561,8 @@ SUBSYSTEM_DEF(persistence)
ending_human.client.prefs.scars_list["[ending_human.client.prefs.scars_index]"] = ""
else
for(var/k in ending_human.all_wounds)
- var/datum/wound/W = k
- W.remove_wound() // so we can get the scars for open wounds
+ var/datum/wound/iter_wound = k
+ iter_wound.remove_wound() // so we can get the scars for open wounds
if(!ending_human.client)
return
ending_human.client.prefs.scars_list["[ending_human.client.prefs.scars_index]"] = ending_human.format_scars()
diff --git a/code/controllers/subsystem/processing/circuit.dm b/code/controllers/subsystem/processing/circuit.dm
index 880e7a16a8..ac720a7fb4 100644
--- a/code/controllers/subsystem/processing/circuit.dm
+++ b/code/controllers/subsystem/processing/circuit.dm
@@ -50,20 +50,17 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
/obj/item/electronic_assembly/simple,
/obj/item/electronic_assembly/hook,
/obj/item/electronic_assembly/pda,
- /obj/item/electronic_assembly/dildo,
/obj/item/electronic_assembly/small/default,
/obj/item/electronic_assembly/small/cylinder,
/obj/item/electronic_assembly/small/scanner,
/obj/item/electronic_assembly/small/hook,
/obj/item/electronic_assembly/small/box,
- /obj/item/electronic_assembly/small/dildo,
/obj/item/electronic_assembly/medium/default,
/obj/item/electronic_assembly/medium/box,
/obj/item/electronic_assembly/medium/clam,
/obj/item/electronic_assembly/medium/medical,
/obj/item/electronic_assembly/medium/gun,
/obj/item/electronic_assembly/medium/radio,
- /obj/item/electronic_assembly/medium/dildo,
/obj/item/electronic_assembly/large/default,
/obj/item/electronic_assembly/large/scope,
/obj/item/electronic_assembly/large/terminal,
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 765f0c8382..0bc4e6665a 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -711,7 +711,8 @@ SUBSYSTEM_DEF(ticker)
'sound/roundend/yeehaw.ogg',
'sound/roundend/disappointed.ogg',
'sound/roundend/gondolabridge.ogg',
- 'sound/roundend/haveabeautifultime.ogg'\
+ 'sound/roundend/haveabeautifultime.ogg',
+ 'sound/roundend/CitadelStationHasSeenBetterDays.ogg'\
)
SEND_SOUND(world, sound(round_end_sound))
diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm
index b5b8849155..4f56f58d23 100644
--- a/code/datums/components/butchering.dm
+++ b/code/datums/components/butchering.dm
@@ -67,7 +67,7 @@
H.apply_damage(source.force, BRUTE, BODY_ZONE_HEAD, wound_bonus=CANT_WOUND) // easy tiger, we'll get to that in a sec
var/obj/item/bodypart/slit_throat = H.get_bodypart(BODY_ZONE_HEAD)
if(slit_throat)
- var/datum/wound/brute/cut/critical/screaming_through_a_slit_throat = new
+ var/datum/wound/slash/critical/screaming_through_a_slit_throat = new
screaming_through_a_slit_throat.apply_wound(slit_throat)
H.apply_status_effect(/datum/status_effect/neck_slice)
diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm
index ce124646f4..51098756d3 100644
--- a/code/datums/components/embedded.dm
+++ b/code/datums/components/embedded.dm
@@ -29,7 +29,6 @@
*/
-
/datum/component/embedded
dupe_mode = COMPONENT_DUPE_ALLOWED
var/obj/item/bodypart/limb
@@ -139,30 +138,36 @@
limb.embedded_objects |= weapon // on the inside... on the inside...
weapon.forceMove(victim)
RegisterSignal(weapon, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING), .proc/byeItemCarbon)
-
+ var/damage = 0
if(harmful)
victim.visible_message("[weapon] embeds itself in [victim]'s [limb.name]!",ignored_mobs=victim)
to_chat(victim, "[weapon] embeds itself in your [limb.name]!")
victim.throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
playsound(victim,'sound/weapons/bladeslice.ogg', 40)
weapon.add_mob_blood(victim)//it embedded itself in you, of course it's bloody!
- var/damage = weapon.w_class * impact_pain_mult
- limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus=-30, sharpness = TRUE)
+ damage = weapon.w_class * impact_pain_mult
SEND_SIGNAL(victim, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
else
victim.visible_message("[weapon] sticks itself to [victim]'s [limb.name]!",ignored_mobs=victim)
to_chat(victim, "[weapon] sticks itself to your [limb.name]!")
+ if(damage > 0)
+ var/armor = victim.run_armor_check(limb.body_zone, "melee", "Your armor has protected your [limb.name].", "Your armor has softened a hit to your [limb.name].",weapon.armour_penetration)
+ limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, blocked=armor, sharpness = weapon.get_sharpness())
+
/// Called every time a carbon with a harmful embed moves, rolling a chance for the item to cause pain. The chance is halved if the carbon is crawling or walking.
/datum/component/embedded/proc/jostleCheck()
var/mob/living/carbon/victim = parent
- var/chance = jostle_chance
+ var/damage = weapon.w_class * pain_mult
+ var/pain_chance_current = jostle_chance
if(victim.m_intent == MOVE_INTENT_WALK || !(victim.mobility_flags & MOBILITY_STAND))
- chance *= 0.5
+ pain_chance_current *= 0.5
- if(harmful && prob(chance))
- var/damage = weapon.w_class * jostle_pain_mult
+ if(pain_stam_pct && IS_STAMCRIT(victim)) //if it's a less-lethal embed, give them a break if they're already stamcritted
+ pain_chance_current *= 0.2
+ damage *= 0.5
+ if(harmful && prob(pain_chance_current))
limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND)
to_chat(victim, "[weapon] embedded in your [limb.name] jostles and stings!")
@@ -199,7 +204,7 @@
if(harmful)
var/damage = weapon.w_class * remove_pain_mult
- limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, sharpness=TRUE) //It hurts to rip it out, get surgery you dingus.
+ limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND) //It hurts to rip it out, get surgery you dingus.
victim.emote("scream")
victim.visible_message("[victim] successfully rips [weapon] out of [victim.p_their()] [limb.name]!", "You successfully remove [weapon] from your [limb.name].")
else
@@ -279,11 +284,13 @@
limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND)
to_chat(victim, "[weapon] embedded in your [limb.name] hurts!")
- if(prob(fall_chance))
+ var/fall_chance_current = fall_chance
+ if(victim.mobility_flags & ~MOBILITY_STAND)
+ fall_chance_current *= 0.2
+
+ if(prob(fall_chance_current))
fallOutCarbon()
-
-
////////////////////////////////////////
//////////////TURF PROCS////////////////
////////////////////////////////////////
diff --git a/code/datums/components/killerqueen.dm b/code/datums/components/killerqueen.dm
new file mode 100644
index 0000000000..1c660d0a87
--- /dev/null
+++ b/code/datums/components/killerqueen.dm
@@ -0,0 +1,91 @@
+/**
+ * KILLER QUEEN
+ *
+ * Simple contact bomb component
+ * Blows up the first person to touch it.
+ */
+/datum/component/killerqueen
+ can_transfer = TRUE
+ /// strength of explosion on the touch-er. 0 to disable. usually only used if the normal explosion is disabled (this is the default).
+ var/ex_strength = EXPLODE_HEAVY
+ /// callback to invoke with (parent, victim) before standard detonation - useful for losing a reference to this component or implementing custom behavior. return FALSE to prevent explosion.
+ var/datum/callback/pre_explode
+ /// callback to invoke with (parent) when deleting without an explosion
+ var/datum/callback/failure
+ /// did we explode
+ var/exploded = FALSE
+ /// examine message
+ var/examine_message
+ /// light explosion radius
+ var/light = 0
+ /// heavy explosion radius
+ var/heavy = 0
+ /// dev explosion radius
+ var/dev = 0
+ /// flame explosion radius
+ var/flame = 0
+ /// only triggered by living mobs
+ var/living_only = TRUE
+
+
+/datum/component/killerqueen/Initialize(ex_strength = EXPLODE_HEAVY, datum/callback/pre_explode, datum/callback/failure, examine_message, light = 0, heavy = 0, dev = 0, flame = 0, living_only = TRUE)
+ . = ..()
+ if(. & COMPONENT_INCOMPATIBLE)
+ return
+ if(!isatom(parent))
+ return COMPONENT_INCOMPATIBLE
+ src.ex_strength = ex_strength
+ src.pre_explode = pre_explode
+ src.failure = failure
+ src.examine_message = examine_message
+ src.light = light
+ src.heavy = heavy
+ src.dev = dev
+ src.flame = flame
+ src.living_only = living_only
+
+/datum/component/killerqueen/Destroy()
+ if(!exploded)
+ failure?.Invoke(parent)
+ return ..()
+
+/datum/component/killerqueen/RegisterWithParent()
+ . = ..()
+ RegisterSignal(parent, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW, COMSIG_ATOM_ATTACK_ANIMAL), .proc/touch_detonate)
+ RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/bump_detonate)
+ RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby_detonate)
+ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
+
+/datum/component/killerqueen/UnregisterFromParent()
+ . = ..()
+ UnregisterSignal(parent, list(COMSIG_ATOM_ATTACK_ANIMAL, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW,
+ COMSIG_MOVABLE_BUMP, COMSIG_PARENT_ATTACKBY, COMSIG_PARENT_EXAMINE))
+
+/datum/component/killerqueen/proc/attackby_detonate(datum/source, obj/item/I, mob/user)
+ detonate(user)
+
+/datum/component/killerqueen/proc/bump_detonate(datum/source, atom/A)
+ detonate(A)
+
+/datum/component/killerqueen/proc/touch_detonate(datum/source, mob/user)
+ detonate(user)
+
+/datum/component/killerqueen/proc/on_examine(datum/source, mob/examiner, list/examine_return)
+ if(examine_message)
+ examine_return += examine_message
+
+/datum/component/killerqueen/proc/detonate(atom/victim)
+ if(!isliving(victim) && living_only)
+ return
+ if(pre_explode && !pre_explode.Invoke(parent, victim))
+ return
+ if(ex_strength)
+ victim.ex_act(ex_strength)
+ if(light || heavy || dev || flame)
+ explosion(parent, dev, heavy, light, flame_range = flame)
+ else
+ var/turf/T = get_turf(parent)
+ playsound(T, 'sound/effects/explosion2.ogg', 200, 1)
+ new /obj/effect/temp_visual/explosion(T)
+ exploded = TRUE
+ qdel(src)
diff --git a/code/datums/components/pellet_cloud.dm b/code/datums/components/pellet_cloud.dm
index 938d9f5f56..6a1028cc65 100644
--- a/code/datums/components/pellet_cloud.dm
+++ b/code/datums/components/pellet_cloud.dm
@@ -1,3 +1,8 @@
+// the following defines are used for [/datum/component/pellet_cloud/var/list/wound_info_by_part] to store the damage, wound_bonus, and bw_bonus for each bodypart hit
+#define CLOUD_POSITION_DAMAGE 1
+#define CLOUD_POSITION_W_BONUS 2
+#define CLOUD_POSITION_BW_BONUS 3
+
/*
* This component is used when you want to create a bunch of shrapnel or projectiles (say, shrapnel from a fragmentation grenade, or buckshot from a shotgun) from a central point,
* without necessarily printing a separate message for every single impact. This component should be instantiated right when you need it (like the moment of firing), then activated
@@ -29,7 +34,10 @@
var/list/pellets = list()
/// An associated list with the atom hit as the key and how many pellets they've eaten for the value, for printing aggregate messages
var/list/targets_hit = list()
- /// For grenades, any /mob/living's the grenade is moved onto, see [/datum/component/pellet_cloud/proc/handle_martyrs()]
+
+ /// Another associated list for hit bodyparts on carbons so we can track how much wounding potential we have for each bodypart
+ var/list/wound_info_by_part = list()
+ /// For grenades, any /mob/living's the grenade is moved onto, see [/datum/component/pellet_cloud/proc/handle_martyrs]
var/list/bodies
/// For grenades, tracking people who die covering a grenade for achievement purposes, see [/datum/component/pellet_cloud/proc/handle_martyrs()]
var/list/purple_hearts
@@ -64,6 +72,7 @@
/datum/component/pellet_cloud/Destroy(force, silent)
purple_hearts = null
pellets = null
+ wound_info_by_part = null
targets_hit = null
bodies = null
return ..()
@@ -187,10 +196,26 @@
break
///One of our pellets hit something, record what it was and check if we're done (terminated == num_pellets)
-/datum/component/pellet_cloud/proc/pellet_hit(obj/item/projectile/P, atom/movable/firer, atom/target, Angle)
+/datum/component/pellet_cloud/proc/pellet_hit(obj/item/projectile/P, atom/movable/firer, atom/target, Angle, hit_zone)
pellets -= P
terminated++
hits++
+ var/obj/item/bodypart/hit_part
+ if(iscarbon(target) && hit_zone)
+ var/mob/living/carbon/hit_carbon = target
+ hit_part = hit_carbon.get_bodypart(hit_zone)
+ if(hit_part)
+ target = hit_part
+ if(P.wound_bonus != CANT_WOUND) // handle wounding
+ // unfortunately, due to how pellet clouds handle finalizing only after every pellet is accounted for, that also means there might be a short delay in dealing wounds if one pellet goes wide
+ // while buckshot may reach a target or miss it all in one tick, we also have to account for possible ricochets that may take a bit longer to hit the target
+ if(isnull(wound_info_by_part[hit_part]))
+ wound_info_by_part[hit_part] = list(0, 0, 0)
+ wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE] += P.damage // these account for decay
+ wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS] += P.wound_bonus
+ wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS] += P.bare_wound_bonus
+ P.wound_bonus = CANT_WOUND // actual wounding will be handled aggregate
+
targets_hit[target]++
if(targets_hit[target] == 1)
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/on_target_qdel, override=TRUE)
@@ -231,13 +256,23 @@
for(var/atom/target in targets_hit)
var/num_hits = targets_hit[target]
UnregisterSignal(target, COMSIG_PARENT_QDELETING)
- if(num_hits > 1)
- target.visible_message("[target] is hit by [num_hits] [proj_name]s!", null, null, COMBAT_MESSAGE_RANGE, target)
- to_chat(target, "You're hit by [num_hits] [proj_name]s!")
- else
- target.visible_message("[target] is hit by a [proj_name]!", null, null, COMBAT_MESSAGE_RANGE, target)
- to_chat(target, "You're hit by a [proj_name]!")
+ var/obj/item/bodypart/hit_part
+ if(isbodypart(target))
+ hit_part = target
+ target = hit_part.owner
+ var/damage_dealt = wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE]
+ var/w_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS]
+ var/bw_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS]
+ var/wound_type = (initial(P.damage_type) == BRUTE) ? WOUND_BLUNT : WOUND_BURN // sharpness is handled in the wound rolling
+ wound_info_by_part[hit_part] = null
+ hit_part.painless_wound_roll(wound_type, damage_dealt, w_bonus, bw_bonus, initial(P.sharpness))
+ if(num_hits > 1)
+ target.visible_message("[target] is hit by [num_hits] [proj_name]s[hit_part ? " in the [hit_part.name]" : ""]!", null, null, COMBAT_MESSAGE_RANGE, target)
+ to_chat(target, "You're hit by [num_hits] [proj_name]s[hit_part ? " in the [hit_part.name]" : ""]!")
+ else
+ target.visible_message("[target] is hit by a [proj_name][hit_part ? " in the [hit_part.name]" : ""]!", null, null, COMBAT_MESSAGE_RANGE, target)
+ to_chat(target, "You're hit by a [proj_name][hit_part ? " in the [hit_part.name]" : ""]!")
UnregisterSignal(parent, COMSIG_PARENT_PREQDELETED)
if(queued_delete)
qdel(parent)
@@ -281,3 +316,7 @@
targets_hit -= target
bodies -= target
purple_hearts -= target
+
+#undef CLOUD_POSITION_DAMAGE
+#undef CLOUD_POSITION_W_BONUS
+#undef CLOUD_POSITION_BW_BONUS
diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm
index 8a7acde9cb..876414330f 100644
--- a/code/datums/elements/embed.dm
+++ b/code/datums/elements/embed.dm
@@ -2,7 +2,7 @@
The presence of this element allows an item (or a projectile carrying an item) to embed itself in a human or turf when it is thrown into a target (whether by hand, gun, or explosive wave) with either
at least 4 throwspeed (EMBED_THROWSPEED_THRESHOLD) or ignore_throwspeed_threshold set to TRUE. Items meant to be used as shrapnel for projectiles should have ignore_throwspeed_threshold set to true.
- Whether we're dealing with a direct /obj/item (throwing a knife at someone) or an /obj/projectile with a shrapnel_type, how we handle things plays out the same, with one extra step separating them.
+ Whether we're dealing with a direct /obj/item (throwing a knife at someone) or an /obj/item/projectile with a shrapnel_type, how we handle things plays out the same, with one extra step separating them.
Items simply make their COMSIG_MOVABLE_IMPACT or COMSIG_MOVABLE_IMPACT_ZONE check (against a closed turf or a carbon, respectively), while projectiles check on COMSIG_PROJECTILE_SELF_ON_HIT.
Upon a projectile hitting a valid target, it spawns whatever type of payload it has defined, then has that try to embed itself in the target on its own.
@@ -37,10 +37,10 @@
if(!isitem(target) && !isprojectile(target))
return ELEMENT_INCOMPATIBLE
+ RegisterSignal(target, COMSIG_ELEMENT_ATTACH, .proc/severancePackage)
if(isitem(target))
RegisterSignal(target, COMSIG_MOVABLE_IMPACT_ZONE, .proc/checkEmbedMob)
RegisterSignal(target, COMSIG_MOVABLE_IMPACT, .proc/checkEmbedOther)
- RegisterSignal(target, COMSIG_ELEMENT_ATTACH, .proc/severancePackage)
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/examined)
RegisterSignal(target, COMSIG_EMBED_TRY_FORCE, .proc/tryForceEmbed)
RegisterSignal(target, COMSIG_ITEM_DISABLE_EMBED, .proc/detachFromWeapon)
@@ -68,7 +68,7 @@
if(isitem(target))
UnregisterSignal(target, list(COMSIG_MOVABLE_IMPACT_ZONE, COMSIG_ELEMENT_ATTACH, COMSIG_MOVABLE_IMPACT, COMSIG_PARENT_EXAMINE, COMSIG_EMBED_TRY_FORCE, COMSIG_ITEM_DISABLE_EMBED))
else
- UnregisterSignal(target, list(COMSIG_PROJECTILE_SELF_ON_HIT))
+ UnregisterSignal(target, list(COMSIG_PROJECTILE_SELF_ON_HIT, COMSIG_ELEMENT_ATTACH))
/// Checking to see if we're gonna embed into a human
@@ -79,13 +79,13 @@
var/actual_chance = embed_chance
if(!weapon.isEmbedHarmless()) // all the armor in the world won't save you from a kick me sign
- var/armor = max(victim.run_armor_check(hit_zone, "bullet", silent=TRUE), victim.run_armor_check(hit_zone, "bomb", silent=TRUE)) // we'll be nice and take the better of bullet and bomb armor
+ var/armor = max(victim.run_armor_check(hit_zone, "bullet", silent=TRUE), victim.run_armor_check(hit_zone, "bomb", silent=TRUE)) * 0.5 // we'll be nice and take the better of bullet and bomb armor, halved
if(armor) // we only care about armor penetration if there's actually armor to penetrate
var/pen_mod = -armor + weapon.armour_penetration // even a little bit of armor can make a big difference for shrapnel with large negative armor pen
actual_chance += pen_mod // doing the armor pen as a separate calc just in case this ever gets expanded on
if(actual_chance <= 0)
- victim.visible_message("[weapon] bounces off [victim]'s armor!", "[weapon] bounces off your armor!", vision_distance = COMBAT_MESSAGE_RANGE)
+ victim.visible_message("[weapon] bounces off [victim]'s armor, unable to embed!", "[weapon] bounces off your armor, unable to embed!", vision_distance = COMBAT_MESSAGE_RANGE)
return
var/roll_embed = prob(actual_chance)
@@ -147,7 +147,7 @@
return TRUE
///A different embed element has been attached, so we'll detach and let them handle things
-/datum/element/embed/proc/severancePackage(obj/item/weapon, datum/element/E)
+/datum/element/embed/proc/severancePackage(obj/weapon, datum/element/E)
if(istype(E, /datum/element/embed))
Detach(weapon)
@@ -169,46 +169,35 @@
* it to call tryForceEmbed() on its own embed element (it's out of our hands here, our projectile is done), where it will run through all the checks it needs to.
*/
/datum/element/embed/proc/checkEmbedProjectile(obj/item/projectile/P, atom/movable/firer, atom/hit, angle, hit_zone)
- if(!iscarbon(hit) && !isclosedturf(hit))
+ if(!iscarbon(hit))
Detach(P)
return // we don't care
var/obj/item/payload = new payload_type(get_turf(hit))
- var/did_embed
- if(iscarbon(hit))
- var/mob/living/carbon/C = hit
- var/obj/item/bodypart/limb
- limb = C.get_bodypart(hit_zone)
- if(!limb)
- limb = C.get_bodypart()
- did_embed = payload.tryEmbed(limb)
- else
- did_embed = payload.tryEmbed(hit)
+ if(istype(payload, /obj/item/shrapnel/bullet))
+ payload.name = P.name
+ payload.embedding = P.embedding
+ payload.updateEmbedding()
+ var/mob/living/carbon/C = hit
+ var/obj/item/bodypart/limb = C.get_bodypart(hit_zone)
+ if(!limb)
+ limb = C.get_bodypart()
- if(!did_embed)
- payload.failedEmbed()
+ payload.tryEmbed(limb)
Detach(P)
/**
- * tryForceEmbed() is called here when we fire COMSIG_EMBED_TRY_FORCE from [/obj/item/proc/tryEmbed]. Mostly, this means we're a piece of shrapnel from a projectile that just impacted something, and we're trying to embed in it.
- *
- * The reason for this extra mucking about is avoiding having to do an extra hitby(), and annoying the target by impacting them once with the projectile, then again with the shrapnel (which likely represents said bullet), and possibly
- * AGAIN if we actually embed. This way, we save on at least one message. Runs the standard embed checks on the mob/turf.
- *
* Arguments:
- * * I- what we're trying to embed, obviously
- * * target- what we're trying to shish-kabob, either a bodypart, a carbon, or a closed turf
+ * * I- the item we're trying to insert into the target
+ * * target- what we're trying to shish-kabob, either a bodypart or a carbon
* * hit_zone- if our target is a carbon, try to hit them in this zone, if we don't have one, pick a random one. If our target is a bodypart, we already know where we're hitting.
* * forced- if we want this to succeed 100%
*/
/datum/element/embed/proc/tryForceEmbed(obj/item/I, atom/target, hit_zone, forced=FALSE)
var/obj/item/bodypart/limb
var/mob/living/carbon/C
- var/turf/closed/T
-
if(!forced && !prob(embed_chance))
return
-
if(iscarbon(target))
C = target
if(!hit_zone)
@@ -218,10 +207,5 @@
limb = target
hit_zone = limb.body_zone
C = limb.owner
- else if(isclosedturf(target))
- T = target
-
- if(C)
- return checkEmbedMob(I, C, hit_zone, forced=TRUE)
- else if(T)
- return checkEmbedOther(I, T, forced=TRUE)
+ checkEmbedMob(I, C, hit_zone, forced=TRUE)
+ return TRUE
diff --git a/code/datums/elements/photosynthesis.dm b/code/datums/elements/photosynthesis.dm
index 93e4369b8b..4fe0615b1f 100644
--- a/code/datums/elements/photosynthesis.dm
+++ b/code/datums/elements/photosynthesis.dm
@@ -60,7 +60,7 @@
if(L.stat == DEAD)
continue
if(light_nutrition_gain)
- L.adjust_nutrition(light_amount * light_nutrition_gain * attached_atoms[AM], NUTRITION_LEVEL_FULL)
+ L.adjust_nutrition(light_amount * light_nutrition_gain * attached_atoms[AM], NUTRITION_LEVEL_WELL_FED)
if(light_amount > bonus_lum || light_amount < malus_lum)
var/mult = ((light_amount > bonus_lum) ? 1 : -1) * attached_atoms[AM]
if(light_bruteheal)
diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm
index dc32902e5e..dc9569a4d5 100644
--- a/code/datums/explosion.dm
+++ b/code/datums/explosion.dm
@@ -196,14 +196,12 @@ GLOBAL_LIST_EMPTY(explosions)
//------- EX_ACT AND TURF FIRES -------
- if(T == epicenter) // Ensures explosives detonating from bags trigger other explosives in that bag
- var/list/items = list()
- for(var/I in T)
- var/atom/A = I
- if (!(A.flags_1 & PREVENT_CONTENTS_EXPLOSION_1)) //The atom/contents_explosion() proc returns null if the contents ex_acting has been handled by the atom, and TRUE if it hasn't.
- items += A.GetAllContents()
- for(var/O in items)
- var/atom/A = O
+ if((T == epicenter) && !QDELETED(explosion_source) && ismovable(explosion_source) && (get_turf(explosion_source) == T)) // Ensures explosives detonating from bags trigger other explosives in that bag
+ var/list/atoms = list()
+ for(var/atom/A in explosion_source.loc) // the ismovableatom check 2 lines above makes sure we don't nuke an /area
+ atoms += A
+ for(var/i in atoms)
+ var/atom/A = i
if(!QDELETED(A))
A.ex_act(dist)
diff --git a/code/datums/mutations/actions.dm b/code/datums/mutations/actions.dm
index 7e6d567cfa..bd9ecaeeaa 100644
--- a/code/datums/mutations/actions.dm
+++ b/code/datums/mutations/actions.dm
@@ -410,7 +410,7 @@
throw_speed = 4
embedding = list("embedded_pain_multiplier" = 4, "embed_chance" = 100, "embedded_fall_chance" = 0)
w_class = WEIGHT_CLASS_SMALL
- sharpness = IS_SHARP
+ sharpness = SHARP_POINTY
var/mob/living/carbon/human/fired_by
/// if we missed our target
var/missed = TRUE
diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm
index bc7b9171a8..5d363124d9 100644
--- a/code/datums/mutations/hulk.dm
+++ b/code/datums/mutations/hulk.dm
@@ -27,6 +27,24 @@
target.attack_hulk(owner)
return INTERRUPT_UNARMED_ATTACK | NO_AUTO_CLICKDELAY_HANDLING
+/**
+ *Checks damage of a hulk's arm and applies bone wounds as necessary.
+ *
+ *Called by specific atoms being attacked, such as walls. If an atom
+ *does not call this proc, than punching that atom will not cause
+ *arm breaking (even if the atom deals recoil damage to hulks).
+ *Arguments:
+ *arg1 is the arm to evaluate damage of and possibly break.
+ */
+/datum/mutation/human/hulk/proc/break_an_arm(obj/item/bodypart/arm)
+ switch(arm.brute_dam)
+ if(45 to 50)
+ arm.force_wound_upwards(/datum/wound/blunt/critical)
+ if(41 to 45)
+ arm.force_wound_upwards(/datum/wound/blunt/severe)
+ if(35 to 41)
+ arm.force_wound_upwards(/datum/wound/blunt/moderate)
+
/datum/mutation/human/hulk/on_life()
if(owner.health < 0)
on_losing(owner)
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index aa27c6424e..6e59d4fa2c 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -97,6 +97,21 @@
duration = set_duration
return ..()
+/datum/status_effect/off_balance
+ id = "offbalance"
+ alert_type = null
+
+/datum/status_effect/off_balance/on_creation(mob/living/new_owner, set_duration)
+ if(isnum(set_duration))
+ duration = set_duration
+ return ..()
+
+/datum/status_effect/off_balance/on_remove()
+ var/active_item = owner.get_active_held_item()
+ if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
+ owner.visible_message("[owner.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE)
+ return ..()
+
/obj/screen/alert/status_effect/asleep
name = "Asleep"
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
@@ -433,7 +448,7 @@
var/still_bleeding = FALSE
for(var/thing in throat.wounds)
var/datum/wound/W = thing
- if(W.wound_type == WOUND_LIST_CUT && W.severity > WOUND_SEVERITY_MODERATE)
+ if(W.wound_type == WOUND_SLASH && W.severity > WOUND_SEVERITY_MODERATE)
still_bleeding = TRUE
break
if(!still_bleeding)
@@ -547,8 +562,8 @@
owner.DefaultCombatKnockdown(15, TRUE, FALSE, 15)
if(iscarbon(owner))
var/mob/living/carbon/C = owner
- C.silent = max(2, C.silent)
- C.stuttering = max(5, C.stuttering)
+ C.silent = max(5, C.silent) //Increased, now lasts until five seconds after it ends, instead of 2
+ C.stuttering = max(10, C.stuttering) //Increased, now lasts for five seconds after the mute ends, instead of 3
if(!old_health)
old_health = owner.health
if(!old_oxyloss)
diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm
index 91440d36de..045b1b257d 100644
--- a/code/datums/status_effects/wound_effects.dm
+++ b/code/datums/status_effects/wound_effects.dm
@@ -117,8 +117,7 @@
/datum/status_effect/wound/on_creation(mob/living/new_owner, incoming_wound)
. = ..()
- var/datum/wound/W = incoming_wound
- linked_wound = W
+ linked_wound = incoming_wound
linked_limb = linked_wound.limb
/datum/status_effect/wound/on_remove()
@@ -140,9 +139,9 @@
// bones
-/datum/status_effect/wound/bone
+/datum/status_effect/wound/blunt
-/datum/status_effect/wound/bone/interact_speed_modifier()
+/datum/status_effect/wound/blunt/interact_speed_modifier()
var/mob/living/carbon/C = owner
if(C.get_active_hand() == linked_limb)
@@ -151,7 +150,7 @@
return 1
-/datum/status_effect/wound/bone/action_cooldown_mod()
+/datum/status_effect/wound/blunt/action_cooldown_mod()
var/mob/living/carbon/C = owner
if(C.get_active_hand() == linked_limb)
@@ -159,24 +158,34 @@
return 1
-/datum/status_effect/wound/bone/moderate
+/datum/status_effect/wound/blunt/moderate
id = "disjoint"
-/datum/status_effect/wound/bone/severe
+/datum/status_effect/wound/blunt/severe
id = "hairline"
-/datum/status_effect/wound/bone/critical
+/datum/status_effect/wound/blunt/critical
id = "compound"
// cuts
-/datum/status_effect/wound/cut/moderate
+/datum/status_effect/wound/slash/moderate
id = "abrasion"
-/datum/status_effect/wound/cut/severe
+/datum/status_effect/wound/slash/severe
id = "laceration"
-/datum/status_effect/wound/cut/critical
+/datum/status_effect/wound/slash/critical
id = "avulsion"
+// pierce
+/datum/status_effect/wound/pierce/moderate
+ id = "breakage"
+
+/datum/status_effect/wound/pierce/severe
+ id = "puncture"
+
+/datum/status_effect/wound/pierce/critical
+ id = "rupture"
+
// burns
/datum/status_effect/wound/burn/moderate
id = "seconddeg"
diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm
index 87126ae28f..68b5d6f987 100644
--- a/code/datums/traits/negative.dm
+++ b/code/datums/traits/negative.dm
@@ -14,7 +14,7 @@
if(NOBLOOD in H.dna.species.species_traits) //can't lose blood if your species doesn't have any
return
else
- quirk_holder.blood_volume -= 0.275
+ quirk_holder.blood_volume -= 0.2
/datum/quirk/depression
name = "Depression"
@@ -54,7 +54,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
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
+ heirloom_type = /obj/item/healthanalyzer
if("Paramedic")
heirloom_type = /obj/item/lighter
if("Station Engineer")
@@ -337,10 +337,8 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
dumb_thing = FALSE //only once per life
if(prob(1))
new/obj/item/reagent_containers/food/snacks/pastatomato(get_turf(H)) //now that's what I call spaghetti code
+
// small chance to make eye contact with inanimate objects/mindless mobs because of nerves
-
-
-
/datum/quirk/social_anxiety/proc/looks_at_floor(datum/source, atom/A)
var/mob/living/mind_check = A
if(prob(85) || (istype(mind_check) && mind_check.mind))
diff --git a/code/datums/wounds/_scars.dm b/code/datums/wounds/_scars.dm
index bfbaab835e..8cd0d8a047 100644
--- a/code/datums/wounds/_scars.dm
+++ b/code/datums/wounds/_scars.dm
@@ -53,8 +53,12 @@
if(victim)
LAZYADD(victim.all_scars, src)
- description = pick(W.scarring_descriptions)
- precise_location = pick(limb.specific_locations)
+ if(victim && victim.get_biological_state() == BIO_JUST_BONE)
+ description = pick(strings(BONE_SCAR_FILE, W.scar_keyword)) || "general disfigurement"
+ else
+ description = pick(strings(FLESH_SCAR_FILE, W.scar_keyword)) || "general disfigurement"
+
+ precise_location = pick(strings(SCAR_LOC_FILE, limb.body_zone))
switch(W.severity)
if(WOUND_SEVERITY_MODERATE)
visibility = 2
@@ -62,6 +66,9 @@
visibility = 3
if(WOUND_SEVERITY_CRITICAL)
visibility = 5
+ if(WOUND_SEVERITY_LOSS)
+ visibility = 7
+ precise_location = "amputation"
/// Used when we finalize a scar from a healing cut
/datum/scar/proc/lazy_attach(obj/item/bodypart/BP, datum/wound/W)
@@ -71,10 +78,11 @@
LAZYADD(victim.all_scars, src)
/// Used to "load" a persistent scar
-/datum/scar/proc/load(obj/item/bodypart/BP, description, specific_location, severity=WOUND_SEVERITY_SEVERE)
- if(!(BP.body_zone in applicable_zones))
+/datum/scar/proc/load(obj/item/bodypart/BP, version, description, specific_location, severity=WOUND_SEVERITY_SEVERE)
+ if(!(BP.body_zone in applicable_zones) || !BP.is_organic_limb())
qdel(src)
return
+
limb = BP
src.severity = severity
LAZYADD(limb.scars, src)
@@ -90,6 +98,8 @@
visibility = 3
if(WOUND_SEVERITY_CRITICAL)
visibility = 5
+ if(WOUND_SEVERITY_LOSS)
+ visibility = 7
return TRUE
/// What will show up in examine_more() if this scar is visible
@@ -102,9 +112,12 @@
if(WOUND_SEVERITY_MODERATE)
msg = "[msg]"
if(WOUND_SEVERITY_SEVERE)
- msg = "[msg]"
+ msg = "[msg]"
if(WOUND_SEVERITY_CRITICAL)
- msg = "[msg]"
+ msg = "[msg]"
+ if(WOUND_SEVERITY_LOSS)
+ msg = "[victim.p_their(TRUE)] [limb.name] [description]." // different format
+ msg = "[msg]"
return "\t[msg]"
/// Whether a scar can currently be seen by the viewer
@@ -117,12 +130,12 @@
if(!ishuman(victim) || isobserver(viewer) || victim == viewer)
return TRUE
- var/mob/living/carbon/human/H = victim
+ var/mob/living/carbon/human/human_victim = victim
if(istype(limb, /obj/item/bodypart/head))
- if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE)))
+ if((human_victim.wear_mask && (human_victim.wear_mask.flags_inv & HIDEFACE)) || (human_victim.head && (human_victim.head.flags_inv & HIDEFACE)))
return FALSE
else if(limb.scars_covered_by_clothes)
- var/num_covers = LAZYLEN(H.clothingonpart(limb))
+ var/num_covers = LAZYLEN(human_victim.clothingonpart(limb))
if(num_covers + get_dist(viewer, victim) >= visibility)
return FALSE
@@ -131,4 +144,9 @@
/// Used to format a scar to safe in preferences for persistent scars
/datum/scar/proc/format()
if(!fake)
- return "[limb.body_zone]|[description]|[precise_location]|[severity]"
+ return "[SCAR_CURRENT_VERSION]|[limb.body_zone]|[description]|[precise_location]|[severity]"
+
+/// Used to format a scar to safe in preferences for persistent scars
+/datum/scar/proc/format_amputated(body_zone)
+ description = pick(list("is several skintone shades paler than the rest of the body", "is a gruesome patchwork of artificial flesh", "has a large series of attachment scars at the articulation points"))
+ return "[SCAR_CURRENT_VERSION]|[body_zone]|[description]|amputated|[WOUND_SEVERITY_LOSS]"
\ No newline at end of file
diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm
index b1ba49b7ab..29c87b32d4 100644
--- a/code/datums/wounds/_wounds.dm
+++ b/code/datums/wounds/_wounds.dm
@@ -33,15 +33,13 @@
/// Either WOUND_SEVERITY_TRIVIAL (meme wounds like stubbed toe), WOUND_SEVERITY_MODERATE, WOUND_SEVERITY_SEVERE, or WOUND_SEVERITY_CRITICAL (or maybe WOUND_SEVERITY_LOSS)
var/severity = WOUND_SEVERITY_MODERATE
- /// The list of wounds it belongs in, WOUND_LIST_BONE, WOUND_LIST_CUT, or WOUND_LIST_BURN
+ /// The list of wounds it belongs in, WOUND_LIST_BLUNT, WOUND_LIST_SLASH, or WOUND_LIST_BURN
var/wound_type
/// What body zones can we affect
var/list/viable_zones = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
/// Who owns the body part that we're wounding
var/mob/living/carbon/victim = null
- /// If we only work on organics (everything right now)
- var/organic_only = TRUE
/// The bodypart we're parented to
var/obj/item/bodypart/limb = null
@@ -51,8 +49,6 @@
var/list/treatable_by_grabbed
/// Tools with the specified tool flag will also be able to try directly treating this wound
var/treatable_tool
- /// Set to TRUE if we don't give a shit about the patient's comfort and are allowed to just use any random sharp thing on this wound. Will require an aggressive grab or more to perform
- var/treatable_sharp
/// How long it will take to treat this wound with a standard effective tool, assuming it doesn't need surgery
var/base_treat_time = 5 SECONDS
@@ -65,17 +61,13 @@
/// How much we're contributing to this limb's bleed_rate
var/blood_flow
- /// The minimum we need to roll on [/obj/item/bodypart/proc/check_wounding()] to begin suffering this wound, see check_wounding_mods() for more
+ /// The minimum we need to roll on [/obj/item/bodypart/proc/check_wounding] to begin suffering this wound, see check_wounding_mods() for more
var/threshold_minimum
/// How much having this wound will add to all future check_wounding() rolls on this limb, to allow progression to worse injuries with repeated damage
var/threshold_penalty
/// If we need to process each life tick
var/processes = FALSE
- /// If TRUE and an item that can treat multiple different types of coexisting wounds (gauze can be used to splint broken bones, staunch bleeding, and cover burns), we get first dibs if we come up first for it, then become nonpriority.
- /// Otherwise, if no untreated wound claims the item, we cycle through the non priority wounds and pick a random one who can use that item.
- var/treat_priority = FALSE
-
/// If having this wound makes currently makes the parent bodypart unusable
var/disabling
@@ -89,12 +81,15 @@
var/cryo_progress
/// What kind of scars this wound will create description wise once healed
- var/list/scarring_descriptions = list("general disfigurement")
+ var/scar_keyword = "generic"
/// If we've already tried scarring while removing (since remove_wound calls qdel, and qdel calls remove wound, .....) TODO: make this cleaner
var/already_scarred = FALSE
/// If we forced this wound through badmin smite, we won't count it towards the round totals
var/from_smite
+ /// What flags apply to this wound
+ var/wound_flags = (FLESH_WOUND | BONE_WOUND | ACCEPTS_GAUZE)
+
/datum/wound/Destroy()
if(attached_surgery)
QDEL_NULL(attached_surgery)
@@ -115,13 +110,13 @@
* * smited- If this is a smite, we don't care about this wound for stat tracking purposes (not yet implemented)
*/
/datum/wound/proc/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE)
- if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || isalien(L.owner))
+ if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || isalien(L.owner) || !L.is_organic_limb())
qdel(src)
return
if(ishuman(L.owner))
var/mob/living/carbon/human/H = L.owner
- if(organic_only && ((NOBLOOD in H.dna.species.species_traits) || !L.is_organic_limb()))
+ if(((wound_flags & BONE_WOUND) && !(HAS_BONE in H.dna.species.species_traits)) || ((wound_flags & FLESH_WOUND) && !(HAS_FLESH in H.dna.species.species_traits)))
qdel(src)
return
@@ -161,7 +156,7 @@
victim.visible_message(msg, "Your [limb.name] [occur_text]!", vision_distance = vis_dist)
if(sound_effect)
- playsound(L.owner, sound_effect, 60 + 20 * severity, TRUE)
+ playsound(L.owner, sound_effect, 70 + 20 * severity, TRUE)
if(!demoted)
wound_injury(old_wound)
@@ -181,7 +176,7 @@
SEND_SIGNAL(victim, COMSIG_CARBON_LOSE_WOUND, src, limb)
if(limb && !ignore_limb)
LAZYREMOVE(limb.wounds, src)
- limb.update_wounds()
+ limb.update_wounds(replaced)
/**
* replace_wound() is used when you want to replace the current wound with a new wound, presumably of the same category, just of a different severity (either up or down counts)
@@ -189,7 +184,7 @@
* This proc actually instantiates the new wound based off the specific type path passed, then returns the new instantiated wound datum.
*
* Arguments:
- * * new_type- The TYPE PATH of the wound you want to replace this, like /datum/wound/brute/cut/severe
+ * * new_type- The TYPE PATH of the wound you want to replace this, like /datum/wound/slash/severe
* * smited- If this is a smite, we don't care about this wound for stat tracking purposes (not yet implemented)
*/
/datum/wound/proc/replace_wound(new_type, smited = FALSE)
@@ -206,7 +201,6 @@
/// Additional beneficial effects when the wound is gained, in case you want to give a temporary boost to allow the victim to try an escape or last stand
/datum/wound/proc/second_wind()
-
switch(severity)
if(WOUND_SEVERITY_MODERATE)
victim.reagents.add_reagent(/datum/reagent/determination, WOUND_DETERMINATION_MODERATE)
@@ -214,11 +208,13 @@
victim.reagents.add_reagent(/datum/reagent/determination, WOUND_DETERMINATION_SEVERE)
if(WOUND_SEVERITY_CRITICAL)
victim.reagents.add_reagent(/datum/reagent/determination, WOUND_DETERMINATION_CRITICAL)
+ if(WOUND_SEVERITY_LOSS)
+ victim.reagents.add_reagent(/datum/reagent/determination, WOUND_DETERMINATION_LOSS)
/**
- * try_treating() is an intercept run from [/mob/living/carbon/attackby()] right after surgeries but before anything else. Return TRUE here if the item is something that is relevant to treatment to take over the interaction.
+ * try_treating() is an intercept run from [/mob/living/carbon/proc/attackby] right after surgeries but before anything else. Return TRUE here if the item is something that is relevant to treatment to take over the interaction.
*
- * This proc leads into [/datum/wound/proc/treat()] and probably shouldn't be added onto in children types. You can specify what items or tools you want to be intercepted
+ * This proc leads into [/datum/wound/proc/treat] and probably shouldn't be added onto in children types. You can specify what items or tools you want to be intercepted
* with var/list/treatable_by and var/treatable_tool, then if an item fulfills one of those requirements and our wound claims it first, it goes over to treat() and treat_self().
*
* Arguments:
@@ -258,7 +254,7 @@
treat(I, user)
return TRUE
-/// Return TRUE if we have an item that can only be used while aggro grabbed (unhanded aggro grab treatments go in [/datum/wound/proc/try_handling()]). Treatment is still is handled in [/datum/wound/proc/treat()]
+/// Return TRUE if we have an item that can only be used while aggro grabbed (unhanded aggro grab treatments go in [/datum/wound/proc/try_handling]). Treatment is still is handled in [/datum/wound/proc/treat]
/datum/wound/proc/check_grab_treatments(obj/item/I, mob/user)
return FALSE
@@ -288,10 +284,22 @@
if(cryo_progress > 33 * severity)
qdel(src)
+/// When synthflesh is applied to the victim, we call this. No sense in setting up an entire chem reaction system for wounds when we only care for a few chems. Probably will change in the future
+/datum/wound/proc/on_synthflesh(power)
+ return
+
+/// Called when the patient is undergoing stasis, so that having fully treated a wound doesn't make you sit there helplessly until you think to unbuckle them
+/datum/wound/proc/on_stasis()
+ return
+
/// Called when we're crushed in an airlock or firedoor, for one of the improvised joint dislocation fixes
/datum/wound/proc/crush()
return
+/// Used when we're being dragged while bleeding, the value we return is how much bloodloss this wound causes from being dragged. Since it's a proc, you can let bandages soak some of the blood
+/datum/wound/proc/drag_bleed_amount()
+ return
+
/**
* get_examine_description() is used in carbon/examine and human/examine to show the status of this wound. Useful if you need to show some status like the wound being splinted or bandaged.
*
@@ -301,7 +309,8 @@
* * mob/user: The user examining the wound's owner, if that matters
*/
/datum/wound/proc/get_examine_description(mob/user)
- return "[victim.p_their(TRUE)] [limb.name] [examine_desc]!"
+ . = "[victim.p_their(TRUE)] [limb.name] [examine_desc]"
+ . = severity <= WOUND_SEVERITY_MODERATE ? "[.]." : "[.]!"
/datum/wound/proc/get_scanner_description(mob/user)
return "Type: [name]\nSeverity: [severity_text()]\nDescription: [desc]\nRecommended Treatment: [treat_text]"
diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm
index 80d922cba3..128c860a6d 100644
--- a/code/datums/wounds/bones.dm
+++ b/code/datums/wounds/bones.dm
@@ -1,4 +1,3 @@
-
/*
Bones
*/
@@ -7,12 +6,10 @@
/*
Base definition
*/
-/datum/wound/brute/bone
- sound_effect = 'sound/effects/crack1.ogg'
- wound_type = WOUND_LIST_BONE
-
- /// The item we're currently splinted with, if there is one
- var/obj/item/stack/splinted
+/datum/wound/blunt
+ sound_effect = 'sound/effects/wounds/crack1.ogg'
+ wound_type = WOUND_BLUNT
+ wound_flags = (BONE_WOUND | ACCEPTS_GAUZE)
/// Have we been taped?
var/taped
@@ -31,12 +28,12 @@
/// How long do we wait +/- 20% for the next trauma?
var/trauma_cycle_cooldown
/// If this is a chest wound and this is set, we have this chance to cough up blood when hit in the chest
- var/chance_internal_bleeding = 0
+ var/internal_bleeding_chance = 0
/*
Overwriting of base procs
*/
-/datum/wound/brute/bone/wound_injury(datum/wound/old_wound = null)
+/datum/wound/blunt/wound_injury(datum/wound/old_wound = null)
if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group)
processes = TRUE
active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND)
@@ -53,14 +50,14 @@
update_inefficiencies()
-/datum/wound/brute/bone/remove_wound(ignore_limb, replaced)
+/datum/wound/blunt/remove_wound(ignore_limb, replaced)
limp_slowdown = 0
QDEL_NULL(active_trauma)
if(victim)
UnregisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK)
return ..()
-/datum/wound/brute/bone/handle_process()
+/datum/wound/blunt/handle_process()
. = ..()
if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle)
if(active_trauma)
@@ -86,7 +83,7 @@
remove_wound()
/// If we're a human who's punching something with a broken arm, we might hurt ourselves doing so
-/datum/wound/brute/bone/proc/attack_with_hurt_hand(mob/M, atom/target, proximity)
+/datum/wound/blunt/proc/attack_with_hurt_hand(mob/M, atom/target, proximity)
if(victim.get_active_hand() != limb || victim.a_intent == INTENT_HELP || !ismob(target) || severity <= WOUND_SEVERITY_MODERATE)
return
@@ -104,61 +101,54 @@
limb.receive_damage(brute=rand(3,7))
return COMPONENT_NO_ATTACK_HAND
-/datum/wound/brute/bone/receive_damage(wounding_type, wounding_dmg, wound_bonus)
- if(!victim)
+/datum/wound/blunt/receive_damage(wounding_type, wounding_dmg, wound_bonus)
+ if(!victim || wounding_dmg < WOUND_MINIMUM_DAMAGE)
return
+ if(ishuman(victim))
+ var/mob/living/carbon/human/human_victim = victim
+ if(NOBLOOD in human_victim.dna?.species.species_traits)
+ return
- if(limb.body_zone == BODY_ZONE_CHEST && victim.blood_volume && prob(chance_internal_bleeding + wounding_dmg))
+ if(limb.body_zone == BODY_ZONE_CHEST && victim.blood_volume && prob(internal_bleeding_chance + wounding_dmg))
var/blood_bled = rand(1, wounding_dmg * (severity == WOUND_SEVERITY_CRITICAL ? 2 : 1.5)) // 12 brute toolbox can cause up to 18/24 bleeding with a severe/critical chest wound
switch(blood_bled)
if(1 to 6)
victim.bleed(blood_bled, TRUE)
if(7 to 13)
- victim.visible_message("[victim] coughs up a bit of blood from the blow to [victim.p_their()] chest.", "You cough up a bit of blood from the blow to your chest.")
+ victim.visible_message("[victim] coughs up a bit of blood from the blow to [victim.p_their()] chest.", "You cough up a bit of blood from the blow to your chest.", vision_distance=COMBAT_MESSAGE_RANGE)
victim.bleed(blood_bled, TRUE)
if(14 to 19)
- victim.visible_message("[victim] spits out a string of blood from the blow to [victim.p_their()] chest!", "You spit out a string of blood from the blow to your chest!")
+ victim.visible_message("[victim] spits out a string of blood from the blow to [victim.p_their()] chest!", "You spit out a string of blood from the blow to your chest!", vision_distance=COMBAT_MESSAGE_RANGE)
new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
victim.bleed(blood_bled)
if(20 to INFINITY)
- victim.visible_message("[victim] chokes up a spray of blood from the blow to [victim.p_their()] chest!", "You choke up on a spray of blood from the blow to your chest!")
+ victim.visible_message("[victim] chokes up a spray of blood from the blow to [victim.p_their()] chest!", "You choke up on a spray of blood from the blow to your chest!", vision_distance=COMBAT_MESSAGE_RANGE)
victim.bleed(blood_bled)
new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
victim.add_splatter_floor(get_step(victim.loc, victim.dir))
- if(!(wounding_type in list(WOUND_SHARP, WOUND_BURN)) || !splinted || wound_bonus == CANT_WOUND)
- return
- splinted.take_damage(wounding_dmg, damage_type = (wounding_type == WOUND_SHARP ? BRUTE : BURN), sound_effect = FALSE)
- if(QDELETED(splinted))
- var/destroyed_verb = (wounding_type == WOUND_SHARP ? "torn" : "burned")
- victim.visible_message("The splint securing [victim]'s [limb.name] is [destroyed_verb] away!", "The splint securing your [limb.name] is [destroyed_verb] away!", vision_distance=COMBAT_MESSAGE_RANGE)
- splinted = null
- treat_priority = TRUE
- update_inefficiencies()
-
-
-/datum/wound/brute/bone/get_examine_description(mob/user)
- if(!splinted && !gelled && !taped)
+/datum/wound/blunt/get_examine_description(mob/user)
+ if(!limb.current_gauze && !gelled && !taped)
return ..()
- var/msg = ""
- if(!splinted)
- msg = "[victim.p_their(TRUE)] [limb.name] [examine_desc]"
+ var/list/msg = list()
+ if(!limb.current_gauze)
+ msg += "[victim.p_their(TRUE)] [limb.name] [examine_desc]"
else
- var/splint_condition = ""
+ var/sling_condition = ""
// how much life we have left in these bandages
- switch(splinted.obj_integrity / splinted.max_integrity * 100)
+ switch(limb.current_gauze.obj_integrity / limb.current_gauze.max_integrity * 100)
if(0 to 25)
- splint_condition = "just barely "
+ sling_condition = "just barely "
if(25 to 50)
- splint_condition = "loosely "
+ sling_condition = "loosely "
if(50 to 75)
- splint_condition = "mostly "
+ sling_condition = "mostly "
if(75 to INFINITY)
- splint_condition = "tightly "
+ sling_condition = "tightly "
- msg = "[victim.p_their(TRUE)] [limb.name] is [splint_condition] fastened in a splint of [splinted.name]"
+ msg += "[victim.p_their(TRUE)] [limb.name] is [sling_condition] fastened in a sling of [limb.current_gauze.name]"
if(taped)
msg += ", and appears to be reforming itself under some surgical tape!"
@@ -166,58 +156,35 @@
msg += ", with fizzing flecks of blue bone gel sparking off the bone!"
else
msg += "!"
- return "[msg]"
+ return "[msg.Join()]"
/*
- New common procs for /datum/wound/brute/bone/
+ New common procs for /datum/wound/blunt/
*/
-/datum/wound/brute/bone/proc/update_inefficiencies()
+/datum/wound/blunt/proc/update_inefficiencies()
if(limb.body_zone in list(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
- if(splinted)
- limp_slowdown = initial(limp_slowdown) * splinted.splint_factor
+ if(limb.current_gauze)
+ limp_slowdown = initial(limp_slowdown) * limb.current_gauze.splint_factor
else
limp_slowdown = initial(limp_slowdown)
victim.apply_status_effect(STATUS_EFFECT_LIMP)
else if(limb.body_zone in list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
- if(splinted)
- interaction_efficiency_penalty = 1 + ((interaction_efficiency_penalty - 1) * splinted.splint_factor)
+ if(limb.current_gauze)
+ interaction_efficiency_penalty = 1 + ((interaction_efficiency_penalty - 1) * limb.current_gauze.splint_factor)
else
interaction_efficiency_penalty = interaction_efficiency_penalty
- if(initial(disabling) && splinted)
- disabling = FALSE
- else if(initial(disabling))
- disabling = TRUE
+ if(initial(disabling))
+ disabling = !limb.current_gauze
limb.update_wounds()
-/*
- BEWARE OF REDUNDANCY AHEAD THAT I MUST PARE DOWN
-*/
-
-/datum/wound/brute/bone/proc/splint(obj/item/stack/I, mob/user)
- if(splinted && splinted.splint_factor >= I.splint_factor)
- to_chat(user, "The splint already on [user == victim ? "your" : "[victim]'s"] [limb.name] is better than you can do with [I].")
- return
-
- user.visible_message("[user] begins splinting [victim]'s [limb.name] with [I].", "You begin splinting [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
-
- if(!do_after(user, base_treat_time * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, .proc/still_exists)))
- return
-
- user.visible_message("[user] finishes splinting [victim]'s [limb.name]!", "You finish splinting [user == victim ? "your" : "[victim]'s"] [limb.name]!")
- treat_priority = FALSE
- splinted = new I.type(limb)
- splinted.amount = 1
- I.use(1)
- update_inefficiencies()
-
/*
Moderate (Joint Dislocation)
*/
-/datum/wound/brute/bone/moderate
+/datum/wound/blunt/moderate
name = "Joint Dislocation"
desc = "Patient's bone has been unset from socket, causing pain and reduced motor function."
treat_text = "Recommended application of bonesetter to affected limb, though manual relocation by applying an aggressive grab to the patient and helpfully interacting with afflicted limb may suffice."
@@ -226,19 +193,20 @@
severity = WOUND_SEVERITY_MODERATE
viable_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
interaction_efficiency_penalty = 1.5
- limp_slowdown = 3
- threshold_minimum = 35
+ limp_slowdown = 1.5
+ threshold_minimum = 45
threshold_penalty = 15
treatable_tool = TOOL_BONESET
- status_effect_type = /datum/status_effect/wound/bone/moderate
- scarring_descriptions = list("light discoloring", "a slight blue tint")
+ wound_flags = (BONE_WOUND)
+ status_effect_type = /datum/status_effect/wound/blunt/moderate
+ scar_keyword = "bluntmoderate"
-/datum/wound/brute/bone/moderate/crush()
+/datum/wound/blunt/moderate/crush()
if(prob(33))
victim.visible_message("[victim]'s dislocated [limb.name] pops back into place!", "Your dislocated [limb.name] pops back into place! Ow!")
remove_wound()
-/datum/wound/brute/bone/moderate/try_handling(mob/living/carbon/human/user)
+/datum/wound/blunt/moderate/try_handling(mob/living/carbon/human/user)
if(user.pulling != victim || user.zone_selected != limb.body_zone || user.a_intent == INTENT_GRAB)
return FALSE
@@ -256,7 +224,7 @@
return TRUE
/// If someone is snapping our dislocated joint back into place by hand with an aggro grab and help intent
-/datum/wound/brute/bone/moderate/proc/chiropractice(mob/living/carbon/human/user)
+/datum/wound/blunt/moderate/proc/chiropractice(mob/living/carbon/human/user)
var/time = base_treat_time
if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, .proc/still_exists)))
@@ -275,7 +243,7 @@
chiropractice(user)
/// If someone is snapping our dislocated joint into a fracture by hand with an aggro grab and harm or disarm intent
-/datum/wound/brute/bone/moderate/proc/malpractice(mob/living/carbon/human/user)
+/datum/wound/blunt/moderate/proc/malpractice(mob/living/carbon/human/user)
var/time = base_treat_time
if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, .proc/still_exists)))
@@ -293,7 +261,7 @@
malpractice(user)
-/datum/wound/brute/bone/moderate/treat(obj/item/I, mob/user)
+/datum/wound/blunt/moderate/treat(obj/item/I, mob/user)
if(victim == user)
victim.visible_message("[user] begins resetting [victim.p_their()] [limb.name] with [I].", "You begin resetting your [limb.name] with [I]...")
else
@@ -317,56 +285,57 @@
Severe (Hairline Fracture)
*/
-/datum/wound/brute/bone/severe
+/datum/wound/blunt/severe
name = "Hairline Fracture"
desc = "Patient's bone has suffered a crack in the foundation, causing serious pain and reduced limb functionality."
- treat_text = "Recommended light surgical application of bone gel, though splinting will prevent worsening situation."
- examine_desc = "appears bruised and grotesquely swollen"
-
+ treat_text = "Recommended light surgical application of bone gel, though a sling of medical gauze will prevent worsening situation."
+ examine_desc = "appears grotesquely swollen, its attachment weakened"
occur_text = "sprays chips of bone and develops a nasty looking bruise"
+
severity = WOUND_SEVERITY_SEVERE
interaction_efficiency_penalty = 2
- limp_slowdown = 6
- threshold_minimum = 60
+ limp_slowdown = 4
+ threshold_minimum = 70
threshold_penalty = 30
- treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/gauze, /obj/item/stack/medical/bone_gel)
- status_effect_type = /datum/status_effect/wound/bone/severe
- treat_priority = TRUE
- scarring_descriptions = list("a faded, fist-sized bruise", "a vaguely triangular peel scar")
+ treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/bone_gel)
+ status_effect_type = /datum/status_effect/wound/blunt/severe
+ scar_keyword = "bluntsevere"
brain_trauma_group = BRAIN_TRAUMA_MILD
trauma_cycle_cooldown = 1.5 MINUTES
- chance_internal_bleeding = 40
+ internal_bleeding_chance = 40
+ wound_flags = (BONE_WOUND | ACCEPTS_GAUZE | MANGLES_BONE)
-/datum/wound/brute/bone/critical
+/datum/wound/blunt/critical
name = "Compound Fracture"
desc = "Patient's bones have suffered multiple gruesome fractures, causing significant pain and near uselessness of limb."
treat_text = "Immediate binding of affected limb, followed by surgical intervention ASAP."
- examine_desc = "has a cracked bone sticking out of it"
+ examine_desc = "is mangled and pulped, seemingly held together by tissue alone"
occur_text = "cracks apart, exposing broken bones to open air"
+
severity = WOUND_SEVERITY_CRITICAL
interaction_efficiency_penalty = 4
- limp_slowdown = 9
- sound_effect = 'sound/effects/crack2.ogg'
- threshold_minimum = 115
+ limp_slowdown = 6
+ sound_effect = 'sound/effects/wounds/crack2.ogg'
+ threshold_minimum = 125
threshold_penalty = 50
disabling = TRUE
- treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/gauze, /obj/item/stack/medical/bone_gel)
- status_effect_type = /datum/status_effect/wound/bone/critical
- treat_priority = TRUE
- scarring_descriptions = list("a section of janky skin lines and badly healed scars", "a large patch of uneven skin tone", "a cluster of calluses")
+ treatable_by = list(/obj/item/stack/sticky_tape/surgical, /obj/item/stack/medical/bone_gel)
+ status_effect_type = /datum/status_effect/wound/blunt/critical
+ scar_keyword = "bluntcritical"
brain_trauma_group = BRAIN_TRAUMA_SEVERE
trauma_cycle_cooldown = 2.5 MINUTES
- chance_internal_bleeding = 60
+ internal_bleeding_chance = 60
+ wound_flags = (BONE_WOUND | ACCEPTS_GAUZE | MANGLES_BONE)
// doesn't make much sense for "a" bone to stick out of your head
-/datum/wound/brute/bone/critical/apply_wound(obj/item/bodypart/L, silent, datum/wound/old_wound, smited)
+/datum/wound/blunt/critical/apply_wound(obj/item/bodypart/L, silent, datum/wound/old_wound, smited)
if(L.body_zone == BODY_ZONE_HEAD)
occur_text = "splits open, exposing a bare, cracked skull through the flesh and blood"
examine_desc = "has an unsettling indent, with bits of skull poking out"
. = ..()
/// if someone is using bone gel on our wound
-/datum/wound/brute/bone/proc/gel(obj/item/stack/medical/bone_gel/I, mob/user)
+/datum/wound/blunt/proc/gel(obj/item/stack/medical/bone_gel/I, mob/user)
if(gelled)
to_chat(user, "[user == victim ? "Your" : "[victim]'s"] [limb.name] is already coated with bone gel!")
return
@@ -385,12 +354,12 @@
var/painkiller_bonus = 0
if(victim.drunkenness)
painkiller_bonus += 5
- if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/medicine/morphine))
+ if(victim.reagents?.has_reagent(/datum/reagent/medicine/morphine))
painkiller_bonus += 10
- if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/determination))
+ if(victim.reagents?.has_reagent(/datum/reagent/determination))
painkiller_bonus += 5
- if(prob(25 + (20 * (severity - 2)) - painkiller_bonus)) // 25%/45% chance to fail self-applying with severe and critical wounds, modded by painkillers
+ if(prob(25 + (20 * severity - 2) - painkiller_bonus)) // 25%/45% chance to fail self-applying with severe and critical wounds, modded by painkillers
victim.visible_message("[victim] fails to finish applying [I] to [victim.p_their()] [limb.name], passing out from the pain!", "You black out from the pain of applying [I] to your [limb.name] before you can finish!")
victim.AdjustUnconscious(5 SECONDS)
return
@@ -401,7 +370,7 @@
gelled = TRUE
/// if someone is using surgical tape on our wound
-/datum/wound/brute/bone/proc/tape(obj/item/stack/sticky_tape/surgical/I, mob/user)
+/datum/wound/blunt/proc/tape(obj/item/stack/sticky_tape/surgical/I, mob/user)
if(!gelled)
to_chat(user, "[user == victim ? "Your" : "[victim]'s"] [limb.name] must be coated with bone gel to perform this emergency operation!")
return
@@ -426,15 +395,13 @@
taped = TRUE
processes = TRUE
-/datum/wound/brute/bone/treat(obj/item/I, mob/user)
+/datum/wound/blunt/treat(obj/item/I, mob/user)
if(istype(I, /obj/item/stack/medical/bone_gel))
gel(I, user)
else if(istype(I, /obj/item/stack/sticky_tape/surgical))
tape(I, user)
- else if(istype(I, /obj/item/stack/medical/gauze))
- splint(I, user)
-/datum/wound/brute/bone/get_scanner_description(mob/user)
+/datum/wound/blunt/get_scanner_description(mob/user)
. = ..()
. += "
"
@@ -444,7 +411,7 @@
else if(!taped)
. += "
Continue Alternative Treatment: Apply surgical tape directly to injured limb to begin bone regeneration. Note, this is both excruciatingly painful and slow.\n"
else
- . += "
Note: Bone regeneration in effect. Bone is [round((regen_points_current*100)/regen_points_needed,0.1)]% regenerated.\n"
+ . += "
Note: Bone regeneration in effect. Bone is [round(regen_points_current*100/regen_points_needed)]% regenerated.\n"
if(limb.body_zone == BODY_ZONE_HEAD)
. += "Cranial Trauma Detected: Patient will suffer random bouts of [severity == WOUND_SEVERITY_SEVERE ? "mild" : "severe"] brain traumas until bone is repaired."
diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm
index 6a6629a0c9..f3e22807cf 100644
--- a/code/datums/wounds/burns.dm
+++ b/code/datums/wounds/burns.dm
@@ -1,14 +1,14 @@
-
// TODO: well, a lot really, but specifically I want to add potential fusing of clothing/equipment on the affected area, and limb infections, though those may go in body part code
/datum/wound/burn
a_or_from = "from"
- wound_type = WOUND_LIST_BURN
+ wound_type = WOUND_BURN
processes = TRUE
- sound_effect = 'sound/effects/sizzle1.ogg'
+ sound_effect = 'sound/effects/wounds/sizzle1.ogg'
+ wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
- treatable_by = list(/obj/item/stack/medical/gauze, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh) // sterilizer and alcohol will require reagent treatments, coming soon
+ treatable_by = list(/obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh) // sterilizer and alcohol will require reagent treatments, coming soon
// Flesh damage vars
/// How much damage to our flesh we currently have. Once both this and infestation reach 0, the wound is considered healed
@@ -27,8 +27,6 @@
/// Once we reach infestation beyond WOUND_INFESTATION_SEPSIS, we get this many warnings before the limb is completely paralyzed (you'd have to ignore a really bad burn for a really long time for this to happen)
var/strikes_to_lose_limb = 3
- /// The current bandage we have for this wound (maybe move bandages to the limb?)
- var/obj/item/stack/current_bandage
/datum/wound/burn/handle_process()
. = ..()
@@ -47,15 +45,11 @@
sanitization += 0.3
flesh_healing += 0.5
- if(current_bandage)
- current_bandage.absorption_capacity -= WOUND_BURN_SANITIZATION_RATE
- if(current_bandage.absorption_capacity <= 0)
- victim.visible_message("
Pus soaks through \the [current_bandage] on [victim]'s [limb.name].", "
Pus soaks through \the [current_bandage] on your [limb.name].", vision_distance=COMBAT_MESSAGE_RANGE)
- QDEL_NULL(current_bandage)
- treat_priority = TRUE
+ if(limb.current_gauze)
+ limb.seep_gauze(WOUND_BURN_SANITIZATION_RATE)
if(flesh_healing > 0)
- var/bandage_factor = (current_bandage ? current_bandage.splint_factor : 1)
+ var/bandage_factor = (limb.current_gauze ? limb.current_gauze.splint_factor : 1)
flesh_damage = max(0, flesh_damage - 1)
flesh_healing = max(0, flesh_healing - bandage_factor) // good bandages multiply the length of flesh healing
@@ -67,7 +61,7 @@
// sanitization is checked after the clearing check but before the rest, because we freeze the effects of infection while we have sanitization
if(sanitization > 0)
- var/bandage_factor = (current_bandage ? current_bandage.splint_factor : 1)
+ var/bandage_factor = (limb.current_gauze ? limb.current_gauze.splint_factor : 1)
infestation = max(0, infestation - WOUND_BURN_SANITIZATION_RATE)
sanitization = max(0, sanitization - (WOUND_BURN_SANITIZATION_RATE * bandage_factor))
return
@@ -122,10 +116,10 @@
if(strikes_to_lose_limb <= 0)
return "
[victim.p_their(TRUE)] [limb.name] is completely dead and unrecognizable as organic."
- var/condition = ""
- if(current_bandage)
+ var/list/condition = list("[victim.p_their(TRUE)] [limb.name] [examine_desc]")
+ if(limb.current_gauze)
var/bandage_condition
- switch(current_bandage.absorption_capacity)
+ switch(limb.current_gauze.absorption_capacity)
if(0 to 1.25)
bandage_condition = "nearly ruined "
if(1.25 to 2.75)
@@ -135,7 +129,7 @@
if(4 to INFINITY)
bandage_condition = "clean "
- condition += " underneath a dressing of [bandage_condition] [current_bandage.name]"
+ condition += " underneath a dressing of [bandage_condition] [limb.current_gauze.name]"
else
switch(infestation)
if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE)
@@ -149,7 +143,7 @@
else
condition += "!"
- return "
[victim.p_their(TRUE)] [limb.name] [examine_desc][condition]"
+ return "
[condition.Join()]"
/datum/wound/burn/get_scanner_description(mob/user)
if(strikes_to_lose_limb == 0)
@@ -186,7 +180,7 @@
/// if someone is using ointment on our burns
/datum/wound/burn/proc/ointment(obj/item/stack/medical/ointment/I, mob/user)
user.visible_message("
[user] begins applying [I] to [victim]'s [limb.name]...", "
You begin applying [I] to [user == victim ? "your" : "[victim]'s"] [limb.name]...")
- if(!do_after(user, (user == victim ? I.self_delay : I.other_delay), target = victim))
+ if(!do_after(user, (user == victim ? I.self_delay : I.other_delay), extra_checks = CALLBACK(src, .proc/still_exists)))
return
limb.heal_damage(I.heal_brute, I.heal_burn)
@@ -200,36 +194,6 @@
else
try_treating(I, user)
-/// for use in the burn dressing surgery since we don't want to make them do another do_after obviously
-/datum/wound/burn/proc/force_bandage(obj/item/stack/medical/gauze/I, mob/user)
- QDEL_NULL(current_bandage)
- current_bandage = new I.type(limb)
- current_bandage.amount = 1
- treat_priority = FALSE
- sanitization += I.sanitization
- I.use(1)
-
-/// if someone is wrapping gauze on our burns
-/datum/wound/burn/proc/bandage(obj/item/stack/medical/gauze/I, mob/user)
- if(current_bandage)
- if(current_bandage.absorption_capacity > I.absorption_capacity + 1)
- to_chat(user, "
The [current_bandage] on [victim]'s [limb.name] is still in better condition than your [I.name]!")
- return
- user.visible_message("
[user] begins to redress the burns on [victim]'s [limb.name] with [I]...", "
You begin redressing the burns on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
- else
- user.visible_message("
[user] begins to dress the burns on [victim]'s [limb.name] with [I]...", "
You begin dressing the burns on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
-
- if(!do_after(user, (user == victim ? I.self_delay : I.other_delay), target=victim, extra_checks = CALLBACK(src, .proc/still_exists)))
- return
-
- user.visible_message("
[user] applies [I] to [victim].", "
You apply [I] to [user == victim ? "your" : "[victim]'s"] [limb.name].")
- QDEL_NULL(current_bandage)
- current_bandage = new I.type(limb)
- current_bandage.amount = 1
- treat_priority = FALSE
- sanitization += I.sanitization
- I.use(1)
-
/// if someone is using mesh on our burns
/datum/wound/burn/proc/mesh(obj/item/stack/medical/mesh/I, mob/user)
user.visible_message("
[user] begins wrapping [victim]'s [limb.name] with [I]...", "
You begin wrapping [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
@@ -249,7 +213,7 @@
/// Paramedic UV penlights
/datum/wound/burn/proc/uv(obj/item/flashlight/pen/paramedic/I, mob/user)
- if(I.uv_cooldown > world.time)
+ if(!COOLDOWN_FINISHED(I, uv_cooldown))
to_chat(user, "
[I] is still recharging!")
return
if(infestation <= 0 || infestation < sanitization)
@@ -258,20 +222,29 @@
user.visible_message("
[user] flashes the burns on [victim]'s [limb] with [I].", "
You flash the burns on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I].", vision_distance=COMBAT_MESSAGE_RANGE)
sanitization += I.uv_power
- I.uv_cooldown = world.time + I.uv_cooldown_length
+ COOLDOWN_START(I, uv_cooldown, I.uv_cooldown_length)
/datum/wound/burn/treat(obj/item/I, mob/user)
- if(istype(I, /obj/item/stack/medical/gauze))
- bandage(I, user)
- else if(istype(I, /obj/item/stack/medical/ointment))
+ if(istype(I, /obj/item/stack/medical/ointment))
ointment(I, user)
else if(istype(I, /obj/item/stack/medical/mesh))
mesh(I, user)
else if(istype(I, /obj/item/flashlight/pen/paramedic))
uv(I, user)
-/// basic support for instabitaluri/synthflesh healing flesh damage, more chem support in the future
-/datum/wound/burn/proc/regenerate_flesh(amount)
+// people complained about burns not healing on stasis beds, so in addition to checking if it's cured, they also get the special ability to very slowly heal on stasis beds if they have the healing effects stored
+/datum/wound/burn/on_stasis()
+ . = ..()
+ if(flesh_healing > 0)
+ flesh_damage = max(0, flesh_damage - 0.2)
+ if((flesh_damage <= 0) && (infestation <= 1))
+ to_chat(victim, "
The burns on your [limb.name] have cleared up!")
+ qdel(src)
+ return
+ if(sanitization > 0)
+ infestation = max(0, infestation - WOUND_BURN_SANITIZATION_RATE * 0.2)
+
+/datum/wound/burn/on_synthflesh(amount)
flesh_healing += amount * 0.5 // 20u patch will heal 10 flesh standard
// we don't even care about first degree burns, straight to second
@@ -282,12 +255,12 @@
examine_desc = "is badly burned and breaking out in blisters"
occur_text = "breaks out with violent red burns"
severity = WOUND_SEVERITY_MODERATE
- damage_mulitplier_penalty = 1.1
- threshold_minimum = 40
+ damage_mulitplier_penalty = 1.05
+ threshold_minimum = 50
threshold_penalty = 30 // burns cause significant decrease in limb integrity compared to other wounds
status_effect_type = /datum/status_effect/wound/burn/moderate
flesh_damage = 5
- scarring_descriptions = list("small amoeba-shaped skinmarks", "a faded streak of depressed skin")
+ scar_keyword = "burnmoderate"
/datum/wound/burn/severe
name = "Third Degree Burns"
@@ -296,14 +269,14 @@
examine_desc = "appears seriously charred, with aggressive red splotches"
occur_text = "chars rapidly, exposing ruined tissue and spreading angry red burns"
severity = WOUND_SEVERITY_SEVERE
- damage_mulitplier_penalty = 1.2
- threshold_minimum = 80
+ damage_mulitplier_penalty = 1.1
+ threshold_minimum = 90
threshold_penalty = 40
status_effect_type = /datum/status_effect/wound/burn/severe
- treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/gauze, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh)
+ treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh)
infestation_rate = 0.05 // appx 13 minutes to reach sepsis without any treatment
flesh_damage = 12.5
- scarring_descriptions = list("a large, jagged patch of faded skin", "random spots of shiny, smooth skin", "spots of taut, leathery skin")
+ scar_keyword = "burnsevere"
/datum/wound/burn/critical
name = "Catastrophic Burns"
@@ -312,12 +285,12 @@
examine_desc = "is a ruined mess of blanched bone, melted fat, and charred tissue"
occur_text = "vaporizes as flesh, bone, and fat melt together in a horrifying mess"
severity = WOUND_SEVERITY_CRITICAL
- damage_mulitplier_penalty = 1.3
- sound_effect = 'sound/effects/sizzle2.ogg'
- threshold_minimum = 140
+ damage_mulitplier_penalty = 1.15
+ sound_effect = 'sound/effects/wounds/sizzle2.ogg'
+ threshold_minimum = 150
threshold_penalty = 80
status_effect_type = /datum/status_effect/wound/burn/critical
- treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/gauze, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh)
+ treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh)
infestation_rate = 0.15 // appx 4.33 minutes to reach sepsis without any treatment
flesh_damage = 20
- scarring_descriptions = list("massive, disfiguring keloid scars", "several long streaks of badly discolored and malformed skin", "unmistakeable splotches of dead tissue from serious burns")
+ scar_keyword = "burncritical"
diff --git a/code/datums/wounds/loss.dm b/code/datums/wounds/loss.dm
new file mode 100644
index 0000000000..6c5e536fb2
--- /dev/null
+++ b/code/datums/wounds/loss.dm
@@ -0,0 +1,41 @@
+/datum/wound/loss
+ name = "Dismembered"
+ desc = "oof ouch!!"
+
+ sound_effect = 'sound/effects/dismember.ogg'
+ severity = WOUND_SEVERITY_LOSS
+ threshold_minimum = 180
+ status_effect_type = null
+ scar_keyword = "dismember"
+ wound_flags = null
+
+/// Our special proc for our special dismembering, the wounding type only matters for what text we have
+/datum/wound/loss/proc/apply_dismember(obj/item/bodypart/dismembered_part, wounding_type=WOUND_SLASH)
+ if(!istype(dismembered_part) || !dismembered_part.owner || !(dismembered_part.body_zone in viable_zones) || isalien(dismembered_part.owner) || !dismembered_part.can_dismember())
+ qdel(src)
+ return
+
+ already_scarred = TRUE // so we don't scar a limb we don't have. If I add different levels of amputation desc, do it here
+
+ switch(wounding_type)
+ if(WOUND_BLUNT)
+ occur_text = "is shattered through the last bone holding it together, severing it completely!"
+ if(WOUND_SLASH)
+ occur_text = "is slashed through the last tissue holding it together, severing it completely!"
+ if(WOUND_PIERCE)
+ occur_text = "is pierced through the last tissue holding it together, severing it completely!"
+ if(WOUND_BURN)
+ occur_text = "is completely incinerated, falling to dust!"
+
+ victim = dismembered_part.owner
+
+ var/msg = "
[victim]'s [dismembered_part.name] [occur_text]!"
+
+ victim.visible_message(msg, "
Your [dismembered_part.name] [occur_text]!")
+
+ limb = dismembered_part
+ severity = WOUND_SEVERITY_LOSS
+ second_wind()
+ log_wound(victim, src)
+ dismembered_part.dismember(wounding_type == WOUND_BURN ? BURN : BRUTE)
+ qdel(src)
diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm
new file mode 100644
index 0000000000..56c60b31d7
--- /dev/null
+++ b/code/datums/wounds/pierce.dm
@@ -0,0 +1,170 @@
+/*
+ Pierce
+*/
+
+/datum/wound/pierce
+ sound_effect = 'sound/weapons/slice.ogg'
+ processes = TRUE
+ wound_type = WOUND_PIERCE
+ treatable_by = list(/obj/item/stack/medical/suture)
+ treatable_tool = TOOL_CAUTERY
+ base_treat_time = 3 SECONDS
+ wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
+
+ /// How much blood we start losing when this wound is first applied
+ var/initial_flow
+ /// If gauzed, what percent of the internal bleeding actually clots of the total absorption rate
+ var/gauzed_clot_rate
+
+ /// When hit on this bodypart, we have this chance of losing some blood + the incoming damage
+ var/internal_bleeding_chance
+ /// If we let off blood when hit, the max blood lost is this * the incoming damage
+ var/internal_bleeding_coefficient
+
+/datum/wound/pierce/wound_injury(datum/wound/old_wound)
+ blood_flow = initial_flow
+
+/datum/wound/pierce/receive_damage(wounding_type, wounding_dmg, wound_bonus)
+ if(victim.stat == DEAD || wounding_dmg < 5)
+ return
+ if(victim.blood_volume && prob(internal_bleeding_chance + wounding_dmg))
+ if(limb.current_gauze && limb.current_gauze.splint_factor)
+ wounding_dmg *= (1 - limb.current_gauze.splint_factor)
+ var/blood_bled = rand(1, wounding_dmg * internal_bleeding_coefficient) // 12 brute toolbox can cause up to 15/18/21 bloodloss on mod/sev/crit
+ switch(blood_bled)
+ if(1 to 6)
+ victim.bleed(blood_bled, TRUE)
+ if(7 to 13)
+ victim.visible_message("
Blood droplets fly from the hole in [victim]'s [limb.name].", "
You cough up a bit of blood from the blow to your [limb.name].", vision_distance=COMBAT_MESSAGE_RANGE)
+ victim.bleed(blood_bled, TRUE)
+ if(14 to 19)
+ victim.visible_message("
A small stream of blood spurts from the hole in [victim]'s [limb.name]!", "
You spit out a string of blood from the blow to your [limb.name]!", vision_distance=COMBAT_MESSAGE_RANGE)
+ new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
+ victim.bleed(blood_bled)
+ if(20 to INFINITY)
+ victim.visible_message("
A spray of blood streams from the gash in [victim]'s [limb.name]!", "
You choke up on a spray of blood from the blow to your [limb.name]!", vision_distance=COMBAT_MESSAGE_RANGE)
+ victim.bleed(blood_bled)
+ new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
+ victim.add_splatter_floor(get_step(victim.loc, victim.dir))
+
+/datum/wound/pierce/handle_process()
+ blood_flow = min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW)
+
+ if(victim.bodytemperature < (BODYTEMP_NORMAL - 10))
+ blood_flow -= 0.2
+ if(prob(5))
+ to_chat(victim, "
You feel the [lowertext(name)] in your [limb.name] firming up from the cold!")
+
+ if(victim.reagents?.has_reagent(/datum/reagent/toxin/heparin))
+ blood_flow += 0.5 // old herapin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first
+
+ if(limb.current_gauze)
+ blood_flow -= limb.current_gauze.absorption_rate * gauzed_clot_rate
+ limb.current_gauze.absorption_capacity -= limb.current_gauze.absorption_rate
+
+ if(blood_flow <= 0)
+ qdel(src)
+
+/datum/wound/pierce/on_stasis()
+ . = ..()
+ if(blood_flow <= 0)
+ qdel(src)
+
+/datum/wound/pierce/treat(obj/item/I, mob/user)
+ if(istype(I, /obj/item/stack/medical/suture))
+ suture(I, user)
+ else if(I.tool_behaviour == TOOL_CAUTERY || I.get_temperature() > 300)
+ tool_cauterize(I, user)
+
+/datum/wound/pierce/on_xadone(power)
+ . = ..()
+ blood_flow -= 0.03 * power // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort
+
+/datum/wound/pierce/on_synthflesh(power)
+ . = ..()
+ blood_flow -= 0.05 * power // 20u * 0.05 = -1 blood flow, less than with slashes but still good considering smaller bleed rates
+
+/// If someone is using a suture to close this cut
+/datum/wound/pierce/proc/suture(obj/item/stack/medical/suture/I, mob/user)
+ var/self_penalty_mult = (user == victim ? 1.4 : 1)
+ user.visible_message("
[user] begins stitching [victim]'s [limb.name] with [I]...", "
You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
+ if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, .proc/still_exists)))
+ return
+ user.visible_message("
[user] stitches up some of the bleeding on [victim].", "
You stitch up some of the bleeding on [user == victim ? "yourself" : "[victim]"].")
+ var/blood_sutured = I.stop_bleeding / self_penalty_mult * 0.5
+ blood_flow -= blood_sutured
+ limb.heal_damage(I.heal_brute, I.heal_burn)
+
+ if(blood_flow > 0)
+ try_treating(I, user)
+ else
+ to_chat(user, "
You successfully close the hole in [user == victim ? "your" : "[victim]'s"] [limb.name].")
+
+/// If someone is using either a cautery tool or something with heat to cauterize this pierce
+/datum/wound/pierce/proc/tool_cauterize(obj/item/I, mob/user)
+ var/self_penalty_mult = (user == victim ? 1.5 : 1)
+ user.visible_message("
[user] begins cauterizing [victim]'s [limb.name] with [I]...", "
You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
+ if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, .proc/still_exists)))
+ return
+
+ user.visible_message("
[user] cauterizes some of the bleeding on [victim].", "
You cauterize some of the bleeding on [victim].")
+ limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND)
+ if(prob(30))
+ victim.emote("scream")
+ var/blood_cauterized = (0.6 / self_penalty_mult) * 0.5
+ blood_flow -= blood_cauterized
+
+ if(blood_flow > 0)
+ try_treating(I, user)
+
+/datum/wound/pierce/moderate
+ name = "Minor Breakage"
+ desc = "Patient's skin has been broken open, causing severe bruising and minor internal bleeding in affected area."
+ treat_text = "Treat affected site with bandaging or exposure to extreme cold. In dire cases, brief exposure to vacuum may suffice." // space is cold in ss13, so it's like an ice pack!
+ examine_desc = "has a small, circular hole, gently bleeding"
+ occur_text = "spurts out a thin stream of blood"
+ sound_effect = 'sound/effects/wounds/pierce1.ogg'
+ severity = WOUND_SEVERITY_MODERATE
+ initial_flow = 1.5
+ gauzed_clot_rate = 0.8
+ internal_bleeding_chance = 30
+ internal_bleeding_coefficient = 1.25
+ threshold_minimum = 40
+ threshold_penalty = 15
+ status_effect_type = /datum/status_effect/wound/pierce/moderate
+ scar_keyword = "piercemoderate"
+
+/datum/wound/pierce/severe
+ name = "Open Puncture"
+ desc = "Patient's internal tissue is penetrated, causing sizeable internal bleeding and reduced limb stability."
+ treat_text = "Repair punctures in skin by suture or cautery, extreme cold may also work."
+ examine_desc = "is pierced clear through, with bits of tissue obscuring the open hole"
+ occur_text = "looses a violent spray of blood, revealing a pierced wound"
+ sound_effect = 'sound/effects/wounds/pierce2.ogg'
+ severity = WOUND_SEVERITY_SEVERE
+ initial_flow = 2.25
+ gauzed_clot_rate = 0.6
+ internal_bleeding_chance = 60
+ internal_bleeding_coefficient = 1.5
+ threshold_minimum = 60
+ threshold_penalty = 25
+ status_effect_type = /datum/status_effect/wound/pierce/severe
+ scar_keyword = "piercesevere"
+
+/datum/wound/pierce/critical
+ name = "Ruptured Cavity"
+ desc = "Patient's internal tissue and circulatory system is shredded, causing significant internal bleeding and damage to internal organs."
+ treat_text = "Surgical repair of puncture wound, followed by supervised resanguination."
+ examine_desc = "is ripped clear through, barely held together by exposed bone"
+ occur_text = "blasts apart, sending chunks of viscera flying in all directions"
+ sound_effect = 'sound/effects/wounds/pierce3.ogg'
+ severity = WOUND_SEVERITY_CRITICAL
+ initial_flow = 3
+ gauzed_clot_rate = 0.4
+ internal_bleeding_chance = 80
+ internal_bleeding_coefficient = 1.75
+ threshold_minimum = 110
+ threshold_penalty = 40
+ status_effect_type = /datum/status_effect/wound/pierce/critical
+ scar_keyword = "piercecritical"
+ wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE | MANGLES_FLESH)
diff --git a/code/datums/wounds/cuts.dm b/code/datums/wounds/slash.dm
similarity index 60%
rename from code/datums/wounds/cuts.dm
rename to code/datums/wounds/slash.dm
index 59ce286884..9044835272 100644
--- a/code/datums/wounds/cuts.dm
+++ b/code/datums/wounds/slash.dm
@@ -1,17 +1,16 @@
-
/*
Cuts
*/
-/datum/wound/brute/cut
+/datum/wound/slash
sound_effect = 'sound/weapons/slice.ogg'
processes = TRUE
- wound_type = WOUND_LIST_CUT
- treatable_by = list(/obj/item/stack/medical/suture, /obj/item/stack/medical/gauze)
+ wound_type = WOUND_SLASH
+ treatable_by = list(/obj/item/stack/medical/suture)
treatable_by_grabbed = list(/obj/item/gun/energy/laser)
treatable_tool = TOOL_CAUTERY
- treat_priority = TRUE
base_treat_time = 3 SECONDS
+ wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
/// How much blood we start losing when this wound is first applied
var/initial_flow
@@ -27,75 +26,82 @@
var/max_per_type
/// The maximum flow we've had so far
var/highest_flow
- /// How much flow we've already cauterized
- var/cauterized
- /// How much flow we've already sutured
- var/sutured
- /// The current bandage we have for this wound (maybe move bandages to the limb?)
- var/obj/item/stack/current_bandage
/// A bad system I'm using to track the worst scar we earned (since we can demote, we want the biggest our wound has been, not what it was when it was cured (probably moderate))
var/datum/scar/highest_scar
-/datum/wound/brute/cut/wound_injury(datum/wound/brute/cut/old_wound = null)
+/datum/wound/slash/wound_injury(datum/wound/slash/old_wound = null)
blood_flow = initial_flow
if(old_wound)
blood_flow = max(old_wound.blood_flow, initial_flow)
if(old_wound.severity > severity && old_wound.highest_scar)
highest_scar = old_wound.highest_scar
old_wound.highest_scar = null
- if(old_wound.current_bandage)
- current_bandage = old_wound.current_bandage
- old_wound.current_bandage = null
if(!highest_scar)
highest_scar = new
highest_scar.generate(limb, src, add_to_scars=FALSE)
-/datum/wound/brute/cut/remove_wound(ignore_limb, replaced)
+/datum/wound/slash/remove_wound(ignore_limb, replaced)
if(!replaced && highest_scar)
already_scarred = TRUE
highest_scar.lazy_attach(limb)
return ..()
-/datum/wound/brute/cut/get_examine_description(mob/user)
- if(!current_bandage)
+/datum/wound/slash/get_examine_description(mob/user)
+ if(!limb.current_gauze)
return ..()
- var/bandage_condition = ""
+ var/list/msg = list("The cuts on [victim.p_their()] [limb.name] are wrapped with")
// how much life we have left in these bandages
- switch(current_bandage.absorption_capacity)
+ switch(limb.current_gauze.absorption_capacity)
if(0 to 1.25)
- bandage_condition = "nearly ruined "
+ msg += "nearly ruined "
if(1.25 to 2.75)
- bandage_condition = "badly worn "
+ msg += "badly worn "
if(2.75 to 4)
- bandage_condition = "slightly bloodied "
+ msg += "slightly bloodied "
if(4 to INFINITY)
- bandage_condition = "clean "
- return "
The cuts on [victim.p_their()] [limb.name] are wrapped with [bandage_condition] [current_bandage.name]!"
+ msg += "clean "
+ msg += "[limb.current_gauze.name]!"
-/datum/wound/brute/cut/receive_damage(wounding_type, wounding_dmg, wound_bonus)
- if(victim.stat != DEAD && wounding_type == WOUND_SHARP) // can't stab dead bodies to make it bleed faster this way
+ return "
[msg.Join()]"
+
+/datum/wound/slash/receive_damage(wounding_type, wounding_dmg, wound_bonus)
+ if(victim.stat != DEAD && wounding_type == WOUND_SLASH) // can't stab dead bodies to make it bleed faster this way
blood_flow += 0.05 * wounding_dmg
-/datum/wound/brute/cut/handle_process()
- blood_flow = min(blood_flow, WOUND_CUT_MAX_BLOODFLOW)
+/datum/wound/slash/drag_bleed_amount()
+ // say we have 3 severe cuts with 3 blood flow each, pretty reasonable
+ // compare with being at 100 brute damage before, where you bled (brute/100 * 2), = 2 blood per tile
+ var/bleed_amt = min(blood_flow * 0.1, 1) // 3 * 3 * 0.1 = 0.9 blood total, less than before! the share here is .3 blood of course.
- if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/toxin/heparin))
+ if(limb.current_gauze) // gauze stops all bleeding from dragging on this limb, but wears the gauze out quicker
+ limb.seep_gauze(bleed_amt * 0.33)
+ return
+
+ return bleed_amt
+
+/datum/wound/slash/handle_process()
+ if(victim.stat == DEAD)
+ blood_flow -= max(clot_rate, WOUND_SLASH_DEAD_CLOT_MIN)
+ if(blood_flow < minimum_flow)
+ if(demotes_to)
+ replace_wound(demotes_to)
+ return
+ qdel(src)
+ return
+
+ blood_flow = min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW)
+
+ if(victim.reagents?.has_reagent(/datum/reagent/toxin/heparin))
blood_flow += 0.5 // old herapin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first
- else if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/medicine/coagulant))
- blood_flow -= 0.25
- if(current_bandage)
+ if(limb.current_gauze)
if(clot_rate > 0)
blood_flow -= clot_rate
- blood_flow -= current_bandage.absorption_rate
- current_bandage.absorption_capacity -= current_bandage.absorption_rate
- if(current_bandage.absorption_capacity < 0)
- victim.visible_message("
Blood soaks through \the [current_bandage] on [victim]'s [limb.name].", "
Blood soaks through \the [current_bandage] on your [limb.name].", vision_distance=COMBAT_MESSAGE_RANGE)
- QDEL_NULL(current_bandage)
- treat_priority = TRUE
+ blood_flow -= limb.current_gauze.absorption_rate
+ limb.seep_gauze(limb.current_gauze.absorption_rate)
else
blood_flow -= clot_rate
@@ -109,41 +115,57 @@
to_chat(victim, "
The cut on your [limb.name] has stopped bleeding!")
qdel(src)
+
+/datum/wound/slash/on_stasis()
+ if(blood_flow >= minimum_flow)
+ return
+ if(demotes_to)
+ replace_wound(demotes_to)
+ return
+ qdel(src)
+
/* BEWARE, THE BELOW NONSENSE IS MADNESS. bones.dm looks more like what I have in mind and is sufficiently clean, don't pay attention to this messiness */
-/datum/wound/brute/cut/check_grab_treatments(obj/item/I, mob/user)
+/datum/wound/slash/check_grab_treatments(obj/item/I, mob/user)
if(istype(I, /obj/item/gun/energy/laser))
return TRUE
-/datum/wound/brute/cut/treat(obj/item/I, mob/user)
+/datum/wound/slash/treat(obj/item/I, mob/user)
if(istype(I, /obj/item/gun/energy/laser))
las_cauterize(I, user)
else if(I.tool_behaviour == TOOL_CAUTERY || I.get_temperature() > 300)
tool_cauterize(I, user)
- else if(istype(I, /obj/item/stack/medical/gauze))
- bandage(I, user)
else if(istype(I, /obj/item/stack/medical/suture))
suture(I, user)
-/datum/wound/brute/cut/try_handling(mob/living/carbon/human/user)
+/datum/wound/slash/try_handling(mob/living/carbon/human/user)
if(user.pulling != victim || user.zone_selected != limb.body_zone || user.a_intent == INTENT_GRAB)
return FALSE
if(!iscatperson(user))
return FALSE
- if(!(user.client?.prefs.vore_flags & LICKABLE))
- return FALSE
-
lick_wounds(user)
return TRUE
/// if a felinid is licking this cut to reduce bleeding
-/datum/wound/brute/cut/proc/lick_wounds(mob/living/carbon/human/user)
+/datum/wound/slash/proc/lick_wounds(mob/living/carbon/human/user)
if(INTERACTING_WITH(user, victim))
to_chat(user, "
You're already interacting with [victim]!")
return
+ if(user.is_mouth_covered())
+ to_chat(user, "
Your mouth is covered, you can't lick [victim]'s wounds!")
+ return
+
+ if(!user.getorganslot(ORGAN_SLOT_TONGUE))
+ to_chat(user, "
You can't lick wounds without a tongue!") // f in chat
+ return
+
+ // transmission is one way patient -> felinid since google said cat saliva is antiseptic or whatever, and also because felinids are already risking getting beaten for this even without people suspecting they're spreading a deathvirus
+ for(var/datum/disease/D in victim.diseases)
+ user.ForceContractDisease(D)
+
user.visible_message("
[user] begins licking the wounds on [victim]'s [limb.name].", "
You begin licking the wounds on [victim]'s [limb.name]...", ignored_mobs=victim)
to_chat(victim, "
[user] begins to lick the wounds on your [limb.name].You successfully lower the severity of [victim]'s cuts.")
-/datum/wound/brute/cut/on_xadone(power)
+/datum/wound/slash/on_xadone(power)
. = ..()
blood_flow -= 0.03 * power // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort
+/datum/wound/slash/on_synthflesh(power)
+ . = ..()
+ blood_flow -= 0.075 * power // 20u * 0.075 = -1.5 blood flow, pretty good for how little effort it is
+
/// If someone's putting a laser gun up to our cut to cauterize it
-/datum/wound/brute/cut/proc/las_cauterize(obj/item/gun/energy/laser/lasgun, mob/user)
+/datum/wound/slash/proc/las_cauterize(obj/item/gun/energy/laser/lasgun, mob/user)
var/self_penalty_mult = (user == victim ? 1.25 : 1)
user.visible_message("
[user] begins aiming [lasgun] directly at [victim]'s [limb.name]...", "
You begin aiming [lasgun] directly at [user == victim ? "your" : "[victim]'s"] [limb.name]...")
if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, .proc/still_exists)))
@@ -180,11 +206,10 @@
return
victim.emote("scream")
blood_flow -= damage / (5 * self_penalty_mult) // 20 / 5 = 4 bloodflow removed, p good
- cauterized += damage / (5 * self_penalty_mult)
victim.visible_message("
The cuts on [victim]'s [limb.name] scar over!")
/// If someone is using either a cautery tool or something with heat to cauterize this cut
-/datum/wound/brute/cut/proc/tool_cauterize(obj/item/I, mob/user)
+/datum/wound/slash/proc/tool_cauterize(obj/item/I, mob/user)
var/self_penalty_mult = (user == victim ? 1.5 : 1)
user.visible_message("
[user] begins cauterizing [victim]'s [limb.name] with [I]...", "
You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, .proc/still_exists)))
@@ -196,7 +221,6 @@
victim.emote("scream")
var/blood_cauterized = (0.6 / self_penalty_mult)
blood_flow -= blood_cauterized
- cauterized += blood_cauterized
if(blood_flow > minimum_flow)
try_treating(I, user)
@@ -204,15 +228,15 @@
to_chat(user, "
You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts.")
/// If someone is using a suture to close this cut
-/datum/wound/brute/cut/proc/suture(obj/item/stack/medical/suture/I, mob/user)
+/datum/wound/slash/proc/suture(obj/item/stack/medical/suture/I, mob/user)
var/self_penalty_mult = (user == victim ? 1.4 : 1)
user.visible_message("
[user] begins stitching [victim]'s [limb.name] with [I]...", "
You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
+
if(!do_after(user, base_treat_time * self_penalty_mult, target=victim, extra_checks = CALLBACK(src, .proc/still_exists)))
return
user.visible_message("
[user] stitches up some of the bleeding on [victim].", "
You stitch up some of the bleeding on [user == victim ? "yourself" : "[victim]"].")
var/blood_sutured = I.stop_bleeding / self_penalty_mult
blood_flow -= blood_sutured
- sutured += blood_sutured
limb.heal_damage(I.heal_brute, I.heal_burn)
if(blood_flow > minimum_flow)
@@ -220,95 +244,57 @@
else if(demotes_to)
to_chat(user, "
You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts.")
-/// If someone is using gauze on this cut
-/datum/wound/brute/cut/proc/bandage(obj/item/stack/I, mob/user)
- if(current_bandage)
- if(current_bandage.absorption_capacity > I.absorption_capacity + 1)
- to_chat(user, "
The [current_bandage] on [victim]'s [limb.name] is still in better condition than your [I.name]!")
- return
- else
- user.visible_message("
[user] begins rewrapping the cuts on [victim]'s [limb.name] with [I]...", "
You begin rewrapping the cuts on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
- else
- user.visible_message("
[user] begins wrapping the cuts on [victim]'s [limb.name] with [I]...", "
You begin wrapping the cuts on [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]...")
- if(!do_after(user, base_treat_time, target=victim, extra_checks = CALLBACK(src, .proc/still_exists)))
- return
- user.visible_message("
[user] applies [I] to [victim]'s [limb.name].", "
You bandage some of the bleeding on [user == victim ? "yourself" : "[victim]"].")
- QDEL_NULL(current_bandage)
- current_bandage = new I.type(limb)
- current_bandage.amount = 1
- treat_priority = FALSE
- I.use(1)
-
-
-/datum/wound/brute/cut/moderate
+/datum/wound/slash/moderate
name = "Rough Abrasion"
desc = "Patient's skin has been badly scraped, generating moderate blood loss."
treat_text = "Application of clean bandages or first-aid grade sutures, followed by food and rest."
examine_desc = "has an open cut"
occur_text = "is cut open, slowly leaking blood"
- sound_effect = 'sound/effects/blood1.ogg'
+ sound_effect = 'sound/effects/wounds/blood1.ogg'
severity = WOUND_SEVERITY_MODERATE
- initial_flow = 2
- minimum_flow = 0.5
+ initial_flow = 1.5
+ minimum_flow = 0.375
max_per_type = 3
- clot_rate = 0.15
- threshold_minimum = 20
+ clot_rate = 0.12
+ threshold_minimum = 30
threshold_penalty = 10
- status_effect_type = /datum/status_effect/wound/cut/moderate
- scarring_descriptions = list("light, faded lines", "minor cut marks", "a small faded slit", "a series of small scars")
+ status_effect_type = /datum/status_effect/wound/slash/moderate
+ scar_keyword = "slashmoderate"
-/datum/wound/brute/cut/severe
+/datum/wound/slash/severe
name = "Open Laceration"
desc = "Patient's skin is ripped clean open, allowing significant blood loss."
treat_text = "Speedy application of first-aid grade sutures and clean bandages, followed by vitals monitoring to ensure recovery."
examine_desc = "has a severe cut"
occur_text = "is ripped open, veins spurting blood"
- sound_effect = 'sound/effects/blood2.ogg'
+ sound_effect = 'sound/effects/wounds/blood2.ogg'
severity = WOUND_SEVERITY_SEVERE
- initial_flow = 3.25
- minimum_flow = 2.75
+ initial_flow = 2.4375
+ minimum_flow = 2.0625
clot_rate = 0.07
max_per_type = 4
- threshold_minimum = 50
+ threshold_minimum = 60
threshold_penalty = 25
- demotes_to = /datum/wound/brute/cut/moderate
- status_effect_type = /datum/status_effect/wound/cut/severe
- scarring_descriptions = list("a twisted line of faded gashes", "a gnarled sickle-shaped slice scar", "a long-faded puncture wound")
+ demotes_to = /datum/wound/slash/moderate
+ status_effect_type = /datum/status_effect/wound/slash/severe
+ scar_keyword = "slashsevere"
-/datum/wound/brute/cut/critical
+/datum/wound/slash/critical
name = "Weeping Avulsion"
desc = "Patient's skin is completely torn open, along with significant loss of tissue. Extreme blood loss will lead to quick death without intervention."
treat_text = "Immediate bandaging and either suturing or cauterization, followed by supervised resanguination."
- examine_desc = "is spurting blood at an alarming rate"
+ examine_desc = "is carved down to the bone, spraying blood wildly"
occur_text = "is torn open, spraying blood wildly"
- sound_effect = 'sound/effects/blood3.ogg'
+ sound_effect = 'sound/effects/wounds/blood3.ogg'
severity = WOUND_SEVERITY_CRITICAL
- initial_flow = 4.25
- minimum_flow = 4
+ initial_flow = 3.1875
+ minimum_flow = 3
clot_rate = -0.05 // critical cuts actively get worse instead of better
max_per_type = 5
- threshold_minimum = 80
+ threshold_minimum = 90
threshold_penalty = 40
- demotes_to = /datum/wound/brute/cut/severe
- status_effect_type = /datum/status_effect/wound/cut/critical
- scarring_descriptions = list("a winding path of very badly healed scar tissue", "a series of peaks and valleys along a gruesome line of cut scar tissue", "a grotesque snake of indentations and stitching scars")
-
-// TODO: see about moving dismemberment over to this, i'll have to add judging dismembering power/wound potential wrt item size i guess
-/datum/wound/brute/cut/loss
- name = "Dismembered"
- desc = "oof ouch!!"
- occur_text = "is violently dismembered!"
- sound_effect = 'sound/effects/dismember.ogg'
- viable_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
- severity = WOUND_SEVERITY_LOSS
- threshold_minimum = 180
- status_effect_type = null
-
-/datum/wound/brute/cut/loss/apply_wound(obj/item/bodypart/L, silent, datum/wound/brute/cut/old_wound, smited = FALSE)
- if(!L.dismemberable)
- qdel(src)
- return
-
- L.dismember()
- qdel(src)
+ demotes_to = /datum/wound/slash/severe
+ status_effect_type = /datum/status_effect/wound/slash/critical
+ scar_keyword = "slashcritical"
+ wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE | MANGLES_FLESH)
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 154d2df563..406e142a25 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -213,6 +213,9 @@ Credit where due:
var/list/slots = list("In your left pocket" = SLOT_L_STORE, "In your right pocket" = SLOT_R_STORE, "In your backpack" = SLOT_IN_BACKPACK)
if(ishuman(L))
var/mob/living/carbon/human/H = L
+ var/obj/item/clockwork/replica_fabricator/F = new
+ if(H.equip_to_slot_or_del(F, SLOT_IN_BACKPACK))
+ to_chat(H, "
You have been equipped with a replica fabricator, an advanced tool that can convert objects like doors, tables or even coats into clockwork equivalents.")
slot = H.equip_in_one_of_slots(S, slots)
if(slot == "In your backpack")
slot = "In your [H.back.name]"
diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm
index afa3dbfeaa..a27cb02ea8 100644
--- a/code/game/gamemodes/clown_ops/clown_weapons.dm
+++ b/code/game/gamemodes/clown_ops/clown_weapons.dm
@@ -62,7 +62,7 @@
hitsound = null
attack_verb_on = list("slipped")
clumsy_check = FALSE
- sharpness = IS_BLUNT
+ sharpness = SHARP_NONE
sword_color = "yellow"
heat = 0
light_color = "#ffff00"
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index b5e752cc6b..4771e2eca7 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1112,7 +1112,6 @@
detonated = 1
charge = null
for(var/mob/living/carbon/human/H in orange(2,src))
- H.Unconscious(160)
H.adjust_fire_stacks(20)
H.IgniteMob() //Guaranteed knockout and ignition for nearby people
H.apply_damage(40, BRUTE, BODY_ZONE_CHEST)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index f3886d0036..4248e1684f 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -342,7 +342,8 @@
L.visible_message("
[src] closes on [L], crushing [L.p_them()]!", "
[src] closes on you and crushes you!")
if(iscarbon(L))
var/mob/living/carbon/C = L
- for(var/datum/wound/W in C.all_wounds)
+ for(var/i in C.all_wounds) // should probably replace with signal
+ var/datum/wound/W = i
W.crush(DOOR_CRUSH_DAMAGE)
if(isalien(L)) //For xenos
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE * 1.5) //Xenos go into crit after aproximately the same amount of crushes as humans.
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index 2a60711a81..f69a722473 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -533,16 +533,16 @@
return
/obj/machinery/porta_turret/proc/shootAt(atom/movable/target, stagger_enabled = FALSE)
- if(stagger_enabled)
- randomize_shot_stagger()
- sleep(shot_stagger)
if(!raised) //the turret has to be raised in order to fire - makes sense, right?
return
- if(!(obj_flags & EMAGGED)) //if it hasn't been emagged, cooldown before shooting again
- if(last_fired + shot_delay > world.time)
- return
- last_fired = world.time
+ if(last_fired + shot_delay > world.time)
+ return
+ last_fired = world.time
+
+ if(stagger_enabled)
+ randomize_shot_stagger()
+ sleep(shot_stagger)
var/turf/T = get_turf(src)
var/turf/U = get_turf(target)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 5870c8a780..b4c114eb6a 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -103,12 +103,12 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged
- var/list/embedding = NONE
+ var/list/embedding
var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES
var/heat = 0
- ///All items with sharpness of IS_SHARP or higher will automatically get the butchering component.
- var/sharpness = IS_BLUNT
+ ///All items with sharpness of SHARP_EDGED or higher will automatically get the butchering component.
+ var/sharpness = SHARP_NONE
var/tool_behaviour = NONE
var/toolspeed = 1
@@ -206,7 +206,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(GLOB.rpg_loot_items)
AddComponent(/datum/component/fantasy)
- if(sharpness) //give sharp objects butchering functionality, for consistency
+ if(sharpness && force > 5) //give sharp objects butchering functionality, for consistency
AddComponent(/datum/component/butchering, 80 * toolspeed)
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
@@ -1090,7 +1090,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/obj/item/proc/updateEmbedding()
- if(!islist(embedding) || !LAZYLEN(embedding))
+ if(!LAZYLEN(embedding))
return
AddElement(/datum/element/embed,\
diff --git a/code/game/objects/items/chainsaw.dm b/code/game/objects/items/chainsaw.dm
index f382aa1ed3..ebb26fab93 100644
--- a/code/game/objects/items/chainsaw.dm
+++ b/code/game/objects/items/chainsaw.dm
@@ -16,7 +16,7 @@
custom_materials = list(/datum/material/iron=13000)
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = "swing_hit"
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
actions_types = list(/datum/action/item_action/startchainsaw)
tool_behaviour = TOOL_SAW
toolspeed = 0.5
@@ -71,10 +71,6 @@
/obj/item/chainsaw/update_icon_state()
icon_state = "chainsaw_[on ? "on" : "off"]"
-/obj/item/chainsaw/get_dismemberment_chance()
- if(wielded)
- . = ..()
-
/obj/item/chainsaw/doomslayer
name = "THE GREAT COMMUNICATOR"
desc = "
VRRRRRRR!!!"
diff --git a/code/game/objects/items/dualsaber.dm b/code/game/objects/items/dualsaber.dm
index 08460993ee..9db9449fcb 100644
--- a/code/game/objects/items/dualsaber.dm
+++ b/code/game/objects/items/dualsaber.dm
@@ -105,7 +105,7 @@
to_chat(user, "
You lack the grace to wield this!")
return COMPONENT_TWOHANDED_BLOCK_WIELD
wielded = TRUE
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
w_class = w_class_on
total_mass = total_mass_on
hitsound = 'sound/weapons/blade1.ogg'
diff --git a/code/game/objects/items/fireaxe.dm b/code/game/objects/items/fireaxe.dm
index 7cb22d5eb0..6fb7b89262 100644
--- a/code/game/objects/items/fireaxe.dm
+++ b/code/game/objects/items/fireaxe.dm
@@ -13,11 +13,12 @@
slot_flags = ITEM_SLOT_BACK
attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
max_integrity = 200
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
resistance_flags = FIRE_PROOF
- wound_bonus = -20
+ wound_bonus = -15
+ bare_wound_bonus = 20
var/wielded = FALSE // track wielded status on item
/obj/item/fireaxe/Initialize()
diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm
index 1554142c8c..609cc3b719 100644
--- a/code/game/objects/items/granters.dm
+++ b/code/game/objects/items/granters.dm
@@ -79,7 +79,7 @@
ADD_TRAIT(user, granted_trait, BOOK_TRAIT)
/obj/item/book/granter/trait/rifleman
- name = "\proper the Neo-Russian Rifleman\'s Primer"
+ name = "The Neo-Russian Rifleman\'s Primer"
desc = "A book with stains of vodka and...blood? The back is hard to read, but says something about bolt-actions. Or pump-actions. Both, maybe."
oneuse = FALSE
granted_trait = TRAIT_FAST_PUMP
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index 691b4c4228..58146be20f 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -352,7 +352,7 @@
w_class = WEIGHT_CLASS_HUGE
slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_BELT
block_chance = 30
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
@@ -452,7 +452,7 @@
w_class = WEIGHT_CLASS_BULKY
armour_penetration = 35
slot_flags = ITEM_SLOT_BACK
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
attack_verb = list("chopped", "sliced", "cut", "reaped")
/obj/item/nullrod/scythe/Initialize()
@@ -575,7 +575,7 @@
righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi'
w_class = WEIGHT_CLASS_HUGE
item_flags = ABSTRACT
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
total_mass = TOTAL_MASS_HAND_REPLACEMENT
@@ -594,7 +594,7 @@
name = "clown dagger"
desc = "Used for absolutely hilarious sacrifices."
hitsound = 'sound/items/bikehorn.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
/obj/item/nullrod/pride_hammer
@@ -645,7 +645,7 @@
throw_speed = 4
throw_range = 7
throwforce = 30
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
attack_verb = list("enlightened", "redpilled")
/obj/item/nullrod/armblade
@@ -657,7 +657,7 @@
righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
item_flags = ABSTRACT
w_class = WEIGHT_CLASS_HUGE
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
wound_bonus = -20
bare_wound_bonus = 25
total_mass = TOTAL_MASS_HAND_REPLACEMENT
@@ -699,7 +699,7 @@
force = 15
block_chance = 40
slot_flags = ITEM_SLOT_BACK
- sharpness = IS_BLUNT
+ sharpness = SHARP_NONE
hitsound = "swing_hit"
attack_verb = list("smashed", "slammed", "whacked", "thwacked")
icon = 'icons/obj/items_and_weapons.dmi'
@@ -754,7 +754,7 @@
name = "arrhythmic knife"
w_class = WEIGHT_CLASS_HUGE
desc = "They say fear is the true mind killer, but stabbing them in the head works too. Honour compels you to not sheathe it once drawn."
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
slot_flags = null
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
@@ -782,7 +782,7 @@
desc = "Holding this makes you look absolutely devilish."
attack_verb = list("poked", "impaled", "pierced", "jabbed")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
/obj/item/nullrod/egyptian
name = "egyptian staff"
diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm
index 6cdc5ee824..897cb9b750 100644
--- a/code/game/objects/items/implants/implant_misc.dm
+++ b/code/game/objects/items/implants/implant_misc.dm
@@ -38,6 +38,23 @@
if(!uses)
qdel(src)
+/obj/item/implant/warp
+ name = "warp implant"
+ desc = "Saves your position somewhere, and then warps you back to it after five seconds."
+ icon_state = "warp"
+ uses = 15
+
+/obj/item/implant/warp/activate()
+ . = ..()
+ uses--
+ imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list(/datum/reagent/fermi/eigenstate = 1.2), "
You feel an internal prick as as the bluespace starts ramping up!")
+ to_chat(imp_in, "
You feel an internal prick as as the bluespace starts ramping up!")
+ if(!uses)
+ qdel(src)
+
+/obj/item/implanter/warp
+ name = "implanter (warp)"
+ imp_type = /obj/item/implant/warp
/obj/item/implant/emp
name = "emp implant"
diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm
index 8f274c04aa..e7cf8defc9 100644
--- a/code/game/objects/items/kitchen.dm
+++ b/code/game/objects/items/kitchen.dm
@@ -18,7 +18,7 @@
name = "fork"
desc = "Pointy."
icon_state = "fork"
- force = 5
+ force = 4
w_class = WEIGHT_CLASS_TINY
throwforce = 0
throw_speed = 3
@@ -28,6 +28,7 @@
attack_verb = list("attacked", "stabbed", "poked")
hitsound = 'sound/weapons/bladeslice.ogg'
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
+ sharpness = SHARP_POINTY
var/datum/reagent/forkload //used to eat omelette
/obj/item/kitchen/fork/suicide_act(mob/living/carbon/user)
@@ -61,7 +62,7 @@
throw_speed = 4
throw_range = 6
embedding = list("pain_mult" = 2, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
/obj/item/kitchen/knife
name = "kitchen knife"
@@ -76,7 +77,7 @@
throw_range = 6
custom_materials = list(/datum/material/iron=12000)
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
- sharpness = IS_SHARP_ACCURATE
+ sharpness = SHARP_POINTY
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
var/bayonet = FALSE //Can this be attached to a gun?
wound_bonus = -5
diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm
index ef5b7b6cba..b2f8b4bee2 100644
--- a/code/game/objects/items/latexballoon.dm
+++ b/code/game/objects/items/latexballoon.dm
@@ -54,5 +54,5 @@
var/obj/item/tank/T = W
blow(T, user)
return
- if (W.get_sharpness() || W.get_temperature() || is_pointed(W))
+ if (W.get_sharpness() || W.get_temperature())
burst()
diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm
index e0b08ba8ef..679491aeb6 100644
--- a/code/game/objects/items/melee/energy.dm
+++ b/code/game/objects/items/melee/energy.dm
@@ -102,7 +102,7 @@
attack_verb_off = list("tapped", "poked")
throw_speed = 3
throw_range = 5
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
embedding = list("embed_chance" = 75, "impact_pain_mult" = 10)
armour_penetration = 35
item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY
@@ -180,7 +180,7 @@
sword_color = null //stops icon from breaking when turned on.
hitcost = 75 //Costs more than a standard cyborg esword
w_class = WEIGHT_CLASS_NORMAL
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
light_color = "#40ceff"
tool_behaviour = TOOL_SAW
toolspeed = 0.7
@@ -255,7 +255,7 @@
throw_range = 1
w_class = WEIGHT_CLASS_BULKY//So you can't hide it in your pocket or some such.
var/datum/effect_system/spark_spread/spark_system
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
//Most of the other special functions are handled in their own files. aka special snowflake code so kewl
/obj/item/melee/transforming/energy/blade/Initialize()
@@ -291,7 +291,7 @@
attack_verb_off = list("tapped", "poked")
throw_speed = 3
throw_range = 5
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
embedding = list("embedded_pain_multiplier" = 6, "embed_chance" = 20, "embedded_fall_chance" = 60)
armour_penetration = 10
block_chance = 35
diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm
index 9a7d455df6..01d2924a90 100644
--- a/code/game/objects/items/melee/misc.dm
+++ b/code/game/objects/items/melee/misc.dm
@@ -44,7 +44,7 @@
throwforce = 10
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "impaled", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
total_mass = TOTAL_MASS_HAND_REPLACEMENT
/obj/item/melee/synthetic_arm_blade/Initialize()
@@ -64,7 +64,7 @@
throwforce = 15
w_class = WEIGHT_CLASS_BULKY
armour_penetration = 75
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
attack_verb = list("slashed", "cut")
hitsound = 'sound/weapons/rapierhit.ogg'
custom_materials = list(/datum/material/iron = 1000)
@@ -168,7 +168,7 @@
flags_1 = CONDUCT_1
obj_flags = UNIQUE_RENAME
w_class = WEIGHT_CLASS_BULKY
- sharpness = IS_SHARP_ACCURATE //It cant be sharpend cook -_-
+ sharpness = SHARP_POINTY //It cant be sharpend cook -_-
attack_verb = list("stabs", "punctures", "pierces", "pokes")
hitsound = 'sound/weapons/rapierhit.ogg'
total_mass = 0.4
diff --git a/code/game/objects/items/melee/transforming.dm b/code/game/objects/items/melee/transforming.dm
index 66752c4c9a..8c44a15cd4 100644
--- a/code/game/objects/items/melee/transforming.dm
+++ b/code/game/objects/items/melee/transforming.dm
@@ -1,5 +1,5 @@
/obj/item/melee/transforming
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
var/active = FALSE
var/force_on = 30 //force when active
var/faction_bonus_force = 0 //Bonus force dealt against certain factions
diff --git a/code/game/objects/items/pitchfork.dm b/code/game/objects/items/pitchfork.dm
index 49d0b64498..b296e2d0cb 100644
--- a/code/game/objects/items/pitchfork.dm
+++ b/code/game/objects/items/pitchfork.dm
@@ -9,7 +9,7 @@
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("attacked", "impaled", "pierced")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
max_integrity = 200
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
resistance_flags = FIRE_PROOF
diff --git a/code/game/objects/items/sharpener.dm b/code/game/objects/items/sharpener.dm
index 6bf0b27fb4..fc19e61cd6 100644
--- a/code/game/objects/items/sharpener.dm
+++ b/code/game/objects/items/sharpener.dm
@@ -39,7 +39,7 @@
I.force = clamp(I.force + increment, 0, max)
user.visible_message("
[user] sharpens [I] with [src]!", "
You sharpen [I], making it much more deadly than before.")
- I.sharpness = IS_SHARP_ACCURATE
+ I.sharpness = SHARP_POINTY
I.throwforce = clamp(I.throwforce + increment, 0, max)
I.name = "[prefix] [I.name]"
name = "worn out [name]"
diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm
index 992c173d3b..4952c93928 100644
--- a/code/game/objects/items/shields.dm
+++ b/code/game/objects/items/shields.dm
@@ -106,8 +106,8 @@
var/disarming = (target_downed && (shield_flags & SHIELD_BASH_GROUND_SLAM_DISARM)) || (shield_flags & SHIELD_BASH_ALWAYS_DISARM) || (wallhit && (shield_flags & SHIELD_BASH_WALL_DISARM))
var/knockdown = !target_downed && ((shield_flags & SHIELD_BASH_ALWAYS_KNOCKDOWN) || (wallhit && (shield_flags & SHIELD_BASH_WALL_KNOCKDOWN)))
if(shieldbash_stagger_duration || knockdown)
- target.visible_message("
[target] is knocked [knockdown? "to the floor" : "off balanace"]!",
- "
You are knocked [knockdown? "to the floor" : "off balanace"]!")
+ target.visible_message("
[target] is knocked [knockdown? "to the floor" : "off balance"]!",
+ "
You are knocked [knockdown? "to the floor" : "off balance"]!")
if(knockdown)
target.KnockToFloor(disarming)
else if(disarming)
diff --git a/code/game/objects/items/shrapnel.dm b/code/game/objects/items/shrapnel.dm
index b74b0563b7..5904cb6c0b 100644
--- a/code/game/objects/items/shrapnel.dm
+++ b/code/game/objects/items/shrapnel.dm
@@ -7,13 +7,13 @@
icon_state = "large"
w_class = WEIGHT_CLASS_TINY
item_flags = DROPDEL
- sharpness = TRUE
+ sharpness = SHARP_EDGED
/obj/item/shrapnel/stingball // stingbang grenades
name = "stingball"
embedding = list(embed_chance=90, fall_chance=3, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.7, pain_mult=5, jostle_pain_mult=6, rip_time=15, embed_chance_turf_mod=-100)
icon_state = "tiny"
- sharpness = FALSE
+ sharpness = SHARP_NONE
/obj/item/shrapnel/bullet // bullets
name = "bullet"
@@ -30,23 +30,24 @@
/obj/item/projectile/bullet/shrapnel
name = "flying shrapnel shard"
- damage = 8
- range = 10
+ damage = 14
+ range = 20
armour_penetration = -30
dismemberment = 5
ricochets_max = 2
- ricochet_chance = 40
+ ricochet_chance = 70
shrapnel_type = /obj/item/shrapnel
ricochet_incidence_leeway = 60
- sharpness = TRUE
- wound_bonus = 30
+ sharpness = SHARP_EDGED
+ wound_bonus = 40
/obj/item/projectile/bullet/shrapnel/mega
name = "flying shrapnel hunk"
- range = 25
- dismemberment = 10
- ricochets_max = 4
- ricochet_chance = 90
+ range = 45
+ dismemberment = 15
+ ricochets_max = 6
+ ricochet_chance = 130
+ ricochet_incidence_leeway = 0
ricochet_decay_chance = 0.9
/obj/item/projectile/bullet/pellet/stingball
@@ -71,10 +72,10 @@
name = "breakbang pellet"
damage = 10
wound_bonus = 40
- sharpness = FALSE
+ sharpness = SHARP_NONE
/obj/item/projectile/bullet/pellet/stingball/shred
name = "shredbang pellet"
damage = 10
wound_bonus = 30
- sharpness = TRUE
+ sharpness = SHARP_EDGED
diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm
index 41cb68559b..f40c774551 100644
--- a/code/game/objects/items/spear.dm
+++ b/code/game/objects/items/spear.dm
@@ -15,14 +15,14 @@
custom_materials = list(/datum/material/iron=1150, /datum/material/glass=2075)
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "poked", "jabbed", "torn", "gored")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
max_integrity = 200
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
var/obj/item/grenade/explosive = null
var/war_cry = "AAAAARGH!!!"
var/icon_prefix = "spearglass"
var/wielded = FALSE // track wielded status on item
- wound_bonus = -25
+ wound_bonus = -15
bare_wound_bonus = 15
/obj/item/spear/Initialize()
@@ -179,7 +179,7 @@
custom_materials = null
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "poked", "jabbed", "torn", "gored")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
icon_prefix = "bone_spear"
/obj/item/spear/bonespear/ComponentInitialize()
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 1ceb525b8a..6b6e9d7d65 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -28,8 +28,7 @@
/obj/item/stack/medical/attack(mob/living/M, mob/user)
. = ..()
- try_heal(M, user)
-
+ INVOKE_ASYNC(src, .proc/try_heal, M, user)
/obj/item/stack/medical/proc/try_heal(mob/living/M, mob/user, silent = FALSE)
if(!M.can_inject(user, TRUE))
@@ -132,11 +131,34 @@
// gauze is only relevant for wounds, which are handled in the wounds themselves
/obj/item/stack/medical/gauze/try_heal(mob/living/M, mob/user, silent)
var/obj/item/bodypart/limb = M.get_bodypart(check_zone(user.zone_selected))
- if(limb)
- if(limb.brute_dam > 40)
- to_chat(user, "
The bleeding on [user==M ? "your" : "[M]'s"] [limb.name] is from bruising, and cannot be treated with [src]!")
- else
- to_chat(user, "
There's no bleeding on [user==M ? "your" : "[M]'s"] [limb.name]")
+ if(!limb)
+ to_chat(user, "
There's nothing there to bandage!")
+ return
+ if(!LAZYLEN(limb.wounds))
+ to_chat(user, "
There's no wounds that require bandaging on [user==M ? "your" : "[M]'s"] [limb.name]!") // good problem to have imo
+ return
+
+ var/gauzeable_wound = FALSE
+ for(var/i in limb.wounds)
+ var/datum/wound/woundies = i
+ if(woundies.wound_flags & ACCEPTS_GAUZE)
+ gauzeable_wound = TRUE
+ break
+ if(!gauzeable_wound)
+ to_chat(user, "
There's no wounds that require bandaging on [user==M ? "your" : "[M]'s"] [limb.name]!") // good problem to have imo
+ return
+
+ if(limb.current_gauze && (limb.current_gauze.absorption_capacity * 0.8 > absorption_capacity)) // ignore if our new wrap is < 20% better than the current one, so someone doesn't bandage it 5 times in a row
+ to_chat(user, "
The bandage currently on [user==M ? "your" : "[M]'s"] [limb.name] is still in good condition!")
+ return
+
+ user.visible_message("
[user] begins wrapping the wounds on [M]'s [limb.name] with [src]...", "
You begin wrapping the wounds on [user == M ? "your" : "[M]'s"] [limb.name] with [src]...")
+
+ if(!do_after(user, (user == M ? self_delay : other_delay), target=M))
+ return
+
+ user.visible_message("
[user] applies [src] to [M]'s [limb.name].", "
You bandage the wounds on [user == M ? "yourself" : "[M]'s"] [limb.name].")
+ limb.apply_gauze(src)
/obj/item/stack/medical/gauze/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_WIRECUTTER || I.get_sharpness())
@@ -378,9 +400,9 @@
C.emote("scream")
for(var/i in C.bodyparts)
var/obj/item/bodypart/bone = i
- var/datum/wound/brute/bone/severe/oof_ouch = new
+ var/datum/wound/blunt/severe/oof_ouch = new
oof_ouch.apply_wound(bone)
- var/datum/wound/brute/bone/critical/oof_OUCH = new
+ var/datum/wound/blunt/critical/oof_OUCH = new
oof_OUCH.apply_wound(bone)
for(var/i in C.bodyparts)
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index d4baea2487..29b4dea6d8 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -289,7 +289,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
resistance_flags = ACID_PROOF
armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100)
max_integrity = 40
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
var/icon_prefix
embedding = list("embed_chance" = 65)
diff --git a/code/game/objects/items/storage/_storage.dm b/code/game/objects/items/storage/_storage.dm
index fd4cc793ab..2fc1b6484d 100644
--- a/code/game/objects/items/storage/_storage.dm
+++ b/code/game/objects/items/storage/_storage.dm
@@ -19,8 +19,9 @@
return TRUE
/obj/item/storage/contents_explosion(severity, target)
+ var/in_storage = istype(loc, /obj/item/storage)? (max(0, severity - 1)) : (severity)
for(var/atom/A in contents)
- A.ex_act(severity, target)
+ A.ex_act(in_storage, target)
CHECK_TICK
//Cyberboss says: "USE THIS TO FILL IT, NOT INITIALIZE OR NEW"
diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm
index 5e3ff67f4c..ed0ee8ad07 100644
--- a/code/game/objects/items/storage/toolbox.dm
+++ b/code/game/objects/items/storage/toolbox.dm
@@ -20,7 +20,8 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
var/has_latches = TRUE
var/can_rubberify = TRUE
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //very protecc too
- wound_bonus = 5
+ wound_bonus = -10
+ bare_wound_bonus = 5
/obj/item/storage/toolbox/greyscale
icon_state = "toolbox_default"
diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm
index 3b66e32d0a..4f65a4597e 100644
--- a/code/game/objects/items/storage/uplink_kits.dm
+++ b/code/game/objects/items/storage/uplink_kits.dm
@@ -169,6 +169,14 @@
O.imp = new /obj/item/implant/freedom(O)
O.update_icon()
+/obj/item/storage/box/syndie_kit/imp_warp
+ name = "boxed warp implant (with injector)"
+
+/obj/item/storage/box/syndie_kit/imp_warp/PopulateContents()
+ var/obj/item/implanter/O = new(src)
+ O.imp = new /obj/item/implant/warp(O)
+ O.update_icon()
+
/obj/item/storage/box/syndie_kit/imp_microbomb
name = "Microbomb Implant (with injector)"
@@ -401,7 +409,7 @@
/obj/item/storage/box/syndie_kit/revolver
/obj/item/storage/box/syndie_kit/revolver/PopulateContents()
- new /obj/item/gun/ballistic/revolver(src)
+ new /obj/item/gun/ballistic/revolver/syndicate(src)
new /obj/item/ammo_box/a357(src)
/obj/item/storage/box/syndie_kit/pistol
diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm
index d39da2f543..6159ab7ba0 100644
--- a/code/game/objects/items/tools/crowbar.dm
+++ b/code/game/objects/items/tools/crowbar.dm
@@ -18,6 +18,9 @@
toolspeed = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
+ wound_bonus = -10
+ bare_wound_bonus = 5
+
/obj/item/crowbar/suicide_act(mob/user)
user.visible_message("
[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!")
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm
index e9f517a9f1..86c223606d 100644
--- a/code/game/objects/items/tools/screwdriver.dm
+++ b/code/game/objects/items/tools/screwdriver.dm
@@ -31,6 +31,9 @@
"yellow" = rgb(255, 165, 0)
)
+ wound_bonus = -10
+ bare_wound_bonus = 5
+
/obj/item/screwdriver/suicide_act(mob/user)
user.visible_message("
[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!")
return(BRUTELOSS)
diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm
index 9560f7fab3..2e12a2ab8c 100644
--- a/code/game/objects/items/tools/weldingtool.dm
+++ b/code/game/objects/items/tools/weldingtool.dm
@@ -33,6 +33,8 @@
heat = 3800
tool_behaviour = TOOL_WELDER
toolspeed = 1
+ wound_bonus = 0
+ bare_wound_bonus = 5
/obj/item/weldingtool/Initialize()
. = ..()
diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm
index 678096db28..e1c09f394e 100644
--- a/code/game/objects/items/tools/wrench.dm
+++ b/code/game/objects/items/tools/wrench.dm
@@ -18,6 +18,9 @@
toolspeed = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
+ wound_bonus = -10
+ bare_wound_bonus = 5
+
/obj/item/wrench/suicide_act(mob/user)
user.visible_message("
[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!")
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index e69bb1ffa0..4e82df2452 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -447,7 +447,7 @@
block_parry_data = null
attack_verb = list("attacked", "struck", "hit")
total_mass_on = TOTAL_MASS_TOY_SWORD
- sharpness = IS_BLUNT
+ sharpness = SHARP_NONE
/obj/item/dualsaber/toy/ComponentInitialize()
AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=0, wieldsound='sound/weapons/saberon.ogg', unwieldsound='sound/weapons/saberoff.ogg')
@@ -466,7 +466,7 @@
attack_verb = list("attacked", "struck", "hit")
total_mass_on = TOTAL_MASS_TOY_SWORD
slowdown_wielded = 0
- sharpness = IS_BLUNT
+ sharpness = SHARP_NONE
/obj/item/dualsaber/hypereutactic/toy/ComponentInitialize()
AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=0, wieldsound='sound/weapons/saberon.ogg', unwieldsound='sound/weapons/saberoff.ogg')
@@ -1230,7 +1230,7 @@
name = "steampunk watch"
desc = "A stylish steampunk watch made out of thousands of tiny cogwheels."
icon = 'icons/obj/clockwork_objects.dmi'
- icon_state = "dread_ipad"
+ icon_state = "clockwork_slab"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index e21c4aaffa..0ab1f1b4fd 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -65,7 +65,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
block_chance = 50
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
max_integrity = 200
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
resistance_flags = FIRE_PROOF
@@ -231,7 +231,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
block_chance = 50
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
max_integrity = 200
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
resistance_flags = FIRE_PROOF
@@ -375,6 +375,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
w_class = WEIGHT_CLASS_NORMAL
custom_materials = list(/datum/material/iron=1150, /datum/material/glass=75)
attack_verb = list("hit", "bludgeoned", "whacked", "bonked")
+ wound_bonus = -10
/obj/item/wirerod/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/shard))
@@ -412,13 +413,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
force = 2
- throwforce = 20 //This is never used on mobs since this has a 100% embed chance.
+ throwforce = 10 //This is never used on mobs since this has a 100% embed chance.
throw_speed = 4
embedding = list("pain_mult" = 4, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
armour_penetration = 40
w_class = WEIGHT_CLASS_SMALL
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
custom_materials = list(/datum/material/iron=500, /datum/material/glass=500)
resistance_flags = FIRE_PROOF
@@ -431,7 +432,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/throwing_star/toy
name = "toy throwing star"
desc = "An aerodynamic disc strapped with adhesive for sticking to people, good for playing pranks and getting yourself killed by security."
- sharpness = IS_BLUNT
+ sharpness = SHARP_NONE
force = 0
throwforce = 0
embedding = list("pain_mult" = 0, "jostle_pain_mult" = 0, "embed_chance" = 100, "fall_chance" = 0)
@@ -468,7 +469,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
icon_state = extended_icon_state
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
else
force = initial(force)
w_class = WEIGHT_CLASS_SMALL
@@ -476,7 +477,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
icon_state = retracted_icon_state
attack_verb = list("stubbed", "poked")
hitsound = 'sound/weapons/genhit.ogg'
- sharpness = IS_BLUNT
+ sharpness = SHARP_NONE
/obj/item/switchblade/suicide_act(mob/user)
user.visible_message("
[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!")
@@ -577,7 +578,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
throwforce = 0
throw_range = 0
throw_speed = 0
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
total_mass = TOTAL_MASS_HAND_REPLACEMENT
@@ -706,6 +707,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
obj_flags = UNIQUE_RENAME
var/chaplain_spawnable = TRUE
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
+ wound_bonus = -5
/obj/item/melee/baseball_bat/chaplain/Initialize()
. = ..()
@@ -975,7 +977,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
block_chance = 40
throwforce = 20
throw_speed = 4
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
attack_verb = list("cut", "sliced", "diced")
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 37248f814c..0623f2b9d2 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -127,18 +127,45 @@
dismantle_wall(1)
return
-/turf/closed/wall/attack_hulk(mob/user, does_attack_animation = 0)
- ..(user, 1)
+/turf/closed/wall/attack_hulk(mob/living/carbon/user)
+ ..()
+ var/obj/item/bodypart/arm = user.hand_bodyparts[user.active_hand_index]
+ if(!arm)
+ return
+ if(arm.disabled)
+ return
if(prob(hardness))
- playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
+ playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE)
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
+ hulk_recoil(arm, user)
dismantle_wall(1)
+
else
- playsound(src, 'sound/effects/bang.ogg', 50, 1)
+ playsound(src, 'sound/effects/bang.ogg', 50, TRUE)
add_dent(WALL_DENT_HIT)
- to_chat(user, text("
You punch the wall."))
+ user.visible_message("
[user] smashes \the [src]!", \
+ "
You smash \the [src]!", \
+ "
You hear a booming smash!")
return TRUE
+/**
+ *Deals damage back to the hulk's arm.
+ *
+ *When a hulk manages to break a wall using their hulk smash, this deals back damage to the arm used.
+ *This is in its own proc just to be easily overridden by other wall types. Default allows for three
+ *smashed walls per arm. Also, we use CANT_WOUND here because wounds are random. Wounds are applied
+ *by hulk code based on arm damage and checked when we call break_an_arm().
+ *Arguments:
+ **arg1 is the arm to deal damage to.
+ **arg2 is the hulk
+ */
+/turf/closed/wall/proc/hulk_recoil(obj/item/bodypart/arm, mob/living/carbon/human/hulkman, var/damage = 20)
+ arm.receive_damage(brute = damage, blocked = 0, wound_bonus = CANT_WOUND)
+ var/datum/mutation/human/hulk/smasher = locate(/datum/mutation/human/hulk) in hulkman.dna.mutations
+ if(!smasher || !damage) //sanity check but also snow and wood walls deal no recoil damage, so no arm breaky
+ return
+ smasher.break_an_arm(arm)
+
/turf/closed/wall/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
to_chat(user, "
You push the wall but nothing happens!")
playsound(src, 'sound/weapons/genhit.ogg', 25, 1)
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index c559135bd1..5997558c60 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1283,9 +1283,9 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
ADMIN_PUNISHMENT_SHOES,
ADMIN_PUNISHMENT_PICKLE,
ADMIN_PUNISHMENT_FRY,
- ADMIN_PUNISHMENT_CRACK,
- ADMIN_PUNISHMENT_BLEED,
- ADMIN_PUNISHMENT_SCARIFY)
+ ADMIN_PUNISHMENT_CRACK,
+ ADMIN_PUNISHMENT_BLEED,
+ ADMIN_PUNISHMENT_SCARIFY)
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
@@ -1368,28 +1368,74 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
to_chat(usr,"
This must be used on a carbon mob.", confidential = TRUE)
return
var/mob/living/carbon/C = target
- for(var/obj/item/bodypart/squish_part in C.bodyparts)
- var/type_wound = pick(list(/datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/moderate))
+ for(var/i in C.bodyparts)
+ var/obj/item/bodypart/squish_part = i
+ var/type_wound = pick(list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate))
squish_part.force_wound_upwards(type_wound, smited=TRUE)
if(ADMIN_PUNISHMENT_BLEED)
if(!iscarbon(target))
to_chat(usr,"
This must be used on a carbon mob.", confidential = TRUE)
return
var/mob/living/carbon/C = target
- for(var/obj/item/bodypart/slice_part in C.bodyparts)
- var/type_wound = pick(list(/datum/wound/brute/cut/severe, /datum/wound/brute/cut/moderate))
+ for(var/i in C.bodyparts)
+ var/obj/item/bodypart/slice_part = i
+ var/type_wound = pick(list(/datum/wound/slash/severe, /datum/wound/slash/moderate))
slice_part.force_wound_upwards(type_wound, smited=TRUE)
- type_wound = pick(list(/datum/wound/brute/cut/critical, /datum/wound/brute/cut/severe, /datum/wound/brute/cut/moderate))
+ type_wound = pick(list(/datum/wound/slash/critical, /datum/wound/slash/severe, /datum/wound/slash/moderate))
slice_part.force_wound_upwards(type_wound, smited=TRUE)
- type_wound = pick(list(/datum/wound/brute/cut/critical, /datum/wound/brute/cut/severe))
+ type_wound = pick(list(/datum/wound/slash/critical, /datum/wound/slash/severe))
slice_part.force_wound_upwards(type_wound, smited=TRUE)
if(ADMIN_PUNISHMENT_SCARIFY)
if(!iscarbon(target))
to_chat(usr,"
This must be used on a carbon mob.", confidential = TRUE)
return
- var/mob/living/carbon/C = target
- C.generate_fake_scars(rand(1, 4))
- to_chat(C, "
You feel your body grow jaded and torn...")
+ var/mob/living/carbon/dude = target
+ dude.generate_fake_scars(rand(1, 4))
+ to_chat(dude, "
You feel your body grow jaded and torn...")
+ if(ADMIN_PUNISHMENT_PERFORATE)
+ if(!iscarbon(target))
+ to_chat(usr,"
This must be used on a carbon mob.", confidential = TRUE)
+ return
+
+ var/list/how_fucked_is_this_dude = list("A little", "A lot", "So fucking much", "FUCK THIS DUDE")
+ var/hatred = input("How much do you hate this guy?") in how_fucked_is_this_dude
+ var/repetitions
+ var/shots_per_limb_per_rep = 2
+ var/damage
+ switch(hatred)
+ if("A little")
+ repetitions = 1
+ damage = 5
+ if("A lot")
+ repetitions = 2
+
+ damage = 8
+ if("So fucking much")
+ repetitions = 3
+ damage = 10
+ if("FUCK THIS DUDE")
+ repetitions = 4
+ damage = 10
+
+ var/mob/living/carbon/dude = target
+ var/list/open_adj_turfs = get_adjacent_open_turfs(dude)
+ var/list/wound_bonuses = list(15, 70, 110, 250)
+
+ var/delay_per_shot = 1
+ var/delay_counter = 1
+
+ dude.Immobilize(5 SECONDS)
+ for(var/wound_bonus_rep in 1 to repetitions)
+ for(var/i in dude.bodyparts)
+ var/obj/item/bodypart/slice_part = i
+ var/shots_this_limb = 0
+ for(var/t in shuffle(open_adj_turfs))
+ var/turf/iter_turf = t
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/firing_squad, dude, iter_turf, slice_part.body_zone, wound_bonuses[wound_bonus_rep], damage), delay_counter)
+ delay_counter += delay_per_shot
+ shots_this_limb++
+ if(shots_this_limb > shots_per_limb_per_rep)
+ break
if(ADMIN_PUNISHMENT_PICKLE)
target.turn_into_pickle()
if(ADMIN_PUNISHMENT_FRY)
@@ -1408,6 +1454,31 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
punish_log(target, punishment)
+/**
+ * firing_squad is a proc for the :B:erforate smite to shoot each individual bullet at them, so that we can add actual delays without sleep() nonsense
+ *
+ * Hilariously, if you drag someone away mid smite, the bullets will still chase after them from the original spot, possibly hitting other people. Too funny to fix imo
+ *
+ * Arguments:
+ * * target- guy we're shooting obviously
+ * * source_turf- where the bullet begins, preferably on a turf next to the target
+ * * body_zone- which bodypart we're aiming for, if there is one there
+ * * wound_bonus- the wounding power we're assigning to the bullet, since we don't care about the base one
+ * * damage- the damage we're assigning to the bullet, since we don't care about the base one
+ */
+/proc/firing_squad(mob/living/carbon/target, turf/source_turf, body_zone, wound_bonus, damage)
+ if(!target.get_bodypart(body_zone))
+ return
+ playsound(target, 'sound/weapons/shot.ogg', 100)
+ var/obj/item/projectile/bullet/smite/divine_wrath = new(source_turf)
+ divine_wrath.damage = damage
+ divine_wrath.wound_bonus = wound_bonus
+ divine_wrath.original = target
+ divine_wrath.def_zone = body_zone
+ divine_wrath.spread = 0
+ divine_wrath.preparePixelProjectile(target, source_turf)
+ divine_wrath.fire()
+
/client/proc/punish_log(var/whom, var/punishment)
var/msg = "[key_name_admin(usr)] punished [key_name_admin(whom)] with [punishment]."
message_admins(msg)
diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm
index 2d25ebb156..a81f702a75 100644
--- a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm
+++ b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm
@@ -270,13 +270,15 @@
/datum/antagonist/bloodsucker/AmFinalDeath()
return owner && owner.AmFinalDeath()
-/datum/antagonist/changeling/AmFinalDeath()
- return owner && owner.AmFinalDeath()
/datum/mind/proc/AmFinalDeath()
return !current || QDELETED(current) || !isliving(current) || isbrain(current) || !get_turf(current) // NOTE: "isliving()" is not the same as STAT == CONSCIOUS. This is to make sure you're not a BORG (aka silicon)
/datum/antagonist/bloodsucker/proc/FinalDeath()
+ //Dont bother if we are already supposed to be dead
+ if(FinalDeath)
+ return
+ FinalDeath = TRUE //We are now supposed to die. Lets not spam it.
if(!iscarbon(owner.current)) //Check for non carbons.
owner.current.gib()
return
diff --git a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm
index 715de0648d..1fcffff810 100644
--- a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm
+++ b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm
@@ -38,6 +38,7 @@
var/level_bloodcost
var/passive_blood_drain = -0.1 //The amount of blood we loose each bloodsucker life() tick
var/notice_healing //Var to see if you are healing for preventing spam of the chat message inform the user of such
+ var/FinalDeath //Have we reached final death? Used to prevent spam.
// LISTS
var/static/list/defaultTraits = list (TRAIT_STABLEHEART, TRAIT_NOBREATH, TRAIT_SLEEPIMMUNE, TRAIT_NOCRITDAMAGE, TRAIT_RESISTCOLD, TRAIT_RADIMMUNE, TRAIT_NIGHT_VISION, \
TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT, TRAIT_AGEUSIA, TRAIT_COLDBLOODED, TRAIT_NONATURALHEAL, TRAIT_NOMARROW, TRAIT_NOPULSE, TRAIT_VIRUSIMMUNE, TRAIT_NODECAP, TRAIT_NOGUT)
@@ -683,6 +684,8 @@
owner.current.hud_used.sunlight_display.invisibility = INVISIBILITY_ABSTRACT
/datum/antagonist/bloodsucker/proc/update_hud(updateRank=FALSE)
+ if(FinalDeath)
+ return
// No Hud? Get out.
if(!owner.current.hud_used)
return
diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm
index 9af2553644..536c07cd62 100644
--- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm
+++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm
@@ -361,9 +361,9 @@
torture_time -= I.force / 4
torture_dmg_brute += I.force / 4
//torture_dmg_burn += I.
- if(I.sharpness == IS_SHARP)
+ if(I.sharpness == SHARP_EDGED)
torture_time -= 1
- else if(I.sharpness == IS_SHARP_ACCURATE)
+ else if(I.sharpness == SHARP_POINTY)
torture_time -= 2
if(istype(I, /obj/item/weldingtool))
var/obj/item/weldingtool/welder = I
diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm
index 7d50374e96..24288be078 100644
--- a/code/modules/antagonists/changeling/powers/mutations.dm
+++ b/code/modules/antagonists/changeling/powers/mutations.dm
@@ -164,7 +164,7 @@
armour_penetration = 20
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
wound_bonus = -60
bare_wound_bonus = 20
var/can_drop = FALSE
diff --git a/code/modules/antagonists/changeling/powers/regenerate.dm b/code/modules/antagonists/changeling/powers/regenerate.dm
index bcebd8c62e..a88422e7eb 100644
--- a/code/modules/antagonists/changeling/powers/regenerate.dm
+++ b/code/modules/antagonists/changeling/powers/regenerate.dm
@@ -30,8 +30,8 @@
C.regenerate_limbs(1)
C.regenerate_organs()
for(var/i in C.all_wounds)
- var/datum/wound/W = i
- W.remove_wound()
+ var/datum/wound/iter_wound = i
+ iter_wound.remove_wound()
if(!user.getorganslot(ORGAN_SLOT_BRAIN))
var/obj/item/organ/brain/B
if(C.has_dna() && C.dna.species.mutant_brain)
diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
index e579023a7a..454870d1e1 100644
--- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
+++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
@@ -405,3 +405,49 @@
animation_number = initial(animation_number)
sigil_active = FALSE
animate(src, alpha = initial(alpha), time = 10, flags = ANIMATION_END_NOW)
+
+/obj/effect/clockwork/sigil/rite
+ name = "radiant sigil"
+ desc = "A glowing sigil glowing with barely-contained power."
+ clockwork_desc = "A sigil that will allow you to perform certain rites on it, provided you have access to sufficient power and materials."
+ icon_state = "sigiltransmission" //am big lazy - recolored transmission sigil
+ sigil_name = "Sigil of Rites"
+ alpha = 255
+ var/performing_rite = FALSE
+ color = "#ffe63a"
+ light_color = "#ffe63a"
+ light_range = 1
+ light_power = 2
+
+/obj/effect/clockwork/sigil/rite/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
+ . = ..()
+ if(.)
+ return
+ if(!is_servant_of_ratvar(user))
+ return
+ if(!GLOB.all_clockwork_rites.len) //Did we already generate the list?
+ generate_all_rites()
+ if(performing_rite)
+ to_chat(user, "
Someone is already performing a rite here!")
+ return
+ var/list/possible_rites = list()
+ for(var/datum/clockwork_rite/R in GLOB.all_clockwork_rites)
+ possible_rites[R] = R
+ var/input_key = input(user, "Choose a rite", "Choosing a rite") as null|anything in possible_rites
+ if(!input_key)
+ return
+ var/datum/clockwork_rite/CR = possible_rites[input_key]
+ if(!CR)
+ return
+ var/choice = alert(user, "What to do with this rite?", "What to do?", "Cast", "Show Info", "Cancel")
+ switch(choice)
+ if("Cast")
+ CR.try_cast(src, user)
+ if("Show Info")
+ var/infotext = CR.build_info()
+ to_chat(user, infotext)
+
+/obj/effect/clockwork/sigil/rite/proc/generate_all_rites() //The first time someone uses a sigil of rites, all the rites are actually generated. No need to have a bunch of random datums laying around all the time.
+ for(var/V in subtypesof(/datum/clockwork_rite))
+ var/datum/clockwork_rite/R = new V
+ GLOB.all_clockwork_rites += R
diff --git a/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm b/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm
new file mode 100644
index 0000000000..7dabb18f03
--- /dev/null
+++ b/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm
@@ -0,0 +1,196 @@
+//This file is for clock rites, mainly used by the Sigil of Rites in clock_sigils.dm
+//The rites themselves are in this file to prevent bloating the other file too much, aswell as for easier access
+
+#define INFINITE -1
+
+//The base clockwork rite. This should never be visible
+/datum/clockwork_rite
+ var/name = "Rite of THE frog" //The name of the rite
+ var/desc = "This rite is used to summon the legendary frog whose-name-shall-not-be-spoken, ender of many worlds." //What does this rite do? Shown to cultists if they choose 'Show Info' after selecting the rite.
+ var/list/required_ingredients = list(/obj/item/clockwork) //What does this rite require?
+ var/power_cost = 0 //How much power does this rite cost.. or does it even add power?
+ var/requires_human = FALSE //Does the rite require a ../carbon/human on the rune?
+ var/must_be_servant = TRUE //If the above is true, does the human need to be a servant?
+ var/target_can_be_invoker = TRUE //Does this rite work if the invoker is also the target?
+ var/cast_time = 0 //How long does the rite take to cast?
+ var/limit = INFINITE //How often can this rite be used per round? Set this to INFINITE for unlimited, 0 for disallowed, anything above 0 for a limit
+ var/times_used = 0 //How often has the rite already been used this shift?
+ var/rite_cast_sound = 'sound/items/bikehorn.ogg' //The sound played when successfully casting the rite. If it honks, the one adding the rite forgot to set one (or was just lazy).
+
+/datum/clockwork_rite/proc/try_cast(var/obj/effect/clockwork/sigil/rite/R, var/mob/living/invoker) //Performs a ton of checks to see if the invoker can cast the rite
+ if(!istype(R))
+ return FALSE
+ if(!R || !R.loc)
+ return FALSE
+ var/turf/T = R.loc
+ if(!T) //Uh oh something is fucky
+ return FALSE
+
+ if(limit != INFINITE && times_used >= limit) //Is the limit on casts exceeded?
+ to_chat(invoker, "There are no more uses left for this rite!")
+ return FALSE
+
+ var/mob/living/carbon/human/H //This is only used if requires_human is TRUE
+ if(requires_human) //In case this requires a target
+ for(var/mob/living/carbon/human/possible_H in T)
+ if((!must_be_servant || is_servant_of_ratvar(possible_H)) && (target_can_be_invoker || invoker != possible_H))
+ H = possible_H
+ break
+ if(!H)
+ to_chat(invoker, "There is no target for the rite on the sigil!")
+ return FALSE
+
+ if(required_ingredients.len) //In case this requires materials
+ var/is_missing_materials = FALSE
+ for(var/I in required_ingredients)
+ var/obj/item/Material = locate(I) in T
+ if(!Material)
+ is_missing_materials = TRUE
+ break
+ if(is_missing_materials)
+ var/still_required_string = ""
+ for(var/i = 1 to required_ingredients.len)
+ var/obj/O = required_ingredients[i]
+ if(i != 1)
+ still_required_string += ", "
+ still_required_string += "a [initial(O.name)]"
+ to_chat(invoker, "There are still materials missing for this rite. You require [still_required_string].")
+ return FALSE
+
+ if(power_cost) //If this costs power
+ if(!get_clockwork_power(power_cost))
+ to_chat(invoker, "There is not enough power for this rite!")
+ return FALSE
+ R.performing_rite = TRUE
+ if(!do_after(invoker, cast_time, target = R))
+ to_chat(invoker, "Your rite is disrupted.")
+ R.performing_rite = FALSE
+ return FALSE
+ . = cast(invoker, T, H)
+ if(!.)
+ to_chat(invoker, " You fail casting [name]")
+ post_cast(FALSE)
+ else
+ to_chat(invoker, "You successfully cast [name]")
+ post_cast(TRUE)
+ R.performing_rite = FALSE
+ return
+
+/datum/clockwork_rite/proc/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target) //Casts the rite and uses up ingredients. Doublechecks some things to prevent bypassing some restrictions via funky timing or badminnery.
+ if(!T || !invoker)
+ return FALSE
+ if(requires_human && !target)
+ return FALSE
+ if(power_cost && !get_clockwork_power(power_cost))
+ return FALSE
+ adjust_clockwork_power(-power_cost)
+ if(limit != INFINITE && times_used >= limit)
+ return FALSE
+ if(required_ingredients.len)
+ var/is_missing_materials = FALSE
+ for(var/I in required_ingredients)
+ var/obj/item/Material = locate(I) in T
+ if(!Material)
+ is_missing_materials = TRUE
+ break
+ qdel(Material)
+ if(is_missing_materials)
+ return FALSE
+ playsound(T, rite_cast_sound, 50, 2)
+ return TRUE
+
+/datum/clockwork_rite/proc/post_cast(var/cast_succeeded)
+ if(cast_succeeded)
+ times_used++
+ return TRUE
+
+/datum/clockwork_rite/proc/build_info() //Constructs the info text of a given rite, based on the vars of the rite
+ . = ""
+ . += "This is the [name].\n"
+ . += "[desc]\n"
+ . += "It requires: "
+ if(required_ingredients.len)
+ var/material_string = ""
+ for(var/i = 1 to required_ingredients.len)
+ var/obj/O = required_ingredients[i]
+ if(i != 1)
+ material_string += ", "
+ material_string += "a [initial(O.name)]"
+ . += "[material_string].\n"
+ else
+ . += "no materials.\n"
+ . += "It [power_cost >= 0 ? "costs" : "generates"] [power_cost ? "[power_cost]" : "no"] power.\n"
+ . += "It requires [requires_human ? " a human" : " no"] target.\n"
+ if(requires_human)
+ . += "The target [must_be_servant ? "cannot be" : "can be"] a nonservant.\n"
+ . += "The target [target_can_be_invoker ? "can be" : "cannot be"] the invoker.\n"
+ . += "It requires [cast_time/10] seconds to cast.\n"
+ . += "It has been used [times_used] time[times_used != 1 ? "s" : ""], out of [limit != INFINITE ? "[limit]" : "infinite"] available uses."
+
+//Adds a organ or cybernetic implant to a servant without the need for surgery. Cannot be used with brains for.. reasons.
+/datum/clockwork_rite/advancement
+ name = "Rite of Advancement"
+ desc = "This rite is used to augment a servant with organs or cybernetic implants. The organ of choice, aswell as the servant and the required ingredients must be placed on the sigil for this rite to take place."
+ required_ingredients = list(/obj/item/assembly/prox_sensor, /obj/item/stock_parts/cell)
+ power_cost = 500
+ requires_human = TRUE
+ cast_time = 40
+ rite_cast_sound = 'sound/magic/blind.ogg'
+
+/datum/clockwork_rite/advancement/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target)
+ var/obj/item/organ/O = locate(/obj/item/organ) in T
+ if(!O)
+ return FALSE
+ if(istype(O, /obj/item/organ/brain)) //NOPE
+ return FALSE
+ . = ..()
+ if(!.)
+ return FALSE
+ O.Insert(target)
+ new /obj/effect/temp_visual/ratvar/sigil/transgression(T)
+
+//Heals all wounds (not damage) on the target, causing toxloss proportional to amount of wounds healed. 10 damage per wound.
+/datum/clockwork_rite/treat_wounds
+ name = "Rite of Woundmending"
+ desc = "This rite is used to heal wounds of the servant on the rune. It causes toxins damage proportional to the amount of wounds healed. This can be lethal if performed on an critically injured target."
+ required_ingredients = list(/obj/item/stock_parts/cell, /obj/item/healthanalyzer, /obj/item/reagent_containers/food/drinks/bottle/holyoil)
+ power_cost = 300
+ requires_human = TRUE
+ must_be_servant = FALSE
+ target_can_be_invoker = FALSE
+ cast_time = 80
+ rite_cast_sound = 'sound/magic/staff_healing.ogg'
+
+/datum/clockwork_rite/treat_wounds/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target)
+ if(!target)
+ return FALSE
+ if(!target.all_wounds.len)
+ to_chat(invoker, "This one does not require mending.")
+ return FALSE
+ .= ..()
+ if(!.)
+ return FALSE
+ target.adjustToxLoss(10 * target.all_wounds.len)
+ QDEL_LIST(target.all_wounds)
+ to_chat(target, "You feel your wounds heal, but are overcome with deep nausea.")
+ new /obj/effect/temp_visual/ratvar/sigil/vitality(T)
+
+//Summons a brass claw implant on the sigil, which can extend a claw that benefits from repeatedly attacking a single target. Can only be cast a limited amount of times.
+/datum/clockwork_rite/summon_claw
+ name = "Rite of the Claw"
+ desc = "Summons a special arm implant that, when added to a servant's limb, will allow them to extend and retract a claw at will. Don't leave any implants you want to keep on this rune when casting the rite."
+ required_ingredients = list(/obj/item/stock_parts/cell, /obj/item/organ/cyberimp, /obj/item/assembly/flash)
+ power_cost = 1000
+ cast_time = 60
+ limit = 4
+ rite_cast_sound = 'sound/magic/clockwork/fellowship_armory.ogg'
+
+/datum/clockwork_rite/summon_claw/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target)
+ . = ..()
+ if(!.)
+ return FALSE
+ var/obj/item/organ/cyberimp/arm/clockwork/claw/CL = new /obj/item/organ/cyberimp/arm/clockwork/claw(T)
+ CL.visible_message("[CL] materialises out of thin air!")
+ new /obj/effect/temp_visual/ratvar/sigil/transmission(T,2)
+
+#undef INFINITE
diff --git a/code/modules/antagonists/clockcult/clock_items/clock_augments.dm b/code/modules/antagonists/clockcult/clock_items/clock_augments.dm
new file mode 100644
index 0000000000..2131aa7160
--- /dev/null
+++ b/code/modules/antagonists/clockcult/clock_items/clock_augments.dm
@@ -0,0 +1,32 @@
+//This file is for snowflakey clock augmentations and clock-themed cybernetic implants.
+
+//The base clockie arm implant, which only clock cultist can use unless it is emagged. THIS SHOULD NEVER ACTUALLY EXIST
+/obj/item/organ/cyberimp/arm/clockwork
+ name = "clock-themed arm-mounted implant"
+ var/clockwork_desc = "According to Ratvar, this really shouldn't exist. Tell Him about this immediately."
+ syndicate_implant = TRUE
+ icon_state = "clock_arm_implant"
+
+/obj/item/organ/cyberimp/arm/clockwork/ui_action_click()
+ if(is_servant_of_ratvar(owner) || (obj_flags & EMAGGED)) //If you somehow manage to steal a clockie's implant AND have an emag AND manage to get it implanted for yourself, good on ya!
+ return ..()
+ to_chat(owner, "The implant refuses to activate..")
+
+/obj/item/organ/cyberimp/arm/clockwork/examine(mob/user)
+ if((is_servant_of_ratvar(user) || isobserver(user)) && clockwork_desc)
+ desc = clockwork_desc
+ . = ..()
+ desc = initial(desc)
+
+/obj/item/organ/cyberimp/arm/clockwork/emag_act()
+ if(obj_flags & EMAGGED)
+ return
+ obj_flags |= EMAGGED
+ to_chat(usr, "You emag [src], hoping it'll achieve something..")
+
+//Brass claw implant. Holds the brass claw from brass_claw.dm and can extend / retract it at will.
+/obj/item/organ/cyberimp/arm/clockwork/claw
+ name = "brass claw implant"
+ desc = "Yikes, the claw attached to this looks pretty darn sharp."
+ clockwork_desc = "This implant, when added to a servant's arm, allows them to extend and retract a claw at will, though this is mildly painful to do. It will refuse to work for any non-servants."
+ contents = newlist(/obj/item/clockwork/brass_claw)
diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/brass_claw.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/brass_claw.dm
new file mode 100644
index 0000000000..340f01f6f8
--- /dev/null
+++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/brass_claw.dm
@@ -0,0 +1,51 @@
+//Brass claw, an armblade-like weapon used by a clock implant. Stealthy if retracted, very obvious if active.
+//Bit weaker than an armblade strength-wise but gains combo on consecutive attacks against the same target, which causes bonus damage
+
+/obj/item/clockwork/brass_claw
+ name = "brass claw"
+ desc = "A very sharp claw made out of brass."
+ clockwork_desc = "A incredibly sharp claw made out of brass. It is quite effective at crippling enemies, though very obvious when extended.\nGains combo on consecutive attacks against a target, causing bonus damage."
+ icon_state = "brass_claw" //Codersprite moment
+ item_state = "brass_claw"
+ lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi'
+ w_class = WEIGHT_CLASS_HUGE
+ force = 15 //Doesn't generate vitality like the spear does / has somewhat less damage, but quite good at wounding and gets through armor pretty well. Also gains 2 bonus damage per consecutive attack on the same target
+ throwforce = 0 //haha yes lets be safe about this
+ throw_range = 0
+ throw_speed = 0
+ armour_penetration = 20
+ hitsound = 'sound/weapons/bladeslice.ogg'
+ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ sharpness = SHARP_EDGED
+ wound_bonus = 5
+ bare_wound_bonus = 15
+ total_mass = TOTAL_MASS_HAND_REPLACEMENT
+ var/mob/living/last_attacked
+ var/combo = 0
+ var/damage_per_combo = 2
+ var/maximum_combo_damage = 18 //33 damage on max stacks. Usually the target will already be dead by then but if they somehow aren't, better to have this capped
+
+/obj/item/clockwork/brass_claw/Initialize()
+ . = ..()
+ AddComponent(/datum/component/butchering, 60, 80)
+
+/obj/item/clockwork/brass_claw/examine(mob/user)
+ if(is_servant_of_ratvar(user))
+ clockwork_desc += "\nIt has [combo] combo stacks built up against the current target, causing [min(maximum_combo_damage, combo * damage_per_combo)] bonus damage."
+ . = ..()
+ clockwork_desc = initial(clockwork_desc)
+
+/obj/item/clockwork/brass_claw/attack(mob/living/target, mob/living/carbon/human/user)
+ . = ..()
+ if(QDELETED(target) || target.anti_magic_check(chargecost = 0) || is_servant_of_ratvar(target))
+ return
+ if(target != last_attacked) //Loses all combat on switching targets
+ last_attacked = target
+ combo = 0
+ else
+ if(!iscultist(target)) //Hostile cultists being hit stacks up combo far faster than usual
+ combo++
+ else
+ combo += 3
+ target.adjustBruteLoss(min(maximum_combo_damage, combo * damage_per_combo))
diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm
index 527745b81a..aa69478217 100644
--- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm
@@ -8,10 +8,12 @@
force = 15 //Extra damage is dealt to targets in attack()
throwforce = 25
armour_penetration = 10
- sharpness = IS_SHARP_ACCURATE
+ sharpness = SHARP_POINTY
attack_verb = list("stabbed", "poked", "slashed")
hitsound = 'sound/weapons/bladeslice.ogg'
w_class = WEIGHT_CLASS_BULKY
+ block_parry_data = /datum/block_parry_data/ratvarian_spear
+ item_flags = ITEM_CAN_PARRY
var/bonus_burn = 5
/obj/item/clockwork/weapon/ratvarian_spear/ratvar_act()
@@ -43,7 +45,7 @@
else if(iscultist(target) || isconstruct(target))
to_chat(target, "Your body flares with agony at [src]'s presence!")
bonus_damage *= 3 //total 30 damage on cultists, 50 with ratvar
- GLOB.clockwork_vitality += target.adjustFireLoss(bonus_damage) //adds the damage done to existing vitality
+ GLOB.clockwork_vitality += max(0, target.adjustFireLoss(bonus_damage)) //adds the damage done to existing vitality
/obj/item/clockwork/weapon/ratvarian_spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
var/turf/T = get_turf(hit_atom)
@@ -80,3 +82,15 @@
new /obj/effect/temp_visual/ratvar/spearbreak(T)
action.weapon_reset(RATVARIAN_WEAPON_COOLDOWN)
+//A very short, very effective parry that counts on you predicting when the enemy will attack.
+/datum/block_parry_data/ratvarian_spear
+ parry_time_windup = 0 //Very good for predicting
+ parry_time_active = 3 //Very short
+ parry_time_spindown = 1
+ parry_time_perfect = 2
+ parry_efficiency_perfect = 110 //Very low leeway for counterattacks...
+ parry_efficiency_considered_successful = 0.8
+ parry_efficiency_to_counterattack = 1
+ parry_cooldown = 15 //But also very low cooldown..
+ parry_failed_stagger_duration = 2 SECONDS //And relatively small penalties for failing.
+ parry_failed_clickcd_duration = 1 SECONDS
diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm
index f941c84abe..79b919b1e9 100644
--- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm
+++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm
@@ -143,6 +143,8 @@
movement_type = FLYING
AIStatus = AI_OFF //this has to be manually set so that the guardian doesn't start bashing the host, how annoying -_-
loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor)
+ max_shield_health = 0
+ shield_health = 0
var/true_name = "Meme Master 69" //Required to call forth the guardian
var/global/list/possible_true_names = list("Servant", "Warden", "Serf", "Page", "Usher", "Knave", "Vassal", "Escort")
var/mob/living/host //The mob that the guardian is living inside of
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm
index c4b1913832..00c4d73428 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm
@@ -97,7 +97,7 @@
desc = "Charges your slab with divine energy, allowing you to overwhelm a target with Ratvar's light."
invocations = list("Divinity, show them your light!")
whispered = TRUE
- channel_time = 10 // I think making kindle channel a third of the time less is a good make up for the fact that it silences people for such a little amount of time.
+ channel_time = 15 // I think making kindle channel a third of the time less is a good make up for the fact that it silences people for such a little amount of time.
power_cost = 125
usage_tip = "The light can be used from up to two tiles away. Damage taken will GREATLY REDUCE the stun's duration."
tier = SCRIPTURE_DRIVER
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm
index d96765d536..8819544928 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm
@@ -81,6 +81,25 @@
return /obj/effect/clockwork/sigil/vitality/neutered
return ..()
+//Sigil of Rites: Creates a sigil that allows to perform certain rites on it. More information on these can be found in clock_rites.dm, they usually require power, materials and sometimes a target.
+/datum/clockwork_scripture/create_object/sigil_of_rites
+ descname = "Sigil, Access to rites"
+ name = "Sigil of Rites"
+ desc = "Places a sigil that, when interacted with, will allow for a variety of rites to be performed on the sigil. These usually require power cells, clockwork power, and some other components."
+ invocations = list("Engine, allow us..", ".. to be blessed with your rites.")
+ channel_time = 80
+ power_cost = 1400
+ invokers_required = 2
+ multiple_invokers_used = TRUE
+ whispered = TRUE
+ object_path = /obj/effect/clockwork/sigil/rite
+ creator_message = "A sigil of Rites appears beneath you. It will allow you to perform certain rites, given sufficient materials and power."
+ usage_tip = "It may be useful to coordinate to acquire needed materials quickly."
+ tier = SCRIPTURE_SCRIPT
+ one_per_tile = TRUE
+ primary_component = HIEROPHANT_ANSIBLE
+ sort_priority = 4
+
//Judicial Visor: Creates a judicial visor, which can smite an area.
/datum/clockwork_scripture/create_object/judicial_visor
descname = "Delayed Area Knockdown Glasses"
@@ -96,7 +115,7 @@
tier = SCRIPTURE_SCRIPT
space_allowed = TRUE
primary_component = BELLIGERENT_EYE
- sort_priority = 4
+ sort_priority = 5
quickbind = TRUE
quickbind_desc = "Creates a Judicial Visor, which can smite an area, applying Belligerent and briefly stunning."
@@ -115,7 +134,7 @@
tier = SCRIPTURE_SCRIPT
space_allowed = TRUE
primary_component = VANGUARD_COGWHEEL
- sort_priority = 6
+ sort_priority = 7
quickbind = TRUE
quickbind_desc = "Creates a Ratvarian shield, which can absorb energy from attacks for use in powerful bashes."
@@ -131,7 +150,7 @@
usage_tip = "Throwing the spear at a mob will do massive damage and knock them down, but break the spear. You will need to wait for 30 seconds before resummoning it."
tier = SCRIPTURE_SCRIPT
primary_component = VANGUARD_COGWHEEL
- sort_priority = 7
+ sort_priority = 8
important = TRUE
quickbind = TRUE
quickbind_desc = "Permanently binds clockwork armor and a Ratvarian spear to you."
@@ -229,7 +248,7 @@
usage_tip = "This is a very effective way to rapidly reinforce a base after an attack."
tier = SCRIPTURE_SCRIPT
primary_component = VANGUARD_COGWHEEL
- sort_priority = 8
+ sort_priority = 9
quickbind = TRUE
quickbind_desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed.
Maximum 10 chants."
var/heal_attempts = 4
@@ -342,7 +361,7 @@
usage_tip = "Though it requires you to stand still, this scripture can do massive damage."
tier = SCRIPTURE_SCRIPT
primary_component = BELLIGERENT_EYE
- sort_priority = 5
+ sort_priority = 6
quickbind = TRUE
quickbind_desc = "Allows you to fire energy rays at target locations.
Maximum 5 chants."
var/static/list/nzcrentr_insults = list("You're not very good at aiming.", "You hunt badly.", "What a waste of energy.", "Almost funny to watch.",
@@ -391,7 +410,7 @@
usage_tip = "It may be useful to end channelling early if the burning becomes too much to handle.."
tier = SCRIPTURE_SCRIPT
primary_component = GEIS_CAPACITOR
- sort_priority = 10
+ sort_priority = 11
quickbind = TRUE
quickbind_desc = "Quickly drains power in an area around the invoker, causing burns proportional to the amount of energy drained.
Maximum of 20 chants."
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index f305d5b678..35151953a0 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -53,7 +53,7 @@
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
flags_1 = CONDUCT_1
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
w_class = WEIGHT_CLASS_BULKY
force = 30 // whoever balanced this got beat in the head by a bible too many times good lord
throwforce = 10
@@ -114,7 +114,7 @@
armour_penetration = 45
throw_speed = 1
throw_range = 3
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
light_color = "#ff0000"
attack_verb = list("cleaved", "slashed", "torn", "hacked", "ripped", "diced", "carved")
icon_state = "cultbastard"
@@ -708,7 +708,7 @@
armour_penetration = 30
block_chance = 30
attack_verb = list("attacked", "impaled", "stabbed", "torn", "gored")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
hitsound = 'sound/weapons/bladeslice.ogg'
var/datum/action/innate/cult/spear/spear_act
var/wielded = FALSE // track wielded status on item
diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm
index 35a674fb0e..3ae9cfcfb0 100644
--- a/code/modules/antagonists/slaughter/slaughter.dm
+++ b/code/modules/antagonists/slaughter/slaughter.dm
@@ -38,7 +38,7 @@
melee_damage_upper = 22.5
wound_bonus = -10
bare_wound_bonus = 0
- sharpness = TRUE
+ sharpness = SHARP_EDGED
see_in_dark = 8
blood_volume = 0 //No bleeding on getting shot, for skeddadles
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 2701a2d006..d8a8e9a1be 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -259,7 +259,7 @@
to_chat(target, "You suddenly feel very hot")
target.adjust_bodytemperature(50)
GiveHint(target)
- else if(is_pointed(I))
+ else if(I.get_sharpness() == SHARP_POINTY)
to_chat(target, "You feel a stabbing pain in [parse_zone(user.zone_selected)]!")
target.DefaultCombatKnockdown(40)
GiveHint(target)
diff --git a/code/modules/cargo/packs/goodies.dm b/code/modules/cargo/packs/goodies.dm
index 2ff02d0473..86a7c73a34 100644
--- a/code/modules/cargo/packs/goodies.dm
+++ b/code/modules/cargo/packs/goodies.dm
@@ -81,3 +81,9 @@
desc = "Contains one hellgun, an old pattern of laser gun infamous for its ability to horribly disfigure targets with burns. Technically violates the Space Geneva Convention when used on humanoids."
cost = 1500
contains = list(/obj/item/gun/energy/laser/hellgun)
+
+/datum/supply_pack/goody/medipen_twopak
+ name = "Medipen Two-Pak"
+ desc = "Contains one standard epinephrine medipen and one standard emergency first-aid kit medipen. For when you want to prepare for the worst."
+ cost = 500
+ contains = list(/obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/hypospray/medipen/ekit)
diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm
index 5eacc2f583..6a4165f840 100644
--- a/code/modules/cargo/packs/medical.dm
+++ b/code/modules/cargo/packs/medical.dm
@@ -218,3 +218,18 @@
/obj/item/storage/box/beakers)
crate_name = "virus containment unit crate"
crate_type = /obj/structure/closet/crate/secure/plasma
+
+/datum/supply_pack/medical/medipen_variety
+ name = "Medipen Variety-Pak"
+ desc = "Contains eight different medipens in three different varieties, to assist in quickly treating seriously injured patients."
+ cost = 2000
+ contains = list(/obj/item/reagent_containers/hypospray/medipen/,
+ /obj/item/reagent_containers/hypospray/medipen/,
+ /obj/item/reagent_containers/hypospray/medipen/ekit,
+ /obj/item/reagent_containers/hypospray/medipen/ekit,
+ /obj/item/reagent_containers/hypospray/medipen/ekit,
+ /obj/item/reagent_containers/hypospray/medipen/blood_loss,
+ /obj/item/reagent_containers/hypospray/medipen/blood_loss,
+ /obj/item/reagent_containers/hypospray/medipen/blood_loss)
+
+ crate_name = "medipen crate"
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 75e914ea68..3c9697c03a 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -40,7 +40,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//If it's 0, that's good, if it's anything but 0, the owner of this prefs file's antag choices were,
//autocorrected this round, not that you'd need to check that.
-
var/UI_style = null
var/buttons_locked = FALSE
var/hotkeys = FALSE
@@ -832,7 +831,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Socks Color: Change
"
dat += "Backpack:[backbag]"
dat += "Jumpsuit:
[jumpsuit_style]
"
- if(CAN_SCAR in pref_species.species_traits)
+ if((HAS_FLESH in pref_species.species_traits) || (HAS_BONE in pref_species.species_traits))
dat += "
Temporal Scarring:
[(persistent_scars) ? "Enabled" : "Disabled"]"
dat += "Clear scar slots"
dat += "Uplink Location:[uplink_spawn_loc]"
@@ -1065,6 +1064,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "| [gear_points] loadout points remaining. \[Clear Loadout\] |
"
dat += "| You can only choose one item per category, unless it's an item that spawns in your backpack or hands. |
"
dat += "| "
+
var/firstcat = TRUE
for(var/i in GLOB.loadout_items)
if(firstcat)
@@ -1075,6 +1075,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += " [i] "
else
dat += " [i] "
+
dat += " |
"
dat += "
|
"
dat += "| [gear_tab] |
"
@@ -1130,6 +1131,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Hypno: [(cit_toggles & NEVER_HYPNO) ? "Disallowed" : "Allowed"]
"
dat += "Aphrodisiacs: [(cit_toggles & NO_APHRO) ? "Disallowed" : "Allowed"]
"
dat += "Ass Slapping: [(cit_toggles & NO_ASS_SLAP) ? "Disallowed" : "Allowed"]
"
+ dat += "Automatic Wagging: [(cit_toggles & NO_AUTO_WAG) ? "Disabled" : "Enabled"]
"
dat += ""
dat += "
"
if(5) // Custom keybindings
@@ -2644,6 +2646,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("bimbo")
cit_toggles ^= BIMBOFICATION
+ if("auto_wag")
+ cit_toggles ^= NO_AUTO_WAG
+
//END CITADEL EDIT
if("ambientocclusion")
@@ -2796,6 +2801,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(custom_tongue != "default")
var/new_tongue = GLOB.roundstart_tongues[custom_tongue]
if(new_tongue)
+ character.dna.species.mutanttongue = new_tongue //this means we get our tongue when we clone
var/obj/item/organ/tongue/T = character.getorganslot(ORGAN_SLOT_TONGUE)
if(T)
qdel(T)
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 59d99674eb..dffab645a4 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -224,7 +224,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
var/needs_update = savefile_needs_update(S)
if(needs_update == -2) //fatal, can't load any data
return 0
-
+
. = TRUE
//general preferences
@@ -443,7 +443,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
return 0
. = TRUE
-
+
//Species
var/species_id
S["species"] >> species_id
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index 01effea6f2..350a577fb1 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -96,7 +96,7 @@
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
/obj/item/clothing/glasses/meson/eyepatch
name = "eyepatch mesons"
@@ -180,7 +180,7 @@
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
vision_correction = 1
glass_colour_type = /datum/client_colour/glass_colour/lightgreen
@@ -237,7 +237,7 @@
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
/obj/item/clothing/glasses/sunglasses/garb/supergarb
name = "black giga gar glasses"
@@ -257,7 +257,7 @@
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
glass_colour_type = /datum/client_colour/glass_colour/orange
/obj/item/clothing/glasses/sunglasses/gar/supergar
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index c745cd74f0..9ca98b0bca 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -70,7 +70,7 @@
flash_protect = -2
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/green
-
+
/obj/item/clothing/glasses/hud/health/night/syndicate
name = "combat night vision health scanner HUD"
desc = "An advanced shielded medical heads-up display that allows soldiers to approximate how much lead poisoning their allies have suffered in complete darkness."
@@ -221,7 +221,7 @@
throw_speed = 4
attack_verb = list("sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
/obj/item/clothing/glasses/hud/security/sunglasses/gars/supergars
name = "giga HUD gar glasses"
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index 72d0f68c18..124ece8fdc 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -469,3 +469,16 @@
icon_state = "maid"
item_state = "maid"
dynamic_hair_suffix = ""
+
+/obj/item/clothing/head/widered
+ name = "Wide red hat"
+ desc = "It is both wide, and red. Stylish!"
+ icon_state = "widehat_red"
+ item_state = "widehat_red"
+
+/obj/item/clothing/head/kabuto
+ name = "Kabuto helmet"
+ desc = "A traditional kabuto helmet."
+ icon_state = "kabuto"
+ item_state = "kabuto"
+ flags_inv = HIDEHAIR|HIDEEARS
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index 746bd3458a..49256b490d 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -257,10 +257,8 @@
if(14 to 25) // 1.3ish% chance to stumble and be a bit off balance (like being disarmed)
to_chat(our_guy, "You stumble a bit on your untied shoelaces!")
- if(!our_guy.has_movespeed_modifier(/datum/movespeed_modifier/shove))
- our_guy.add_movespeed_modifier(/datum/movespeed_modifier/shove)
- addtimer(CALLBACK(our_guy, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
-
+ our_guy.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
+ our_guy.Stagger(SHOVE_OFFBALANCE_DURATION) //yes, same.
if(26 to 1000)
wiser = FALSE
if(wiser)
diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm
index 82dd3142ed..cba27845f1 100644
--- a/code/modules/clothing/spacesuits/_spacesuits.dm
+++ b/code/modules/clothing/spacesuits/_spacesuits.dm
@@ -7,7 +7,7 @@
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS
item_state = "spaceold"
permeability_coefficient = 0.01
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70, "wound" = 5)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
dynamic_hair_suffix = ""
dynamic_fhair_suffix = ""
@@ -36,7 +36,7 @@
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/flashlight, /obj/item/tank/internals)
slowdown = 1
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70, "wound" = 5)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAUR
cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm
index 4dc6fd1f6c..3f77a2befc 100644
--- a/code/modules/clothing/spacesuits/chronosuit.dm
+++ b/code/modules/clothing/spacesuits/chronosuit.dm
@@ -4,7 +4,7 @@
icon_state = "chronohelmet"
item_state = "chronohelmet"
slowdown = 1
- armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 100, "wound" = 80)
resistance_flags = FIRE_PROOF | ACID_PROOF
var/obj/item/clothing/suit/space/chronos/suit = null
@@ -19,7 +19,7 @@
icon_state = "chronosuit"
item_state = "chronosuit"
actions_types = list(/datum/action/item_action/toggle)
- armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 1000)
+ armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 1000, "wound" = 80)
resistance_flags = FIRE_PROOF | ACID_PROOF
mutantrace_variation = STYLE_DIGITIGRADE
var/list/chronosafe_items = list(/obj/item/chrono_eraser, /obj/item/gun/energy/chrono_gun)
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index b588deaf01..40797b97ed 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -5,7 +5,7 @@
icon_state = "hardsuit0-engineering"
item_state = "eng_helm"
max_integrity = 300
- armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75)
+ armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75, "wound" = 10)
var/basestate = "hardsuit"
var/brightness_on = 4 //luminosity when on
var/on = FALSE
@@ -717,7 +717,7 @@
item_state = "rig0-soviet"
hardsuit_type = "soviet"
icon_state = "rig0-soviet"
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75)
+ armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75, "wound" = 15)
mutantrace_variation = NONE
/obj/item/clothing/suit/space/hardsuit/soviet
@@ -726,7 +726,7 @@
item_state = "rig-soviet"
icon_state = "rig-soviet"
slowdown = 0.8
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75)
+ armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75, "wound" = 15)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/soviet
mutantrace_variation = NONE
@@ -771,7 +771,7 @@
item_state = "ert_medical"
hardsuit_type = "ert_medical"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf
- armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95)
+ armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95, "wound" = 30)
slowdown = 0
max_charges = 5
@@ -800,7 +800,7 @@
icon_state = "hardsuit0-ert_medical"
item_state = "hardsuit0-ert_medical"
hardsuit_type = "ert_medical"
- armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95)
+ armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95, "wound" = 30)
/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red
icon_state = "hardsuit0-ert_security"
@@ -879,7 +879,7 @@
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | LAVA_PROOF
heat_protection = HEAD
- armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
+ armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, "wound" = 30)
brightness_on = 7
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator)
var/energy_color = "#35FFF0"
@@ -923,7 +923,7 @@
item_state = "swat_suit"
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | LAVA_PROOF
- armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
+ armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, "wound" = 30)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/lavaknight
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm
index ee70f54ed0..5124c5d62e 100644
--- a/code/modules/clothing/spacesuits/miscellaneous.dm
+++ b/code/modules/clothing/spacesuits/miscellaneous.dm
@@ -51,7 +51,7 @@ Contains:
icon_state = "heavy"
item_state = "swat_suit"
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat)
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 50, "bio" = 90, "rad" = 20, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 50, "bio" = 90, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 25)
strip_delay = 120
resistance_flags = FIRE_PROOF | ACID_PROOF
mutantrace_variation = STYLE_DIGITIGRADE
@@ -63,7 +63,7 @@ Contains:
dynamic_hair_suffix = "+generic"
dynamic_fhair_suffix = "+generic"
flags_inv = 0
- armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30)
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -79,7 +79,7 @@ Contains:
flags_inv = 0
w_class = WEIGHT_CLASS_NORMAL
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
- armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30)
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -140,7 +140,7 @@ Contains:
desc = "A thick, space-proof tricorne from the royal Space Queen. It's lined with a layer of reflective kevlar."
icon_state = "pirate"
item_state = "pirate"
- armor = list("melee" = 30, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 60, "acid" = 75)
+ armor = list("melee" = 30, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 60, "acid" = 75, "wound" = 30)
flags_inv = HIDEHAIR
strip_delay = 40
equip_delay_other = 20
@@ -163,7 +163,7 @@ Contains:
flags_inv = 0
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/melee/transforming/energy/sword/pirate, /obj/item/clothing/glasses/eyepatch, /obj/item/reagent_containers/food/drinks/bottle/rum)
slowdown = 0
- armor = list("melee" = 30, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 60, "acid" = 75)
+ armor = list("melee" = 30, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 60, "acid" = 75, "wound" = 30)
strip_delay = 40
equip_delay_other = 20
mutantrace_variation = STYLE_DIGITIGRADE
@@ -175,7 +175,7 @@ Contains:
icon_state = "hardsuit0-ert_commander"
item_state = "hardsuit0-ert_commander"
hardsuit_type = "ert_commander"
- armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80)
+ armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 30)
strip_delay = 130
brightness_on = 7
resistance_flags = ACID_PROOF
@@ -191,7 +191,7 @@ Contains:
item_state = "ert_command"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
- armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80)
+ armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 30)
slowdown = 0
strip_delay = 130
resistance_flags = ACID_PROOF
@@ -244,7 +244,7 @@ Contains:
icon_state = "hardsuit0-ert_commander-alert"
item_state = "hardsuit0-ert_commander-alert"
hardsuit_type = "ert_commander-alert"
- armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 50)
brightness_on = 8
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -254,7 +254,7 @@ Contains:
icon_state = "ert_command-alert"
item_state = "ert_command-alert"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert
- armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 50)
resistance_flags = FIRE_PROOF | ACID_PROOF
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC
@@ -303,7 +303,7 @@ Contains:
icon_state = "space"
item_state = "s_suit"
desc = "A lightweight space suit with the basic ability to protect the wearer from the vacuum of space during emergencies."
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65, "wound" = 10)
/obj/item/clothing/head/helmet/space/eva
name = "EVA helmet"
@@ -311,7 +311,7 @@ Contains:
item_state = "space"
desc = "A lightweight space helmet with the basic ability to protect the wearer from the vacuum of space during emergencies."
flash_protect = 0
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65, "wound" = 10)
//Radiation
/obj/item/clothing/head/helmet/space/rad
@@ -319,7 +319,7 @@ Contains:
desc = "A special helmet that protects against radiation and space. Not much else unfortunately."
icon_state = "cespace_helmet"
item_state = "nothing"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0, "wound" = 5)
resistance_flags = FIRE_PROOF
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
actions_types = list()
@@ -329,7 +329,7 @@ Contains:
desc = "A special suit that protects against radiation and space. Not much else unfortunately."
icon_state = "hardsuit-rad"
item_state = "nothing"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0, "wound" = 5)
resistance_flags = FIRE_PROOF
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
mutantrace_variation = NONE
@@ -339,7 +339,7 @@ Contains:
desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle."
icon_state = "griffinhat"
item_state = "griffinhat"
- armor = list("melee" = 20, "bullet" = 40, "laser" = 30, "energy" = 25, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80)
+ armor = list("melee" = 20, "bullet" = 40, "laser" = 30, "energy" = 25, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 20)
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = ACID_PROOF | FIRE_PROOF
@@ -351,7 +351,7 @@ Contains:
icon_state = "freedom"
item_state = "freedom"
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
- armor = list("melee" = 20, "bullet" = 40, "laser" = 30,"energy" = 25, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80)
+ armor = list("melee" = 20, "bullet" = 40, "laser" = 30,"energy" = 25, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 20)
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = ACID_PROOF | FIRE_PROOF
@@ -364,7 +364,7 @@ Contains:
desc = "Spaceworthy and it looks like a space carp's head, smells like one too."
icon_state = "carp_helm"
item_state = "syndicate"
- armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75) //As whimpy as a space carp
+ armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75, "wound" = 5) //As whimpy as a space carp
brightness_on = 0 //luminosity when on
actions_types = list()
mutantrace_variation = NONE
@@ -380,7 +380,7 @@ Contains:
icon_state = "carp_suit"
item_state = "space_suit_syndicate"
slowdown = 0 //Space carp magic, never stop believing
- armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75) //As whimpy whimpy whoo
+ armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75, "wound" = 5) //As whimpy whimpy whoo
allowed = list(/obj/item/tank/internals, /obj/item/gun/ballistic/automatic/speargun) //I'm giving you a hint here
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/carp
mutantrace_variation = STYLE_DIGITIGRADE
@@ -442,14 +442,14 @@ Contains:
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old
desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats. Alas, this one looks pretty worn out and rusted."
- armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60)
+ armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20)
slowdown = 0.8
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old
charges = 12
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old
desc = "A helmet worn by those who deal with paranormal threats for a living. Alas, this one looks pretty worn out and rusted."
- armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60)
+ armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20)
charges = 12
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker
@@ -467,14 +467,14 @@ Contains:
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old
desc = "Voices echo from the hardsuit, driving the user insane. This one is pretty battle-worn, but still fearsome."
- armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60)
+ armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20)
slowdown = 0.8
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old
charges = 6
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old
desc = "Peering into the eyes of the helmet is enough to seal damnation. This one is pretty battle-worn, but still fearsome."
- armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60)
+ armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20)
charges = 6
/obj/item/clothing/head/helmet/space/fragile
@@ -482,7 +482,7 @@ Contains:
desc = "A bulky, air-tight helmet meant to protect the user during emergency situations. It doesn't look very durable."
icon_state = "syndicate-helm-orange"
item_state = "syndicate-helm-orange"
- armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 0, "acid" = 0, "wound" = 5)
strip_delay = 65
/obj/item/clothing/suit/space/fragile
@@ -492,7 +492,7 @@ Contains:
icon_state = "syndicate-orange"
item_state = "syndicate-orange"
slowdown = 2
- armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 0, "acid" = 0, "wound" = 5)
strip_delay = 65
/obj/item/clothing/suit/space/fragile/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
@@ -525,7 +525,7 @@ Contains:
icon_state = "hunter"
item_state = "swat_suit"
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat)
- armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wpound" = 25)
strip_delay = 130
resistance_flags = FIRE_PROOF | ACID_PROOF
diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm
index f17eb91b74..5128f77433 100644
--- a/code/modules/clothing/spacesuits/plasmamen.dm
+++ b/code/modules/clothing/spacesuits/plasmamen.dm
@@ -5,7 +5,7 @@
name = "EVA plasma envirosuit"
desc = "A special plasma containment suit designed to be space-worthy, as well as worn over other clothing. Like its smaller counterpart, it can automatically extinguish the wearer in a crisis, and holds twice as many charges."
allowed = list(/obj/item/gun, /obj/item/ammo_casing, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword, /obj/item/restraints/handcuffs, /obj/item/tank)
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 10)
resistance_flags = FIRE_PROOF
icon_state = "plasmaman_suit"
item_state = "plasmaman_suit"
@@ -40,7 +40,7 @@
icon_state = "plasmaman-helm"
item_state = "plasmaman-helm"
strip_delay = 80
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 10)
resistance_flags = FIRE_PROOF
var/brightness_on = 4 //luminosity when the light is on
var/on = FALSE
@@ -77,7 +77,7 @@
desc = "A plasmaman containment helmet designed for security officers, protecting them from being flashed and burning alive, along-side other undesirables."
icon_state = "security_envirohelm"
item_state = "security_envirohelm"
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75)
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 20)
/obj/item/clothing/head/helmet/space/plasmaman/security/warden
name = "warden's plasma envirosuit helmet"
@@ -132,7 +132,7 @@
desc = "A sturdier plasmaman envirohelmet designed for research directors."
icon_state = "rd_envirohelm"
item_state = "rd_envirohelm"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 10)
/obj/item/clothing/head/helmet/space/plasmaman/robotics
name = "robotics plasma envirosuit helmet"
@@ -145,7 +145,7 @@
desc = "A space-worthy helmet specially designed for engineer plasmamen, the usual purple stripes being replaced by engineering's orange."
icon_state = "engineer_envirohelm"
item_state = "engineer_envirohelm"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 75)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 75, "wound" = 10)
/obj/item/clothing/head/helmet/space/plasmaman/engineering/ce
name = "chief engineer's plasma envirosuit helmet"
@@ -194,7 +194,7 @@
desc = "A blue and gold envirohelm designed for the station's captain, nonetheless. Made of superior materials to protect them from the station hazards and more."
icon_state = "captain_envirohelm"
item_state = "captain_envirohelm"
- armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 85)
+ armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 85, "wound" = 15)
/obj/item/clothing/head/helmet/space/plasmaman/curator
name = "curator's plasma envirosuit helmet"
diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm
index 662e333f59..f55379da2f 100644
--- a/code/modules/clothing/spacesuits/syndi.dm
+++ b/code/modules/clothing/spacesuits/syndi.dm
@@ -4,7 +4,7 @@
icon_state = "syndicate"
item_state = "syndicate"
desc = "Has a tag on it: Totally not property of an enemy corporation, honest!"
- armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85)
+ armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85, "wound" = 20)
/obj/item/clothing/suit/space/syndicate
name = "red space suit"
@@ -13,7 +13,7 @@
desc = "Has a tag on it: Totally not property of an enemy corporation, honest!"
w_class = WEIGHT_CLASS_NORMAL
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
- armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85)
+ armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85, "wound" = 20)
mutantrace_variation = STYLE_DIGITIGRADE
//Green syndicate space suit
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index b61743729f..cf7dbc7462 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -8,7 +8,7 @@
equip_delay_other = 40
max_integrity = 250
resistance_flags = NONE
- armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 15)
+ armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10)
/obj/item/clothing/suit/armor/Initialize()
@@ -58,7 +58,7 @@
icon_state = "hos"
item_state = "greatcoat"
body_parts_covered = CHEST|GROIN|ARMS|LEGS
- armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90, "wound" = 20)
+ armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90, "wound" = 10)
cold_protection = CHEST|GROIN|LEGS|ARMS
heat_protection = CHEST|GROIN|LEGS|ARMS
strip_delay = 80
@@ -148,7 +148,7 @@
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
- armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80, "wound" = 30)
+ armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80, "wound" = 20)
blocks_shove_knockdown = TRUE
strip_delay = 80
equip_delay_other = 60
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 0b1121b22b..607a8ecb55 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -1057,3 +1057,9 @@
desc = "Reminds you of someone, but you just can't put your finger on it..."
icon_state = "waldo_shirt"
item_state = "waldo_shirt"
+
+/obj/item/clothing/suit/samurai
+ name = "Samurai outfit"
+ desc = "An outfit used by traditional japanese warriors."
+ icon_state = "samurai"
+ item_state = "samurai"
\ No newline at end of file
diff --git a/code/modules/clothing/under/costume.dm b/code/modules/clothing/under/costume.dm
index 3e7bc755cb..18cd104ff8 100644
--- a/code/modules/clothing/under/costume.dm
+++ b/code/modules/clothing/under/costume.dm
@@ -329,3 +329,29 @@
desc = "cloud"
icon_state = "cloud"
can_adjust = FALSE
+
+/obj/item/clothing/under/costume/kimono
+ name = "Kimono"
+ desc = "A traditional piece of clothing from japan"
+ icon_state = "kimono"
+ item_state = "kimono"
+
+/obj/item/clothing/under/costume/kimono/black
+ name = "Black Kimono"
+ icon_state = "kimono_a"
+ item_state = "kimono_a"
+
+/obj/item/clothing/under/costume/kimono/kamishimo
+ name = "Kamishimo"
+ icon_state = "kamishimo"
+ item_state = "kamishimo"
+
+/obj/item/clothing/under/costume/kimono/fancy
+ name = "Fancy Kimono"
+ icon_state = "fancy_kimono"
+ item_state = "fancy_kimono"
+
+/obj/item/clothing/under/costume/kimono/sakura
+ name = "Sakura Kimono'"
+ icon_state = "sakura_kimono"
+ item_state = "sakura_kimono"
diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
index 5928819b16..082d783bea 100644
--- a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
+++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
@@ -57,7 +57,7 @@
desc = "An expensive piece of plasmaman envirosuit fashion. guaranteed to keep you cool while the station goes down in fierceful fires."
icon_state = "captain_envirosuit"
item_state = "captain_envirosuit"
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 15)
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
diff --git a/code/modules/clothing/under/jobs/Plasmaman/engineering.dm b/code/modules/clothing/under/jobs/Plasmaman/engineering.dm
index 15eb189fa8..4850a605e7 100644
--- a/code/modules/clothing/under/jobs/Plasmaman/engineering.dm
+++ b/code/modules/clothing/under/jobs/Plasmaman/engineering.dm
@@ -3,7 +3,7 @@
desc = "An air-tight suit designed to be used by plasmamen exployed as engineers, the usual purple stripes being replaced by engineer's orange. It protects the user from fire and acid damage."
icon_state = "engineer_envirosuit"
item_state = "engineer_envirosuit"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 95, "acid" = 95)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 95, "acid" = 95, "wound" = 5)
/obj/item/clothing/under/plasmaman/engineering/ce
name = "chief engineer's plasma envirosuit"
diff --git a/code/modules/clothing/under/jobs/Plasmaman/medsci.dm b/code/modules/clothing/under/jobs/Plasmaman/medsci.dm
index 03d089c10d..52f817dcce 100644
--- a/code/modules/clothing/under/jobs/Plasmaman/medsci.dm
+++ b/code/modules/clothing/under/jobs/Plasmaman/medsci.dm
@@ -21,7 +21,7 @@
desc = "A plasmaman envirosuit designed for the research director to aid them in their job of directing research into the right direction."
icon_state = "rd_envirosuit"
item_state = "rd_envirosuit"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 5)
/obj/item/clothing/under/plasmaman/robotics
name = "robotics plasma envirosuit"
diff --git a/code/modules/clothing/under/jobs/Plasmaman/security.dm b/code/modules/clothing/under/jobs/Plasmaman/security.dm
index ddbda041f3..3330d72844 100644
--- a/code/modules/clothing/under/jobs/Plasmaman/security.dm
+++ b/code/modules/clothing/under/jobs/Plasmaman/security.dm
@@ -3,7 +3,7 @@
desc = "A plasmaman containment suit designed for security officers, offering a limited amount of extra protection."
icon_state = "security_envirosuit"
item_state = "security_envirosuit"
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 10)
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
diff --git a/code/modules/clothing/under/jobs/civilian/civilian.dm b/code/modules/clothing/under/jobs/civilian/civilian.dm
index 4eb6a18258..5dffc8f88d 100644
--- a/code/modules/clothing/under/jobs/civilian/civilian.dm
+++ b/code/modules/clothing/under/jobs/civilian/civilian.dm
@@ -110,7 +110,7 @@
desc = "It's the official uniform of the station's janitor. It has minor protection from biohazards."
name = "janitor's jumpsuit"
icon_state = "janitor"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/civilian/janitor/skirt
name = "janitor's jumpskirt"
diff --git a/code/modules/clothing/under/jobs/engineering.dm b/code/modules/clothing/under/jobs/engineering.dm
index 3eaaa42620..5693468b3b 100644
--- a/code/modules/clothing/under/jobs/engineering.dm
+++ b/code/modules/clothing/under/jobs/engineering.dm
@@ -4,7 +4,7 @@
name = "chief engineer's jumpsuit"
icon_state = "chiefengineer"
item_state = "gy_suit"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 80, "acid" = 40)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 80, "acid" = 40, "wound" = 5)
resistance_flags = NONE
/obj/item/clothing/under/rank/engineering/chief_engineer/skirt
@@ -39,7 +39,7 @@
name = "engineer's jumpsuit"
icon_state = "engine"
item_state = "engi_suit"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 60, "acid" = 20)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 60, "acid" = 20, "wound" = 5)
resistance_flags = NONE
/obj/item/clothing/under/rank/engineering/engineer/hazard
diff --git a/code/modules/clothing/under/jobs/medical.dm b/code/modules/clothing/under/jobs/medical.dm
index c4eedf93a4..c66b972624 100644
--- a/code/modules/clothing/under/jobs/medical.dm
+++ b/code/modules/clothing/under/jobs/medical.dm
@@ -4,7 +4,7 @@
icon_state = "cmo"
item_state = "w_suit"
permeability_coefficient = 0.5
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/medical/chief_medical_officer/skirt
name = "chief medical officer's jumpskirt"
@@ -30,7 +30,7 @@
icon_state = "genetics"
item_state = "w_suit"
permeability_coefficient = 0.5
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/medical/geneticist/skirt
name = "geneticist's jumpskirt"
@@ -48,7 +48,7 @@
icon_state = "virology"
item_state = "w_suit"
permeability_coefficient = 0.5
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/medical/virologist/skirt
name = "virologist's jumpskirt"
@@ -66,7 +66,7 @@
icon_state = "chemistry"
item_state = "w_suit"
permeability_coefficient = 0.5
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 65)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 65, "wound" = 5)
/obj/item/clothing/under/rank/medical/chemist/skirt
name = "chemist's jumpskirt"
@@ -84,7 +84,7 @@
icon_state = "paramedic-dark"
item_state = "w_suit"
permeability_coefficient = 0.5
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/medical/paramedic/light
desc = "It's made of a special fiber that provides minor protection against biohazards. It has a dark blue cross on the chest denoting that the wearer is a trained paramedic."
@@ -110,7 +110,7 @@
icon_state = "nursesuit"
item_state = "w_suit"
permeability_coefficient = 0.5
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
body_parts_covered = CHEST|GROIN|ARMS
fitted = NO_FEMALE_UNIFORM
can_adjust = FALSE
@@ -122,7 +122,7 @@
icon_state = "medical"
item_state = "w_suit"
permeability_coefficient = 0.5
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/medical/doctor/blue
name = "blue medical scrubs"
diff --git a/code/modules/clothing/under/jobs/rnd.dm b/code/modules/clothing/under/jobs/rnd.dm
index f7bd6d5e33..03eb910736 100644
--- a/code/modules/clothing/under/jobs/rnd.dm
+++ b/code/modules/clothing/under/jobs/rnd.dm
@@ -3,7 +3,7 @@
name = "research director's vest suit"
icon_state = "director"
item_state = "lb_suit"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 35)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 35, "wound" = 5)
can_adjust = FALSE
/obj/item/clothing/under/rank/rnd/research_director/skirt
@@ -20,7 +20,7 @@
name = "research director's tan suit"
icon_state = "rdwhimsy"
item_state = "rdwhimsy"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
can_adjust = TRUE
alt_covers_chest = TRUE
@@ -39,7 +39,7 @@
name = "research director's turtleneck"
icon_state = "rdturtle"
item_state = "p_suit"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
can_adjust = TRUE
alt_covers_chest = TRUE
@@ -59,7 +59,7 @@
icon_state = "toxins"
item_state = "w_suit"
permeability_coefficient = 0.5
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/rank/rnd/scientist/skirt
name = "scientist's jumpskirt"
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index 997f10a379..27fb0cc00d 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -66,7 +66,7 @@
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.01
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
- armor = list("melee" = 100, "bullet" = 100, "laser" = 100,"energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 100, "bullet" = 100, "laser" = 100,"energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 1000) //wound defense at 100 wont stop wounds
cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
@@ -308,3 +308,21 @@
icon_state = "polyfemtankpantsu"
poly_states = 2
poly_colors = list("#808080", "#FF3535")
+
+/obj/item/clothing/under/misc/black_dress
+ name = "little black dress"
+ desc = "A small black dress"
+ icon_state = "littleblackdress_s"
+ item_state = "littleblackdress_s"
+
+/obj/item/clothing/under/misc/pinktutu
+ name = "pink tutu"
+ desc = "A pink tutu"
+ icon_state = "pinktutu_s"
+ item_state = "pinktutu_s"
+
+/obj/item/clothing/under/misc/bathrobe
+ name = "bathrobe"
+ desc = "A blue bathrobe."
+ icon_state = "bathrobe"
+ item_state = "bathrobe"
diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm
index 6a6c38d26e..72af4e9572 100644
--- a/code/modules/clothing/under/syndicate.dm
+++ b/code/modules/clothing/under/syndicate.dm
@@ -4,7 +4,7 @@
icon_state = "syndicate"
item_state = "bl_suit"
has_sensor = NO_SENSORS
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5)
alt_covers_chest = TRUE
/obj/item/clothing/under/syndicate/skirt
@@ -13,7 +13,7 @@
icon_state = "syndicate_skirt"
item_state = "bl_suit"
has_sensor = NO_SENSORS
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5)
alt_covers_chest = TRUE
fitted = FEMALE_UNIFORM_TOP
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
@@ -24,7 +24,7 @@
icon_state = "bloodred_pajamas"
item_state = "bl_suit"
dummy_thick = TRUE
- armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 50, "acid" = 40)
+ armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 50, "acid" = 40, "wound" = 10)
resistance_flags = FIRE_PROOF | ACID_PROOF
can_adjust = FALSE
@@ -33,21 +33,21 @@
desc = "Do operatives dream of nuclear sheep?"
icon_state = "bloodred_pajamas"
item_state = "bl_suit"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5)
/obj/item/clothing/under/syndicate/tacticool
name = "tacticool turtleneck"
desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-."
icon_state = "tactifool"
item_state = "bl_suit"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5)
/obj/item/clothing/under/syndicate/tacticool/skirt
name = "tacticool skirtleneck"
desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-."
icon_state = "tactifool_skirt"
item_state = "bl_suit"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5)
fitted = FEMALE_UNIFORM_TOP
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
@@ -57,7 +57,7 @@
icon_state = "tactifool"
item_state = "bl_suit"
has_sensor = TRUE
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
/obj/item/clothing/under/syndicate/sniper
name = "Tactical turtleneck suit"
@@ -81,7 +81,7 @@
desc = "Badly translated labels tell you to clean this in Vodka. Great for squatting in."
icon_state = "trackpants"
can_adjust = FALSE
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
resistance_flags = NONE
/obj/item/clothing/under/syndicate/combat
@@ -96,7 +96,7 @@
desc = "Military grade tracksuits for frontline squatting."
icon_state = "rus_under"
can_adjust = FALSE
- armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
resistance_flags = NONE
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
@@ -106,7 +106,7 @@
icon_state = "syndicatebaseball"
item_state = "syndicatebaseball"
has_sensor = NO_SENSORS
- armor = list("melee" = 15, "bullet" = 5, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
+ armor = list("melee" = 15, "bullet" = 5, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 10)
alt_covers_chest = TRUE
mutantrace_variation = USE_TAUR_CLIP_MASK
diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm
index 08dae1b469..c7b982eda8 100644
--- a/code/modules/events/travelling_trader.dm
+++ b/code/modules/events/travelling_trader.dm
@@ -1,8 +1,8 @@
/datum/round_event_control/travelling_trader
name = "Travelling Trader"
typepath = /datum/round_event/travelling_trader
- weight = 10
- max_occurrences = 3
+ weight = 8
+ max_occurrences = 2
earliest_start = 0 MINUTES
/datum/round_event/travelling_trader
@@ -52,6 +52,14 @@
var/acceptance_speech = "This is exactly what I wanted! I shall be on my way now, thank you.!"
var/refusal_speech = "A given_item? I wanted a requested_item!" //what they say when refusing an item
var/active = TRUE
+ var/examine_text = list("You attempt to look directly at the being's face, but it's just a blur!")
+ move_resist = MOVE_FORCE_VERY_STRONG
+ mob_size = MOB_SIZE_LARGE
+ alpha = 200
+
+/mob/living/carbon/human/dummy/travelling_trader/examine(mob/user)
+ SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, examine_text)
+ return examine_text
/mob/living/carbon/human/dummy/travelling_trader/proc/setup_speech(var/input_speech, var/obj/item/given_item)
if(requested_item)
@@ -92,6 +100,8 @@
/mob/living/carbon/human/dummy/travelling_trader/Initialize()
..()
+ add_atom_colour("#570d6b", FIXED_COLOUR_PRIORITY) //make them purple (otherworldly!)
+ set_light(1, -0.7, "#AAD84B")
ADD_TRAIT(src,TRAIT_PIERCEIMMUNE, "trader_pierce_immune") //don't let people take their blood
equipOutfit(trader_outfit, TRUE)
for(var/obj/item/item in src.get_equipped_items())
@@ -159,15 +169,11 @@
trader_name = "Otherworldly Animal Specialist"
trader_outfit = /datum/outfit/job/doctor
initial_speech = "Greetings, lifeform. I am here to locate a special creature aboard your station."
- request_speech = "Find me the creature known as 'requested_item' and you shall be rewarded for your efforts."
+ request_speech = "Find me the creature known as 'requested_item' and hand it to me, preferably in a suitable container."
refusal_speech = "Do you think me to be a fool, lifeform? I know a requested_item when I see one."
- possible_wanted_items = list(/mob/living/simple_animal/pet/dog/corgi/Ian = 1,
- /mob/living/simple_animal/sloth/paperwork = 1,
- /mob/living/carbon/monkey/punpun = 1,
- /mob/living/simple_animal/pet/fox/Renault = 1,
- /mob/living/simple_animal/hostile/carp/cayenne = 1,
- /mob/living/simple_animal/pet/bumbles = 1,
- /mob/living/simple_animal/parrot/Poly = 1)
+ possible_wanted_items = list(/mob/living/simple_animal/pet/dog/corgi = 4,
+ /mob/living/carbon/monkey = 1,
+ /mob/living/simple_animal/mouse = 2)
possible_rewards = list(/mob/living/simple_animal/pet/dog/corgi/exoticcorgi = 1, //rewards are animals, friendly to only the person who handed the reward in!
/mob/living/simple_animal/cockroach = 1,
/mob/living/simple_animal/hostile/skeleton = 1,
@@ -184,13 +190,6 @@
mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize()
acceptance_speech = pick(list("This lifeform shall make for a great stew, thank you.", "This lifeform shall be of a true use to our cause, thank you.", "The lifeform is adequate. Goodbye.", "This lifeform shall make a great addition to my collection."))
- //make sure they only ask for animals that are still alive
- for(var/mob/living/animal in possible_wanted_items)
- if(!(animal in GLOB.mob_living_list))
- possible_wanted_items -= animal
- if(!possible_wanted_items)
- //all the pets are dead, so ask for a monkey, or sometimes a corgi (corgis are more annoying to get a hold of)
- possible_wanted_items = list(/mob/living/simple_animal/pet/dog/corgi = 1, /mob/living/carbon/monkey = 3)
..()
/mob/living/carbon/human/dummy/travelling_trader/animal_hunter/check_item(var/obj/item/supplied_item) //item is likely to be in contents of whats supplied
diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm
index 45ab6f6af1..a3ee8c5228 100644
--- a/code/modules/food_and_drinks/drinks/drinks.dm
+++ b/code/modules/food_and_drinks/drinks/drinks.dm
@@ -299,6 +299,31 @@
desc = "An insult to Duke Purple is an insult to the Space Queen! Any proper gentleman will fight you, if you sully this tea."
list_reagents = list(/datum/reagent/consumable/tea = 30)
+/obj/item/reagent_containers/food/drinks/mug/tea/red
+ name = "Dutchess Red tea"
+ icon_state = "tea"
+ desc = "Duchess Red's personal blend of red tea leaves and hot water. Great addition to any meal."
+ list_reagents = list(/datum/reagent/consumable/tea/red = 30)
+
+/obj/item/reagent_containers/food/drinks/mug/tea/green
+ name = "Prince Green tea"
+ icon_state = "tea"
+ desc = "Prince Green's brew of tea. The blend may be different from time to time, but Prince Green swears by it!"
+ list_reagents = list(/datum/reagent/consumable/tea/green = 30)
+
+/obj/item/reagent_containers/food/drinks/mug/tea/forest
+ name = "Royal Forest tea"
+ icon_state = "tea"
+ desc = "Tea fit for anyone with a sweet tooth like Royal Forest."
+ list_reagents = list(/datum/reagent/consumable/tea/forest = 30)
+
+/obj/item/reagent_containers/food/drinks/mug/tea/mush
+ name = "Rebel Mush tea"
+ icon_state = "tea"
+ desc = "Rebel Mush, a hallucinogenic tea to help people find their inner self."
+ list_reagents = list(/datum/reagent/consumable/tea/mush = 30)
+
+
/obj/item/reagent_containers/food/drinks/mug/coco
name = "Dutch hot coco"
desc = "Made in Space South America."
diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
index d87eb8fbc0..e31a9704df 100644
--- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
@@ -87,7 +87,7 @@
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("stabbed", "slashed", "attacked")
var/icon/broken_outline = icon('icons/obj/drinks.dmi', "broken")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
/obj/item/broken_bottle/Initialize()
. = ..()
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index 4b79dc1fd4..895699434a 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -249,21 +249,9 @@ All foods are distributed among various categories. Use common sense.
to_chat(user, "You cannot slice [src] here! You need a table or at least a tray.")
return FALSE
- var/slices_lost = 0
- if (accuracy >= IS_SHARP_ACCURATE)
- user.visible_message( \
- "[user] slices [src].", \
- "You slice [src]." \
- )
- else
- user.visible_message( \
- "[user] inaccurately slices [src] with [W]!", \
- "You inaccurately slice [src] with your [W]!" \
- )
- slices_lost = rand(1,min(1,round(slices_num/2)))
-
+ user.visible_message("[user] slices [src].", "You slice [src].")
var/reagents_per_slice = reagents.total_volume/slices_num
- for(var/i=1 to (slices_num-slices_lost))
+ for(var/i=1 to slices_num)
var/obj/item/reagent_containers/food/snacks/slice = new slice_path (loc)
initialize_slice(slice, reagents_per_slice)
qdel(src)
diff --git a/code/modules/food_and_drinks/recipes/drinks_recipes.dm b/code/modules/food_and_drinks/recipes/drinks_recipes.dm
index c1a17b87a4..972f9a8cc3 100644
--- a/code/modules/food_and_drinks/recipes/drinks_recipes.dm
+++ b/code/modules/food_and_drinks/recipes/drinks_recipes.dm
@@ -18,12 +18,6 @@
results = list(/datum/reagent/consumable/ethanol/bilk = 2)
required_reagents = list(/datum/reagent/consumable/milk = 1, /datum/reagent/consumable/ethanol/beer = 1)
-/datum/chemical_reaction/icetea
- name = "Iced Tea"
- id = /datum/reagent/consumable/icetea
- results = list(/datum/reagent/consumable/icetea = 4)
- required_reagents = list(/datum/reagent/consumable/ice = 1, /datum/reagent/consumable/tea = 3)
-
/datum/chemical_reaction/icecoffee
name = "Iced Coffee"
id = /datum/reagent/consumable/icecoffee
@@ -581,13 +575,6 @@
required_reagents = list(/datum/reagent/consumable/lemonjuice = 2, /datum/reagent/water = 2, /datum/reagent/consumable/sugar = 1, /datum/reagent/consumable/ice = 1)
mix_message = "You're suddenly reminded of home."
-/datum/chemical_reaction/arnold_palmer
- name = "Arnold Palmer"
- id = /datum/reagent/consumable/tea/arnold_palmer
- results = list(/datum/reagent/consumable/tea/arnold_palmer = 2)
- required_reagents = list(/datum/reagent/consumable/tea = 1, /datum/reagent/consumable/lemonade = 1)
- mix_message = "The smells of fresh green grass and sand traps waft through the air as the mixture turns a friendly yellow-orange."
-
/datum/chemical_reaction/chocolate_milk
name = "chocolate milk"
id = /datum/reagent/consumable/milk/chocolate_milk
@@ -756,12 +743,6 @@
results = list(/datum/reagent/consumable/pinkmilk = 2)
required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/milk = 1)
-/datum/chemical_reaction/pinktea
- name = "Strawberry Tea"
- id = /datum/reagent/consumable/pinktea
- results = list(/datum/reagent/consumable/pinktea = 5)
- required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/tea/arnold_palmer = 1, /datum/reagent/consumable/sugar = 1)
-
/datum/chemical_reaction/blank_paper
name = "Blank Paper"
id = /datum/reagent/consumable/ethanol/blank_paper
@@ -903,12 +884,6 @@
results = list(/datum/reagent/consumable/ethanol/mauna_loa = 5)
required_reagents = list(/datum/reagent/consumable/capsaicin = 2, /datum/reagent/consumable/ethanol/kahlua = 1, /datum/reagent/consumable/ethanol/bahama_mama = 2)
-/datum/chemical_reaction/catnip_tea
- name = "Catnip Tea"
- id = /datum/reagent/consumable/catnip_tea
- results = list(/datum/reagent/consumable/catnip_tea = 3)
- required_reagents = list(/datum/reagent/consumable/tea = 5, /datum/reagent/pax/catnip = 2)
-
/datum/chemical_reaction/commander_and_chief
name = "Commander and Chief"
id = /datum/reagent/consumable/ethanol/commander_and_chief
@@ -916,6 +891,76 @@
required_reagents = list(/datum/reagent/consumable/ethanol/alliescocktail = 50, /datum/reagent/consumable/ethanol/champagne = 20, /datum/reagent/consumable/doctor_delight = 10, /datum/reagent/consumable/ethanol/quintuple_sec = 10, /datum/reagent/consumable/ethanol/screwdrivercocktail = 10)
mix_message = "When your powers combine, I am Captain Pl-..."
+////////////////////////////////////////// Tea Base Drinks //////////////////////////////////////
+
+/datum/chemical_reaction/mush
+ name = "Mush Tea"
+ id = /datum/reagent/consumable/tea/mush
+ results = list(/datum/reagent/consumable/tea/mush = 3)
+ required_reagents = list(/datum/reagent/drug/mushroomhallucinogen = 3, /datum/reagent/consumable/tea = 3)
+
+/datum/chemical_reaction/foresttea1
+ name = "Forest Tea"
+ id = /datum/reagent/consumable/tea/forest
+ results = list(/datum/reagent/consumable/tea/forest = 3)
+ required_reagents = list(/datum/reagent/consumable/buzz_fuzz= 3, /datum/reagent/consumable/tea = 3)
+
+/datum/chemical_reaction/foresttea2
+ name = "Forest Tea"
+ id = /datum/reagent/consumable/tea/forest
+ results = list(/datum/reagent/consumable/tea/forest = 3)
+ required_reagents = list(/datum/reagent/consumable/honey = 1, /datum/reagent/consumable/tea = 3)
+
+/datum/chemical_reaction/redtea1
+ name = "Red Tea"
+ id = /datum/reagent/consumable/tea/red
+ results = list(/datum/reagent/consumable/tea/red = 3)
+ required_reagents = list(/datum/reagent/colorful_reagent/crayonpowder/red = 1, /datum/reagent/consumable/tea = 3)
+
+/datum/chemical_reaction/greentea1
+ name = "Green Tea"
+ id = /datum/reagent/consumable/tea/green
+ results = list(/datum/reagent/consumable/tea/green = 3)
+ required_reagents = list(/datum/reagent/colorful_reagent/crayonpowder/green = 1, /datum/reagent/consumable/tea = 3)
+
+/datum/chemical_reaction/redtea2
+ name = "Red Tea"
+ id = /datum/reagent/consumable/tea/red
+ results = list(/datum/reagent/consumable/tea/red = 3)
+ required_reagents = list(/datum/reagent/toxin/teapowder/red = 1, /datum/reagent/water = 3)
+
+/datum/chemical_reaction/greentea2
+ name = "Green Tea"
+ id = /datum/reagent/consumable/tea/green
+ results = list(/datum/reagent/consumable/tea/green = 3)
+ required_reagents = list(/datum/reagent/toxin/teapowder/green = 1, /datum/reagent/water = 3)
+
+/datum/chemical_reaction/arnold_palmer
+ name = "Arnold Palmer"
+ id = /datum/reagent/consumable/tea/arnold_palmer
+ results = list(/datum/reagent/consumable/tea/arnold_palmer = 2)
+ required_reagents = list(/datum/reagent/consumable/tea = 1, /datum/reagent/consumable/lemonade = 1)
+ mix_message = "The smells of fresh green grass and sand traps waft through the air as the mixture turns a friendly yellow-orange."
+
+/datum/chemical_reaction/icetea
+ name = "Iced Tea"
+ id = /datum/reagent/consumable/icetea
+ results = list(/datum/reagent/consumable/icetea = 4)
+ required_reagents = list(/datum/reagent/consumable/ice = 1, /datum/reagent/consumable/tea = 3)
+
+/datum/chemical_reaction/pinktea
+ name = "Strawberry Tea"
+ id = /datum/reagent/consumable/pinktea
+ results = list(/datum/reagent/consumable/pinktea = 5)
+ required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/tea/arnold_palmer = 1, /datum/reagent/consumable/sugar = 1)
+
+/datum/chemical_reaction/catnip_tea
+ name = "Catnip Tea"
+ id = /datum/reagent/consumable/catnip_tea
+ results = list(/datum/reagent/consumable/catnip_tea = 3)
+ required_reagents = list(/datum/reagent/consumable/tea = 5, /datum/reagent/pax/catnip = 2)
+
+
////////////////////////////////////////// Race Base Drinks //////////////////////////////////////
/datum/chemical_reaction/coldscales
diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css
index 93c733391e..2669a3634a 100644
--- a/code/modules/goonchat/browserassets/css/browserOutput.css
+++ b/code/modules/goonchat/browserassets/css/browserOutput.css
@@ -303,7 +303,10 @@ h1.alert, h2.alert {color: #000000;}
.passive {color: #660000;}
.userdanger {color: #ff0000; font-weight: bold; font-size: 185%;}
+.bolddanger {color: #c51e1e;font-weight: bold;}
.danger {color: #ff0000;}
+.tinydanger {color: #c51e1e; font-size: 85%;}
+.smalldanger {color: #c51e1e; font-size: 90%;}
.warning {color: #ff0000; font-style: italic;}
.alertwarning {color: #FF0000; font-weight: bold}
.boldwarning {color: #ff0000; font-style: italic; font-weight: bold}
@@ -313,8 +316,9 @@ h1.alert, h2.alert {color: #000000;}
.rose {color: #ff5050;}
.info {color: #0000CC;}
.notice {color: #000099;}
-.tinynotice {color: #6685f5; font-style: italic; font-size: 85%;}
-.smallnotice {color: #6685f5; font-style: italic; font-size: 90%;}
+.tinynotice {color: #6685f5; font-style: italic; font-size: 85%;}
+.smallnotice {color: #6685f5; font-size: 90%;}
+.smallnoticeital {color: #6685f5; font-style: italic; font-size: 90%;}
.boldnotice {color: #000099; font-weight: bold;}
.adminnotice {color: #0000ff;}
.adminhelp {color: #ff0000; font-weight: bold;}
diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm
index 0411a80443..81318f8fe1 100644
--- a/code/modules/hydroponics/grown/banana.dm
+++ b/code/modules/hydroponics/grown/banana.dm
@@ -27,6 +27,12 @@
juice_results = list(/datum/reagent/consumable/banana = 0)
distill_reagent = /datum/reagent/consumable/ethanol/bananahonk
+/obj/item/reagent_containers/food/snacks/grown/banana/generate_trash(atom/location)
+ . = ..()
+ var/obj/item/grown/bananapeel/peel = .
+ if(istype(peel))
+ peel.grind_results = list(/datum/reagent/consumable/banana_peel = seed.potency * 0.2)
+
/obj/item/reagent_containers/food/snacks/grown/banana/suicide_act(mob/user)
user.visible_message("[user] is aiming [src] at [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!")
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1, -1)
diff --git a/code/modules/hydroponics/grown/chili.dm b/code/modules/hydroponics/grown/chili.dm
index 1f60afe655..001a90b441 100644
--- a/code/modules/hydroponics/grown/chili.dm
+++ b/code/modules/hydroponics/grown/chili.dm
@@ -81,7 +81,8 @@
wine_power = 50
/obj/item/reagent_containers/food/snacks/grown/ghost_chili/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
- if( ismob(loc) )
+ . = ..()
+ if(ishuman(loc))
held_mob = loc
START_PROCESSING(SSobj, src)
diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm
index 9b5983c8e9..abf6632939 100644
--- a/code/modules/hydroponics/hydroitemdefines.dm
+++ b/code/modules/hydroponics/hydroitemdefines.dm
@@ -82,7 +82,7 @@
custom_materials = list(/datum/material/iron = 15000)
attack_verb = list("chopped", "torn", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
/obj/item/hatchet/Initialize()
. = ..()
diff --git a/code/modules/instruments/songs/_song.dm b/code/modules/instruments/songs/_song.dm
index 463398d2f2..d842dbc003 100644
--- a/code/modules/instruments/songs/_song.dm
+++ b/code/modules/instruments/songs/_song.dm
@@ -303,3 +303,19 @@
return TRUE
var/obj/structure/musician/M = parent
return M.should_stop_playing(user)
+
+/datum/song/holoparasite
+ var/mob/living/simple_animal/hostile/guardian/stand
+
+/datum/song/holoparasite/New(atom/parent, list/instrument_ids)
+ . = ..()
+ stand = istype(parent, /mob/living/simple_animal/hostile/guardian) && parent
+
+/datum/song/holoparasite/updateDialog()
+ stand.ui_interact(src)
+
+/datum/song/holoparasite/should_stop_playing(mob/user)
+ return FALSE
+
+/datum/song/holoparasite/check_can_use(mob/user)
+ return (user == stand)
diff --git a/code/modules/instruments/songs/editor.dm b/code/modules/instruments/songs/editor.dm
index d9595797d7..8c5171667a 100644
--- a/code/modules/instruments/songs/editor.dm
+++ b/code/modules/instruments/songs/editor.dm
@@ -109,8 +109,11 @@
linenum++
updateDialog(usr) // make sure updates when complete
+/datum/song/proc/check_can_use(mob/user)
+ return user.canUseTopic(parent, TRUE, FALSE, FALSE, FALSE)
+
/datum/song/Topic(href, href_list)
- if(!usr.canUseTopic(parent, TRUE, FALSE, FALSE, FALSE))
+ if(!check_can_use(usr))
usr << browse(null, "window=instrument")
usr.unset_machine()
return
diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm
index 7c9f811c34..903ff13fa8 100644
--- a/code/modules/integrated_electronics/core/assemblies.dm
+++ b/code/modules/integrated_electronics/core/assemblies.dm
@@ -651,11 +651,6 @@
icon_state = "setup_small_pda"
desc = "It's a case, for building small electronics with. This one resembles a PDA."
-/obj/item/electronic_assembly/dildo
- name = "type-g electronic assembly"
- icon_state = "setup_dildo_medium"
- desc = "It's a case, for building small electronics with. This one has a phallic design."
-
/obj/item/electronic_assembly/small
name = "electronic device"
icon_state = "setup_device"
@@ -687,11 +682,6 @@
icon_state = "setup_device_box"
desc = "It's a case, for building tiny-sized electronics with. This one has a boxy design."
-/obj/item/electronic_assembly/small/dildo
- name = "type-f electronic device"
- icon_state = "setup_dildo_small"
- desc = "It's a case, for building tiny-sized electronics with. This one has a phallic design."
-
/obj/item/electronic_assembly/medium
name = "electronic mechanism"
icon_state = "setup_medium"
@@ -732,12 +722,6 @@
icon_state = "setup_medium_radio"
desc = "It's a case, for building medium-sized electronics with. This one resembles an old radio."
-/obj/item/electronic_assembly/medium/dildo
- name = "type-g electronic mechanism"
- icon_state = "setup_dildo_large"
- desc = "It's a case, for building medium-sized electronics with. This one has a phallic design."
-
-
/obj/item/electronic_assembly/large
name = "electronic machine"
icon_state = "setup_large"
diff --git a/code/modules/jobs/job_types/detective.dm b/code/modules/jobs/job_types/detective.dm
index e5afe7e1b3..463113f14c 100644
--- a/code/modules/jobs/job_types/detective.dm
+++ b/code/modules/jobs/job_types/detective.dm
@@ -23,7 +23,7 @@
mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM)
display_order = JOB_DISPLAY_ORDER_DETECTIVE
- blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/nonviolent, /datum/quirk/paraplegic)
+ blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/monophobia)
threat = 1
/datum/outfit/job/detective
diff --git a/code/modules/jobs/job_types/head_of_security.dm b/code/modules/jobs/job_types/head_of_security.dm
index 69ed63a514..3d7d07d894 100644
--- a/code/modules/jobs/job_types/head_of_security.dm
+++ b/code/modules/jobs/job_types/head_of_security.dm
@@ -31,7 +31,7 @@
paycheck_department = ACCOUNT_SEC
display_order = JOB_DISPLAY_ORDER_HEAD_OF_SECURITY
- blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/insanity)
+ blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/blindness, /datum/quirk/monophobia, /datum/quirk/insanity)
threat = 3
/datum/outfit/job/hos
diff --git a/code/modules/jobs/job_types/security_officer.dm b/code/modules/jobs/job_types/security_officer.dm
index bc6f6a94c7..7e71b2d1f4 100644
--- a/code/modules/jobs/job_types/security_officer.dm
+++ b/code/modules/jobs/job_types/security_officer.dm
@@ -23,7 +23,7 @@
mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM)
display_order = JOB_DISPLAY_ORDER_SECURITY_OFFICER
- blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/nonviolent, /datum/quirk/paraplegic)
+ blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/blindness, /datum/quirk/monophobia)
threat = 2
/datum/job/officer/get_access()
diff --git a/code/modules/jobs/job_types/warden.dm b/code/modules/jobs/job_types/warden.dm
index 5762731f62..22e3f9b0f1 100644
--- a/code/modules/jobs/job_types/warden.dm
+++ b/code/modules/jobs/job_types/warden.dm
@@ -24,7 +24,7 @@
mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM)
display_order = JOB_DISPLAY_ORDER_WARDEN
- blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/nonviolent, /datum/quirk/paraplegic)
+ blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/blindness, /datum/quirk/monophobia)
threat = 2
/datum/job/warden/get_access()
diff --git a/code/modules/language/language_holder.dm b/code/modules/language/language_holder.dm
index 6e3d27f2b8..55e9352843 100644
--- a/code/modules/language/language_holder.dm
+++ b/code/modules/language/language_holder.dm
@@ -276,7 +276,8 @@ Key procs
/datum/language/draconic = list(LANGUAGE_ATOM))
/datum/language_holder/lizard/ash
- selected_language = /datum/language/draconic
+ understood_languages = list(/datum/language/draconic = list(LANGUAGE_ATOM))
+ spoken_languages = list(/datum/language/draconic = list(LANGUAGE_ATOM))
/datum/language_holder/monkey
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index 745c46b131..7a755265dc 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -17,7 +17,7 @@
custom_materials = list(/datum/material/iron=1150, /datum/material/glass=2075)
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
actions_types = list(/datum/action/item_action/toggle_light)
var/list/trophies = list()
var/charged = TRUE
@@ -175,6 +175,20 @@
if(light_on)
. += "[icon_state]_lit"
+/obj/item/kinetic_crusher/glaive
+ name = "proto-kinetic glaive"
+ desc = "A modified design of a proto-kinetic crusher, it is still little more of a combination of various mining tools cobbled together \
+ and kit-bashed into a high-tech cleaver on a stick - with a handguard and a goliath hide grip. While it is still of little use to any \
+ but the most skilled and/or suicidal miners against local fauna, it's an elegant weapon for a more civilized hunter."
+ attack_verb = list("stabbed", "diced", "sliced", "cleaved", "chopped", "lacerated", "cut", "jabbed", "punctured")
+ icon_state = "crusher-glaive"
+ item_state = "crusher0-glaive"
+ //ideas: altclick that lets you pummel people with the handguard/handle?
+ //parrying functionality?
+
+/obj/item/kinetic_crusher/glaive/update_icon_state()
+ item_state = "crusher[wielded]-glaive" // this is not icon_state and not supported by 2hcomponent
+
//destablizing force
/obj/item/projectile/destabilizer
name = "destabilizing force"
diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm
index 50a3dec9dd..27259ce812 100644
--- a/code/modules/mining/equipment/mining_tools.dm
+++ b/code/modules/mining/equipment/mining_tools.dm
@@ -143,7 +143,7 @@
w_class = WEIGHT_CLASS_NORMAL
custom_materials = list(/datum/material/iron=350)
attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
/obj/item/shovel/Initialize()
. = ..()
@@ -181,4 +181,4 @@
w_class = WEIGHT_CLASS_NORMAL
toolspeed = 0.7
attack_verb = list("slashed", "impaled", "stabbed", "sliced")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 270d3601fd..e03de83e02 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -659,7 +659,7 @@
hitsound = 'sound/weapons/bladeslice.ogg'
hitsound_on = 'sound/weapons/bladeslice.ogg'
w_class = WEIGHT_CLASS_BULKY
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
faction_bonus_force = 30
nemesis_factions = list("mining", "boss")
var/transform_cooldown
@@ -766,7 +766,7 @@
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
flags_1 = CONDUCT_1
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
w_class = WEIGHT_CLASS_BULKY
force = 1
throwforce = 1
@@ -930,6 +930,9 @@
/obj/item/lava_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
+ INVOKE_ASYNC(src, .proc/attempt_lava, target, user, proximity_flag, click_parameters)
+
+/obj/item/lava_staff/proc/attempt_lava(atom/target, mob/user, proximity_flag, click_parameters)
if(timer > world.time)
return
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index b00e291685..564d554319 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -32,7 +32,7 @@
new /datum/data/mining_equipment("500 Point Transfer Card", /obj/item/card/mining_point_card/mp500, 500),
new /datum/data/mining_equipment("Tracking Implant Kit", /obj/item/storage/box/minertracker, 600),
new /datum/data/mining_equipment("Jaunter", /obj/item/wormhole_jaunter, 750),
- new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/kinetic_crusher, 750),
+ new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/kinetic_crusher, 750),
new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/gun/energy/kinetic_accelerator, 750),
new /datum/data/mining_equipment("Survival Medipen", /obj/item/reagent_containers/hypospray/medipen/survival, 750),
new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/storage/firstaid/brute, 800),
@@ -68,6 +68,7 @@
new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 150),
new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250),
new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300),
+ new /datum/data/mining_equipment("Kinetic Glaive", /obj/item/kinetic_crusher/glaive, 1500),
new /datum/data/mining_equipment("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000),
new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000),
new /datum/data/mining_equipment("KA Cooldown Decrease", /obj/item/borg/upgrade/modkit/cooldown, 1000),
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 49a3bffd42..768c4c943e 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -557,7 +557,6 @@
if(frn)
client.prefs.random_character()
client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
- client.prefs.copy_to(H)
var/cur_scar_index = client.prefs.scars_index
if(client.prefs.persistent_scars && client.prefs.scars_list["[cur_scar_index]"])
var/scar_string = client.prefs.scars_list["[cur_scar_index]"]
@@ -568,7 +567,6 @@
client.prefs.scars_list["[cur_scar_index]"] = valid_scars
client.prefs.save_character()
-
client.prefs.copy_to(H)
H.dna.update_dna_identity()
if(mind)
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index 36a6f6296b..cf1a158fc5 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -62,10 +62,6 @@
//Effects of bloodloss
var/word = pick("dizzy","woozy","faint")
switch(blood_volume)
- if(BLOOD_VOLUME_EXCESS to BLOOD_VOLUME_MAX_LETHAL)
- if(prob(15))
- to_chat(src, "Blood starts to tear your skin apart. You're going to burst!")
- gib()
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
if(prob(10))
to_chat(src, "You feel terribly bloated.")
diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm
index d3dbfac8c8..24d456bf8f 100644
--- a/code/modules/mob/living/bloodcrawl.dm
+++ b/code/modules/mob/living/bloodcrawl.dm
@@ -73,7 +73,7 @@
if(victim.stat == CONSCIOUS)
src.visible_message("[victim] kicks free of the blood pool just before entering it!", null, "You hear splashing and struggling.")
- else if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/consumable/ethanol/demonsblood))
+ else if(victim.reagents?.has_reagent(/datum/reagent/consumable/ethanol/demonsblood))
visible_message("Something prevents [victim] from entering the pool!", "A strange force is blocking [victim] from entering!", "You hear a splash and a thud.")
else
victim.forceMove(src)
@@ -104,7 +104,7 @@
if(!victim)
return FALSE
- if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/consumable/ethanol/devilskiss))
+ if(victim.reagents?.has_reagent(/datum/reagent/consumable/ethanol/devilskiss))
to_chat(src, "AAH! THEIR FLESH! IT BURNS!")
adjustBruteLoss(25) //I can't use adjustHealth() here because bloodcrawl affects /mob/living and adjustHealth() only affects simple mobs
var/found_bloodpool = FALSE
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 1e31655278..edb681e60f 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -92,17 +92,8 @@
if(!all_wounds || !(user.a_intent == INTENT_HELP || user == src))
return ..()
- // The following priority/nonpriority searching is so that if we have two wounds on a limb that use the same item for treatment (gauze can bandage cuts AND splint broken bones),
- // we prefer whichever wound is not already treated (ignore the splinted broken bone for the open cut). If there's no priority wounds that this can treat, go through the
- // non-priority ones randomly.
- var/list/nonpriority_wounds = list()
- for(var/datum/wound/W in shuffle(all_wounds))
- if(!W.treat_priority)
- nonpriority_wounds += W
- else if(W.treat_priority && W.try_treating(I, user))
- return 1
-
- for(var/datum/wound/W in shuffle(nonpriority_wounds))
+ for(var/i in shuffle(all_wounds))
+ var/datum/wound/W = i
if(W.try_treating(I, user))
return 1
@@ -1209,16 +1200,16 @@
/**
* generate_fake_scars()- for when you want to scar someone, but you don't want to hurt them first. These scars don't count for temporal scarring (hence, fake)
*
- * If you want a specific wound scar, pass that wound type as the second arg, otherwise you can pass a list like WOUND_LIST_CUT to generate a random cut scar.
+ * If you want a specific wound scar, pass that wound type as the second arg, otherwise you can pass a list like WOUND_LIST_SLASH to generate a random cut scar.
*
* Arguments:
* * num_scars- A number for how many scars you want to add
- * * forced_type- Which wound or category of wounds you want to choose from, WOUND_LIST_BONE, WOUND_LIST_CUT, or WOUND_LIST_BURN (or some combination). If passed a list, picks randomly from the listed wounds. Defaults to all 3 types
+ * * forced_type- Which wound or category of wounds you want to choose from, WOUND_LIST_BLUNT, WOUND_LIST_SLASH, or WOUND_LIST_BURN (or some combination). If passed a list, picks randomly from the listed wounds. Defaults to all 3 types
*/
/mob/living/carbon/proc/generate_fake_scars(num_scars, forced_type)
for(var/i in 1 to num_scars)
- var/datum/scar/S = new
- var/obj/item/bodypart/BP = pick(bodyparts)
+ var/datum/scar/scaries = new
+ var/obj/item/bodypart/scar_part = pick(bodyparts)
var/wound_type
if(forced_type)
@@ -1227,9 +1218,17 @@
else
wound_type = forced_type
else
- wound_type = pick(WOUND_LIST_BONE + WOUND_LIST_CUT + WOUND_LIST_BURN)
+ wound_type = pick(GLOB.global_all_wound_types)
- var/datum/wound/W = new wound_type
- S.generate(BP, W)
- S.fake = TRUE
- QDEL_NULL(W)
+ var/datum/wound/phantom_wound = new wound_type
+ scaries.generate(scar_part, phantom_wound)
+ scaries.fake = TRUE
+ QDEL_NULL(phantom_wound)
+
+/**
+ * get_biological_state is a helper used to see what kind of wounds we roll for. By default we just assume carbons (read:monkeys) are flesh and bone, but humans rely on their species datums
+ *
+ * go look at the species def for more info [/datum/species/proc/get_biological_state]
+ */
+/mob/living/carbon/proc/get_biological_state()
+ return BIO_FLESH_BONE
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index ac261e6d5b..566c004142 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -76,7 +76,7 @@
if(!affecting) //missing limb? we select the first bodypart (you can never have zero, because of chest)
affecting = bodyparts[1]
SEND_SIGNAL(I, COMSIG_ITEM_ATTACK_ZONE, src, user, affecting)
- send_item_attack_message(I, user, affecting.name, totitemdamage)
+ send_item_attack_message(I, user, affecting.name, affecting, totitemdamage)
I.do_stagger_action(src, user, totitemdamage)
if(I.force)
apply_damage(totitemdamage, I.damtype, affecting, wound_bonus = I.wound_bonus, bare_wound_bonus = I.bare_wound_bonus, sharpness = I.get_sharpness()) //CIT CHANGE - replaces I.force with totitemdamage
@@ -100,12 +100,6 @@
head.add_mob_blood(src)
update_inv_head()
- //dismemberment
- var/probability = I.get_dismemberment_chance(affecting)
- if(prob(probability))
- if(affecting.dismember(I.damtype))
- I.add_mob_blood(src)
- playsound(get_turf(src), I.get_dismember_sound(), 80, 1)
return TRUE //successful attack
/mob/living/carbon/attack_drone(mob/living/simple_animal/drone/user)
@@ -131,9 +125,10 @@
if(S.next_step(user, act_intent))
return TRUE
- for(var/datum/wound/W in all_wounds)
+ for(var/i in all_wounds)
+ var/datum/wound/W = i
if(W.try_handling(user))
- return 1
+ return TRUE
/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M)
@@ -157,6 +152,7 @@
for(var/thing in M.diseases)
var/datum/disease/D = thing
ForceContractDisease(D)
+ return TRUE
/mob/living/carbon/attack_slime(mob/living/simple_animal/slime/M)
. = ..()
@@ -295,12 +291,12 @@
target_message = "[M] gives you a pat on the head to make you feel better!")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat)
friendly_check = TRUE
- if(S?.can_wag_tail(src) && !dna.species.is_wagging_tail())
- var/static/list/many_tails = list("tail_human", "tail_lizard", "mam_tail")
- for(var/T in many_tails)
- if(S.mutant_bodyparts[T] && dna.features[T] != "None")
- emote("wag")
- break
+ if(!(client?.prefs.cit_toggles & NO_AUTO_WAG))
+ if(S?.can_wag_tail(src) && !dna.species.is_wagging_tail())
+ var/static/list/many_tails = list("tail_human", "tail_lizard", "mam_tail")
+ for(var/T in many_tails)
+ if(S.mutant_bodyparts[T] && dna.features[T] != "None")
+ emote("wag")
else if(check_zone(M.zone_selected) == BODY_ZONE_R_ARM || check_zone(M.zone_selected) == BODY_ZONE_L_ARM)
M.visible_message( \
@@ -397,7 +393,7 @@
to_chat(src, "Your eyes are really starting to hurt. This can't be good for you!")
if(has_bane(BANE_LIGHT))
mind.disrupt_spells(-500)
- return 1
+ return TRUE
else if(damage == 0) // just enough protection
if(prob(20))
to_chat(src, "Something bright flashes in the corner of your vision!")
@@ -472,3 +468,35 @@
var/obj/item/bodypart/limb = get_bodypart(zone)
if(!limb)
return
+
+/mob/living/carbon/send_item_attack_message(obj/item/I, mob/living/user, hit_area, obj/item/bodypart/hit_bodypart, totitemdamage)
+ var/message_verb = "attacked"
+ if(length(I.attack_verb))
+ message_verb = "[pick(I.attack_verb)]"
+ else if(!I.force)
+ return
+
+ var/extra_wound_details = ""
+ if(I.damtype == BRUTE && hit_bodypart.can_dismember())
+ var/mangled_state = hit_bodypart.get_mangled_state()
+ var/bio_state = get_biological_state()
+ if(mangled_state == BODYPART_MANGLED_BOTH)
+ extra_wound_details = ", threatening to sever it entirely"
+ else if((mangled_state == BODYPART_MANGLED_FLESH && I.get_sharpness()) || (mangled_state & BODYPART_MANGLED_BONE && bio_state == BIO_JUST_BONE))
+ extra_wound_details = ", [I.get_sharpness() == SHARP_EDGED ? "slicing" : "piercing"] through to the bone"
+ else if((mangled_state == BODYPART_MANGLED_BONE && I.get_sharpness()) || (mangled_state & BODYPART_MANGLED_FLESH && bio_state == BIO_JUST_FLESH))
+ extra_wound_details = ", [I.get_sharpness() == SHARP_EDGED ? "slicing" : "piercing"] at the remaining tissue"
+
+ var/message_hit_area = ""
+ if(hit_area)
+ message_hit_area = " in the [hit_area]"
+ var/attack_message = "[src] is [message_verb][message_hit_area] with [I][extra_wound_details]!"
+ var/attack_message_local = "You're [message_verb][message_hit_area] with [I][extra_wound_details]!"
+ if(user in viewers(src, null))
+ attack_message = "[user] [message_verb] [src][message_hit_area] with [I][extra_wound_details]!"
+ attack_message_local = "[user] [message_verb] you[message_hit_area] with [I][extra_wound_details]!"
+ if(user == src)
+ attack_message_local = "You [message_verb] yourself[message_hit_area] with [I][extra_wound_details]"
+ visible_message("[attack_message]",\
+ "[attack_message_local]", null, COMBAT_MESSAGE_RANGE)
+ return TRUE
diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm
index ddf1019f2a..5c5a1d6d52 100644
--- a/code/modules/mob/living/carbon/damage_procs.dm
+++ b/code/modules/mob/living/carbon/damage_procs.dm
@@ -1,6 +1,6 @@
-/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
+/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
var/hit_percent = (100-blocked)/100
if(!forced && hit_percent <= 0)
@@ -202,7 +202,7 @@
//Damages ONE bodypart randomly selected from damagable ones.
//It automatically updates damage overlays if necessary
//It automatically updates health status
-/mob/living/carbon/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
+/mob/living/carbon/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
if(!parts.len)
return
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index be046a3713..5eabae16f7 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -44,7 +44,8 @@
msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!\n"
else
msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!\n"
- for(var/datum/wound/W in BP.wounds)
+ for(var/i in BP.wounds)
+ var/datum/wound/W = i
msg += "[W.get_examine_description(user)]\n"
for(var/X in disabled)
@@ -109,7 +110,7 @@
switch(scar_severity)
if(1 to 2)
- msg += "[t_He] [t_has] visible scarring, you can look again to take a closer look...\n"
+ msg += "[t_He] [t_has] visible scarring, you can look again to take a closer look...\n"
if(3 to 4)
msg += "[t_He] [t_has] several bad scars, you can look again to take a closer look...\n"
if(5 to 6)
diff --git a/code/modules/mob/living/carbon/human/damage_procs.dm b/code/modules/mob/living/carbon/human/damage_procs.dm
index 5cd00b7e6a..04ec1196fd 100644
--- a/code/modules/mob/living/carbon/human/damage_procs.dm
+++ b/code/modules/mob/living/carbon/human/damage_procs.dm
@@ -1,5 +1,5 @@
// depending on the species, it will run the corresponding apply_damage code there
-/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
+/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage, wound_bonus, bare_wound_bonus, sharpness)
diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm
index 96517d5ea2..1e2a375b39 100644
--- a/code/modules/mob/living/carbon/human/dummy.dm
+++ b/code/modules/mob/living/carbon/human/dummy.dm
@@ -47,6 +47,5 @@ GLOBAL_LIST_EMPTY(dummy_mob_list)
return
var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotnumber]
if(istype(D))
- D.set_species(/datum/species/human,icon_update = TRUE, pref_load = TRUE) //for some fucking reason, if you don't change the species every time, some species will dafault certain things when it's their own species on the mannequin two times in a row, like lizards losing spines and tails setting to smooth. If you can find a fix for this that isn't this, good on you
D.wipe_state()
D.in_use = FALSE
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index cbea9293f5..65b2931e08 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -163,8 +163,9 @@
msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!\n"
else
msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!\n"
- for(var/datum/wound/W in BP.wounds)
- msg += "[W.get_examine_description(user)]\n"
+ for(var/i in BP.wounds)
+ var/datum/wound/iter_wound = i
+ msg += "[iter_wound.get_examine_description(user)]\n"
for(var/X in disabled)
var/obj/item/bodypart/BP = X
@@ -270,7 +271,12 @@
bleeding_limbs += BP
var/num_bleeds = LAZYLEN(bleeding_limbs)
- var/bleed_text = "[t_He] [t_is] bleeding from [t_his]"
+ var/list/bleed_text
+ if(appears_dead)
+ bleed_text = list("Blood is visible in [t_his] open")
+ else
+ bleed_text = list("[t_He] [t_is] bleeding from [t_his]")
+
switch(num_bleeds)
if(1 to 2)
bleed_text += " [bleeding_limbs[1].name][num_bleeds == 2 ? " and [bleeding_limbs[2].name]" : ""]"
@@ -280,8 +286,15 @@
bleed_text += " [BP.name],"
bleed_text += " and [bleeding_limbs[num_bleeds].name]"
- bleed_text += "!\n"
- msg += bleed_text
+
+ if(appears_dead)
+ bleed_text += ", but it has pooled and is not flowing.\n"
+ else
+ if(reagents.has_reagent(/datum/reagent/toxin/heparin))
+ bleed_text += " incredibly quickly"
+
+ bleed_text += "!\n"
+ msg += bleed_text.Join()
if(reagents.has_reagent(/datum/reagent/teslium))
msg += "[t_He] [t_is] emitting a gentle blue glow!\n"
@@ -365,7 +378,7 @@
switch(scar_severity)
if(1 to 2)
- msg += "[t_He] [t_has] visible scarring, you can look again to take a closer look...\n"
+ msg += "[t_He] [t_has] visible scarring, you can look again to take a closer look...\n"
if(3 to 4)
msg += "[t_He] [t_has] several bad scars, you can look again to take a closer look...\n"
if(5 to 6)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 145db1be1e..b402260611 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1040,12 +1040,6 @@
return TRUE
return FALSE
-/mob/living/carbon/human/proc/clear_shove_slowdown()
- remove_movespeed_modifier(/datum/movespeed_modifier/shove)
- var/active_item = get_active_held_item()
- if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
- visible_message("[src.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE)
-
/mob/living/carbon/human/updatehealth()
. = ..()
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 8672c0e83d..af95b9e1b7 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -154,19 +154,29 @@
/// For use formatting all of the scars this human has for saving for persistent scarring
/mob/living/carbon/human/proc/format_scars()
- if(!all_scars)
+ var/list/missing_bodyparts = get_missing_limbs()
+ if(!all_scars && !length(missing_bodyparts))
return
var/scars = ""
+ for(var/i in missing_bodyparts)
+ var/datum/scar/scaries = new
+ scars += "[scaries.format_amputated(i)]"
for(var/i in all_scars)
- var/datum/scar/S = i
- scars += "[S.format()];"
+ var/datum/scar/scaries = i
+ scars += "[scaries.format()];"
return scars
/// Takes a single scar from the persistent scar loader and recreates it from the saved data
/mob/living/carbon/human/proc/load_scar(scar_line)
var/list/scar_data = splittext(scar_line, "|")
- if(LAZYLEN(scar_data) != 4)
+ if(LAZYLEN(scar_data) != SCAR_SAVE_LENGTH)
return // invalid, should delete
- var/obj/item/bodypart/BP = get_bodypart("[scar_data[SCAR_SAVE_ZONE]]")
- var/datum/scar/S = new
- return S.load(BP, scar_data[SCAR_SAVE_DESC], scar_data[SCAR_SAVE_PRECISE_LOCATION], text2num(scar_data[SCAR_SAVE_SEVERITY]))
+ var/version = text2num(scar_data[SCAR_SAVE_VERS])
+ if(!version || version < SCAR_CURRENT_VERSION) // get rid of old scars
+ return
+ var/obj/item/bodypart/the_part = get_bodypart("[scar_data[SCAR_SAVE_ZONE]]")
+ var/datum/scar/scaries = new
+ return scaries.load(the_part, scar_data[SCAR_SAVE_VERS], scar_data[SCAR_SAVE_DESC], scar_data[SCAR_SAVE_PRECISE_LOCATION], text2num(scar_data[SCAR_SAVE_SEVERITY]))
+
+/mob/living/carbon/human/get_biological_state()
+ return dna.species.get_biological_state()
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 430227a39c..dc7fe86aca 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -73,7 +73,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/datum/outfit/outfit_important_for_life // A path to an outfit that is important for species life e.g. plasmaman outfit
// species-only traits. Can be found in DNA.dm
- var/list/species_traits = list(CAN_SCAR) //by default they can scar unless set to something else
+ var/list/species_traits = list(HAS_FLESH,HAS_BONE) //by default they can scar and have bones/flesh unless set to something else
// generic traits tied to having the species
var/list/inherent_traits = list()
var/inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID
@@ -1746,20 +1746,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
apply_damage(totitemdamage * weakness, I.damtype, def_zone, armor_block, H, wound_bonus = Iwound_bonus, bare_wound_bonus = I.bare_wound_bonus, sharpness = I.get_sharpness())
- H.send_item_attack_message(I, user, hit_area, totitemdamage)
+ H.send_item_attack_message(I, user, hit_area, affecting, totitemdamage)
I.do_stagger_action(H, user, totitemdamage)
if(!totitemdamage)
return 0 //item force is zero
- //dismemberment
- var/probability = I.get_dismemberment_chance(affecting)
- if(prob(probability) || (HAS_TRAIT(H, TRAIT_EASYDISMEMBER) && prob(probability))) //try twice
- if(affecting.dismember(I.damtype))
- I.add_mob_blood(H)
- playsound(get_turf(H), I.get_dismember_sound(), 80, 1)
-
var/bloody = 0
if(((I.damtype == BRUTE) && I.force && prob(25 + (I.force * 2))))
if(affecting.status == BODYPART_ORGANIC)
@@ -1942,11 +1935,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
target.visible_message("[user.name] shoves [target.name]!",
"[user.name] shoves you!", null, COMBAT_MESSAGE_RANGE, null,
user, "You shove [target.name]!")
+ target.Stagger(SHOVE_STAGGER_DURATION)
var/obj/item/target_held_item = target.get_active_held_item()
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
- if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove))
- target.add_movespeed_modifier(/datum/movespeed_modifier/shove)
+ if(!target.has_status_effect(STATUS_EFFECT_OFF_BALANCE))
if(target_held_item)
if(!HAS_TRAIT(target_held_item, TRAIT_NODROP))
target.visible_message("[target.name]'s grip on \the [target_held_item] loosens!",
@@ -1954,15 +1947,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
append_message += ", loosening their grip on [target_held_item]"
else
append_message += ", but couldn't loose their grip on [target_held_item]"
- addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
else if(target_held_item)
if(target.dropItemToGround(target_held_item))
target.visible_message("[target.name] drops \the [target_held_item]!!",
"You drop \the [target_held_item]!!", null, COMBAT_MESSAGE_RANGE)
append_message += ", causing them to drop [target_held_item]"
+ target.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
log_combat(user, target, "shoved", append_message)
-/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
+/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
SEND_SIGNAL(H, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone, wound_bonus, bare_wound_bonus, sharpness) // make sure putting wound_bonus here doesn't screw up other signals or uses for this signal
var/hit_percent = (100-(blocked+armor))/100
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
@@ -2038,6 +2031,25 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
// called before a projectile hit
return
+/**
+
+
+
+ * The human species version of [/mob/living/carbon/proc/get_biological_state]. Depends on the HAS_FLESH and HAS_BONE species traits, having bones lets you have bone wounds, having flesh lets you have burn, slash, and piercing wounds
+
+
+
+ */
+
+
+
+/datum/species/proc/get_biological_state(mob/living/carbon/human/H)
+ . = BIO_INORGANIC
+ if(HAS_FLESH in species_traits)
+ . |= BIO_JUST_FLESH
+ if(HAS_BONE in species_traits)
+ . |= BIO_JUST_BONE
+
/////////////
//BREATHING//
/////////////
diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm
index 1e77775efa..38e10e8662 100644
--- a/code/modules/mob/living/carbon/human/species_types/abductors.dm
+++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm
@@ -3,7 +3,7 @@
id = "abductor"
say_mod = "gibbers"
sexes = FALSE
- species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL,CAN_SCAR)
+ species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL,HAS_FLESH,HAS_BONE)
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_CHUNKYFINGERS,TRAIT_NOHUNGER,TRAIT_NOBREATH)
mutanttongue = /obj/item/organ/tongue/abductor
species_type = "alien"
diff --git a/code/modules/mob/living/carbon/human/species_types/angel.dm b/code/modules/mob/living/carbon/human/species_types/angel.dm
index d6860e1249..2cf054c7b9 100644
--- a/code/modules/mob/living/carbon/human/species_types/angel.dm
+++ b/code/modules/mob/living/carbon/human/species_types/angel.dm
@@ -2,7 +2,7 @@
name = "Angel"
id = "angel"
default_color = "FFFFFF"
- species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,CAN_SCAR)
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE)
mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "wings" = "Angel")
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
no_equip = list(SLOT_BACK)
diff --git a/code/modules/mob/living/carbon/human/species_types/bugmen.dm b/code/modules/mob/living/carbon/human/species_types/bugmen.dm
index 25fb51aa87..2a955e28a4 100644
--- a/code/modules/mob/living/carbon/human/species_types/bugmen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/bugmen.dm
@@ -3,7 +3,7 @@
id = "insect"
say_mod = "chitters"
default_color = "00FF00"
- species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR,CAN_SCAR)
+ species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None",
"insect_wings" = "None", "insect_fluff" = "None", "mam_snouts" = "None", "taur" = "None", "insect_markings" = "None")
diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
index dcd81c90b9..d8dfe63b35 100644
--- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
@@ -2,8 +2,8 @@
name = "Dullahan"
id = "dullahan"
default_color = "FFFFFF"
- species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS)
- inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH,CAN_SCAR)
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE)
+ inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "deco_wings" = "None")
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
mutant_brain = /obj/item/organ/brain/dullahan
diff --git a/code/modules/mob/living/carbon/human/species_types/dwarves.dm b/code/modules/mob/living/carbon/human/species_types/dwarves.dm
index 8eb0e0181c..a465e7c3a9 100644
--- a/code/modules/mob/living/carbon/human/species_types/dwarves.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dwarves.dm
@@ -6,7 +6,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
name = "Dwarf"
id = "dwarf" //Also called Homo sapiens pumilionis
default_color = "FFFFFF"
- species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,CAN_SCAR)
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE)
inherent_traits = list(TRAIT_DWARF,TRAIT_SNOB)
limbs_id = "human"
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
index b99c3e2bc2..c56adaf1b0 100644
--- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
@@ -2,7 +2,7 @@
name = "Anthromorphic Fly"
id = "fly"
say_mod = "buzzes"
- species_traits = list(NOEYES,CAN_SCAR)
+ species_traits = list(NOEYES,HAS_FLESH,HAS_BONE)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
mutanttongue = /obj/item/organ/tongue/fly
mutantliver = /obj/item/organ/liver/fly
diff --git a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
index 18359f415f..7706d4a9d5 100644
--- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
@@ -3,7 +3,7 @@
id = "mammal"
default_color = "4B4B4B"
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
- species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR,CAN_SCAR)
+ species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BEAST
mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
"mam_body_markings" = "Husky", "taur" = "None", "horns" = "None", "legs" = "Plantigrade", "meat_type" = "Mammalian")
diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm
index e93a5106c9..f175ddb921 100644
--- a/code/modules/mob/living/carbon/human/species_types/humans.dm
+++ b/code/modules/mob/living/carbon/human/species_types/humans.dm
@@ -3,7 +3,7 @@
id = "human"
default_color = "FFFFFF"
- species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR,CAN_SCAR)
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR,HAS_FLESH,HAS_BONE)
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF","tail_human" = "None", "ears" = "None", "taur" = "None", "deco_wings" = "None")
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
skinned_type = /obj/item/stack/sheet/animalhide/human
diff --git a/code/modules/mob/living/carbon/human/species_types/ipc.dm b/code/modules/mob/living/carbon/human/species_types/ipc.dm
index b5862b2bd2..3aef14c256 100644
--- a/code/modules/mob/living/carbon/human/species_types/ipc.dm
+++ b/code/modules/mob/living/carbon/human/species_types/ipc.dm
@@ -6,7 +6,7 @@
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
blacklisted = 0
sexes = 0
- species_traits = list(MUTCOLORS,NOEYES,NOTRANSSTING)
+ species_traits = list(MUTCOLORS,NOEYES,NOTRANSSTING,HAS_FLESH,HAS_BONE)
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
mutant_bodyparts = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index dc821c11ef..9d7f99c14e 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -4,7 +4,7 @@
id = "jelly"
default_color = "00FF90"
say_mod = "chirps"
- species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR)
+ species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR,HAS_FLESH)
mutantlungs = /obj/item/organ/lungs/slime
mutant_heart = /obj/item/organ/heart/slime
mutant_bodyparts = list("mcolor" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None")
diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
index 7bcf6c89f4..d768788e87 100644
--- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
@@ -4,7 +4,7 @@
id = "lizard"
say_mod = "hisses"
default_color = "00FF00"
- species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR,CAN_SCAR)
+ species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE)
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur", "deco_wings")
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE
mutanttongue = /obj/item/organ/tongue/lizard
diff --git a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
index 4cb5442bf8..f91c3518a3 100644
--- a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
@@ -8,7 +8,7 @@
nojumpsuit = TRUE
say_mod = "poofs" //what does a mushroom sound like
- species_traits = list(MUTCOLORS, NOEYES, NO_UNDERWEAR,NOGENITALS,NOAROUSAL,CAN_SCAR)
+ species_traits = list(MUTCOLORS, NOEYES, NO_UNDERWEAR,NOGENITALS,NOAROUSAL,HAS_FLESH,HAS_BONE)
inherent_traits = list(TRAIT_NOBREATH)
speedmod = 1.5 //faster than golems but not by much
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 5008fb13cd..b61e29b685 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -4,7 +4,7 @@
say_mod = "rattles"
sexes = 0
meat = /obj/item/stack/sheet/mineral/plasma
- species_traits = list(NOBLOOD,NOTRANSSTING,NOGENITALS)
+ species_traits = list(NOBLOOD,NOTRANSSTING,NOGENITALS,HAS_BONE)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER,TRAIT_CALCIUM_HEALER)
inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
mutantlungs = /obj/item/organ/lungs/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 706995d611..f5a2f807e4 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -3,7 +3,7 @@
name = "Anthromorphic Plant"
id = "pod"
default_color = "59CE00"
- species_traits = list(MUTCOLORS,EYECOLOR,CAN_SCAR)
+ species_traits = list(MUTCOLORS,EYECOLOR,CAN_SCAR,HAS_FLESH,HAS_BONE)
attack_verb = "slash"
attack_sound = 'sound/weapons/slice.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 9f7d165edf..b9864bce16 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -9,8 +9,8 @@
blacklisted = 1
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
- species_traits = list(NOBLOOD,NOEYES,CAN_SCAR)
- inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH,CAN_SCAR)
+ species_traits = list(NOBLOOD,NOEYES,HAS_FLESH,HAS_BONE)
+ inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH)
dangerous_existence = 1
mutanteyes = /obj/item/organ/eyes/night_vision
@@ -166,7 +166,7 @@
righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
item_flags = ABSTRACT | DROPDEL
w_class = WEIGHT_CLASS_HUGE
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
total_mass = TOTAL_MASS_HAND_REPLACEMENT
/obj/item/light_eater/Initialize()
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 54d56fea06..51d81bd4d3 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -5,7 +5,7 @@
blacklisted = 0
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
- species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL)
+ species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL,HAS_BONE)
inherent_traits = list(TRAIT_NOBREATH,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutanttongue = /obj/item/organ/tongue/bone
diff --git a/code/modules/mob/living/carbon/human/species_types/synthliz.dm b/code/modules/mob/living/carbon/human/species_types/synthliz.dm
index 41b3d3a96a..5ed806b302 100644
--- a/code/modules/mob/living/carbon/human/species_types/synthliz.dm
+++ b/code/modules/mob/living/carbon/human/species_types/synthliz.dm
@@ -4,7 +4,7 @@
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
say_mod = "beeps"
default_color = "00FF00"
- species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR)
+ species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,HAS_FLESH,HAS_BONE)
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
mutant_bodyparts = list("ipc_antenna" = "Synthetic Lizard - Antennae","mam_tail" = "Synthetic Lizard", "mam_snouts" = "Synthetic Lizard - Snout", "legs" = "Digitigrade", "mam_body_markings" = "Synthetic Lizard - Plates", "taur" = "None")
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index d8fc06b716..723c4848fe 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -2,7 +2,7 @@
name = "Vampire"
id = "vampire"
default_color = "FFFFFF"
- species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD)
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD,HAS_FLESH,HAS_BONE)
inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutant_bodyparts = list("mcolor" = "FFFFFF", "tail_human" = "None", "ears" = "None", "deco_wings" = "None")
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 990e2c9db3..81a7f6e2e7 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -8,7 +8,7 @@
sexes = 0
blacklisted = 1
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
- species_traits = list(NOBLOOD,NOZOMBIE,NOTRANSSTING,CAN_SCAR)
+ species_traits = list(NOBLOOD,NOZOMBIE,NOTRANSSTING,HAS_FLESH,HAS_BONE)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutanttongue = /obj/item/organ/tongue/zombie
@@ -45,7 +45,7 @@
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
. = min(20, amount)
-/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
+/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
. = ..()
if(.)
regen_cooldown = world.time + REGENERATION_DELAY
@@ -63,9 +63,9 @@
C.heal_overall_damage(heal_amt,heal_amt)
C.adjustToxLoss(-heal_amt)
for(var/i in C.all_wounds)
- var/datum/wound/W = i
- if(prob(4-W.severity))
- W.remove_wound()
+ var/datum/wound/iter_wound = i
+ if(prob(4-iter_wound.severity))
+ iter_wound.remove_wound()
if(!C.InCritical() && prob(4))
playsound(C, pick(spooks), 50, TRUE, 10)
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index 012808647e..47c9062148 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -14,7 +14,7 @@
*
* Returns TRUE if damage applied
*/
-/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
+/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
var/hit_percent = (100-blocked)/100
if(!damage || (hit_percent <= 0))
return 0
@@ -245,7 +245,7 @@
update_stamina()
// damage ONE external organ, organ gets randomly selected from damaged ones.
-/mob/living/proc/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
+/mob/living/proc/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
adjustBruteLoss(brute, FALSE) //zero as argument for no instant health update
adjustFireLoss(burn, FALSE)
adjustStaminaLoss(stamina, FALSE)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index a5de3a2fdc..bae2d2106b 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -441,7 +441,7 @@
to_chat(user, "You cannot send IC messages (muted).")
return FALSE
else if(!params)
- var/custom_emote = stripped_multiline_input(user, "Choose an emote to display.", "Custom Emote", null, MAX_MESSAGE_LEN)
+ var/custom_emote = stripped_multiline_input_or_reflect(user, "Choose an emote to display.", "Custom Emote", null, MAX_MESSAGE_LEN)
if(custom_emote && !check_invalid(user, custom_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
switch(type)
@@ -531,3 +531,29 @@
to_chat(user, "You ready your slapping hand.")
else
to_chat(user, "You're incapable of slapping in your current state.")
+
+/datum/emote/living/audio_emote/blorble
+ key = "blorble"
+ key_third_person = "blorbles"
+ message = "blorbles."
+ message_param = "blorbles at %t."
+
+/datum/emote/living/audio_emote/blorble/run_emote(mob/user, params)
+ . = ..()
+ if(. && iscarbon(user))
+ var/mob/living/carbon/C = user
+ if(isjellyperson(C))
+ pick(playsound(C, 'sound/effects/attackblob.ogg', 50, 1),playsound(C, 'sound/effects/blobattack.ogg', 50, 1))
+
+/datum/emote/living/audio_emote/blurp
+ key = "blurp"
+ key_third_person = "blurps"
+ message = "blurps."
+ message_param = "blurps at %t."
+
+/datum/emote/living/audio_emote/blurp/run_emote(mob/user, params)
+ . = ..()
+ if(. && iscarbon(user))
+ var/mob/living/carbon/C = user
+ if(isjellyperson(C))
+ pick(playsound(C, 'sound/effects/meatslap.ogg', 50, 1),playsound(C, 'sound/effects/gib_step.ogg', 50, 1))
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index b04f78f3ec..0f55d5c408 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -605,41 +605,55 @@
SEND_SIGNAL(item, COMSIG_ITEM_WEARERCROSSED, AM)
/mob/living/proc/makeTrail(turf/target_turf, turf/start, direction)
- if(!has_gravity())
+ if(!has_gravity() || !isturf(start) || !blood_volume)
return
- var/blood_exists = FALSE
+ var/blood_exists = locate(/obj/effect/decal/cleanable/trail_holder) in start
- for(var/obj/effect/decal/cleanable/trail_holder/C in start) //checks for blood splatter already on the floor
- blood_exists = TRUE
- if(isturf(start))
- var/trail_type = getTrail()
- if(trail_type)
- var/brute_ratio = round(getBruteLoss() / maxHealth, 0.1)
- if(blood_volume && blood_volume > max((BLOOD_VOLUME_NORMAL*blood_ratio)*(1 - brute_ratio * 0.25), 0))//don't leave trail if blood volume below a threshold
- blood_volume = max(blood_volume - max(1, brute_ratio * 2), 0) //that depends on our brute damage.
- var/newdir = get_dir(target_turf, start)
- if(newdir != direction)
- newdir = newdir | direction
- if(newdir == 3) //N + S
- newdir = NORTH
- else if(newdir == 12) //E + W
- newdir = EAST
- if((newdir in GLOB.cardinals) && (prob(50)))
- newdir = turn(get_dir(target_turf, start), 180)
- if(!blood_exists)
- new /obj/effect/decal/cleanable/trail_holder(start, get_static_viruses())
+ var/trail_type = getTrail()
+ if(!trail_type)
+ return
- for(var/obj/effect/decal/cleanable/trail_holder/TH in start)
- if((!(newdir in TH.existing_dirs) || trail_type == "trails_1" || trail_type == "trails_2") && TH.existing_dirs.len <= 16) //maximum amount of overlays is 16 (all light & heavy directions filled)
- TH.existing_dirs += newdir
- TH.add_overlay(image('icons/effects/blood.dmi', trail_type, dir = newdir))
- TH.transfer_mob_blood_dna(src)
+ var/brute_ratio = round(getBruteLoss() / maxHealth, 0.1)
+ if(blood_volume < max(BLOOD_VOLUME_NORMAL*(1 - brute_ratio * 0.25), 0))//don't leave trail if blood volume below a threshold
+ return
+
+ var/bleed_amount = bleedDragAmount()
+ blood_volume = max(blood_volume - bleed_amount, 0) //that depends on our brute damage.
+ var/newdir = get_dir(target_turf, start)
+ if(newdir != direction)
+ newdir = newdir | direction
+ if(newdir == (NORTH|SOUTH))
+ newdir = NORTH
+ else if(newdir == (EAST|WEST))
+ newdir = EAST
+ if((newdir in GLOB.cardinals) && (prob(50)))
+ newdir = turn(get_dir(target_turf, start), 180)
+ if(!blood_exists)
+ new /obj/effect/decal/cleanable/trail_holder(start, get_static_viruses())
+
+ for(var/obj/effect/decal/cleanable/trail_holder/TH in start)
+ if((!(newdir in TH.existing_dirs) || trail_type == "trails_1" || trail_type == "trails_2") && TH.existing_dirs.len <= 16) //maximum amount of overlays is 16 (all light & heavy directions filled)
+ TH.existing_dirs += newdir
+ TH.add_overlay(image('icons/effects/blood.dmi', trail_type, dir = newdir))
+ TH.transfer_mob_blood_dna(src)
/mob/living/carbon/human/makeTrail(turf/T)
if((NOBLOOD in dna.species.species_traits) || !is_bleeding() || bleedsuppress)
return
..()
+///Returns how much blood we're losing from being dragged a tile, from [mob/living/proc/makeTrail]
+/mob/living/proc/bleedDragAmount()
+ var/brute_ratio = round(getBruteLoss() / maxHealth, 0.1)
+ return max(1, brute_ratio * 2)
+
+/mob/living/carbon/bleedDragAmount()
+ var/bleed_amount = 0
+ for(var/i in all_wounds)
+ var/datum/wound/iter_wound = i
+ bleed_amount += iter_wound.drag_bleed_amount()
+ return bleed_amount
+
/mob/living/proc/getTrail()
if(getBruteLoss() < 300)
return pick("ltrails_1", "ltrails_2")
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 5be9dbf195..19adb7b787 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -86,7 +86,7 @@
totaldamage = block_calculate_resultant_damage(totaldamage, returnlist)
var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null)
if(!P.nodamage)
- apply_damage(totaldamage, P.damage_type, def_zone, armor, wound_bonus=P.wound_bonus, bare_wound_bonus=P.bare_wound_bonus, sharpness=P.sharpness)
+ apply_damage(totaldamage, P.damage_type, def_zone, armor, wound_bonus = P.wound_bonus, bare_wound_bonus = P.bare_wound_bonus, sharpness = P.sharpness)
if(P.dismemberment)
check_projectile_dismemberment(P, def_zone)
var/missing = 100 - final_percent
@@ -136,12 +136,13 @@
dtype = I.damtype
if(!blocked)
- visible_message("[src] has been hit by [I].", \
- "You have been hit by [I].")
- var/armor = run_armor_check(impacting_zone, "melee", "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration)
- apply_damage(total_damage, dtype, impacting_zone, armor, sharpness=I.sharpness)
- if(I.thrownby)
- log_combat(I.thrownby, src, "threw and hit", I)
+ if(!nosell_hit)
+ visible_message("[src] is hit by [I]!", \
+ "You're hit by [I]!")
+ if(!I.throwforce)
+ return
+ var/armor = run_armor_check(impacting_zone, "melee", "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration)
+ apply_damage(I.throwforce, dtype, impacting_zone, armor, sharpness=I.get_sharpness(), wound_bonus=(nosell_hit * CANT_WOUND))
else
return 1
else
diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm
index b89f249c80..7530630d74 100644
--- a/code/modules/mob/living/silicon/damage_procs.dm
+++ b/code/modules/mob/living/silicon/damage_procs.dm
@@ -1,5 +1,5 @@
-/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
+/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
var/hit_percent = (100-blocked)/100
if(!damage || (!forced && hit_percent <= 0))
return 0
diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm
index 65e1047cdc..c0fca997f5 100644
--- a/code/modules/mob/living/silicon/robot/emote.dm
+++ b/code/modules/mob/living/silicon/robot/emote.dm
@@ -3,8 +3,14 @@
emote_type = EMOTE_AUDIBLE
/datum/emote/sound/silicon
- mob_type_allowed_typecache = list(/mob/living/silicon)
+ mob_type_allowed_typecache = list(/mob/living/silicon, /mob/living/carbon/human)
emote_type = EMOTE_AUDIBLE
+ var/unrestricted = FALSE
+
+/datum/emote/sound/silicon/run_emote(mob/user, params)
+ if(!unrestricted && !(issilicon(user) || isipcperson(user)))
+ return
+ return ..()
/datum/emote/silicon/boop
key = "boop"
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index 73ebfa7c77..fb24b0fc09 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -60,11 +60,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/magic_fluff_string = "You draw the Coder, symbolizing bugs and errors. This shouldn't happen! Submit a bug report!"
var/tech_fluff_string = "BOOT SEQUENCE COMPLETE. ERROR MODULE LOADED. THIS SHOULDN'T HAPPEN. Submit a bug report!"
var/carp_fluff_string = "CARP CARP CARP SOME SORT OF HORRIFIC BUG BLAME THE CODERS CARP CARP CARP"
+ /// sigh, fine.
+ var/datum/song/holoparasite/music_datum
/mob/living/simple_animal/hostile/guardian/Initialize(mapload, theme)
GLOB.parasites += src
updatetheme(theme)
-
+ music_datum = new(src, get_allowed_instrument_ids())
. = ..()
/mob/living/simple_animal/hostile/guardian/med_hud_set_health()
@@ -84,8 +86,16 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
/mob/living/simple_animal/hostile/guardian/Destroy()
GLOB.parasites -= src
+ QDEL_NULL(music_datum)
return ..()
+/mob/living/simple_animal/hostile/guardian/verb/music_interact()
+ set name = "Access Internal Synthesizer"
+ set desc = "Access your internal musical synthesizer"
+ set category = "IC"
+
+ music_datum.ui_interact(src)
+
/mob/living/simple_animal/hostile/guardian/proc/updatetheme(theme) //update the guardian's theme
if(!theme)
theme = pick("magic", "tech", "carp")
@@ -638,6 +648,12 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
/obj/item/guardiancreator/tech/choose/dextrous
possible_guardians = list("Assassin", "Chaos", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
+/obj/item/guardiancreator/tech/choose/nukie // lacks support and protector as encouraging nukies to play turtle isnt fun and dextrous is epic
+ possible_guardians = list("Assassin", "Chaos", "Charger", "Dextrous", "Explosive", "Lightning", "Ranged", "Standard")
+
+/obj/item/guardiancreator/tech/choose/nukie/check_uplink_validity()
+ return !used
+
/obj/item/paper/guides/antag/guardian
name = "Holoparasite Guide"
icon_state = "paper_words"
@@ -677,7 +693,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
Charger: Moves extremely fast, does medium damage on attack, and can charge at targets, damaging the first target hit and forcing them to drop any items they are holding.
- Dexterous: Does low damage on attack, but is capable of holding items and storing a single item within it. It will drop items held in its hands when it recalls, but it will retain the stored item.
+ Dextrous: Does low damage on attack, but is capable of holding items and storing a single item within it. It will drop items held in its hands when it recalls, but it will retain the stored item.
Explosive: High damage resist and medium power attack that may explosively teleport targets. Can turn any object, including objects too large to pick up, into a bomb, dealing explosive damage to the next person to touch it. The object will return to normal after the trap is triggered or after a delay.
@@ -691,6 +707,29 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
"}
+/obj/item/paper/guides/antag/guardian/nukie
+ name = "Guardian Guide"
+ info = {"A list of Guardian Types
+
+
+ Assassin: Does medium damage and takes full damage, but can enter stealth, causing its next attack to do massive damage and ignore armor. However, it becomes briefly unable to recall after attacking from stealth.
+
+ Chaos: Ignites enemies on touch and causes them to hallucinate all nearby people as the guardian. Automatically extinguishes the user if they catch on fire.
+
+ Charger: Moves extremely fast, does medium damage on attack, and can charge at targets, damaging the first target hit and forcing them to drop any items they are holding.
+
+ Dextrous: Does low damage on attack, but is capable of holding items and storing a single item within it. It will drop items held in its hands when it recalls, but it will retain the stored item.
+
+ Explosive: High damage resist and medium power attack that may explosively teleport targets. Can turn any object, including objects too large to pick up, into a bomb, dealing explosive damage to the next person to touch it. The object will return to normal after the trap is triggered or after a delay.
+
+ Lightning: Attacks apply lightning chains to targets. Has a lightning chain to the user. Lightning chains shock everything near them, doing constant damage.
+
+ Ranged: Has two modes. Ranged; which fires a constant stream of weak, armor-ignoring projectiles. Scout; Cannot attack, but can move through walls and is quite hard to see. Can lay surveillance snares, which alert it when crossed, in either mode.
+
+ Standard: Devastating close combat attacks and high damage resist. Can smash through weak walls.
+
+"}
+
/obj/item/storage/box/syndie_kit/guardian
name = "holoparasite injector kit"
@@ -699,6 +738,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
new /obj/item/guardiancreator/tech/choose/traitor(src)
new /obj/item/paper/guides/antag/guardian(src)
+/obj/item/storage/box/syndie_kit/nukieguardian
+ name = "holoparasite injector kit"
+
+/obj/item/storage/box/syndie_kit/nukieguardian/PopulateContents()
+ new /obj/item/guardiancreator/tech/choose/nukie(src)
+ new /obj/item/paper/guides/antag/guardian/nukie(src)
+
/obj/item/guardiancreator/carp
name = "holocarp fishsticks"
desc = "Using the power of Carp'sie, you can catch a carp from byond the veil of Carpthulu, and bind it to your fleshy flesh form."
diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
index 4e6923615d..26e5d791f3 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
@@ -36,60 +36,21 @@
return
if(isobj(A) && Adjacent(A))
if(bomb_cooldown <= world.time && !stat)
- var/obj/guardian_bomb/B = new /obj/guardian_bomb(get_turf(A))
+ var/datum/component/killerqueen/K = A.AddComponent(/datum/component/killerqueen, EXPLODE_HEAVY, CALLBACK(src, .proc/on_explode), CALLBACK(src, .proc/on_failure), \
+ examine_message = "It glows with a strange light!")
+ QDEL_IN(K, 1 MINUTES)
to_chat(src, "Success! Bomb armed!")
bomb_cooldown = world.time + 200
- B.spawner = src
- B.disguise(A)
else
to_chat(src, "Your powers are on cooldown! You must wait 20 seconds between bombs.")
-/obj/guardian_bomb
- name = "bomb"
- desc = "You shouldn't be seeing this!"
- var/obj/stored_obj
- var/mob/living/simple_animal/hostile/guardian/spawner
+/mob/living/simple_animal/hostile/guardian/bomb/proc/on_explode(atom/bomb, atom/victim)
+ if((victim == src) || (victim == summoner) || (hasmatchingsummoner(victim)))
+ to_chat(victim, "[src] glows with a strange light, and you don't touch it.")
+ return FALSE
+ to_chat(src, "One of your explosive traps caught [victim]!")
+ to_chat(victim, "[bomb] was boobytrapped!")
+ return TRUE
-
-/obj/guardian_bomb/proc/disguise(obj/A)
- A.forceMove(src)
- stored_obj = A
- opacity = A.opacity
- anchored = A.anchored
- density = A.density
- appearance = A.appearance
- addtimer(CALLBACK(src, .proc/disable), 600)
-
-/obj/guardian_bomb/proc/disable()
- stored_obj.forceMove(get_turf(src))
- to_chat(spawner, "Failure! Your trap didn't catch anyone this time.")
- qdel(src)
-
-/obj/guardian_bomb/proc/detonate(mob/living/user)
- if(isliving(user))
- if(user != spawner && user != spawner.summoner && !spawner.hasmatchingsummoner(user))
- to_chat(user, "[src] was boobytrapped!")
- to_chat(spawner, "Success! Your trap caught [user]")
- var/turf/T = get_turf(src)
- stored_obj.forceMove(T)
- playsound(T,'sound/effects/explosion2.ogg', 200, 1)
- new /obj/effect/temp_visual/explosion(T)
- user.ex_act(EXPLODE_HEAVY)
- qdel(src)
- else
- to_chat(user, "[src] glows with a strange light, and you don't touch it.")
-
-/obj/guardian_bomb/Bump(atom/A)
- detonate(A)
- ..()
-
-/obj/guardian_bomb/attackby(mob/living/user)
- detonate(user)
-
-/obj/guardian_bomb/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
- detonate(user)
-
-/obj/guardian_bomb/examine(mob/user)
- . = stored_obj.examine(user)
- if(get_dist(user,src)<=2)
- . += "It glows with a strange light!"
+/mob/living/simple_animal/hostile/guardian/bomb/proc/on_failure(atom/bomb)
+ to_chat(src, "Failure! Your trap didn't catch anyone this time.")
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index 057d4bdb45..da16ec581b 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -33,7 +33,7 @@
melee_damage_upper = 15
wound_bonus = -5
bare_wound_bonus = 10 // BEAR wound bonus am i right
- sharpness = TRUE
+ sharpness = SHARP_EDGED
attack_verb_continuous = "claws"
attack_verb_simple = "claw"
attack_sound = 'sound/weapons/bladeslice.ogg'
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index 4ea8a3c5dc..fd37bb26aa 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -79,7 +79,7 @@
melee_damage_upper = 15
wound_bonus = -10
bare_wound_bonus = 20
- sharpness = TRUE
+ sharpness = SHARP_EDGED
icon_state = "syndicate_knife"
icon_living = "syndicate_knife"
loot = list(/obj/effect/gibspawner/human)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 1102559aca..706bcc46f5 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -145,7 +145,7 @@
//How much bare wounding power it has
var/bare_wound_bonus = 0
//If the attacks from this are sharp
- var/sharpness = FALSE
+ var/sharpness = SHARP_NONE
/mob/living/simple_animal/Initialize()
. = ..()
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index 0029300936..87fd0cf609 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -500,6 +500,15 @@
S = apply_status_effect(STATUS_EFFECT_SLEEPING, amount, updating)
return S
+///////////////////////////////// OFF BALANCE/SHOVIES ////////////////////////
+/mob/living/proc/ShoveOffBalance(amount)
+ var/datum/status_effect/off_balance/B = has_status_effect(STATUS_EFFECT_OFF_BALANCE)
+ if(B)
+ B.duration = max(world.time + amount, B.duration)
+ else if(amount > 0)
+ B = apply_status_effect(STATUS_EFFECT_OFF_BALANCE, amount)
+ return B
+
///////////////////////////////// FROZEN /////////////////////////////////////
/mob/living/proc/IsFrozen()
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 195c50e958..03a3ab1001 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -161,4 +161,4 @@
/// The timer that will remove our indicator for early aborts (like when an user finishes their message)
var/typing_indicator_timerid
/// Current state of our typing indicator. Used for cut overlay, DO NOT RUNTIME ASSIGN OTHER THAN FROM SHOW/CLEAR. Used to absolutely ensure we do not get stuck overlays.
- var/typing_indicator_current
+ var/mutable_appearance/typing_indicator_current
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 3ceafe4a11..7d97270808 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -43,6 +43,11 @@
if(GLOB.say_disabled) //This is here to try to identify lag problems
to_chat(usr, "Speech is currently admin-disabled.")
return
+
+ if(length(message) > MAX_MESSAGE_LEN)
+ to_chat(usr, message)
+ to_chat(usr, "^^^----- The preceeding message has been DISCARDED for being over the maximum length of [MAX_MESSAGE_LEN]. It has NOT been sent! -----^^^")
+ return
message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
clear_typing_indicator() // clear it immediately!
diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm
index 5ed24af726..5db3ccf216 100644
--- a/code/modules/mob/say_vr.dm
+++ b/code/modules/mob/say_vr.dm
@@ -37,7 +37,7 @@ proc/get_top_level_mob(var/mob/S)
to_chat(user, "You cannot send IC messages (muted).")
return FALSE
else if(!params)
- var/subtle_emote = stripped_multiline_input(user, "Choose an emote to display.", "Subtle", null, MAX_MESSAGE_LEN)
+ var/subtle_emote = stripped_multiline_input_or_reflect(user, "Choose an emote to display.", "Subtle", null, MAX_MESSAGE_LEN)
if(subtle_emote && !check_invalid(user, subtle_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
switch(type)
@@ -98,7 +98,7 @@ proc/get_top_level_mob(var/mob/S)
to_chat(user, "You cannot send IC messages (muted).")
return FALSE
else if(!params)
- var/subtle_emote = stripped_multiline_input(user, "Choose an emote to display.", "Subtler" , null, MAX_MESSAGE_LEN)
+ var/subtle_emote = stripped_multiline_input_or_reflect(user, "Choose an emote to display.", "Subtler" , null, MAX_MESSAGE_LEN)
if(subtle_emote && !check_invalid(user, subtle_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
switch(type)
diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm
index f28cbe4385..6154828f4d 100644
--- a/code/modules/mob/typing_indicator.dm
+++ b/code/modules/mob/typing_indicator.dm
@@ -15,13 +15,23 @@ GLOBAL_LIST_EMPTY(typing_indicator_overlays)
/mob/proc/get_typing_indicator_icon_state()
return typing_indicator_state
+/// Generates the mutable appearance for typing indicator. Should prevent stuck overlays.
+/mob/proc/generate_typing_indicator()
+ var/state = get_typing_indicator_icon_state()
+ if(ispath(state))
+ var/atom/thing = new state(null)
+ var/mutable_appearance/generated = new(thing)
+ return generated
+ else
+ CRASH("Unsupported typing indicator state: [state]")
+
/**
* Displays typing indicator.
* @param timeout_override - Sets how long until this will disappear on its own without the user finishing their message or logging out. Defaults to src.typing_indicator_timeout
* @param state_override - Sets the state that we will fetch. Defaults to src.get_typing_indicator_icon_state()
* @param force - shows even if src.typing_indcator_enabled is FALSE.
*/
-/mob/proc/display_typing_indicator(timeout_override = TYPING_INDICATOR_TIMEOUT, state_override = get_typing_indicator_icon_state(), force = FALSE)
+/mob/proc/display_typing_indicator(timeout_override = TYPING_INDICATOR_TIMEOUT, state_override = generate_typing_indicator(), force = FALSE)
if((!typing_indicator_enabled && !force) || typing_indicator_current)
return
typing_indicator_current = state_override
diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm
index a2176ca95e..d17767bb1f 100644
--- a/code/modules/movespeed/modifiers/mobs.dm
+++ b/code/modules/movespeed/modifiers/mobs.dm
@@ -78,9 +78,6 @@
blacklisted_movetypes = FLOATING
variable = TRUE
-/datum/movespeed_modifier/shove
- multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH
-
/datum/movespeed_modifier/human_carry
variable = TRUE
diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm
index e6d53d914f..00cfa94893 100644
--- a/code/modules/ninja/energy_katana.dm
+++ b/code/modules/ninja/energy_katana.dm
@@ -14,7 +14,7 @@
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
block_chance = 50
slot_flags = ITEM_SLOT_BELT
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
max_integrity = 200
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/datum/effect_system/spark_spread/spark_system
diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm
index 508722ecf2..57faad9493 100644
--- a/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm
@@ -14,5 +14,5 @@
/obj/item/throwing_star/ninja
name = "ninja throwing star"
- throwforce = 30
+ throwforce = 20
embedding = list("pain_mult" = 6, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index 08252d4e05..997ada6b21 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -28,6 +28,7 @@
var/degrees = 0
var/font = PEN_FONT
embedding = list()
+ sharpness = SHARP_POINTY
/obj/item/pen/suicide_act(mob/user)
user.visible_message("[user] is scribbling numbers all over [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit sudoku...")
@@ -84,7 +85,7 @@
throw_speed = 4
colour = "crimson"
custom_materials = list(/datum/material/gold = 750)
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
resistance_flags = FIRE_PROOF
unique_reskin = list("Oak" = "pen-fountain-o",
"Gold" = "pen-fountain-g",
@@ -180,7 +181,7 @@
*/
/obj/item/pen/edagger
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") //these wont show up if the pen is off
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
var/on = FALSE
embedding = list(embed_chance = EMBED_CHANCE)
diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
index e4674f4f4c..987efc0404 100644
--- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
+++ b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
@@ -47,7 +47,7 @@
/obj/item/ammo_box/c38/dumdum
name = "speed loader (.38 DumDum)"
- desc = "Designed to quickly reload revolvers. DumDum bullets shatter on impact and shred the target's innards, likely getting caught inside."
+ desc = "Designed to quickly reload revolvers. These rounds expand on impact, allowing them to shred the target and cause massive bleeding. Very weak against armor and distant targets."
ammo_type = /obj/item/ammo_casing/c38/dumdum
/obj/item/ammo_box/c38/match
diff --git a/code/modules/projectiles/boxes_magazines/external/shotgun.dm b/code/modules/projectiles/boxes_magazines/external/shotgun.dm
index 1001937678..ed41375aee 100644
--- a/code/modules/projectiles/boxes_magazines/external/shotgun.dm
+++ b/code/modules/projectiles/boxes_magazines/external/shotgun.dm
@@ -1,5 +1,5 @@
/obj/item/ammo_box/magazine/m12g
- name = "shotgun magazine (12g buckshot slugs)"
+ name = "shotgun magazine (12g buckshot)"
desc = "A drum magazine."
icon_state = "m12gb"
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
@@ -17,7 +17,7 @@
/obj/item/ammo_box/magazine/m12g/slug
name = "shotgun magazine (12g slugs)"
- icon_state = "m12gb" //this may need an unique sprite
+ icon_state = "m12gsl"
ammo_type = /obj/item/ammo_casing/shotgun
/obj/item/ammo_box/magazine/m12g/dragon
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 4126c81367..c3248bab2f 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -193,7 +193,8 @@
return
if(iscarbon(target))
var/mob/living/carbon/C = target
- for(var/datum/wound/W in C.all_wounds)
+ for(var/i in C.all_wounds)
+ var/datum/wound/W = i
if(W.try_treating(src, user))
return // another coward cured!
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index 289b43a669..a5ed45dd48 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -84,6 +84,11 @@
. = ..()
. += "[get_ammo(0,0)] of those are live rounds."
+/obj/item/gun/ballistic/revolver/syndicate
+ unique_reskin = list("Default" = "revolver",
+ "Silver" = "russianrevolver",
+ "Robust" = "revolvercit")
+
/obj/item/gun/ballistic/revolver/detective
name = "\improper .38 Mars Special"
desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds."
@@ -486,4 +491,4 @@
for(var/i = 0, i < ratio, i++)
var/mutable_appearance/charge_bar = mutable_appearance(icon, "[initial(icon_state)]_charge", color = batt_color)
charge_bar.pixel_x = i
- . += charge_bar
\ No newline at end of file
+ . += charge_bar
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 6489920b98..20e847326e 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -125,7 +125,7 @@
flags_1 = CONDUCT_1
attack_verb = list("attacked", "slashed", "cut", "sliced")
force = 12
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
inaccuracy_modifier = 0.25
can_charge = 0
diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm
index b23b059d89..6ebdc5e7b8 100644
--- a/code/modules/projectiles/guns/magic/staff.dm
+++ b/code/modules/projectiles/guns/magic/staff.dm
@@ -83,7 +83,7 @@
force = 20
armour_penetration = 75
block_chance = 50
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
max_charges = 4
/obj/item/gun/magic/staff/spellblade/Initialize()
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index f3d78af59b..43384280d4 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -149,19 +149,25 @@
var/temporary_unstoppable_movement = FALSE
- ///If defined, on hit we create an item of this type then call hitby() on the hit target with this
+ ///If defined, on hit we create an item of this type then call hitby() on the hit target with this, mainly used for embedding items (bullets) in targets
var/shrapnel_type
///If TRUE, hit mobs even if they're on the floor and not our target
var/hit_stunned_targets = FALSE
wound_bonus = CANT_WOUND
+ ///How much we want to drop both wound_bonus and bare_wound_bonus (to a minimum of 0 for the latter) per tile, for falloff purposes
+ var/wound_falloff_tile
+ ///How much we want to drop the embed_chance value, if we can embed, per tile, for falloff purposes
+ var/embed_falloff_tile
/// For telling whether we want to roll for bone breaking or lacerations if we're bothering with wounds
- sharpness = FALSE
+ sharpness = SHARP_NONE
/obj/item/projectile/Initialize()
. = ..()
permutated = list()
decayedRange = range
+ if(embedding)
+ updateEmbedding()
/**
* Artificially modified to be called at around every world.icon_size pixels of movement.
@@ -169,6 +175,11 @@
*/
/obj/item/projectile/proc/Range()
range--
+ if(wound_bonus != CANT_WOUND)
+ wound_bonus += wound_falloff_tile
+ bare_wound_bonus = max(0, bare_wound_bonus + wound_falloff_tile)
+ if(embedding)
+ embedding["embed_chance"] += embed_falloff_tile
if(range <= 0 && loc)
on_range()
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index 6a081f9b03..b408957aa7 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -8,4 +8,12 @@
flag = "bullet"
hitsound_wall = "ricochet"
impact_effect_type = /obj/effect/temp_visual/impact_effect
- sharpness = TRUE
\ No newline at end of file
+ sharpness = SHARP_POINTY
+ shrapnel_type = /obj/item/shrapnel/bullet
+ embedding = list(embed_chance=15, fall_chance=2, jostle_chance=0, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.5, pain_mult=3, rip_time=10)
+ wound_falloff_tile = -5
+ embed_falloff_tile = -5
+
+/obj/item/projectile/bullet/smite
+ name = "divine retribution"
+ damage = 10
diff --git a/code/modules/projectiles/projectile/bullets/lmg.dm b/code/modules/projectiles/projectile/bullets/lmg.dm
index 2ea1fe7c9a..e3eff6dcb0 100644
--- a/code/modules/projectiles/projectile/bullets/lmg.dm
+++ b/code/modules/projectiles/projectile/bullets/lmg.dm
@@ -25,8 +25,10 @@
/obj/item/projectile/bullet/mm195x129
name = "1.95x129mm bullet"
- damage = 45
+ damage = 40
armour_penetration = 5
+ wound_bonus = -50
+ wound_falloff_tile = 0
/obj/item/projectile/bullet/mm195x129_ap
name = "1.95x129mm armor-piercing bullet"
@@ -35,8 +37,12 @@
/obj/item/projectile/bullet/mm195x129_hp
name = "1.95x129mm hollow-point bullet"
- damage = 60
+ damage = 50
armour_penetration = -60
+ sharpness = SHARP_EDGED
+ wound_bonus = -40
+ bare_wound_bonus = 30
+ wound_falloff_tile = -8
/obj/item/projectile/bullet/incendiary/mm195x129
name = "1.95x129mm incendiary bullet"
diff --git a/code/modules/projectiles/projectile/bullets/pistol.dm b/code/modules/projectiles/projectile/bullets/pistol.dm
index 38c9c9f7d9..23a749415c 100644
--- a/code/modules/projectiles/projectile/bullets/pistol.dm
+++ b/code/modules/projectiles/projectile/bullets/pistol.dm
@@ -3,11 +3,13 @@
/obj/item/projectile/bullet/c9mm
name = "9mm bullet"
damage = 20
+ embedding = list(embed_chance=15, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10)
/obj/item/projectile/bullet/c9mm_ap
name = "9mm armor-piercing bullet"
damage = 15
armour_penetration = 40
+ embedding = null
/obj/item/projectile/bullet/incendiary/c9mm
name = "9mm incendiary bullet"
diff --git a/code/modules/projectiles/projectile/bullets/revolver.dm b/code/modules/projectiles/projectile/bullets/revolver.dm
index c793e9f95e..95d43ba1ce 100644
--- a/code/modules/projectiles/projectile/bullets/revolver.dm
+++ b/code/modules/projectiles/projectile/bullets/revolver.dm
@@ -19,8 +19,9 @@
ricochet_chance = 50
ricochet_auto_aim_angle = 10
ricochet_auto_aim_range = 3
- wound_bonus = -35
- sharpness = TRUE
+ wound_bonus = -20
+ bare_wound_bonus = 10
+ embedding = list(embed_chance=15, fall_chance=2, jostle_chance=2, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=3, jostle_pain_mult=5, rip_time=10)
/obj/item/projectile/bullet/c38/match
name = ".38 Match bullet"
@@ -43,13 +44,21 @@
ricochet_chance = 130
ricochet_decay_damage = 0.8
shrapnel_type = NONE
+ sharpness = SHARP_NONE
+ embedding = null
+// premium .38 ammo from cargo, weak against armor, lower base damage, but excellent at embedding and causing slice wounds at close range
/obj/item/projectile/bullet/c38/dumdum
name = ".38 DumDum bullet"
damage = 15
armour_penetration = -30
ricochets_max = 0
- shrapnel_type = /obj/item/shrapnel/bullet/c38/dumdum
+ sharpness = SHARP_EDGED
+ wound_bonus = 20
+ bare_wound_bonus = 20
+ embedding = list(embed_chance=75, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10)
+ wound_falloff_tile = -5
+ embed_falloff_tile = -15
/obj/item/projectile/bullet/c38/rubber
name = ".38 rubber bullet"
@@ -102,6 +111,7 @@
/obj/item/projectile/bullet/a357
name = ".357 bullet"
damage = 60
+ wound_bonus = -70
/obj/item/projectile/bullet/a357/ap
name = ".357 armor-piercing bullet"
diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm
index ae1611cb00..ce30f5e787 100644
--- a/code/modules/projectiles/projectile/bullets/rifle.dm
+++ b/code/modules/projectiles/projectile/bullets/rifle.dm
@@ -3,12 +3,15 @@
/obj/item/projectile/bullet/a556
name = "5.56mm bullet"
damage = 35
+ wound_bonus = -40
// 7.62 (Nagant Rifle)
/obj/item/projectile/bullet/a762
name = "7.62 bullet"
damage = 60
+ wound_bonus = -35
+ wound_falloff_tile = 0
/obj/item/projectile/bullet/a762_enchanted
name = "enchanted 7.62 bullet"
diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm
index 6e4a72aff0..69f976d213 100644
--- a/code/modules/projectiles/projectile/bullets/shotgun.dm
+++ b/code/modules/projectiles/projectile/bullets/shotgun.dm
@@ -1,23 +1,26 @@
/obj/item/projectile/bullet/shotgun_slug
name = "12g shotgun slug"
- damage = 60
+ damage = 50
+ sharpness = SHARP_POINTY
+ wound_bonus = 0
/obj/item/projectile/bullet/shotgun_slug/executioner
name = "executioner slug" // admin only, can dismember limbs
- sharpness = TRUE
- wound_bonus = 0
+ sharpness = SHARP_EDGED
+ wound_bonus = 80
/obj/item/projectile/bullet/shotgun_slug/pulverizer
name = "pulverizer slug" // admin only, can crush bones
- sharpness = FALSE
- wound_bonus = 0
+ sharpness = SHARP_NONE
+ wound_bonus = 80
/obj/item/projectile/bullet/shotgun_beanbag
name = "beanbag slug"
damage = 10
stamina = 70
wound_bonus = 20
- sharpness = FALSE
+ sharpness = SHARP_NONE
+ embedding = null
/obj/item/projectile/bullet/incendiary/shotgun
name = "incendiary slug"
@@ -83,18 +86,22 @@
return BULLET_ACT_HIT
/obj/item/projectile/bullet/pellet
- var/tile_dropoff = 0.75
+ var/tile_dropoff = 0.45
var/tile_dropoff_s = 1.25
/obj/item/projectile/bullet/pellet/shotgun_buckshot
name = "buckshot pellet"
- damage = 12.5
- wound_bonus = -10
+ damage = 7.5
+ wound_bonus = 5
+ bare_wound_bonus = 5
+ wound_falloff_tile = -2.5 // low damage + additional dropoff will already curb wounding potential anything past point blank
/obj/item/projectile/bullet/pellet/shotgun_rubbershot
name = "rubbershot pellet"
damage = 2
stamina = 15
+ sharpness = SHARP_NONE
+ embedding = null
/obj/item/projectile/bullet/pellet/Range()
..()
@@ -106,8 +113,10 @@
qdel(src)
/obj/item/projectile/bullet/pellet/shotgun_improvised
- tile_dropoff = 0.55 //Come on it does 6 damage don't be like that.
+ tile_dropoff = 0.35 //Come on it does 6 damage don't be like that.
damage = 6
+ wound_bonus = 0
+ bare_wound_bonus = 7.5
/obj/item/projectile/bullet/pellet/shotgun_improvised/Initialize()
. = ..()
diff --git a/code/modules/projectiles/projectile/bullets/smg.dm b/code/modules/projectiles/projectile/bullets/smg.dm
index eb4c8e9776..5c9d5b92a3 100644
--- a/code/modules/projectiles/projectile/bullets/smg.dm
+++ b/code/modules/projectiles/projectile/bullets/smg.dm
@@ -3,6 +3,8 @@
/obj/item/projectile/bullet/c45
name = ".45 bullet"
damage = 30
+ wound_bonus = -10
+ wound_falloff_tile = -10
/obj/item/projectile/bullet/c45_cleaning
name = ".45 bullet"
@@ -51,11 +53,15 @@
/obj/item/projectile/bullet/c46x30mm
name = "4.6x30mm bullet"
damage = 15
+ wound_bonus = -5
+ bare_wound_bonus = 5
+ embed_falloff_tile = -4
/obj/item/projectile/bullet/c46x30mm_ap
name = "4.6x30mm armor-piercing bullet"
damage = 12.5
armour_penetration = 40
+ embedding = null
/obj/item/projectile/bullet/incendiary/c46x30mm
name = "4.6x30mm incendiary bullet"
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index 0c3de579b6..103061088e 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -217,6 +217,9 @@
/datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/M)
if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER))
M.heal_bodypart_damage(1.5,0, 0)
+ for(var/i in M.all_wounds)
+ var/datum/wound/iter_wound = i
+ iter_wound.on_xadone(2)
. = 1
else
if(M.getBruteLoss() && prob(20))
@@ -320,6 +323,83 @@
..()
. = 1
+/datum/reagent/consumable/tea/red
+ name = "Red Tea"
+ description = "Tasty red tea, helps the body digest food. Drink in moderation!"
+ color = "#101000" // rgb: 16, 16, 0
+ nutriment_factor = 0
+ taste_description = "sweet red tea"
+ glass_icon_state = "teaglass"
+ glass_name = "glass of red tea"
+ glass_desc = "A piping hot tea that helps with the digestion of food."
+
+/datum/reagent/consumable/tea/red/on_mob_life(mob/living/carbon/M)
+ if(M.nutrition > NUTRITION_LEVEL_HUNGRY)
+ M.adjust_nutrition(-3)
+ M.dizziness = max(0,M.dizziness-2)
+ M.drowsyness = max(0,M.drowsyness-1)
+ M.jitteriness = max(0,M.jitteriness-3)
+ M.adjust_bodytemperature(23 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL)
+ . = 1
+
+/datum/reagent/consumable/tea/green
+ name = "Green Tea"
+ description = "Tasty green tea, known to heal livers, it's good for you!"
+ color = "#101000" // rgb: 16, 16, 0
+ nutriment_factor = 0
+ taste_description = "tart green tea"
+ glass_icon_state = "teaglass"
+ glass_name = "glass of tea"
+ glass_desc = "A calming glass of green tea to help get you through the day."
+
+/datum/reagent/consumable/tea/green/on_mob_life(mob/living/carbon/M)
+ M.adjustOrganLoss(ORGAN_SLOT_LIVER, -0.5) //Detox!
+ M.dizziness = max(0,M.dizziness-2)
+ M.drowsyness = max(0,M.drowsyness-1)
+ M.jitteriness = max(0,M.jitteriness-3)
+ M.adjust_bodytemperature(15 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL)
+ . = 1
+
+/datum/reagent/consumable/tea/forest
+ name = "Forest Tea"
+ description = "Tea mixed with honey, has both antitoxins and sweetness in one!"
+ color = "#101000" // rgb: 16, 16, 0
+ nutriment_factor = 0
+ quality = DRINK_NICE
+ taste_description = "sweet tea"
+ glass_icon_state = "teaglass"
+ glass_name = "glass of forest tea"
+ glass_desc = "A lovely glass of tea and honey."
+
+/datum/reagent/consumable/tea/forest/on_mob_life(mob/living/carbon/M)
+ if(M.getToxLoss() && prob(40))//Two anti-toxins working here
+ M.adjustToxLoss(-1, 0, TRUE) //heals TOXINLOVERs
+ //Reminder that honey heals toxin lovers
+ M.dizziness = max(0,M.dizziness-2)
+ M.drowsyness = max(0,M.drowsyness-1)
+ M.jitteriness = max(0,M.jitteriness-3)
+ M.adjust_bodytemperature(15 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL)
+ . = 1
+
+/datum/reagent/consumable/tea/mush
+ name = "Mush Tea"
+ description = "Tea mixed with mushroom hallucinogen, used for fun rides or self reflection."
+ color = "#101000" // rgb: 16, 16, 0
+ nutriment_factor = 0
+ quality = DRINK_NICE
+ taste_description = "fungal infections"
+ glass_icon_state = "teaglass"
+ glass_name = "glass of mush tea"
+ glass_desc = "A cold merky brown tea."
+
+/datum/reagent/consumable/tea/mush/on_mob_life(mob/living/carbon/M)
+ M.set_drugginess(20) //Little better then space drugs
+ if(prob(20))
+ M.Dizzy(10)
+ if(prob(10))
+ M.disgust = 0
+ . = 1
+
/datum/reagent/consumable/lemonade
name = "Lemonade"
description = "Sweet, tangy lemonade. Good for the soul."
@@ -1013,4 +1093,23 @@
if(M.getToxLoss() && prob(30))
M.adjustToxLoss(-1, 0)
..()
- . = TRUE
\ No newline at end of file
+ . = TRUE
+
+// i googled "natural coagulant" and a couple of results came up for banana peels, so after precisely 30 more seconds of research, i now dub grinding banana peels good for your blood
+/datum/reagent/consumable/banana_peel
+ name = "Pulped Banana Peel"
+ description = "Okay, so you put a banana peel in a grinder... Why, exactly?"
+ color = "#863333" // rgb: 175, 175, 0
+ reagent_state = SOLID
+ taste_description = "stringy, bitter pulp"
+ glass_name = "glass of banana peel pulp"
+ glass_desc = "Okay, so you put a banana peel in a grinder... Why, exactly?"
+
+/datum/reagent/consumable/baked_banana_peel
+ name = "Baked Banana Peel Powder"
+ description = "You took a banana peel... pulped it... baked it... Where are you going with this?"
+ color = "#863333" // rgb: 175, 175, 0
+ reagent_state = SOLID
+ taste_description = "bitter powder"
+ glass_name = "glass of banana peel powder"
+ description = "You took a banana peel... pulped it... baked it... Where are you going with this?"
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 050b1f29b5..8bb34c0a82 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -145,8 +145,8 @@
M.adjustToxLoss(-power, 0, TRUE) //heals TOXINLOVERs
M.adjustCloneLoss(-power, 0)
for(var/i in M.all_wounds)
- var/datum/wound/W = i
- W.on_xadone(power)
+ var/datum/wound/iter_wound = i
+ iter_wound.on_xadone(power)
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration
. = 1
metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5)
@@ -196,8 +196,8 @@
M.adjustToxLoss(-power, 0, TRUE)
M.adjustCloneLoss(-power, 0)
for(var/i in M.all_wounds)
- var/datum/wound/W = i
- W.on_xadone(power)
+ var/datum/wound/iter_wound = i
+ iter_wound.on_xadone(power)
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC)
. = 1
..()
@@ -365,7 +365,7 @@
/datum/reagent/medicine/salglu_solution
name = "Saline-Glucose Solution"
- description = "Has a 33% chance per metabolism cycle to heal brute and burn damage. Can be used as a temporary blood substitute."
+ description = "Has a 33% chance per metabolism cycle to heal brute and burn damage. Can be used as a temporary blood substitute, as well as slowly speeding blood regeneration."
reagent_state = LIQUID
color = "#DCDCDC"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
@@ -373,6 +373,7 @@
taste_description = "sweetness and salt"
var/last_added = 0
var/maximum_reachable = BLOOD_VOLUME_NORMAL - 10 //So that normal blood regeneration can continue with salglu active
+ var/extra_regen = 0.25 // in addition to acting as temporary blood, also add this much to their actual blood per tick
pH = 5.5
/datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/carbon/M)
@@ -385,7 +386,7 @@
var/amount_to_add = min(M.blood_volume, volume*5)
var/new_blood_level = min(M.blood_volume + amount_to_add, maximum_reachable)
last_added = new_blood_level - M.blood_volume
- M.blood_volume = new_blood_level
+ M.blood_volume = new_blood_level + extra_regen
if(prob(33))
M.adjustBruteLoss(-0.5*REM, 0)
M.adjustFireLoss(-0.5*REM, 0)
@@ -471,8 +472,9 @@
else if(method in list(PATCH, TOUCH))
M.adjustBruteLoss(-1 * reac_volume)
M.adjustFireLoss(-1 * reac_volume)
- for(var/datum/wound/burn/burn_wound in C.all_wounds)
- burn_wound.regenerate_flesh(reac_volume)
+ for(var/i in C.all_wounds)
+ var/datum/wound/iter_wound = i
+ iter_wound.on_synthflesh(reac_volume)
if(show_message)
to_chat(M, "You feel your burns and bruises healing! It stings like hell!")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
@@ -1592,10 +1594,56 @@
to_chat(C, "[pick(GLOB.wisdoms)]") //give them a random wisdom
..()
-// handled in cut wounds process
+// helps bleeding wounds clot faster
/datum/reagent/medicine/coagulant
name = "Sanguirite"
- description = "A coagulant used to help open cuts clot faster."
+ description = "A proprietary coagulant used to help bleeding wounds clot faster."
reagent_state = LIQUID
color = "#bb2424"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
+ overdose_threshold = 20
+ /// How much base clotting we do per bleeding wound, multiplied by the below number for each bleeding wound
+ var/clot_rate = 0.25
+ /// If we have multiple bleeding wounds, we count the number of bleeding wounds, then multiply the clot rate by this^(n) before applying it to each cut, so more cuts = less clotting per cut (though still more total clotting)
+ var/clot_coeff_per_wound = 0.9
+
+/datum/reagent/medicine/coagulant/on_mob_life(mob/living/carbon/M)
+ . = ..()
+ if(!M.blood_volume || !M.all_wounds)
+ return
+
+ var/effective_clot_rate = clot_rate
+
+ for(var/i in M.all_wounds)
+ var/datum/wound/iter_wound = i
+ if(iter_wound.blood_flow)
+ effective_clot_rate *= clot_coeff_per_wound
+
+ for(var/i in M.all_wounds)
+ var/datum/wound/iter_wound = i
+ iter_wound.blood_flow = max(0, iter_wound.blood_flow - effective_clot_rate)
+
+/datum/reagent/medicine/coagulant/overdose_process(mob/living/M)
+ . = ..()
+ if(!M.blood_volume)
+ return
+
+ if(prob(15))
+ M.losebreath += rand(2,4)
+ M.adjustOxyLoss(rand(1,3))
+ if(prob(30))
+ to_chat(M, "You can feel your blood clotting up in your veins!")
+ else if(prob(10))
+ to_chat(M, "You feel like your blood has stopped moving!")
+ if(prob(50))
+ var/obj/item/organ/lungs/our_lungs = M.getorganslot(ORGAN_SLOT_LUNGS)
+ our_lungs.applyOrganDamage(1)
+ else
+ var/obj/item/organ/heart/our_heart = M.getorganslot(ORGAN_SLOT_HEART)
+ our_heart.applyOrganDamage(1)
+
+// can be synthesized on station rather than bought. made by grinding a banana peel, heating it up, then mixing the banana peel powder with salglu
+/datum/reagent/medicine/coagulant/weak
+ name = "Synthi-Sanguirite"
+ description = "A synthetic coagulant used to help bleeding wounds clot faster. Not quite as effective as name brand Sanguirite, especially on patients with lots of cuts."
+ clot_coeff_per_wound = 0.8
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 99e1f1481b..81ad676613 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -244,6 +244,11 @@
glass_desc = "The father of all refreshments."
shot_glass_icon_state = "shotglassclear"
+/datum/reagent/water/on_mob_life(mob/living/carbon/M)
+ . = ..()
+ if(M.blood_volume)
+ M.blood_volume += 0.1 // water is good for you!
+
/*
* Water reaction to turf
*/
@@ -334,6 +339,8 @@
return ..()
/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)
+ if(M.blood_volume)
+ M.blood_volume += 0.1 // water is good for you!
if(!data)
data = list("misc" = 1)
data["misc"]++
@@ -2304,6 +2311,7 @@
metabolization_rate = 0.75 * REAGENTS_METABOLISM // 5u (WOUND_DETERMINATION_CRITICAL) will last for ~17 ticks
/// Whether we've had at least WOUND_DETERMINATION_SEVERE (2.5u) of determination at any given time. No damage slowdown immunity or indication we're having a second wind if it's just a single moderate wound
var/significant = FALSE
+ self_consuming = TRUE
/datum/reagent/determination/on_mob_end_metabolize(mob/living/carbon/M)
if(significant)
@@ -2337,7 +2345,6 @@
color = "#E6E6DA"
taste_mult = 0
-
/datum/reagent/hairball
name = "Hairball"
description = "A bundle of keratinous bits and fibers, not easily digestible."
@@ -2385,4 +2392,4 @@
M.reagents.del_reagent(/datum/reagent/hairball)
return
..()
-
+
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index 7da734e9c4..8dca028b4a 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -373,6 +373,14 @@
pH = 4.9
value = REAGENT_VALUE_VERY_COMMON
+/datum/reagent/toxin/teapowder/red
+ name = "Ground Red Tea Leaves"
+ toxpwr = 0.4
+
+/datum/reagent/toxin/teapowder/green
+ name = "Ground Green Tea Leaves"
+ toxpwr = 0.6
+
/datum/reagent/toxin/mutetoxin //the new zombie powder.
name = "Mute Toxin"
description = "A nonlethal poison that inhibits speech in its victim."
diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm
index e591daeb8e..bb9a951cac 100644
--- a/code/modules/reagents/chemistry/recipes/medicine.dm
+++ b/code/modules/reagents/chemistry/recipes/medicine.dm
@@ -50,6 +50,18 @@
results = list(/datum/reagent/medicine/salglu_solution = 3)
required_reagents = list(/datum/reagent/consumable/sodiumchloride = 1, /datum/reagent/water = 1, /datum/reagent/consumable/sugar = 1)
+/datum/chemical_reaction/baked_banana_peel
+ results = list(/datum/reagent/consumable/baked_banana_peel = 1)
+ required_temp = 413.15 // if it's good enough for caramel it's good enough for this
+ required_reagents = list(/datum/reagent/consumable/banana_peel = 1)
+ mix_message = "The pulp dries up and takes on a powdery state!"
+ mob_react = FALSE
+
+/datum/chemical_reaction/coagulant_weak
+ results = list(/datum/reagent/medicine/coagulant/weak = 3)
+ required_reagents = list(/datum/reagent/medicine/salglu_solution = 2, /datum/reagent/consumable/baked_banana_peel = 1)
+ mob_react = FALSE
+
/datum/chemical_reaction/mine_salve
name = "Miner's Salve"
id = /datum/reagent/medicine/mine_salve
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index 27db55d7af..835ffe2d89 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -135,11 +135,18 @@
/obj/item/reagent_containers/hypospray/medipen/ekit
name = "emergency first-aid autoinjector"
- desc = "An epinephrine medipen with trace amounts of coagulants and antibiotics to help stabilize bad cuts and burns."
+ desc = "An epinephrine medipen with extra coagulant and antibiotics to help stabilize bad cuts and burns."
volume = 15
amount_per_transfer_from_this = 15
list_reagents = list(/datum/reagent/medicine/epinephrine = 12, /datum/reagent/medicine/coagulant = 2.5, /datum/reagent/medicine/spaceacillin = 0.5)
+/obj/item/reagent_containers/hypospray/medipen/blood_loss
+ name = "hypovolemic-response autoinjector"
+ desc = "A medipen designed to stabilize and rapidly reverse severe bloodloss."
+ volume = 15
+ amount_per_transfer_from_this = 15
+ list_reagents = list(/datum/reagent/medicine/epinephrine = 5, /datum/reagent/medicine/coagulant = 2.5, /datum/reagent/iron = 3.5, /datum/reagent/medicine/salglu_solution = 4)
+
/obj/item/reagent_containers/hypospray/medipen/stimulants
name = "illegal stimpack medipen"
desc = "A highly illegal medipen due to its load and small injections, allow for five uses before being drained"
diff --git a/code/modules/reagents/reagent_containers/medspray.dm b/code/modules/reagents/reagent_containers/medspray.dm
index 02a3f987bc..40ad167531 100644
--- a/code/modules/reagents/reagent_containers/medspray.dm
+++ b/code/modules/reagents/reagent_containers/medspray.dm
@@ -32,6 +32,9 @@
to_chat(user, "You will now apply the medspray's contents in [squirt_mode ? "short bursts":"extended sprays"]. You'll now use [amount_per_transfer_from_this] units per use.")
/obj/item/reagent_containers/medspray/attack(mob/living/L, mob/user, def_zone)
+ INVOKE_ASYNC(src, .proc/attempt_spray, L, user, def_zone) // this is shitcode because the params for attack aren't even right but i'm not in the mood to refactor right now.
+
+/obj/item/reagent_containers/medspray/proc/attempt_spray(mob/living/L, mob/user, def_zone)
if(!reagents || !reagents.total_volume)
to_chat(user, "[src] is empty!")
return
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index 0220802c3e..f42ae668c7 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -16,6 +16,7 @@
custom_materials = list(/datum/material/iron=10, /datum/material/glass=20)
reagent_flags = TRANSPARENT
custom_price = PRICE_CHEAP_AS_FREE
+ sharpness = SHARP_POINTY
/obj/item/reagent_containers/syringe/Initialize()
. = ..()
@@ -52,6 +53,9 @@
/obj/item/reagent_containers/syringe/attackby(obj/item/I, mob/user, params)
return
+/obj/item/reagent_containers/syringe/attack()
+ return // no bludgeoning.
+
/obj/item/reagent_containers/syringe/afterattack(atom/target, mob/user, proximity)
. = ..()
INVOKE_ASYNC(src, .proc/attempt_inject, target, user, proximity)
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 64fe786219..ba4870903e 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -375,7 +375,6 @@
log_combat(user, target, "shoved", "into [src] (disposal bin)")
return TRUE
-
/obj/machinery/disposal/bin/flush()
..()
full_pressure = FALSE
diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm
index 440e6cb03b..0076f584e9 100644
--- a/code/modules/shuttle/syndicate.dm
+++ b/code/modules/shuttle/syndicate.dm
@@ -1,4 +1,4 @@
-#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes
+#define SYNDICATE_CHALLENGE_TIMER 9000 // 15 minutes
/obj/machinery/computer/shuttle/syndicate
name = "syndicate shuttle terminal"
@@ -21,8 +21,8 @@
/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list)
if(href_list["move"])
var/obj/item/circuitboard/computer/syndicate_shuttle/board = circuit
- if(board.challenge && world.time < SYNDICATE_CHALLENGE_TIMER)
- to_chat(usr, "You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - world.time)] more to allow them to prepare.")
+ if(board.challenge && ((world.time - SSticker.round_start_time) < SYNDICATE_CHALLENGE_TIMER))
+ to_chat(usr, "You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - (world.time - SSticker.round_start_time))] more to allow them to prepare.")
return 0
board.moved = TRUE
..()
diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm
index 07c80322ae..3d88282937 100644
--- a/code/modules/surgery/bodyparts/_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/_bodyparts.dm
@@ -86,12 +86,12 @@
/// A hat won't cover your face, but a shirt covering your chest will cover your... you know, chest
var/scars_covered_by_clothes = TRUE
- /// Descriptions for the locations on the limb for scars to be assigned, just cosmetic
- var/list/specific_locations = list("general area")
/// So we know if we need to scream if this limb hits max damage
var/last_maxed
/// How much generic bleedstacks we have on this bodypart
var/generic_bleedstacks
+ /// If we have a gauze wrapping currently applied (not including splints)
+ var/obj/item/stack/current_gauze
/obj/item/bodypart/examine(mob/user)
. = ..()
@@ -151,8 +151,20 @@
var/turf/T = get_turf(src)
if(status != BODYPART_ROBOTIC)
playsound(T, 'sound/misc/splort.ogg', 50, 1, -1)
- for(var/obj/item/I in src)
- I.forceMove(T)
+ if(current_gauze)
+ QDEL_NULL(current_gauze)
+ for(var/obj/item/organ/drop_organ in get_organs())
+ drop_organ.transfer_to_limb(src, owner)
+
+///since organs aren't actually stored in the bodypart themselves while attached to a person, we have to query the owner for what we should have
+/obj/item/bodypart/proc/get_organs()
+ if(!owner)
+ return
+ . = list()
+ for(var/i in owner.internal_organs) //internal organs inside the dismembered limb are dropped.
+ var/obj/item/organ/organ_check = i
+ if(check_zone(organ_check.zone) == body_zone)
+ . += organ_check
/obj/item/bodypart/proc/consider_processing()
if(stamina_dam > DAMAGE_PRECISION)
@@ -171,7 +183,7 @@
//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all.
//Damage will not exceed max_damage using this proc
//Cannot apply negative damage
-/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, blocked = 0, updating_health = TRUE, required_status = null, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) // maybe separate BRUTE_SHARP and BRUTE_OTHER eventually somehow hmm
+/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, blocked = 0, updating_health = TRUE, required_status = null, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE) // maybe separate BRUTE_SHARP and BRUTE_OTHER eventually somehow hmm
if(owner && (owner.status_flags & GODMODE))
return FALSE //godmode
var/dmg_mlt = CONFIG_GET(number/damage_multiplier)
@@ -192,16 +204,64 @@
if(ALIEN_BODYPART,LARVA_BODYPART) //aliens take some additional burn //nothing can burn with so much snowflake code around
burn *= 1.2
- var/wounding_type = (brute > burn ? WOUND_BRUTE : WOUND_BURN)
+ /*
+ // START WOUND HANDLING
+ */
+
+ // what kind of wounds we're gonna roll for, take the greater between brute and burn, then if it's brute, we subdivide based on sharpness
+ var/wounding_type = (brute > burn ? WOUND_BLUNT : WOUND_BURN)
var/wounding_dmg = max(brute, burn)
- if(wounding_type == WOUND_BRUTE && sharpness)
- wounding_type = WOUND_SHARP
- // i know this is effectively the same check as above but i don't know if those can null the damage by rounding and want to be safe
- if(owner && wounding_dmg > 4 && wound_bonus != CANT_WOUND)
- // if you want to make tox wounds or some other type, this will need to be expanded and made more modular
- // handle all our wounding stuff
+ var/mangled_state = get_mangled_state()
+ var/bio_state = owner.get_biological_state()
+ var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%)
+
+ if(wounding_type == WOUND_BLUNT)
+ if(sharpness == SHARP_EDGED)
+ wounding_type = WOUND_SLASH
+ else if(sharpness == SHARP_POINTY)
+ wounding_type = WOUND_PIERCE
+
+ //Handling for bone only/flesh only(none right now)/flesh and bone targets
+ switch(bio_state)
+ // if we're bone only, all cutting attacks go straight to the bone
+ if(BIO_JUST_BONE)
+ if(wounding_type == WOUND_SLASH)
+ wounding_type = WOUND_BLUNT
+ wounding_dmg *= (easy_dismember ? 1 : 0.5)
+ else if(wounding_type == WOUND_PIERCE)
+ wounding_type = WOUND_BLUNT
+ wounding_dmg *= (easy_dismember ? 1 : 0.75)
+ if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
+ return
+ // note that there's no handling for BIO_JUST_FLESH since we don't have any that are that right now (slimepeople maybe someday)
+ // standard humanoids
+ if(BIO_FLESH_BONE)
+ // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate
+ // So a big sharp weapon is still all you need to destroy a limb
+ if(mangled_state == BODYPART_MANGLED_FLESH && sharpness)
+ playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
+ if(wounding_type == WOUND_SLASH && !easy_dismember)
+ wounding_dmg *= 0.5 // edged weapons pass along 50% of their wounding damage to the bone since the power is spread out over a larger area
+ if(wounding_type == WOUND_PIERCE && !easy_dismember)
+ wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated
+ wounding_type = WOUND_BLUNT
+ else if(mangled_state == BODYPART_MANGLED_BOTH && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
+ return
+
+ // now we have our wounding_type and are ready to carry on with wounds and dealing the actual damage
+ if(owner && wounding_dmg >= WOUND_MINIMUM_DAMAGE && wound_bonus != CANT_WOUND)
check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)
+ for(var/i in wounds)
+ var/datum/wound/iter_wound = i
+ iter_wound.receive_damage(wounding_type, wounding_dmg, wound_bonus)
+
+ /*
+ // END WOUND HANDLING
+ */
+
+ //back to our regularly scheduled program, we now actually apply damage if there's room below limb damage cap
+
var/can_inflict = max_damage - get_damage()
var/total_damage = brute + burn
@@ -213,10 +273,6 @@
if(can_inflict <= 0)
return FALSE
- for(var/i in wounds)
- var/datum/wound/W = i
- W.receive_damage(wounding_type, wounding_dmg, wound_bonus)
-
brute_dam += brute
burn_dam += burn
@@ -236,14 +292,58 @@
update_disabled()
return update_bodypart_damage_state()
+/// Allows us to roll for and apply a wound without actually dealing damage. Used for aggregate wounding power with pellet clouds
+/obj/item/bodypart/proc/painless_wound_roll(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus, sharpness=SHARP_NONE)
+ if(!owner || phantom_wounding_dmg <= WOUND_MINIMUM_DAMAGE || wound_bonus == CANT_WOUND)
+ return
+
+ var/mangled_state = get_mangled_state()
+ var/bio_state = owner.get_biological_state()
+ var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%)
+
+ if(wounding_type == WOUND_BLUNT)
+ if(sharpness == SHARP_EDGED)
+ wounding_type = WOUND_SLASH
+ else if(sharpness == SHARP_POINTY)
+ wounding_type = WOUND_PIERCE
+
+ //Handling for bone only/flesh only(none right now)/flesh and bone targets
+ switch(bio_state)
+ // if we're bone only, all cutting attacks go straight to the bone
+ if(BIO_JUST_BONE)
+ if(wounding_type == WOUND_SLASH)
+ wounding_type = WOUND_BLUNT
+ phantom_wounding_dmg *= (easy_dismember ? 1 : 0.5)
+ else if(wounding_type == WOUND_PIERCE)
+ wounding_type = WOUND_BLUNT
+ phantom_wounding_dmg *= (easy_dismember ? 1 : 0.75)
+ if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus))
+ return
+ // note that there's no handling for BIO_JUST_FLESH since we don't have any that are that right now (slimepeople maybe someday)
+ // standard humanoids
+ if(BIO_FLESH_BONE)
+ // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate
+ // So a big sharp weapon is still all you need to destroy a limb
+ if(mangled_state == BODYPART_MANGLED_FLESH && sharpness)
+ playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
+ if(wounding_type == WOUND_SLASH && !easy_dismember)
+ phantom_wounding_dmg *= 0.5 // edged weapons pass along 50% of their wounding damage to the bone since the power is spread out over a larger area
+ if(wounding_type == WOUND_PIERCE && !easy_dismember)
+ phantom_wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated
+ wounding_type = WOUND_BLUNT
+ else if(mangled_state == BODYPART_MANGLED_BOTH && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus))
+ return
+
+ check_wounding(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus)
+
/**
* check_wounding() is where we handle rolling for, selecting, and applying a wound if we meet the criteria
*
- * We generate a "score" for how woundable the attack was based on the damage and other factors discussed in [check_wounding_mods()], then go down the list from most severe to least severe wounds in that category.
+ * We generate a "score" for how woundable the attack was based on the damage and other factors discussed in [/obj/item/bodypart/proc/check_wounding_mods], then go down the list from most severe to least severe wounds in that category.
* We can promote a wound from a lesser to a higher severity this way, but we give up if we have a wound of the given type and fail to roll a higher severity, so no sidegrades/downgrades
*
* Arguments:
- * * woundtype- Either WOUND_SHARP, WOUND_BRUTE, or WOUND_BURN based on the attack type.
+ * * woundtype- Either WOUND_BLUNT, WOUND_SLASH, WOUND_PIERCE, or WOUND_BURN based on the attack type.
* * damage- How much damage is tied to this attack, since wounding potential scales with damage in an attack (see: WOUND_DAMAGE_EXPONENT)
* * wound_bonus- The wound_bonus of an attack
* * bare_wound_bonus- The bare_wound_bonus of an attack
@@ -252,19 +352,24 @@
// actually roll wounds if applicable
if(HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE))
damage *= 1.5
+ else
+ damage = min(damage, WOUND_MAX_CONSIDERED_DAMAGE)
- var/base_roll = rand(1, round(damage ** WOUND_DAMAGE_EXPONENT))
+ var/base_roll = rand(max(damage/1.5,25), round(damage ** WOUND_DAMAGE_EXPONENT))
var/injury_roll = base_roll
injury_roll += check_woundings_mods(woundtype, damage, wound_bonus, bare_wound_bonus)
- var/list/wounds_checking
+ var/list/wounds_checking = GLOB.global_wound_types[woundtype]
- switch(woundtype)
- if(WOUND_SHARP)
- wounds_checking = WOUND_LIST_CUT
- if(WOUND_BRUTE)
- wounds_checking = WOUND_LIST_BONE
- if(WOUND_BURN)
- wounds_checking = WOUND_LIST_BURN
+ // quick re-check to see if bare_wound_bonus applies, for the benefit of log_wound(), see about getting the check from check_woundings_mods() somehow
+ if(ishuman(owner))
+ var/mob/living/carbon/human/human_wearer = owner
+ var/list/clothing = human_wearer.clothingonpart(src)
+ for(var/i in clothing)
+ var/obj/item/clothing/clothes_check = i
+ // unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary
+ if(clothes_check.armor.getRating("wound"))
+ bare_wound_bonus = 0
+ break
//cycle through the wounds of the relevant category from the most severe down
for(var/PW in wounds_checking)
@@ -279,21 +384,22 @@
replaced_wound = existing_wound
if(initial(possible_wound.threshold_minimum) < injury_roll)
+ var/datum/wound/new_wound
if(replaced_wound)
- var/datum/wound/new_wound = replaced_wound.replace_wound(possible_wound)
- log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll)
+ new_wound = replaced_wound.replace_wound(possible_wound)
+ log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll) // dismembering wounds are logged in the apply_wound() for loss wounds since they delete themselves immediately, these will be immediately returned
else
- var/datum/wound/new_wound = new possible_wound
+ new_wound = new possible_wound
new_wound.apply_wound(src)
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll)
- return
+ return new_wound
// try forcing a specific wound, but only if there isn't already a wound of that severity or greater for that type on this bodypart
/obj/item/bodypart/proc/force_wound_upwards(specific_woundtype, smited = FALSE)
var/datum/wound/potential_wound = specific_woundtype
for(var/i in wounds)
var/datum/wound/existing_wound = i
- if(existing_wound.type in (initial(potential_wound.wound_type)))
+ if(existing_wound.wound_type == initial(potential_wound.wound_type))
if(existing_wound.severity < initial(potential_wound.severity)) // we only try if the existing one is inferior to the one we're trying to force
existing_wound.replace_wound(potential_wound, smited)
return
@@ -301,12 +407,20 @@
var/datum/wound/new_wound = new potential_wound
new_wound.apply_wound(src, smited = smited)
+/**
+ * check_wounding_mods() is where we handle the various modifiers of a wound roll
+ *
+ * A short list of things we consider: any armor a human target may be wearing, and if they have no wound armor on the limb, if we have a bare_wound_bonus to apply, plus the plain wound_bonus
+ * We also flick through all of the wounds we currently have on this limb and add their threshold penalties, so that having lots of bad wounds makes you more liable to get hurt worse
+ * Lastly, we add the inherent wound_resistance variable the bodypart has (heads and chests are slightly harder to wound), and a small bonus if the limb is already disabled
+ *
+ * Arguments:
+ * * It's the same ones on [receive_damage]
+ */
/obj/item/bodypart/proc/check_woundings_mods(wounding_type, damage, wound_bonus, bare_wound_bonus)
var/armor_ablation = 0
var/injury_mod = 0
- //var/bwb = 0
-
if(owner && ishuman(owner))
var/mob/living/carbon/human/H = owner
var/list/clothing = H.clothingonpart(src)
@@ -314,7 +428,7 @@
var/obj/item/clothing/C = c
// unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary
armor_ablation += C.armor.getRating("wound")
- if(wounding_type == WOUND_SHARP)
+ if(wounding_type == WOUND_SLASH)
C.take_damage_zone(body_zone, damage, BRUTE, armour_penetration)
else if(wounding_type == WOUND_BURN && damage >= 10) // lazy way to block freezing from shredding clothes without adding another var onto apply_damage()
C.take_damage_zone(body_zone, damage, BURN, armour_penetration)
@@ -330,7 +444,7 @@
injury_mod += W.threshold_penalty
var/part_mod = -wound_resistance
- if(is_disabled())
+ if(get_damage(TRUE) >= max_damage)
part_mod += disabled_wound_penalty
injury_mod += part_mod
@@ -383,11 +497,11 @@
return BODYPART_DISABLED_WOUND
if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NODISMEMBER))
. = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled
- if((get_damage(TRUE) >= max_damage) || (HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE) && (get_damage(TRUE) >= (max_damage * 0.6)))) //Easy limb disable disables the limb at 40% health instead of 0%
+ if(get_damage(TRUE) >= max_damage * (HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE) ? 0.6 : 1)) //Easy limb disable disables the limb at 40% health instead of 0%
if(!last_maxed)
owner.emote("scream")
last_maxed = TRUE
- if(!is_organic_limb())
+ if(!is_organic_limb() || stamina_dam >= max_damage)
return BODYPART_DISABLED_DAMAGE
else if(disabled && (get_damage(TRUE) <= (max_damage * 0.8))) // reenabled at 80% now instead of 50% as of wounds update
last_maxed = FALSE
@@ -741,17 +855,29 @@
/obj/item/bodypart/proc/get_wound_type(checking_type)
if(isnull(wounds))
return
- for(var/thing in wounds)
- var/datum/wound/W = thing
- if(istype(W, checking_type))
- return W
+ for(var/i in wounds)
+ if(istype(i, checking_type))
+ return i
-/// very rough start for updating efficiency and other stats on a body part whenever a wound is gained/lost
-/obj/item/bodypart/proc/update_wounds()
+/**
+ * update_wounds() is called whenever a wound is gained or lost on this bodypart, as well as if there's a change of some kind on a bone wound possibly changing disabled status
+ *
+ * Covers tabulating the damage multipliers we have from wounds (burn specifically), as well as deleting our gauze wrapping if we don't have any wounds that can use bandaging
+ *
+ * Arguments:
+ * * replaced- If true, this is being called from the remove_wound() of a wound that's being replaced, so the bandage that already existed is still relevant, but the new wound hasn't been added yet
+ */
+/obj/item/bodypart/proc/update_wounds(replaced = FALSE)
var/dam_mul = 1 //initial(wound_damage_multiplier)
// we can only have one wound per type, but remember there's multiple types
- for(var/datum/wound/W in wounds)
- dam_mul *= W.damage_mulitplier_penalty
+ // we can (normally) only have one wound per type, but remember there's multiple types (smites like :B:loodless can generate multiple cuts on a limb)
+ for(var/i in wounds)
+ var/datum/wound/iter_wound = i
+ dam_mul *= iter_wound.damage_mulitplier_penalty
+
+ if(!LAZYLEN(wounds) && current_gauze && !replaced)
+ owner.visible_message("\The [current_gauze] on [owner]'s [name] fall away.", "The [current_gauze] on your [name] fall away.")
+ QDEL_NULL(current_gauze)
wound_damage_multiplier = dam_mul
update_disabled()
@@ -761,8 +887,6 @@
var/bleed_rate = 0
if(generic_bleedstacks > 0)
bleed_rate++
- if(brute_dam >= 40)
- bleed_rate += (brute_dam * 0.008)
//We want an accurate reading of .len
listclearnulls(embedded_objects)
@@ -773,5 +897,40 @@
for(var/thing in wounds)
var/datum/wound/W = thing
bleed_rate += W.blood_flow
-
+ if(owner.mobility_flags & ~MOBILITY_STAND)
+ bleed_rate *= 0.75
return bleed_rate
+
+/**
+ * apply_gauze() is used to- well, apply gauze to a bodypart
+ *
+ * As of the Wounds 2 PR, all bleeding is now bodypart based rather than the old bleedstacks system, and 90% of standard bleeding comes from flesh wounds (the exception is embedded weapons).
+ * The same way bleeding is totaled up by bodyparts, gauze now applies to all wounds on the same part. Thus, having a slash wound, a pierce wound, and a broken bone wound would have the gauze
+ * applying blood staunching to the first two wounds, while also acting as a sling for the third one. Once enough blood has been absorbed or all wounds with the ACCEPTS_GAUZE flag have been cleared,
+ * the gauze falls off.
+ *
+ * Arguments:
+ * * gauze- Just the gauze stack we're taking a sheet from to apply here
+ */
+/obj/item/bodypart/proc/apply_gauze(obj/item/stack/gauze)
+ if(!istype(gauze) || !gauze.absorption_capacity)
+ return
+ QDEL_NULL(current_gauze)
+ current_gauze = new gauze.type(src, 1)
+ gauze.use(1)
+
+/**
+ * seep_gauze() is for when a gauze wrapping absorbs blood or pus from wounds, lowering its absorption capacity.
+ *
+ * The passed amount of seepage is deducted from the bandage's absorption capacity, and if we reach a negative absorption capacity, the bandages fall off and we're left with nothing.
+ *
+ * Arguments:
+ * * seep_amt - How much absorption capacity we're removing from our current bandages (think, how much blood or pus are we soaking up this tick?)
+ */
+/obj/item/bodypart/proc/seep_gauze(seep_amt = 0)
+ if(!current_gauze)
+ return
+ current_gauze.absorption_capacity -= seep_amt
+ if(current_gauze.absorption_capacity < 0)
+ owner.visible_message("\The [current_gauze] on [owner]'s [name] fall away in rags.", "\The [current_gauze] on your [name] fall away in rags.", vision_distance=COMBAT_MESSAGE_RANGE)
+ QDEL_NULL(current_gauze)
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 2ce6ca8862..fa003e3f3c 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -4,7 +4,7 @@
return TRUE
//Dismember a limb
-/obj/item/bodypart/proc/dismember(dam_type = BRUTE)
+/obj/item/bodypart/proc/dismember(dam_type = BRUTE, silent=TRUE)
if(!owner)
return FALSE
var/mob/living/carbon/C = owner
@@ -16,7 +16,8 @@
return FALSE
var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST)
affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50), wound_bonus=CANT_WOUND) //Damage the chest based on limb's existing damage
- C.visible_message("[C]'s [src.name] has been violently dismembered!")
+ if(!silent)
+ C.visible_message("[C]'s [name] is violently dismembered!")
C.emote("scream")
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
drop_limb()
@@ -30,6 +31,7 @@
burn()
return TRUE
add_mob_blood(C)
+ C.bleed(rand(20, 40))
var/direction = pick(GLOB.cardinals)
var/t_range = rand(2,max(throw_range/2, 2))
var/turf/target_turf = get_turf(src)
@@ -80,8 +82,6 @@
if(organ_spilled)
C.visible_message("[C]'s internal organs spill out onto the floor!")
-
-
//limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in.
/obj/item/bodypart/proc/drop_limb(special, dismembered)
if(!owner)
@@ -153,7 +153,52 @@
forceMove(Tsec)
+/**
+ * get_mangled_state() is relevant for flesh and bone bodyparts, and returns whether this bodypart has mangled skin, mangled bone, or both (or neither i guess)
+ *
+ * Dismemberment for flesh and bone requires the victim to have the skin on their bodypart destroyed (either a critical cut or piercing wound), and at least a hairline fracture
+ * (severe bone), at which point we can start rolling for dismembering. The attack must also deal at least 10 damage, and must be a brute attack of some kind (sorry for now, cakehat, maybe later)
+ *
+ * Returns: BODYPART_MANGLED_NONE if we're fine, BODYPART_MANGLED_FLESH if our skin is broken, BODYPART_MANGLED_BONE if our bone is broken, or BODYPART_MANGLED_BOTH if both are broken and we're up for dismembering
+ */
+/obj/item/bodypart/proc/get_mangled_state()
+ . = BODYPART_MANGLED_NONE
+ for(var/i in wounds)
+ var/datum/wound/iter_wound = i
+ if((iter_wound.wound_flags & MANGLES_BONE))
+ . |= BODYPART_MANGLED_BONE
+ if((iter_wound.wound_flags & MANGLES_FLESH))
+ . |= BODYPART_MANGLED_FLESH
+
+/**
+ * try_dismember() is used, once we've confirmed that a flesh and bone bodypart has both the skin and bone mangled, to actually roll for it
+ *
+ * Mangling is described in the above proc, [/obj/item/bodypart/proc/get_mangled_state()]. This simply makes the roll for whether we actually dismember or not
+ * using how damaged the limb already is, and how much damage this blow was for. If we have a critical bone wound instead of just a severe, we add +10% to the roll.
+ * Lastly, we choose which kind of dismember we want based on the wounding type we hit with. Note we don't care about all the normal mods or armor for this
+ *
+ * Arguments:
+ * * wounding_type: Either WOUND_BLUNT, WOUND_SLASH, or WOUND_PIERCE, basically only matters for the dismember message
+ * * wounding_dmg: The damage of the strike that prompted this roll, higher damage = higher chance
+ * * wound_bonus: Not actually used right now, but maybe someday
+ * * bare_wound_bonus: ditto above
+ */
+/obj/item/bodypart/proc/try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)
+ if(wounding_dmg < DISMEMBER_MINIMUM_DAMAGE)
+ return
+
+ var/base_chance = wounding_dmg + (get_damage() / max_damage * 50) // how much damage we dealt with this blow, + 50% of the damage percentage we already had on this bodypart
+ if(locate(/datum/wound/blunt/critical) in wounds) // we only require a severe bone break, but if there's a critical bone break, we'll add 10% more
+ base_chance += 10
+
+ if(!prob(base_chance))
+ return
+
+ var/datum/wound/loss/dismembering = new
+ dismembering.apply_dismember(src, wounding_type)
+
+ return TRUE
//when a limb is dropped, the internal organs are removed from the mob and put into the limb
/obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/LB, mob/living/carbon/C)
@@ -378,7 +423,7 @@
/mob/living/carbon/regenerate_limb(limb_zone, noheal)
var/obj/item/bodypart/L
if(get_bodypart(limb_zone))
- return 0
+ return FALSE
L = newBodyPart(limb_zone, 0, 0)
if(L)
if(!noheal)
@@ -386,6 +431,8 @@
L.burn_dam = 0
L.brutestate = 0
L.burnstate = 0
-
+ var/datum/scar/scaries = new
+ var/datum/wound/loss/phantom_loss = new // stolen valor, really
+ scaries.generate(L, phantom_loss)
L.attach_limb(src, 1)
- return 1
+ return TRUE
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index a67f16b934..13b1140527 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -36,11 +36,10 @@
var/custom_head
wound_resistance = 10
- specific_locations = list("left eyebrow", "cheekbone", "neck", "throat", "jawline", "entire face")
scars_covered_by_clothes = FALSE
/obj/item/bodypart/head/can_dismember(obj/item/I)
- if(!((owner.stat == DEAD) || owner.InFullCritical()))
+ if(owner && !((owner.stat == DEAD) || owner.InFullCritical()))
return FALSE
return ..()
diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm
index a18b31e4c1..5a887ee6b7 100644
--- a/code/modules/surgery/bodyparts/parts.dm
+++ b/code/modules/surgery/bodyparts/parts.dm
@@ -12,7 +12,7 @@
var/obj/item/cavity_item
/obj/item/bodypart/chest/can_dismember(obj/item/I)
- if(!((owner.stat == DEAD) || owner.InFullCritical()))
+ if(!((owner.stat == DEAD) || owner.InFullCritical()) || !get_organs())
return FALSE
return ..()
diff --git a/code/modules/surgery/bone_mending.dm b/code/modules/surgery/bone_mending.dm
index 81d9fa8d97..0c0083575b 100644
--- a/code/modules/surgery/bone_mending.dm
+++ b/code/modules/surgery/bone_mending.dm
@@ -8,7 +8,7 @@
target_mobtypes = list(/mob/living/carbon/human)
possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
requires_real_bodypart = TRUE
- targetable_wound = /datum/wound/brute/bone/severe
+ targetable_wound = /datum/wound/blunt/severe
/datum/surgery/repair_bone_hairline/can_start(mob/living/user, mob/living/carbon/target)
if(..())
@@ -23,7 +23,7 @@
target_mobtypes = list(/mob/living/carbon/human)
possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
requires_real_bodypart = TRUE
- targetable_wound = /datum/wound/brute/bone/critical
+ targetable_wound = /datum/wound/blunt/critical
/datum/surgery/repair_bone_compound/can_start(mob/living/user, mob/living/carbon/target)
if(..())
diff --git a/code/modules/surgery/burn_dressing.dm b/code/modules/surgery/burn_dressing.dm
index 1688f7b5d1..8bfa52d245 100644
--- a/code/modules/surgery/burn_dressing.dm
+++ b/code/modules/surgery/burn_dressing.dm
@@ -94,7 +94,8 @@
log_combat(user, target, "dressed burns in", addition="INTENT: [uppertext(user.a_intent)]")
burn_wound.sanitization += 3
burn_wound.flesh_healing += 5
- burn_wound.force_bandage(tool)
+ var/obj/item/bodypart/the_part = target.get_bodypart(target_zone)
+ the_part.apply_gauze(tool)
else
to_chat(user, "[target] has no burns there!")
return ..()
diff --git a/code/modules/surgery/organs/tails.dm b/code/modules/surgery/organs/tails.dm
index 55a656f42d..289e9df9d4 100644
--- a/code/modules/surgery/organs/tails.dm
+++ b/code/modules/surgery/organs/tails.dm
@@ -45,14 +45,20 @@
/obj/item/organ/tail/lizard/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
..()
if(istype(H))
- // Checks here are necessary so it wouldn't overwrite the tail of a lizard it spawned in
+ // Checks here are necessary so it wouldn't overwrite the tail of a lizard it spawned in //yes, the if checks may cause snowflakes so that you can't insert another person's tail (haven't actually tested it but I assume that's the result of my addition) but it makes it so never again will lizards break their spine if set_species is called twice in a row (hopefully)
if(!H.dna.species.mutant_bodyparts["tail_lizard"])
- H.dna.features["tail_lizard"] = tail_type
- H.dna.species.mutant_bodyparts["tail_lizard"] = tail_type
+ if (!H.dna.features["tail_lizard"])
+ H.dna.features["tail_lizard"] = tail_type
+ H.dna.species.mutant_bodyparts["tail_lizard"] = tail_type
+ else
+ H.dna.species.mutant_bodyparts["tail_lizard"] = H.dna.features["tail_lizard"]
if(!H.dna.species.mutant_bodyparts["spines"])
- H.dna.features["spines"] = spines
- H.dna.species.mutant_bodyparts["spines"] = spines
+ if (!H.dna.features["spines"])
+ H.dna.features["spines"] = spines
+ H.dna.species.mutant_bodyparts["spines"] = spines
+ else
+ H.dna.species.mutant_bodyparts["spines"] = H.dna.features["spines"]
H.update_body()
/obj/item/organ/tail/lizard/Remove(special = FALSE)
diff --git a/code/modules/surgery/repair_puncture.dm b/code/modules/surgery/repair_puncture.dm
new file mode 100644
index 0000000000..12aefefc82
--- /dev/null
+++ b/code/modules/surgery/repair_puncture.dm
@@ -0,0 +1,108 @@
+
+/////BURN FIXING SURGERIES//////
+
+//the step numbers of each of these two, we only currently use the first to switch back and forth due to advancing after finishing steps anyway
+#define REALIGN_INNARDS 1
+#define WELD_VEINS 2
+
+///// Repair puncture wounds
+/datum/surgery/repair_puncture
+ name = "Repair puncture"
+ steps = list(/datum/surgery_step/incise, /datum/surgery_step/repair_innards, /datum/surgery_step/seal_veins, /datum/surgery_step/close) // repeat between steps 2 and 3 until healed
+ target_mobtypes = list(/mob/living/carbon)
+ possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
+ requires_real_bodypart = TRUE
+ targetable_wound = /datum/wound/pierce
+
+/datum/surgery/repair_puncture/can_start(mob/living/user, mob/living/carbon/target)
+ . = ..()
+ if(.)
+ var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected)
+ var/datum/wound/burn/pierce_wound = targeted_bodypart.get_wound_type(targetable_wound)
+ return(pierce_wound && pierce_wound.blood_flow > 0)
+
+//SURGERY STEPS
+
+///// realign the blood vessels so we can reweld them
+/datum/surgery_step/repair_innards
+ name = "realign blood vessels"
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCALPEL = 85, TOOL_WIRECUTTER = 40)
+ time = 3 SECONDS
+
+/datum/surgery_step/repair_innards/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/datum/wound/pierce/pierce_wound = surgery.operated_wound
+ if(!pierce_wound)
+ user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...")
+ return
+
+ if(pierce_wound.blood_flow <= 0)
+ to_chat(user, "[target]'s [parse_zone(user.zone_selected)] has no puncture to repair!")
+ surgery.status++
+ return
+
+ display_results(user, target, "You begin to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)]...",
+ "[user] begins to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)] with [tool].",
+ "[user] begins to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)].")
+
+/datum/surgery_step/repair_innards/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
+ var/datum/wound/pierce/pierce_wound = surgery.operated_wound
+ if(!pierce_wound)
+ to_chat(user, "[target] has no puncture wound there!")
+ return ..()
+
+ display_results(user, target, "You successfully realign some of the blood vessels in [target]'s [parse_zone(target_zone)].",
+ "[user] successfully realigns some of the blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!",
+ "[user] successfully realigns some of the blood vessels in [target]'s [parse_zone(target_zone)]!")
+ log_combat(user, target, "excised infected flesh in", addition="INTENT: [uppertext(user.a_intent)]")
+ surgery.operated_bodypart.receive_damage(brute=3, wound_bonus=CANT_WOUND)
+ pierce_wound.blood_flow -= 0.25
+ return ..()
+
+/datum/surgery_step/repair_innards/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0)
+ . = ..()
+ display_results(user, target, "You jerk apart some of the blood vessels in [target]'s [parse_zone(target_zone)].",
+ "[user] jerks apart some of the blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!",
+ "[user] jerk apart some of the blood vessels in [target]'s [parse_zone(target_zone)]!")
+ surgery.operated_bodypart.receive_damage(brute=rand(4,8), sharpness=SHARP_EDGED, wound_bonus = 10)
+
+///// Sealing the vessels back together
+/datum/surgery_step/seal_veins
+ name = "weld veins" // if your doctor says they're going to weld your blood vessels back together, you're either A) on SS13, or B) in grave mortal peril
+ implements = list(TOOL_CAUTERY = 100, /obj/item/gun/energy/laser = 90, TOOL_WELDER = 70, /obj/item = 30)
+ time = 4 SECONDS
+
+/datum/surgery_step/seal_veins/tool_check(mob/user, obj/item/tool)
+ if(implement_type == TOOL_WELDER || implement_type == /obj/item)
+ return tool.get_temperature()
+
+ return TRUE
+
+/datum/surgery_step/seal_veins/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/datum/wound/pierce/pierce_wound = surgery.operated_wound
+ if(!pierce_wound)
+ user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...")
+ return
+ display_results(user, target, "You begin to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)]...",
+ "[user] begins to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)] with [tool].",
+ "[user] begins to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)].")
+
+/datum/surgery_step/seal_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
+ var/datum/wound/pierce/pierce_wound = surgery.operated_wound
+ if(!pierce_wound)
+ to_chat(user, "[target] has no puncture there!")
+ return ..()
+
+ display_results(user, target, "You successfully meld some of the split blood vessels in [target]'s [parse_zone(target_zone)] with [tool].",
+ "[user] successfully melds some of the split blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!",
+ "[user] successfully melds some of the split blood vessels in [target]'s [parse_zone(target_zone)]!")
+ log_combat(user, target, "dressed burns in", addition="INTENT: [uppertext(user.a_intent)]")
+ pierce_wound.blood_flow -= 0.5
+ if(pierce_wound.blood_flow > 0)
+ surgery.status = REALIGN_INNARDS
+ to_chat(user, "There still seems to be misaligned blood vessels to finish...")
+ else
+ to_chat(user, "You've repaired all the internal damage in [target]'s [parse_zone(target_zone)]!")
+ return ..()
+
+#undef REALIGN_INNARDS
+#undef WELD_VEINS
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index 150016f570..c4ded65e9c 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -163,7 +163,7 @@
item_flags = SURGICAL_TOOL
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP_ACCURATE
+ sharpness = SHARP_POINTY
tool_behaviour = TOOL_SCALPEL
toolspeed = 1
bare_wound_bonus = 20
@@ -181,7 +181,7 @@
force = 16
toolspeed = 0.7
light_color = LIGHT_COLOR_GREEN
- sharpness = IS_SHARP_ACCURATE
+ sharpness = SHARP_POINTY
/obj/item/scalpel/advanced/Initialize()
. = ..()
@@ -221,7 +221,7 @@
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
toolspeed = 0.5
hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP_ACCURATE
+ sharpness = SHARP_POINTY
/obj/item/scalpel/suicide_act(mob/user)
user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!")
@@ -245,11 +245,11 @@
throw_range = 5
custom_materials = list(/datum/material/iron=10000, /datum/material/glass=6000)
attack_verb = list("attacked", "slashed", "sawed", "cut")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
tool_behaviour = TOOL_SAW
toolspeed = 1
- wound_bonus = 10
- bare_wound_bonus = 15
+ wound_bonus = 5
+ bare_wound_bonus = 10
/obj/item/circular_saw/Initialize()
. = ..()
@@ -272,7 +272,7 @@
custom_materials = list(/datum/material/iron=10000, /datum/material/glass=6000)
toolspeed = 0.5
attack_verb = list("attacked", "slashed", "sawed", "cut")
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
/obj/item/surgical_drapes
name = "surgical drapes"
diff --git a/code/modules/uplink/uplink_items/uplink_ammo.dm b/code/modules/uplink/uplink_items/uplink_ammo.dm
index ce74773f8d..853f6111b2 100644
--- a/code/modules/uplink/uplink_items/uplink_ammo.dm
+++ b/code/modules/uplink/uplink_items/uplink_ammo.dm
@@ -291,10 +291,17 @@
/datum/uplink_item/ammo/bolt_action
name = "Surplus Rifle Clip"
desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds."
- item = /obj/item/ammo_box/a762
+ item = /obj/item/ammo_box/a762
cost = 1
include_modes = list(/datum/game_mode/nuclear)
+/datum/uplink_item/ammo/bolt_action_bulk
+ name = "Surplus Rifle Clip Box"
+ desc = "An ammo box we found in a warehouse, holding 7 clips of 5 rounds for bolt-action rifles. Yes, the cheap ones."
+ item = /obj/item/storage/toolbox/ammo
+ cost = 4
+ include_modes = list(/datum/game_mode/nuclear)
+
/datum/uplink_item/ammo/dark_gygax/bag
name = "Dark Gygax Ammo Bag"
desc = "A duffel bag containing ammo for three full reloads of the incendiary carbine and flash bang launcher that are equipped on a standard Dark Gygax exosuit."
diff --git a/code/modules/uplink/uplink_items/uplink_dangerous.dm b/code/modules/uplink/uplink_items/uplink_dangerous.dm
index e068094776..a43e3fc2ce 100644
--- a/code/modules/uplink/uplink_items/uplink_dangerous.dm
+++ b/code/modules/uplink/uplink_items/uplink_dangerous.dm
@@ -185,6 +185,17 @@
restricted = TRUE
refund_path = /obj/item/guardiancreator/tech/choose/traitor
+/datum/uplink_item/dangerous/nukieguardian // just like the normal holoparasites but without the support or deffensive stands because nukies shouldnt turtle
+ name = "Holoparasites"
+ desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \
+ organic host as a home base and source of fuel. Holoparasites come in various types and share damage with their host."
+ item = /obj/item/storage/box/syndie_kit/nukieguardian
+ cost = 15
+ refundable = TRUE
+ surplus = 50
+ refund_path = /obj/item/guardiancreator/tech/choose/nukie
+ include_modes = list(/datum/game_mode/nuclear)
+
/datum/uplink_item/dangerous/machinegun
name = "L6 Squad Automatic Weapon"
desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \
diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm
index 5149259bb8..5f5eb91a04 100644
--- a/code/modules/uplink/uplink_items/uplink_devices.dm
+++ b/code/modules/uplink/uplink_items/uplink_devices.dm
@@ -147,6 +147,12 @@
item = /obj/item/aiModule/syndicate
cost = 9
+/datum/uplink_item/device_tools/damaged_module
+ name = "Damaged AI Law Upload Module"
+ desc = "This AI law upload module has been laying around our warehouse for god knows how long. We do not know why you would ever use this."
+ item = /obj/item/aiModule/core/full/damaged
+ cost = 5
+
/datum/uplink_item/device_tools/headsetupgrade
name = "Headset Upgrader"
desc = "A device that can be used to make one headset immune to flashbangs."
@@ -200,9 +206,7 @@
this primer of questionable worth and value is rumored to increase your rifle-bolt-working and/or shotgun \
racking fivefold. Then again, the techniques here only work on bolt-actions and pump-actions..."
item = /obj/item/book/granter/trait/rifleman
- cost = 3
- restricted_roles = list("Operative") // i want it to be surplusable but i also want it to be mostly nukie only, please advise
- surplus = 90
+ cost = 3 // fuck it available for everyone
/datum/uplink_item/device_tools/stimpack
name = "Stimpack"
diff --git a/code/modules/uplink/uplink_items/uplink_implants.dm b/code/modules/uplink/uplink_items/uplink_implants.dm
index 02b8b1e01d..bb4e0c7960 100644
--- a/code/modules/uplink/uplink_items/uplink_implants.dm
+++ b/code/modules/uplink/uplink_items/uplink_implants.dm
@@ -29,6 +29,13 @@
item = /obj/item/storage/box/syndie_kit/imp_freedom
cost = 5
+/datum/uplink_item/implants/warp
+ name = "Warp Implant"
+ desc = "An implant injected into the body and later activated at the user's will. It will inject eigenstasium which saves the user's location and teleports them there after five seconds. Lasts only fifteen times."
+ item = /obj/item/storage/box/syndie_kit/imp_warp
+ cost = 6
+ exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
+
/datum/uplink_item/implants/hijack
name = "Hijack Implant"
desc = "An implant that will let you hack into the APCs on station, allowing you to control them at will and the machinery within those rooms."
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index a7b9b6a298..a42fe97cb4 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -530,8 +530,7 @@ GLOBAL_LIST_EMPTY(vending_products)
for(var/i in C.bodyparts)
var/obj/item/bodypart/squish_part = i
if(squish_part.is_organic_limb())
- //var/type_wound = pick(WOUND_LIST_BONE)
- var/type_wound = pick(list(/datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/moderate))
+ var/type_wound = pick(list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate))
squish_part.force_wound_upwards(type_wound)
else
squish_part.receive_damage(brute=30)
@@ -577,7 +576,7 @@ GLOBAL_LIST_EMPTY(vending_products)
"You right [src].")
unbuckle_all_mobs(TRUE)
-
+ anchored = FALSE //so you can push it back into position
tilted = FALSE
layer = initial(layer)
diff --git a/code/modules/vending/coffee.dm b/code/modules/vending/coffee.dm
index ab64756868..fd555526c6 100644
--- a/code/modules/vending/coffee.dm
+++ b/code/modules/vending/coffee.dm
@@ -1,16 +1,20 @@
/obj/machinery/vending/coffee
name = "\improper Solar's Best Hot Drinks"
desc = "A vending machine which dispenses hot drinks."
- product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies"
+ product_ads = "Just what you need!;Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies"
icon_state = "coffee"
icon_vend = "coffee-vend"
products = list(/obj/item/reagent_containers/food/drinks/coffee = 25,
/obj/item/reagent_containers/food/drinks/mug/tea = 25,
+ /obj/item/reagent_containers/food/drinks/mug/tea/red = 10,
+ /obj/item/reagent_containers/food/drinks/mug/tea/green = 10,
/obj/item/reagent_containers/food/drinks/mug/coco = 25)
- contraband = list(/obj/item/reagent_containers/food/drinks/ice = 12)
+ contraband = list(/obj/item/reagent_containers/food/drinks/ice = 12,
+ /obj/item/reagent_containers/food/drinks/mug/tea/mush = 3,)
premium = list(/obj/item/reagent_containers/food/condiment/milk = 2,
/obj/item/reagent_containers/food/drinks/bottle/cream = 2,
- /obj/item/reagent_containers/food/condiment/sugar = 1)
+ /obj/item/reagent_containers/food/condiment/sugar = 1,
+ /obj/item/reagent_containers/food/drinks/mug/tea/forest = 3,)
refill_canister = /obj/item/vending_refill/coffee
default_price = PRICE_REALLY_CHEAP
diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm
index cf61e4b210..3a7cd4b03f 100644
--- a/code/modules/zombie/items.dm
+++ b/code/modules/zombie/items.dm
@@ -12,10 +12,10 @@
var/icon_right = "bloodhand_right"
hitsound = 'sound/hallucinations/growl1.ogg'
force = 18
- sharpness = IS_SHARP_ACCURATE //it's a claw, they're sharp.
+ sharpness = SHARP_POINTY //it's a claw, they're sharp.
damtype = "brute"
total_mass = TOTAL_MASS_HAND_REPLACEMENT
- sharpness = IS_SHARP
+ sharpness = SHARP_EDGED
wound_bonus = -30
bare_wound_bonus = 15
diff --git a/html/changelog.html b/html/changelog.html
index 33305d870a..2e0891ed7f 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -50,6 +50,111 @@
-->
+
07 August 2020
+
dapnee updated:
+
+ - fixed active tufs on some space ruins, murderdome VR, and a few on pubby, changed cargo autolathe to techfab, messed with pipe room leading to monastery.
+
+
lolman360 updated:
+
+ - vendors are now unanchored when tipped. it just fell over it's not bolted to the ground anymore.
+ - podpeople no fat when sunbathing.
+
+
silicons updated:
+
+ - explosions only recurse one level into storage before dropping 1 level per storage layer.
+ - volumetric storage is now minimum 16 pixels per item because 8 was ridiculous
+ - shieldbash balanace --> balance
+ - attempting to send too long of an emote will now reflect it back to you instead of cutting it off and discarding the overflow.
+ - holoparasites can now play music
+ - lethal blood now causes damaging bleeding instead of outright gibbing
+
+
+
06 August 2020
+
Auris456852 updated:
+
+ - Added B.O.O.P. Remote Control cartridges to the PTech.
+
+
Hatterhat updated:
+
+ - Proto-kinetic glaives! Essentially a proto-kinetic crusher with a different blade, handguard, and goliath hide grip. Expensive, but elegant.
+ - Door charges no longer knock people out.
+
+
Ludox235 updated:
+
+ - You can now buy damaged AI upload modules in the traitor's uplink.
+
+
Seris02 updated:
+
+
Trilbyspaceclone updated:
+
+ - 4 New blends of tea have been shipped to the station, and how to make them has been leaked!
+
+
b1tt3r1n0 updated:
+
+ - Added the warp implant
+
+
dapnee updated:
+
+ - added a hallway to telecoms for engineers to get there on meta
+
+
kappa-sama updated:
+
+ - dildo circuit assemblies
+
+
lolman360 updated:
+
+ - The Tendril-Mother on Lavaland has remembered how to make ashwalkers who know how to speak Draconic again.
+
+
timothyteakettle updated:
+
+ - nanotrasen has decided to fire all disabled members of the security division and confiscate certain sentimental items from doctors
+ - the custom tongue preference now passes through cloning so you spawn with your selected tongue
+ - several changes to travelling traders so they look better and spawn slightly less often
+
+
zeroisthebiggay updated:
+
+ - nukies can buy holoparasites
+
+
+
04 August 2020
+
Seris02 updated:
+
+
timothyteakettle updated:
+
+ - due to further advancements in medical technology, you can now have holes poked into your body for fun and enjoyment
+
+
zeroisthebiggay updated:
+
+ - prefs for headpat wagging
+
+
+
03 August 2020
+
KeRSedChaplain updated:
+
+ - fixed clockwork guardians being able to reflect ranged weapons
+
+
Linzolle updated:
+
+ - uv penlight no longer invisible
+
+
dapnee updated:
+
+ - active turfs on box and xenohive, maintenance bar APC not being stringed correctly, turned a monitor to face a direction that makes sense, changed tag of camera in gravgen being misnamed
+
+
silicons updated:
+
+ - shoves have been buffed to apply a status effect rather than a 0.85 movespeed modifier, meaning repeatedly shoving someone now renews the debuff
+ - shoves now stagger for 3.5 seconds.
+ - war operatives now actually time 20 minutes since roundstart to depart instead of 15.
+ - explosive stand bombs can now be examined from any distance
+ - explosive stand bombs are now a component.
+
+
02 August 2020
Auris456852 updated:
@@ -65,6 +170,7 @@
- Removed the abductor teleport consoles they get, removes abscond for the time being as I've not seen much use for it other than just spamming it and hoping you end up in the armory.
- moved around scriptures to make the cult work better as being based around the station, makes the Ark scream more often and work as a summonable object, clockwork armor now has a flat 0 defense up to 10 instead of negatives against laser damage. Makes the Ark work better in a station based setting, as well as the Heralds beacon in case It works for the mode.
- added powerloaderstep.ogg for Neovgre
+ - changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi'
MrJWhit updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 896ef8857c..02aa9cab74 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -26679,6 +26679,7 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
laser damage. Makes the Ark work better in a station based setting, as well
as the Heralds beacon in case It works for the mode.
- soundadd: added powerloaderstep.ogg for Neovgre
+ - tweak: changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi'
MrJWhit:
- tweak: Adjusts abductor spawntext
Seris02:
@@ -26695,3 +26696,77 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- tweak: combat mode now has weaker buffs in terms of damage dealt and took for
being or not being in the mode
- tweak: damage debuff for laying down has been decreased from 0.5x to 0.7x
+2020-08-03:
+ KeRSedChaplain:
+ - bugfix: fixed clockwork guardians being able to reflect ranged weapons
+ Linzolle:
+ - bugfix: uv penlight no longer invisible
+ dapnee:
+ - bugfix: active turfs on box and xenohive, maintenance bar APC not being stringed
+ correctly, turned a monitor to face a direction that makes sense, changed tag
+ of camera in gravgen being misnamed
+ silicons:
+ - rscadd: shoves have been buffed to apply a status effect rather than a 0.85 movespeed
+ modifier, meaning repeatedly shoving someone now renews the debuff
+ - balance: shoves now stagger for 3.5 seconds.
+ - tweak: war operatives now actually time 20 minutes since roundstart to depart
+ instead of 15.
+ - balance: explosive stand bombs can now be examined from any distance
+ - code_imp: explosive stand bombs are now a component.
+2020-08-04:
+ Seris02:
+ - bugfix: lizard spines
+ timothyteakettle:
+ - rscadd: due to further advancements in medical technology, you can now have holes
+ poked into your body for fun and enjoyment
+ zeroisthebiggay:
+ - rscadd: prefs for headpat wagging
+2020-08-06:
+ Auris456852:
+ - rscadd: Added B.O.O.P. Remote Control cartridges to the PTech.
+ Hatterhat:
+ - rscadd: Proto-kinetic glaives! Essentially a proto-kinetic crusher with a different
+ blade, handguard, and goliath hide grip. Expensive, but elegant.
+ - balance: Door charges no longer knock people out.
+ Ludox235:
+ - rscadd: You can now buy damaged AI upload modules in the traitor's uplink.
+ Seris02:
+ - bugfix: fixed ghost chilis
+ Trilbyspaceclone:
+ - rscadd: 4 New blends of tea have been shipped to the station, and how to make
+ them has been leaked!
+ b1tt3r1n0:
+ - rscadd: Added the warp implant
+ dapnee:
+ - tweak: added a hallway to telecoms for engineers to get there on meta
+ kappa-sama:
+ - rscdel: dildo circuit assemblies
+ lolman360:
+ - bugfix: The Tendril-Mother on Lavaland has remembered how to make ashwalkers who
+ know how to speak Draconic again.
+ timothyteakettle:
+ - tweak: nanotrasen has decided to fire all disabled members of the security division
+ and confiscate certain sentimental items from doctors
+ - tweak: the custom tongue preference now passes through cloning so you spawn with
+ your selected tongue
+ - tweak: several changes to travelling traders so they look better and spawn slightly
+ less often
+ zeroisthebiggay:
+ - rscadd: nukies can buy holoparasites
+2020-08-07:
+ dapnee:
+ - bugfix: fixed active tufs on some space ruins, murderdome VR, and a few on pubby,
+ changed cargo autolathe to techfab, messed with pipe room leading to monastery.
+ lolman360:
+ - bugfix: vendors are now unanchored when tipped. it just fell over it's not bolted
+ to the ground anymore.
+ - bugfix: podpeople no fat when sunbathing.
+ silicons:
+ - balance: explosions only recurse one level into storage before dropping 1 level
+ per storage layer.
+ - tweak: volumetric storage is now minimum 16 pixels per item because 8 was ridiculous
+ - spellcheck: shieldbash balanace --> balance
+ - rscadd: attempting to send too long of an emote will now reflect it back to you
+ instead of cutting it off and discarding the overflow.
+ - rscadd: holoparasites can now play music
+ - balance: lethal blood now causes damaging bleeding instead of outright gibbing
diff --git a/html/changelogs/AutoChangeLog-pr-12960.yml b/html/changelogs/AutoChangeLog-pr-12960.yml
new file mode 100644
index 0000000000..e37ac7eff0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12960.yml
@@ -0,0 +1,4 @@
+author: "timothyteakettle"
+delete-after: True
+changes:
+ - rscadd: "more items in the loadout and loadout has subcategories now for easier searching"
diff --git a/html/changelogs/AutoChangeLog-pr-12992.yml b/html/changelogs/AutoChangeLog-pr-12992.yml
new file mode 100644
index 0000000000..41edfb6414
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12992.yml
@@ -0,0 +1,7 @@
+author: "Hatterhat"
+delete-after: True
+changes:
+ - rscadd: "You can now buy a toolbox's worth of Mosin-Nagant ammo for a fairly discounted price."
+ - rscadd: "Revolvers from the dedicated kit now have reskinning capabilities."
+ - bugfix: "You can now actually buy the riflery primer, which lets you pump shotguns and work the Mosin's bolt faster."
+ - imageadd: "Bulldog slug magazines now have a unique sprite."
diff --git a/html/changelogs/AutoChangeLog-pr-13013.yml b/html/changelogs/AutoChangeLog-pr-13013.yml
new file mode 100644
index 0000000000..8e0b953ade
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-13013.yml
@@ -0,0 +1,12 @@
+author: "DeltaFire15"
+delete-after: True
+changes:
+ - balance: "Roundstart cultists now start with a replica fabricator - no brass though, make your own."
+ - balance: "Kindle cast time: 10 > 15, mute after stun end: 2 > 5, slur after mute end: 3 > 5"
+ - bugfix: "The ratvarian spear no longer adds negative vitality under very specific circumstances."
+ - balance: "The Ratvarian Spear can parry now! Short parries with low leeway, but low cooldown."
+ - rscadd: "The brass claw, a implant-based weapon which gains combo on consecutive hits against the same target."
+ - rscadd: "The sigil of rites, a sigil used to perform various rites with a cost of power and materials"
+ - rscadd: "The Rite of Advancement: Used to add a organ or cyberimplant to a clockie without need for surgery."
+ - rscadd: "The Rite of Woundmending: Used to heal all wounds on another cultist, causing toxins damage in return."
+ - rscadd: "The Rite of the Claw: Used to summon a brass claw implant. Maximum of 4 uses per round."
diff --git a/html/changelogs/AutoChangeLog-pr-13038.yml b/html/changelogs/AutoChangeLog-pr-13038.yml
new file mode 100644
index 0000000000..442bd37677
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-13038.yml
@@ -0,0 +1,4 @@
+author: "Sishen1542"
+delete-after: True
+changes:
+ - rscadd: "squishy slime emotes"
diff --git a/html/changelogs/AutoChangeLog-pr-13039.yml b/html/changelogs/AutoChangeLog-pr-13039.yml
new file mode 100644
index 0000000000..de8ea10f35
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-13039.yml
@@ -0,0 +1,5 @@
+author: "timothyteakettle"
+delete-after: True
+changes:
+ - tweak: "heparin makes you bleed half as much now"
+ - tweak: "cuts make you bleed 25% less now"
diff --git a/html/changelogs/AutoChangeLog-pr-13041.yml b/html/changelogs/AutoChangeLog-pr-13041.yml
new file mode 100644
index 0000000000..1ae84967a8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-13041.yml
@@ -0,0 +1,5 @@
+author: "Ludox235"
+delete-after: True
+changes:
+ - rscdel: "Removed an abductee objective that told you to remove all oxygen."
+ - rscadd: "Added a new abductee objective to replace the removed one."
diff --git a/html/changelogs/AutoChangeLog-pr-13043.yml b/html/changelogs/AutoChangeLog-pr-13043.yml
new file mode 100644
index 0000000000..5a9f2ca46f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-13043.yml
@@ -0,0 +1,4 @@
+author: "Sishen1542"
+delete-after: True
+changes:
+ - tweak: "🅱️oneless"
diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi
index ae8e6221c6..9490595484 100644
Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ
diff --git a/icons/mob/clothing/head.dmi b/icons/mob/clothing/head.dmi
index a6e75123bb..0ad9452994 100644
Binary files a/icons/mob/clothing/head.dmi and b/icons/mob/clothing/head.dmi differ
diff --git a/icons/mob/clothing/suit.dmi b/icons/mob/clothing/suit.dmi
index 7a690bb29f..c94e8a46d3 100644
Binary files a/icons/mob/clothing/suit.dmi and b/icons/mob/clothing/suit.dmi differ
diff --git a/icons/mob/clothing/suit_digi.dmi b/icons/mob/clothing/suit_digi.dmi
index 2616c0b893..dd00713770 100644
Binary files a/icons/mob/clothing/suit_digi.dmi and b/icons/mob/clothing/suit_digi.dmi differ
diff --git a/icons/mob/clothing/uniform.dmi b/icons/mob/clothing/uniform.dmi
index fa376635f9..3d24a9addd 100644
Binary files a/icons/mob/clothing/uniform.dmi and b/icons/mob/clothing/uniform.dmi differ
diff --git a/icons/mob/clothing/uniform_digi.dmi b/icons/mob/clothing/uniform_digi.dmi
index af72ac0e7b..bcb894033e 100644
Binary files a/icons/mob/clothing/uniform_digi.dmi and b/icons/mob/clothing/uniform_digi.dmi differ
diff --git a/icons/mob/inhands/antag/clockwork_lefthand.dmi b/icons/mob/inhands/antag/clockwork_lefthand.dmi
index 88bd8ab710..080d7fdc83 100644
Binary files a/icons/mob/inhands/antag/clockwork_lefthand.dmi and b/icons/mob/inhands/antag/clockwork_lefthand.dmi differ
diff --git a/icons/mob/inhands/antag/clockwork_righthand.dmi b/icons/mob/inhands/antag/clockwork_righthand.dmi
index 20190e4add..42715d6e92 100644
Binary files a/icons/mob/inhands/antag/clockwork_righthand.dmi and b/icons/mob/inhands/antag/clockwork_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/hammers_lefthand.dmi b/icons/mob/inhands/weapons/hammers_lefthand.dmi
index 306fd0db8a..b753a1f181 100644
Binary files a/icons/mob/inhands/weapons/hammers_lefthand.dmi and b/icons/mob/inhands/weapons/hammers_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/hammers_righthand.dmi b/icons/mob/inhands/weapons/hammers_righthand.dmi
index 674e4d510b..7650f6c760 100644
Binary files a/icons/mob/inhands/weapons/hammers_righthand.dmi and b/icons/mob/inhands/weapons/hammers_righthand.dmi differ
diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi
index bebb625440..e1caad8279 100644
Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ
diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi
index ae919d85a4..156d4fa0c6 100644
Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 90f1fba315..60304999fa 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index 258eb0dc35..e8a360bc87 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 57424c7b99..76f5722c8b 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi
index 8c50e7da27..9c6df36f49 100644
Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ
diff --git a/icons/obj/implants.dmi b/icons/obj/implants.dmi
index a6d4697673..b7cb90e9f4 100644
Binary files a/icons/obj/implants.dmi and b/icons/obj/implants.dmi differ
diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi
index c3ca67eeae..0e262895fd 100644
Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ
diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi
index 43bc9c48aa..e7063b71db 100644
Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index 3996f0ead2..8db1156dea 100755
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm
index 9f3d8911ec..9c35ddb75f 100644
--- a/interface/stylesheet.dm
+++ b/interface/stylesheet.dm
@@ -66,7 +66,9 @@ h1.alert, h2.alert {color: #000000;}
.passive {color: #660000;}
.userdanger {color: #ff0000; font-weight: bold; font-size: 3;}
-.danger {color: #ff0000;}
+.danger {color: #ff0000; font-weight: bold;}
+.tinydanger {color: #ff0000; font-size: 85%;}
+.smalldanger {color: #ff0000; font-size: 90%;}
.warning {color: #ff0000; font-style: italic;}
.boldwarning {color: #ff0000; font-style: italic; font-weight: bold}
.announce {color: #228b22; font-weight: bold;}
@@ -75,6 +77,9 @@ h1.alert, h2.alert {color: #000000;}
.rose {color: #ff5050;}
.info {color: #0000CC;}
.notice {color: #000099;}
+.tinynotice {color: #000099; font-size: 85%;}
+.smallnotice {color: #000099; font-size: 90%;}
+.smallnoticeital {color: #000099; font-style: italic; font-size: 90%;}
.boldnotice {color: #000099; font-weight: bold;}
.adminnotice {color: #0000ff;}
.adminhelp {color: #ff0000; font-weight: bold;}
diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm
index d428fc290a..54dabba779 100644
--- a/modular_citadel/code/modules/client/loadout/__donator.dm
+++ b/modular_citadel/code/modules/client/loadout/__donator.dm
@@ -1,496 +1,497 @@
//This is the file that handles donator loadout items.
-/datum/gear/pingcoderfailsafe
+/datum/gear/donator
name = "IF YOU SEE THIS, PING A CODER RIGHT NOW!"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/bikehorn/golden
+ category = CATEGORY_DONATOR
ckeywhitelist = list("This entry should never appear with this variable set.") //If it does, then that means somebody fucked up the whitelist system pretty hard
-/datum/gear/donortestingbikehorn
+/datum/gear/donator/donortestingbikehorn
name = "Donor item testing bikehorn"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/bikehorn
geargroupID = list("DONORTEST") //This is a list mainly for the sake of testing, but geargroupID works just fine with ordinary strings
-/datum/gear/kevhorn
+/datum/gear/donator/kevhorn
name = "Airhorn"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/bikehorn/airhorn
ckeywhitelist = list("kevinz000")
-/datum/gear/cebusoap
+/datum/gear/donator/cebusoap
name = "Cebutris' soap"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/custom/ceb_soap
ckeywhitelist = list("cebutris")
-/datum/gear/kiaracloak
+/datum/gear/donator/kiaracloak
name = "Kiara's cloak"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/cloak/inferno
ckeywhitelist = list("inferno707")
-/datum/gear/kiaracollar
+/datum/gear/donator/kiaracollar
name = "Kiara's collar"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/petcollar/inferno
ckeywhitelist = list("inferno707")
-/datum/gear/kiaramedal
+/datum/gear/donator/kiaramedal
name = "Insignia of Steele"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/clothing/accessory/medal/steele
ckeywhitelist = list("inferno707")
-/datum/gear/hheart
+/datum/gear/donator/hheart
name = "The Hollow Heart"
- category = SLOT_WEAR_MASK
+ slot = SLOT_WEAR_MASK
path = /obj/item/clothing/mask/hheart
ckeywhitelist = list("inferno707")
-/datum/gear/engravedzippo
+/datum/gear/donator/engravedzippo
name = "Engraved zippo"
- category = SLOT_HANDS
+ slot = SLOT_HANDS
path = /obj/item/lighter/gold
ckeywhitelist = list("dirtyoldharry")
-/datum/gear/geisha
+/datum/gear/donator/geisha
name = "Geisha suit"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/geisha
ckeywhitelist = list("atiefling")
-/datum/gear/specialscarf
+/datum/gear/donator/specialscarf
name = "Special scarf"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/scarf/zomb
ckeywhitelist = list("zombierobin")
-/datum/gear/redmadcoat
+/datum/gear/donator/redmadcoat
name = "The Mad's labcoat"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/toggle/labcoat/mad/red
ckeywhitelist = list("zombierobin")
-/datum/gear/santahat
+/datum/gear/donator/santahat
name = "Santa hat"
- category = SLOT_HEAD
+ slot = SLOT_HEAD
path = /obj/item/clothing/head/santa/fluff
ckeywhitelist = list("illotafv")
-/datum/gear/reindeerhat
+/datum/gear/donator/reindeerhat
name = "Reindeer hat"
- category = SLOT_HEAD
+ slot = SLOT_HEAD
path = /obj/item/clothing/head/hardhat/reindeer/fluff
ckeywhitelist = list("illotafv")
-/datum/gear/treeplushie
+/datum/gear/donator/treeplushie
name = "Christmas tree plushie"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/toy/plush/tree
ckeywhitelist = list("illotafv")
-/datum/gear/santaoutfit
+/datum/gear/donator/santaoutfit
name = "Santa costume"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/space/santa/fluff
ckeywhitelist = list("illotafv")
-/datum/gear/treecloak
+/datum/gear/donator/treecloak
name = "Christmas tree cloak"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/cloak/festive
ckeywhitelist = list("illotafv")
-/datum/gear/carrotplush
+/datum/gear/donator/carrotplush
name = "Carrot plushie"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/toy/plush/carrot
ckeywhitelist = list("improvedname")
-/datum/gear/carrotcloak
+/datum/gear/donator/carrotcloak
name = "Carrot cloak"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/cloak/carrot
ckeywhitelist = list("improvedname")
-/datum/gear/albortorosamask
+/datum/gear/donator/albortorosamask
name = "Alborto Rosa mask"
- category = SLOT_WEAR_MASK
+ slot = SLOT_WEAR_MASK
path = /obj/item/clothing/mask/luchador/zigfie
ckeywhitelist = list("zigfie")
-/datum/gear/mankini
+/datum/gear/donator/mankini
name = "Mankini"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/stripper/mankini
ckeywhitelist = list("zigfie")
-/datum/gear/pinkshoes
+/datum/gear/donator/pinkshoes
name = "Pink shoes"
- category = SLOT_SHOES
+ slot = SLOT_SHOES
path = /obj/item/clothing/shoes/sneakers/pink
ckeywhitelist = list("zigfie")
-/datum/gear/reecesgreatcoat
+/datum/gear/donator/reecesgreatcoat
name = "Reece's Great Coat"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/trenchcoat/green
ckeywhitelist = list("geemiesif")
-/datum/gear/russianflask
+/datum/gear/donator/russianflask
name = "Russian flask"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/reagent_containers/food/drinks/flask/russian
cost = 2
ckeywhitelist = list("slomka")
-/datum/gear/stalkermask
+/datum/gear/donator/stalkermask
name = "S.T.A.L.K.E.R. mask"
- category = SLOT_WEAR_MASK
+ slot = SLOT_WEAR_MASK
path = /obj/item/clothing/mask/gas/stalker
ckeywhitelist = list("slomka")
-/datum/gear/stripedcollar
+/datum/gear/donator/stripedcollar
name = "Striped collar"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/petcollar/stripe
ckeywhitelist = list("jademanique")
-/datum/gear/performersoutfit
+/datum/gear/donator/performersoutfit
name = "Bluish performer's outfit"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/singer/yellow/custom
ckeywhitelist = list("killer402402")
-/datum/gear/vermillion
+/datum/gear/donator/vermillion
name = "Vermillion clothing"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/suit/vermillion
ckeywhitelist = list("fractious")
-/datum/gear/AM4B
+/datum/gear/donator/AM4B
name = "Foam Force AM4-B"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/gun/ballistic/automatic/AM4B
ckeywhitelist = list("zeronetalpha")
-/datum/gear/carrotsatchel
+/datum/gear/donator/carrotsatchel
name = "Carrot Satchel"
- category = SLOT_HANDS
+ slot = SLOT_HANDS
path = /obj/item/storage/backpack/satchel/carrot
ckeywhitelist = list("improvedname")
-/datum/gear/naomisweater
+/datum/gear/donator/naomisweater
name = "worn black sweater"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/under/sweater/black/naomi
ckeywhitelist = list("technicalmagi")
-/datum/gear/naomicollar
+/datum/gear/donator/naomicollar
name = "worn pet collar"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/petcollar/naomi
ckeywhitelist = list("technicalmagi")
-/datum/gear/gladiator
+/datum/gear/donator/gladiator
name = "Gladiator Armor"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/under/costume/gladiator
ckeywhitelist = list("aroche")
-/datum/gear/bloodredtie
+/datum/gear/donator/bloodredtie
name = "Blood Red Tie"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/tie/bloodred
ckeywhitelist = list("kyutness")
-/datum/gear/puffydress
+/datum/gear/donator/puffydress
name = "Puffy Dress"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/puffydress
ckeywhitelist = list("stallingratt")
-/datum/gear/labredblack
+/datum/gear/donator/labredblack
name = "Black and Red Coat"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/toggle/labcoat/labredblack
ckeywhitelist = list("blakeryan", "durandalphor")
-/datum/gear/torisword
+/datum/gear/donator/torisword
name = "Rainbow Zweihander"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/dualsaber/hypereutactic/toy/rainbow
ckeywhitelist = list("annoymous35")
-/datum/gear/darksabre
+/datum/gear/donator/darksabre
name = "Dark Sabre"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/toy/darksabre
ckeywhitelist = list("inferno707")
-datum/gear/darksabresheath
+/datum/gear/donator/darksabresheath
name = "Dark Sabre Sheath"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/storage/belt/sabre/darksabre
ckeywhitelist = list("inferno707")
-/datum/gear/toriball
+/datum/gear/donator/toriball
name = "Rainbow Tennis Ball"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/toy/tennis/rainbow
ckeywhitelist = list("annoymous35")
-/datum/gear/izzyball
+/datum/gear/donator/izzyball
name = "Katlin's Ball"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/toy/tennis/rainbow/izzy
ckeywhitelist = list("izzyinbox")
-/datum/gear/cloak
+/datum/gear/donator/cloak
name = "Green Cloak"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/cloak/green
ckeywhitelist = list("killer402402")
-/datum/gear/steelflask
+/datum/gear/donator/steelflask
name = "Steel Flask"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/reagent_containers/food/drinks/flask/steel
cost = 2
ckeywhitelist = list("nik707")
-/datum/gear/paperhat
+/datum/gear/donator/paperhat
name = "Paper Hat"
- category = SLOT_HEAD
+ slot = SLOT_HEAD
path = /obj/item/clothing/head/paperhat
ckeywhitelist = list("kered2")
-/datum/gear/cloakce
+/datum/gear/donator/cloakce
name = "Polychromic CE Cloak"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/clothing/neck/cloak/polychromic/polyce
ckeywhitelist = list("worksbythesea", "blakeryan")
-/datum/gear/ssk
+/datum/gear/donator/ssk
name = "Stun Sword Kit"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/ssword_kit
ckeywhitelist = list("phillip458")
-/datum/gear/techcoat
+/datum/gear/donator/techcoat
name = "Techomancers Labcoat"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/clothing/suit/toggle/labcoat/mad/techcoat
ckeywhitelist = list("wilchen")
-/datum/gear/leechjar
+/datum/gear/donator/leechjar
name = "Jar of Leeches"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/custom/leechjar
ckeywhitelist = list("sgtryder")
-/datum/gear/darkarmor
+/datum/gear/donator/darkarmor
name = "Dark Armor"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/clothing/suit/armor/vest/darkcarapace
ckeywhitelist = list("inferno707")
-/datum/gear/devilwings
+/datum/gear/donator/devilwings
name = "Strange Wings"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/devilwings
ckeywhitelist = list("kitsun")
-/datum/gear/flagcape
+/datum/gear/donator/flagcape
name = "US Flag Cape"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/clothing/neck/flagcape
ckeywhitelist = list("darnchacha")
-/datum/gear/luckyjack
+/datum/gear/donator/luckyjack
name = "Lucky Jackboots"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/clothing/shoes/lucky
ckeywhitelist = list("donaldtrumpthecommunist")
-/datum/gear/raiqbawks
+/datum/gear/donator/raiqbawks
name = "Miami Boombox"
- category = SLOT_HANDS
+ slot = SLOT_HANDS
cost = 2
path = /obj/item/boombox/raiq
ckeywhitelist = list("chefferz")
-/datum/gear/m41
+/datum/gear/donator/m41
name = "Toy M41"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/toy/gun/m41
ckeywhitelist = list("thalverscholen")
-/datum/gear/Divine_robes
+/datum/gear/donator/Divine_robes
name = "Divine robes"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/under/custom/lunasune
ckeywhitelist = list("invader4352")
-/datum/gear/gothcoat
+/datum/gear/donator/gothcoat
name = "Goth Coat"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/gothcoat
ckeywhitelist = list("norko")
-/datum/gear/corgisuit
+/datum/gear/donator/corgisuit
name = "Corgi Suit"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/ian_costume
ckeywhitelist = list("cathodetherobot")
-/datum/gear/sharkcloth
+/datum/gear/donator/sharkcloth
name = "Leon's Skimpy Outfit"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/under/custom/leoskimpy
ckeywhitelist = list("spectrosis")
-/datum/gear/mimemask
+/datum/gear/donator/mimemask
name = "Mime Mask"
- category = SLOT_WEAR_MASK
+ slot = SLOT_WEAR_MASK
path = /obj/item/clothing/mask/gas/mime
ckeywhitelist = list("pireamaineach")
-/datum/gear/mimeoveralls
+/datum/gear/donator/mimeoveralls
name = "Mime's Overalls"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/under/custom/mimeoveralls
ckeywhitelist = list("pireamaineach")
-/datum/gear/soulneck
+/datum/gear/donator/soulneck
name = "Soul Necklace"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/undertale
ckeywhitelist = list("twilightic")
-/datum/gear/frenchberet
+/datum/gear/donator/frenchberet
name = "French Beret"
- category = SLOT_HEAD
+ slot = SLOT_HEAD
path = /obj/item/clothing/head/frenchberet
ckeywhitelist = list("notazoltan")
-/datum/gear/zuliecloak
+/datum/gear/donator/zuliecloak
name = "Project: Zul-E"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/cloak/zuliecloak
ckeywhitelist = list("asky")
-/datum/gear/blackredgold
+/datum/gear/donator/blackredgold
name = "Black, Red, and Gold Coat"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/blackredgold
ckeywhitelist = list("ttbnc")
-/datum/gear/fritzplush
+/datum/gear/donator/fritzplush
name = "Fritz Plushie"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/toy/plush/mammal/dog/fritz
ckeywhitelist = list("analwerewolf")
-/datum/gear/kimono
+/datum/gear/donator/kimono
name = "Kimono"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/kimono
ckeywhitelist = list("sfox63")
-/datum/gear/commjacket
+/datum/gear/donator/commjacket
name = "Dusty Commisar's Cloak"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/commjacket
ckeywhitelist = list("sadisticbatter")
-/datum/gear/mw2_russian_para
+/datum/gear/donator/mw2_russian_para
name = "Russian Paratrooper Jumper"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/under/custom/mw2_russian_para
ckeywhitelist = list("investigator77")
-/datum/gear/longblackgloves
+/datum/gear/donator/longblackgloves
name = "Luna's Gauntlets"
- category = SLOT_GLOVES
+ slot = SLOT_GLOVES
path = /obj/item/clothing/gloves/longblackgloves
ckeywhitelist = list("bigmanclancy")
-/datum/gear/trendy_fit
+/datum/gear/donator/trendy_fit
name = "Trendy Fit"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/under/custom/trendy_fit
ckeywhitelist = list("midgetdragon")
-/datum/gear/singery
+/datum/gear/donator/singery
name = "Yellow Performer Outfit"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/singer/yellow
ckeywhitelist = list("maxlynchy")
-/datum/gear/csheet
+/datum/gear/donator/csheet
name = "NT Bedsheet"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/bedsheet/captain
ckeywhitelist = list("tikibomb")
-/datum/gear/borgplush
+/datum/gear/donator/borgplush
name = "Robot Plush"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/toy/plush/borgplushie
ckeywhitelist = list("nicholaiavenicci")
-/datum/gear/donorberet
+/datum/gear/donator/donorberet
name = "Atmos Beret"
- category = SLOT_HEAD
+ slot = SLOT_HEAD
path = /obj/item/clothing/head/blueberet
ckeywhitelist = list("foxystalin")
-/datum/gear/donorgoggles
+/datum/gear/donator/donorgoggles
name = "Flight Goggles"
- category = SLOT_HEAD
+ slot = SLOT_HEAD
path = /obj/item/clothing/head/flight
ckeywhitelist = list("maxlynchy")
-/datum/gear/onionneck
+/datum/gear/donator/onionneck
name = "Onion Necklace"
- category = SLOT_NECK
+ slot = SLOT_NECK
path = /obj/item/clothing/neck/necklace/onion
ckeywhitelist = list("cdrcross")
-/datum/gear/mikubikini
+/datum/gear/donator/mikubikini
name = "starlight singer bikini"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/under/custom/mikubikini
ckeywhitelist = list("grandvegeta")
-/datum/gear/mikujacket
+/datum/gear/donator/mikujacket
name = "starlight singer jacket"
- category = SLOT_WEAR_SUIT
+ slot = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/mikujacket
ckeywhitelist = list("grandvegeta")
-/datum/gear/mikuhair
+/datum/gear/donator/mikuhair
name = "starlight singer hair"
- category = SLOT_W_UNIFORM
+ slot = SLOT_W_UNIFORM
path = /obj/item/clothing/head/mikuhair
ckeywhitelist = list("grandvegeta")
-/datum/gear/mikugloves
+/datum/gear/donator/mikugloves
name = "starlight singer gloves"
- category = SLOT_GLOVES
+ slot = SLOT_GLOVES
path = /obj/item/clothing/gloves/mikugloves
ckeywhitelist = list("grandvegeta")
-/datum/gear/mikuleggings
+/datum/gear/donator/mikuleggings
name = "starlight singer leggings"
- category = SLOT_SHOES
+ slot = SLOT_SHOES
path = /obj/item/clothing/shoes/sneakers/mikuleggings
ckeywhitelist = list("grandvegeta")
-/datum/gear/cosmos
+/datum/gear/donator/cosmos
name = "cosmic space bedsheet"
- category = SLOT_IN_BACKPACK
+ slot = SLOT_IN_BACKPACK
path = /obj/item/bedsheet/cosmos
ckeywhitelist = list("grunnyyy")
diff --git a/modular_citadel/code/modules/client/loadout/_loadout.dm b/modular_citadel/code/modules/client/loadout/_loadout.dm
index 51256f8cde..9988519471 100644
--- a/modular_citadel/code/modules/client/loadout/_loadout.dm
+++ b/modular_citadel/code/modules/client/loadout/_loadout.dm
@@ -28,7 +28,9 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids)
load_loadout_config()
for(var/item in subtypesof(/datum/gear))
var/datum/gear/I = new item
- LAZYSET(GLOB.loadout_items[slot_to_string(I.category)], I.name, I)
+ LAZYINITLIST(GLOB.loadout_items[I.category])
+ LAZYINITLIST(GLOB.loadout_items[I.category][I.subcategory])
+ GLOB.loadout_items[I.category][I.subcategory][I.name] = I
if(islist(I.geargroupID))
var/list/ggidlist = I.geargroupID
I.ckeywhitelist = list()
@@ -41,7 +43,9 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids)
/datum/gear
var/name
- var/category
+ var/category = "NOCATEGORY"
+ var/subcategory = "NOSUBCATEGORY"
+ var/slot
var/description
var/path //item-to-spawn path
var/cost = 1 //normally, each loadout costs a single point.
diff --git a/modular_citadel/code/modules/client/loadout/_medical.dm b/modular_citadel/code/modules/client/loadout/_medical.dm
index 604a0f96ae..bba100faff 100644
--- a/modular_citadel/code/modules/client/loadout/_medical.dm
+++ b/modular_citadel/code/modules/client/loadout/_medical.dm
@@ -1,47 +1,45 @@
-/datum/gear/medicbriefcase
+/datum/gear/hands/medicbriefcase
name = "Medical Briefcase"
- category = SLOT_HANDS
path = /obj/item/storage/briefcase/medical
restricted_roles = list("Medical Doctor", "Chief Medical Officer")
restricted_desc = "MD, CMO"
-/datum/gear/stethoscope
+/datum/gear/neck/stethoscope
name = "Stethoscope"
- category = SLOT_NECK
path = /obj/item/clothing/neck/stethoscope
restricted_roles = list("Medical Doctor", "Chief Medical Officer")
-/datum/gear/bluescrubs
+/datum/gear/uniform/bluescrubs
name = "Blue Scrubs"
- category = SLOT_W_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
path = /obj/item/clothing/under/rank/medical/doctor/blue
restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist")
restricted_desc = "Medical"
-
-/datum/gear/greenscrubs
+
+/datum/gear/uniform/greenscrubs
name = "Green Scrubs"
- category = SLOT_W_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
path = /obj/item/clothing/under/rank/medical/doctor/green
restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist")
restricted_desc = "Medical"
-/datum/gear/purplescrubs
+/datum/gear/uniform/purplescrubs
name = "Purple Scrubs"
- category = SLOT_W_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
path = /obj/item/clothing/under/rank/medical/doctor/purple
restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist")
restricted_desc = "Medical"
-/datum/gear/nursehat
+/datum/gear/head/nursehat
name = "Nurse Hat"
- category = SLOT_HEAD
path = /obj/item/clothing/head/nursehat
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist")
restricted_desc = "Medical"
-/datum/gear/nursesuit
+/datum/gear/uniform/nursesuit
name = "Nurse Suit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/rank/medical/doctor/nurse
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist")
- restricted_desc = "Medical"
\ No newline at end of file
+ restricted_desc = "Medical"
diff --git a/modular_citadel/code/modules/client/loadout/_security.dm b/modular_citadel/code/modules/client/loadout/_security.dm
index 72a6aab394..3ec39008c1 100644
--- a/modular_citadel/code/modules/client/loadout/_security.dm
+++ b/modular_citadel/code/modules/client/loadout/_security.dm
@@ -1,71 +1,70 @@
-/datum/gear/navyblueuniformhos
+/datum/gear/uniform/navyblueuniformhos
name = "Head of Security navyblue uniform"
- category = SLOT_W_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
path = /obj/item/clothing/under/rank/security/head_of_security/formal
restricted_roles = list("Head of Security")
-/datum/gear/navybluehosberet
+/datum/gear/head/navybluehosberet
name = "Head of security's navyblue beret"
- category = SLOT_HEAD
path = /obj/item/clothing/head/beret/sec/navyhos
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_roles = list("Head of Security")
-/datum/gear/navybluejackethos
+/datum/gear/suit/navybluejackethos
name = "head of security's navyblue jacket"
- category = SLOT_WEAR_SUIT
+ subcategory = SUBCATEGORY_SUIT_JOBS
path = /obj/item/clothing/suit/armor/hos/navyblue
restricted_roles = list("Head of Security")
-/datum/gear/navybluejacketofficer
+/datum/gear/suit/navybluejacketofficer
name = "security officer's navyblue jacket"
- category = SLOT_WEAR_SUIT
+ subcategory = SUBCATEGORY_SUIT_JOBS
path = /obj/item/clothing/suit/armor/navyblue
restricted_roles = list("Security Officer")
-/datum/gear/navyblueofficerberet
+/datum/gear/head/navyblueofficerberet
name = "Security officer's Navyblue beret"
- category = SLOT_HEAD
path = /obj/item/clothing/head/beret/sec/navyofficer
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_roles = list("Security Officer")
-/datum/gear/navyblueuniformofficer
+/datum/gear/uniform/navyblueuniformofficer
name = "Security officer navyblue uniform"
- category = SLOT_W_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
path = /obj/item/clothing/under/rank/security/officer/formal
restricted_roles = list("Security Officer")
-/datum/gear/navybluejacketwarden
+/datum/gear/suit/navybluejacketwarden
name = "warden navyblue jacket"
- category = SLOT_WEAR_SUIT
+ subcategory = SUBCATEGORY_SUIT_JOBS
path = /obj/item/clothing/suit/armor/vest/warden/navyblue
restricted_roles = list("Warden")
-/datum/gear/navybluewardenberet
+/datum/gear/head/navybluewardenberet
name = "Warden's navyblue beret"
- category = SLOT_HEAD
path = /obj/item/clothing/head/beret/sec/navywarden
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_roles = list("Warden")
-/datum/gear/navyblueuniformwarden
+/datum/gear/uniform/navyblueuniformwarden
name = "Warden navyblue uniform"
- category = SLOT_W_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
path = /obj/item/clothing/under/rank/security/warden/formal
restricted_roles = list("Warden")
-/datum/gear/secskirt
+/datum/gear/uniform/secskirt
name = "Security skirt"
- category = SLOT_W_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
path = /obj/item/clothing/under/rank/security/officer/skirt
restricted_roles = list("Security Officer", "Warden", "Head of Security")
-/datum/gear/hosskirt
+/datum/gear/uniform/hosskirt
name = "Head of security's skirt"
- category = SLOT_W_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
path = /obj/item/clothing/under/rank/security/head_of_security/skirt
restricted_roles = list("Head of Security")
-/datum/gear/sechud
+/datum/gear/glasses/sechud
name = "Security Hud"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/hud/security
restricted_roles = list("Security Officer", "Warden", "Head of Security")
\ 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 ab3daa5f3c..8949c04604 100644
--- a/modular_citadel/code/modules/client/loadout/_service.dm
+++ b/modular_citadel/code/modules/client/loadout/_service.dm
@@ -1,33 +1,33 @@
-/datum/gear/greytidestationwide
+/datum/gear/uniform/greytidestationwide
name = "Staff Assistant's jumpsuit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/staffassistant
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_roles = list("Assistant")
-/datum/gear/neetsuit
+/datum/gear/suit/neetsuit
name = "D.A.B. suit"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/assu_suit
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_roles = list("Assistant")
cost = 2
-/datum/gear/neethelm
+/datum/gear/head/neethelm
name = "D.A.B. helmet"
- category = SLOT_HEAD
path = /obj/item/clothing/head/assu_helmet
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_roles = list("Assistant")
cost = 2
-/datum/gear/plushvar
+/datum/gear/backpack/plushvar
name = "Ratvar Plushie"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/plush/plushvar
+ subcategory = SUBCATEGORY_BACKPACK_TOYS
cost = 5
restricted_roles = list("Chaplain")
-/datum/gear/narplush
+/datum/gear/backpack/narplush
name = "Narsie Plushie"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/plush/narplush
+ subcategory = SUBCATEGORY_BACKPACK_TOYS
cost = 5
restricted_roles = list("Chaplain")
diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm
index 690e012840..fe308f5b23 100644
--- a/modular_citadel/code/modules/client/loadout/backpack.dm
+++ b/modular_citadel/code/modules/client/loadout/backpack.dm
@@ -1,112 +1,100 @@
-/datum/gear/plushbox
+/datum/gear/backpack
+ category = CATEGORY_BACKPACK
+ subcategory = SUBCATEGORY_BACKPACK_GENERAL
+ slot = SLOT_IN_BACKPACK
+
+/datum/gear/backpack/plushbox
name = "Plushie Choice Box"
- category = SLOT_IN_BACKPACK
path = /obj/item/choice_beacon/box/plushie
+ subcategory = SUBCATEGORY_BACKPACK_TOYS
-/datum/gear/tennis
+/datum/gear/backpack/tennis
name = "Classic Tennis Ball"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/tennis
+ subcategory = SUBCATEGORY_BACKPACK_TOYS
-/datum/gear/tennisred
+/datum/gear/backpack/tennis/red
name = "Red Tennis Ball"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/tennis/red
-/datum/gear/tennisyellow
+/datum/gear/backpack/tennis/yellow
name = "Yellow Tennis Ball"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/tennis/yellow
-/datum/gear/tennisgreen
+/datum/gear/backpack/tennis/green
name = "Green Tennis Ball"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/tennis/green
-/datum/gear/tenniscyan
+/datum/gear/backpack/tennis/cyan
name = "Cyan Tennis Ball"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/tennis/cyan
-/datum/gear/tennisblue
+/datum/gear/backpack/tennis/blue
name = "Blue Tennis Ball"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/tennis/blue
-/datum/gear/tennispurple
+/datum/gear/backpack/tennis/purple
name = "Purple Tennis Ball"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/tennis/purple
-/datum/gear/dildo
+/datum/gear/backpack/dildo
name = "Customizable dildo"
- category = SLOT_IN_BACKPACK
path = /obj/item/dildo/custom
+ subcategory = SUBCATEGORY_BACKPACK_TOYS
-/datum/gear/toykatana
+/datum/gear/backpack/toykatana
name = "Toy Katana"
- category = SLOT_IN_BACKPACK
path = /obj/item/toy/katana
+ subcategory = SUBCATEGORY_BACKPACK_TOYS
cost = 3
-/datum/gear/tapeplayer
+/datum/gear/backpack/tapeplayer
name = "Taperecorder"
- category = SLOT_IN_BACKPACK
path = /obj/item/taperecorder
-/datum/gear/tape
+/datum/gear/backpack/tape
name = "Spare cassette tape"
- category = SLOT_IN_BACKPACK
path = /obj/item/tape/random
-/datum/gear/newspaper
+/datum/gear/backpack/newspaper
name = "Newspaper"
- category = SLOT_IN_BACKPACK
path = /obj/item/newspaper
-/datum/gear/crayons
+/datum/gear/backpack/crayons
name = "Box of crayons"
- category = SLOT_IN_BACKPACK
path = /obj/item/storage/crayons
+ subcategory = SUBCATEGORY_BACKPACK_TOYS
-/datum/gear/multipen
+/datum/gear/backpack/multipen
name = "A multicolored pen"
- category = SLOT_IN_BACKPACK
path = /obj/item/pen/fourcolor
-/datum/gear/fountainpen
+/datum/gear/backpack/fountainpen
name = "A fancy pen"
- category = SLOT_IN_BACKPACK
path = /obj/item/pen/fountain
cost = 2
-/datum/gear/modular_tablet
+/datum/gear/backpack/modular_tablet
name = "A modular tablet"
- category = SLOT_IN_BACKPACK
path = /obj/item/modular_computer/tablet/preset/cheap/
cost = 4
-/datum/gear/modular_laptop
+/datum/gear/backpack/modular_laptop
name = "A modular laptop"
- category = SLOT_IN_BACKPACK
path = /obj/item/modular_computer/laptop/preset/civilian
cost = 7
-/datum/gear/ringbox_gold
+/datum/gear/backpack/ringbox_gold
name = "A gold ring box"
- category = SLOT_IN_BACKPACK
path = /obj/item/storage/fancy/ringbox
cost = 3
-/datum/gear/ringbox_silver
+/datum/gear/backpack/ringbox_silver
name = "A silver ring box"
- category = SLOT_IN_BACKPACK
path = /obj/item/storage/fancy/ringbox/silver
cost = 3
-/datum/gear/ringbox_diamond
+/datum/gear/backpack/ringbox_diamond
name = "A diamond ring box"
- category = SLOT_IN_BACKPACK
path = /obj/item/storage/fancy/ringbox/diamond
cost = 5
-
diff --git a/modular_citadel/code/modules/client/loadout/glasses.dm b/modular_citadel/code/modules/client/loadout/glasses.dm
index 57270d8e57..65bb7ad23c 100644
--- a/modular_citadel/code/modules/client/loadout/glasses.dm
+++ b/modular_citadel/code/modules/client/loadout/glasses.dm
@@ -1,49 +1,43 @@
-/datum/gear/blindfold
+/datum/gear/glasses
+ category = CATEGORY_GLASSES
+ slot = SLOT_GLASSES
+
+/datum/gear/glasses/blindfold
name = "Blindfold"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/sunglasses/blindfold
-/datum/gear/cold
+/datum/gear/glasses/cold
name = "Cold goggles"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/cold
-/datum/gear/eyepatch
+/datum/gear/glasses/eyepatch
name = "Eyepatch"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/eyepatch
-/datum/gear/heat
+/datum/gear/glasses/heat
name = "Heat goggles"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/heat
-/datum/gear/hipster
+/datum/gear/glasses/hipster
name = "Hipster glasses"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/regular/hipster
-/datum/gear/jamjar
+/datum/gear/glasses/jamjar
name = "Jamjar glasses"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/regular/jamjar
-/datum/gear/monocle
+/datum/gear/glasses/monocle
name = "Monocle"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/monocle
-/datum/gear/orange
+/datum/gear/glasses/orange
name = "Orange glasses"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/orange
-/datum/gear/red
+/datum/gear/glasses/red
name = "Red Glasses"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/red
-/datum/gear/prescription
+/datum/gear/glasses/prescription
name = "Prescription glasses"
- category = SLOT_GLASSES
path = /obj/item/clothing/glasses/regular
diff --git a/modular_citadel/code/modules/client/loadout/gloves.dm b/modular_citadel/code/modules/client/loadout/gloves.dm
index e9e8e3939b..43323af43c 100644
--- a/modular_citadel/code/modules/client/loadout/gloves.dm
+++ b/modular_citadel/code/modules/client/loadout/gloves.dm
@@ -1,28 +1,26 @@
-/datum/gear/fingerless
+/datum/gear/gloves
+ category = CATEGORY_GLOVES
+ slot = SLOT_GLOVES
+
+/datum/gear/gloves/fingerless
name = "Fingerless Gloves"
- category = SLOT_GLOVES
path = /obj/item/clothing/gloves/fingerless
-/datum/gear/evening
+/datum/gear/gloves/evening
name = "Evening gloves"
- category = SLOT_GLOVES
path = /obj/item/clothing/gloves/evening
-/datum/gear/goldring
+/datum/gear/gloves/goldring
name = "A gold ring"
- category = SLOT_GLOVES
path = /obj/item/clothing/gloves/ring
cost = 2
-/datum/gear/silverring
+/datum/gear/gloves/silverring
name = "A silver ring"
- category = SLOT_GLOVES
path = /obj/item/clothing/gloves/ring/silver
cost = 2
-/datum/gear/diamondring
+/datum/gear/gloves/diamondring
name = "A diamond ring"
- category = SLOT_GLOVES
path = /obj/item/clothing/gloves/ring/diamond
cost = 4
-
diff --git a/modular_citadel/code/modules/client/loadout/hands.dm b/modular_citadel/code/modules/client/loadout/hands.dm
index 2f03bd3b07..ff4827e6bc 100644
--- a/modular_citadel/code/modules/client/loadout/hands.dm
+++ b/modular_citadel/code/modules/client/loadout/hands.dm
@@ -1,67 +1,54 @@
-/datum/gear/cane
+/datum/gear/hands
+ category = CATEGORY_HANDS
+ slot = SLOT_HANDS
+
+/datum/gear/hands/cane
name = "Cane"
- category = SLOT_HANDS
path = /obj/item/cane
-/datum/gear/cigarettes
+/datum/gear/hands/cigarettes
name = "Cigarette pack"
- category = SLOT_HANDS
path = /obj/item/storage/fancy/cigarettes
-/datum/gear/dice
+/datum/gear/hands/dice
name = "Dice bag"
- category = SLOT_HANDS
path = /obj/item/storage/box/dice
-/datum/gear/eightball
+/datum/gear/hands/eightball
name = "Magic eightball"
- category = SLOT_HANDS
path = /obj/item/toy/eightball
-/datum/gear/matches
+/datum/gear/hands/matches
name = "Matchbox"
- category = SLOT_HANDS
path = /obj/item/storage/box/matches
-/datum/gear/cheaplighter
+/datum/gear/hands/cheaplighter
name = "Cheap lighter"
- category = SLOT_HANDS
path = /obj/item/lighter/greyscale
-/datum/gear/cards
+/datum/gear/hands/cards
name = "Playing cards"
- category = SLOT_HANDS
path = /obj/item/toy/cards/deck
-/datum/gear/skub
+/datum/gear/hands/skub
name = "Skub"
- category = SLOT_HANDS
path = /obj/item/skub
-/datum/gear/carpplushie
- name = "Space carp plushie"
- category = SLOT_HANDS
- path = /obj/item/toy/plush/carpplushie
-
-/datum/gear/wallet
+/datum/gear/hands/wallet
name = "Wallet"
- category = SLOT_HANDS
path = /obj/item/storage/wallet
-/datum/gear/flask
+/datum/gear/hands/flask
name = "Flask"
- category = SLOT_HANDS
path = /obj/item/reagent_containers/food/drinks/flask
cost = 2
-/datum/gear/zippolighter
+/datum/gear/hands/zippolighter
name = "Zippo Lighter"
- category = SLOT_HANDS
path = /obj/item/lighter
cost = 2
-/datum/gear/cigar
+/datum/gear/hands/cigar
name = "Cigar"
- category = SLOT_HANDS
path = /obj/item/clothing/mask/cigarette/cigar
cost = 4 //smoking is bad mkay
diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm
index 2156c9c481..a1495aa7bd 100644
--- a/modular_citadel/code/modules/client/loadout/head.dm
+++ b/modular_citadel/code/modules/client/loadout/head.dm
@@ -1,146 +1,136 @@
-/datum/gear/baseball
+/datum/gear/head
+ category = CATEGORY_HEAD
+ subcategory = SUBCATEGORY_HEAD_GENERAL
+ slot = SLOT_HEAD
+
+/datum/gear/head/baseball
name = "Ballcap"
- category = SLOT_HEAD
path = /obj/item/clothing/head/soft/mime
-/datum/gear/beanie
+/datum/gear/head/beanie
name = "Beanie"
- category = SLOT_HEAD
path = /obj/item/clothing/head/beanie
-/datum/gear/beret
+/datum/gear/head/beret
name = "Black beret"
- category = SLOT_HEAD
path = /obj/item/clothing/head/beret/black
-/datum/gear/flatcap
+/datum/gear/head/flatcap
name = "Flat cap"
- category = SLOT_HEAD
path = /obj/item/clothing/head/flatcap
-/datum/gear/pirate
+/datum/gear/head/pirate
name = "Pirate hat"
- category = SLOT_HEAD
path = /obj/item/clothing/head/pirate
-/datum/gear/rice_hat
+/datum/gear/head/rice_hat
name = "Rice hat"
- category = SLOT_HEAD
path = /obj/item/clothing/head/rice_hat
-/datum/gear/ushanka
- name = "Ushanka"
- category = SLOT_HEAD
+/datum/gear/head/ushanka
path = /obj/item/clothing/head/ushanka
-/datum/gear/slime
+/datum/gear/head/slime
name = "Slime hat"
- category = SLOT_HEAD
path = /obj/item/clothing/head/collectable/slime
-/datum/gear/fedora
+/datum/gear/head/fedora
name = "Fedora"
- category = SLOT_HEAD
path = /obj/item/clothing/head/fedora
-/datum/gear/that
+/datum/gear/head/that
name = "Top Hat"
- category = SLOT_HEAD
path = /obj/item/clothing/head/that
-/datum/gear/maidband
+/datum/gear/head/maidband
name = "Maid headband"
- category = SLOT_HEAD
path= /obj/item/clothing/head/maid
-/datum/gear/flakhelm
+/datum/gear/head/flakhelm
name = "Flak Helmet"
- category = SLOT_HEAD
path = /obj/item/clothing/head/flakhelm
cost = 2
-/datum/gear/bunnyears
+/datum/gear/head/bunnyears
name = "Bunny Ears"
- category = SLOT_HEAD
path = /obj/item/clothing/head/rabbitears
-/datum/gear/mailmanhat
+/datum/gear/head/mailmanhat
name = "Mailman's Hat"
- category = SLOT_HEAD
path = /obj/item/clothing/head/mailman
//trek fancy Hats!
-/datum/gear/trekcap
+/datum/gear/head/trekcap
name = "Federation Officer's Cap (White)"
- category = SLOT_HEAD
path = /obj/item/clothing/head/caphat/formal/fedcover
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_roles = list("Captain","Head of Personnel")
-/datum/gear/trekcapcap
+/datum/gear/head/trekcapcap
name = "Federation Officer's Cap (Black)"
- category = SLOT_HEAD
path = /obj/item/clothing/head/caphat/formal/fedcover/black
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_roles = list("Captain","Head of Personnel")
-/datum/gear/trekcapmedisci
+/datum/gear/head/trekcapmedisci
name = "Federation Officer's Cap (Blue)"
- category = SLOT_HEAD
path = /obj/item/clothing/head/caphat/formal/fedcover/medsci
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist")
-/datum/gear/trekcapeng
+/datum/gear/head/trekcapeng
name = "Federation Officer's Cap (Yellow)"
- category = SLOT_HEAD
path = /obj/item/clothing/head/caphat/formal/fedcover/eng
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_desc = "Engineering, Security, and Cargo"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
-/datum/gear/trekcapsec
+/datum/gear/head/trekcapsec
name = "Federation Officer's Cap (Red)"
- category = SLOT_HEAD
path = /obj/item/clothing/head/caphat/formal/fedcover/sec
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_desc = "Engineering, Security, and Cargo"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
// orvilike "original" kepi
-/datum/gear/orvkepicom
+/datum/gear/head/orvkepicom
name = "Federation Kepi, command"
description = "A visored cap. Intended to be used with ORV uniform."
- category = SLOT_HEAD
path = /obj/item/clothing/head/kepi/orvi/command
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_desc = "Heads of Staff"
restricted_roles = list("Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Research Director", "Chief Medical Officer", "Quartermaster")
-/datum/gear/orvkepiops
+/datum/gear/head/orvkepiops
name = "Federation Kepi, ops/sec"
description = "A visored cap. Intended to be used with ORV uniform."
- category = SLOT_HEAD
path = /obj/item/clothing/head/kepi/orvi/engsec
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_desc = "Engineering, Security and Cargo"
restricted_roles = list("Chief Engineer", "Atmospheric Technician", "Station Engineer", "Warden", "Detective", "Security Officer", "Head of Security", "Cargo Technician", "Shaft Miner", "Quartermaster")
-/datum/gear/orvkepimedsci
+/datum/gear/head/orvkepimedsci
name = "Federation Kepi, medsci"
description = "A visored cap. Intended to be used with ORV uniform."
- category = SLOT_HEAD
path = /obj/item/clothing/head/kepi/orvi/medsci
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Virologist", "Paramedic", "Geneticist", "Research Director", "Scientist", "Roboticist")
-/datum/gear/orvkepisrv
+/datum/gear/head/orvkepisrv
name = "Federation Kepi, service"
description = "A visored cap. Intended to be used with ORV uniform."
- category = SLOT_HEAD
path = /obj/item/clothing/head/kepi/orvi/service
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_desc = "Service and Civilian, barring Clown, Mime and Lawyer"
restricted_roles = list("Assistant", "Bartender", "Botanist", "Cook", "Curator", "Janitor", "Chaplain")
-/datum/gear/orvkepiass
+/datum/gear/head/orvkepiass
name = "Federation Kepi, assistant"
description = "A visored cap. Intended to be used with ORV uniform."
- category = SLOT_HEAD
path = /obj/item/clothing/head/kepi/orvi
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_roles = list("Assistant")
/*Commenting out Until next Christmas or made automatic
@@ -156,35 +146,37 @@
*/
//Cowboy Stuff
-/datum/gear/cowboyhat
+/datum/gear/head/cowboyhat
name = "Cowboy Hat, Brown"
- category = SLOT_HEAD
path = /obj/item/clothing/head/cowboyhat
-/datum/gear/cowboyhat/black
+/datum/gear/head/cowboyhat/black
name = "Cowboy Hat, Black"
- category = SLOT_HEAD
path = /obj/item/clothing/head/cowboyhat/black
-/datum/gear/cowboyhat/white
+/datum/gear/head/cowboyhat/white
name = "Cowboy Hat, White"
- category = SLOT_HEAD
path = /obj/item/clothing/head/cowboyhat/white
-/datum/gear/cowboyhat/pink
+/datum/gear/head/cowboyhat/pink
name = "Cowboy Hat, Pink"
- category = SLOT_HEAD
path = /obj/item/clothing/head/cowboyhat/pink
-/datum/gear/cowboyhat/sec
+/datum/gear/head/cowboyhat/sec
name = "Cowboy Hat, Security"
- category = SLOT_HEAD
path = /obj/item/clothing/head/cowboyhat/sec
+ subcategory = SUBCATEGORY_HEAD_JOBS
restricted_desc = "Security"
restricted_roles = list("Warden","Detective","Security Officer","Head of Security")
-// Misc
-/datum/gear/wkepi
+/datum/gear/head/wkepi
name = "white kepi"
- category = SLOT_HEAD
path = /obj/item/clothing/head/kepi
+
+/datum/gear/head/widered
+ name = "Wide red hat"
+ path = /obj/item/clothing/head/widered
+
+/datum/gear/head/kabuto
+ name = "Kabuto helmet"
+ path = /obj/item/clothing/head/kabuto
diff --git a/modular_citadel/code/modules/client/loadout/mask.dm b/modular_citadel/code/modules/client/loadout/mask.dm
index eeba06cad4..ec77eba93c 100644
--- a/modular_citadel/code/modules/client/loadout/mask.dm
+++ b/modular_citadel/code/modules/client/loadout/mask.dm
@@ -1,16 +1,16 @@
-/datum/gear/balaclava
+/datum/gear/mask
+ category = CATEGORY_MASK
+ slot = SLOT_WEAR_MASK
+
+/datum/gear/mask/balaclava
name = "Balaclava"
- category = SLOT_WEAR_MASK
path = /obj/item/clothing/mask/balaclava
-/datum/gear/moustache
+/datum/gear/mask/moustache
name = "Fake moustache"
- category = SLOT_WEAR_MASK
path = /obj/item/clothing/mask/fakemoustache
-/datum/gear/joy
+/datum/gear/mask/joy
name = "Joy mask"
- category = SLOT_WEAR_MASK
path = /obj/item/clothing/mask/joy
cost = 3
-
diff --git a/modular_citadel/code/modules/client/loadout/neck.dm b/modular_citadel/code/modules/client/loadout/neck.dm
index 0f69296406..2e8ec7001d 100644
--- a/modular_citadel/code/modules/client/loadout/neck.dm
+++ b/modular_citadel/code/modules/client/loadout/neck.dm
@@ -1,99 +1,88 @@
-/datum/gear/bluetie
+/datum/gear/neck
+ category = CATEGORY_NECK
+ subcategory = SUBCATEGORY_NECK_GENERAL
+ slot = SLOT_NECK
+
+/datum/gear/neck/bluetie
name = "Blue tie"
- category = SLOT_NECK
+ subcategory = SUBCATEGORY_NECK_TIE
path = /obj/item/clothing/neck/tie/blue
-/datum/gear/redtie
+/datum/gear/neck/redtie
name = "Red tie"
- category = SLOT_NECK
+ subcategory = SUBCATEGORY_NECK_TIE
path = /obj/item/clothing/neck/tie/red
-/datum/gear/blacktie
+/datum/gear/neck/blacktie
name = "Black tie"
- category = SLOT_NECK
+ subcategory = SUBCATEGORY_NECK_TIE
path = /obj/item/clothing/neck/tie/black
-/datum/gear/collar
+/datum/gear/neck/collar
name = "Collar"
- category = SLOT_NECK
path = /obj/item/clothing/neck/petcollar
-/datum/gear/leathercollar
+/datum/gear/neck/leathercollar
name = "Leather collar"
- category = SLOT_NECK
path = /obj/item/clothing/neck/petcollar/leather
-/datum/gear/choker
+/datum/gear/neck/choker
name = "Choker"
- category = SLOT_NECK
path = /obj/item/clothing/neck/petcollar/choker
-/datum/gear/scarf
+/datum/gear/neck/scarf
name = "White scarf"
- category = SLOT_NECK
+ subcategory = SUBCATEGORY_NECK_SCARVES
path = /obj/item/clothing/neck/scarf
-/datum/gear/blackscarf
+/datum/gear/neck/scarf/black
name = "Black scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/scarf/black
-/datum/gear/redscarf
+/datum/gear/neck/scarf/red
name = "Red scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/scarf/red
-/datum/gear/greenscarf
+/datum/gear/neck/scarf/green
name = "Green scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/scarf/green
-/datum/gear/darkbluescarf
+/datum/gear/neck/scarf/darkblue
name = "Dark blue scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/scarf/darkblue
-/datum/gear/purplescarf
+/datum/gear/neck/scarf/purple
name = "Purple scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/scarf/purple
-/datum/gear/yellowscarf
+/datum/gear/neck/scarf/yellow
name = "Yellow scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/scarf/yellow
-/datum/gear/orangescarf
+/datum/gear/neck/scarf/orange
name = "Orange scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/scarf/orange
-/datum/gear/cyanscarf
+/datum/gear/neck/scarf/cyan
name = "Cyan scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/scarf/cyan
-/datum/gear/stripedredscarf
+/datum/gear/neck/scarf/stripedred
name = "Striped red scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/stripedredscarf
-/datum/gear/stripedbluescarf
+/datum/gear/neck/scarf/stripedblue
name = "Striped blue scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/stripedbluescarf
-/datum/gear/stripedgreenscarf
+/datum/gear/neck/scarf/stripedgreen
name = "Striped green scarf"
- category = SLOT_NECK
path = /obj/item/clothing/neck/stripedgreenscarf
-/datum/gear/headphones
+/datum/gear/neck/headphones
name = "Headphones"
- category = SLOT_NECK
path = /obj/item/clothing/ears/headphones
-/datum/gear/polycloak
+/datum/gear/neck/polycloak
name = "Polychromatic Cloak"
- category = SLOT_NECK
path = /obj/item/clothing/neck/cloak/polychromic
diff --git a/modular_citadel/code/modules/client/loadout/shoes.dm b/modular_citadel/code/modules/client/loadout/shoes.dm
index 3531e69cfd..f92ccbe17c 100644
--- a/modular_citadel/code/modules/client/loadout/shoes.dm
+++ b/modular_citadel/code/modules/client/loadout/shoes.dm
@@ -1,84 +1,71 @@
-/datum/gear/laceup
+/datum/gear/shoes
+ category = CATEGORY_SHOES
+ slot = SLOT_SHOES
+
+/datum/gear/shoes/laceup
name = "Laceup shoes"
- category = SLOT_SHOES
path = /obj/item/clothing/shoes/laceup
-/datum/gear/workboots
+/datum/gear/shoes/workboots
name = "Work boots"
- category = SLOT_SHOES
path = /obj/item/clothing/shoes/workboots
-/datum/gear/jackboots
+/datum/gear/shoes/jackboots
name = "Jackboots"
- category = SLOT_SHOES
path = /obj/item/clothing/shoes/jackboots
-/datum/gear/winterboots
+/datum/gear/shoes/winterboots
name = "Winter boots"
- category = SLOT_SHOES
path = /obj/item/clothing/shoes/winterboots
-/datum/gear/sandals
+/datum/gear/shoes/sandals
name = "Sandals"
- category = SLOT_SHOES
path = /obj/item/clothing/shoes/sandal
-/datum/gear/blackshoes
+/datum/gear/shoes/blackshoes
name = "Black shoes"
- category = SLOT_SHOES
path = /obj/item/clothing/shoes/sneakers/black
-/datum/gear/brownshoes
+/datum/gear/shoes/brownshoes
name = "Brown shoes"
- category = SLOT_SHOES
path = /obj/item/clothing/shoes/sneakers/brown
-/datum/gear/whiteshoes
+/datum/gear/shoes/whiteshoes
name = "White shoes"
- category = SLOT_SHOES
path = /obj/item/clothing/shoes/sneakers/white
-/datum/gear/gildedcuffs
+/datum/gear/shoes/gildedcuffs
name = "Gilded leg wraps"
- category = SLOT_SHOES
path= /obj/item/clothing/shoes/wraps
-/datum/gear/silvercuffs
+/datum/gear/shoes/silvercuffs
name = "Silver leg wraps"
- category = SLOT_SHOES
path= /obj/item/clothing/shoes/wraps/silver
-/datum/gear/redcuffs
+/datum/gear/shoes/redcuffs
name = "Red leg wraps"
- category = SLOT_SHOES
path= /obj/item/clothing/shoes/wraps/red
-/datum/gear/bluecuffs
+/datum/gear/shoes/bluecuffs
name = "Blue leg wraps"
- category = SLOT_SHOES
path= /obj/item/clothing/shoes/wraps/blue
-/datum/gear/christmasbootsr
+/datum/gear/shoes/christmasbootsr
name = "Red Christmas Boots"
- category = SLOT_SHOES
path= /obj/item/clothing/shoes/winterboots/christmasbootsr
-/datum/gear/christmasbootsg
+/datum/gear/shoes/christmasbootsg
name = "Green Christmas Boots"
- category = SLOT_SHOES
path= /obj/item/clothing/shoes/winterboots/christmasbootsg
-/datum/gear/santaboots
+/datum/gear/shoes/santaboots
name = "Santa Boots"
- category = SLOT_SHOES
path= /obj/item/clothing/shoes/winterboots/santaboots
-/datum/gear/cowboyboots
+/datum/gear/shoes/cowboyboots
name = "Cowboy Boots, Brown"
- category = SLOT_SHOES
path = /obj/item/clothing/shoes/cowboyboots
-/datum/gear/cowboyboots/black
+/datum/gear/shoes/cowboyboots/black
name = "Cowboy Boots, Black"
- category = SLOT_SHOES
- path = /obj/item/clothing/shoes/cowboyboots/black
\ No newline at end of file
+ path = /obj/item/clothing/shoes/cowboyboots/black
diff --git a/modular_citadel/code/modules/client/loadout/suit.dm b/modular_citadel/code/modules/client/loadout/suit.dm
index 57c5772f48..539187af8b 100644
--- a/modular_citadel/code/modules/client/loadout/suit.dm
+++ b/modular_citadel/code/modules/client/loadout/suit.dm
@@ -1,261 +1,250 @@
-/datum/gear/poncho
+/datum/gear/suit
+ category = CATEGORY_SUIT
+ subcategory = SUBCATEGORY_SUIT_GENERAL
+ slot = SLOT_WEAR_SUIT
+
+/datum/gear/suit/poncho
name = "Poncho"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/poncho
-/datum/gear/ponchogreen
+/datum/gear/suit/ponchogreen
name = "Green poncho"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/poncho/green
-/datum/gear/ponchored
+/datum/gear/suit/ponchored
name = "Red poncho"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/poncho/red
-/datum/gear/redhood
+/datum/gear/suit/redhood
name = "Red cloak"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/cloak/david
cost = 3
-/datum/gear/jacketbomber
+/datum/gear/suit/jacketbomber
name = "Bomber jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/jacketflannelblack // all of these are reskins of bomber jackets but with the vibe to make you look like a true lumberjack
+/datum/gear/suit/jacketflannelblack // all of these are reskins of bomber jackets but with the vibe to make you look like a true lumberjack
name = "Black flannel jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/flannel
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/jacketflannelred
+/datum/gear/suit/jacketflannelred
name = "Red flannel jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/flannel/red
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/jacketflannelaqua
+/datum/gear/suit/jacketflannelaqua
name = "Aqua flannel jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/flannel/aqua
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/jacketflannelbrown
+/datum/gear/suit/jacketflannelbrown
name = "Brown flannel jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/flannel/brown
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/jacketleather
+/datum/gear/suit/jacketleather
name = "Leather jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/leather
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/overcoatleather
+/datum/gear/suit/overcoatleather
name = "Leather overcoat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/leather/overcoat
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/jacketpuffer
+/datum/gear/suit/jacketpuffer
name = "Puffer jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/puffer
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/vestpuffer
+/datum/gear/suit/vestpuffer
name = "Puffer vest"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/puffer/vest
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/jacketlettermanbrown
+/datum/gear/suit/jacketlettermanbrown
name = "Brown letterman jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/letterman
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/jacketlettermanred
+/datum/gear/suit/jacketlettermanred
name = "Red letterman jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/letterman_red
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/jacketlettermanNT
+/datum/gear/suit/jacketlettermanNT
name = "Nanotrasen letterman jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/letterman_nanotrasen
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/coat
+/datum/gear/suit/coat
name = "Winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat
+ subcategory = SUBCATEGORY_SUIT_COATS
-/datum/gear/coat/aformal
+/datum/gear/suit/coat/aformal
name = "Assistant's formal winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/aformal
-/datum/gear/coat/runed
+/datum/gear/suit/coat/runed
name = "Runed winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/narsie/fake
-/datum/gear/coat/brass
+/datum/gear/suit/coat/brass
name = "Brass winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/ratvar/fake
-/datum/gear/coat/polycoat
+/datum/gear/suit/coat/polycoat
name = "Polychromic winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/polychromic
cost = 4 //too many people with neon green coats is hard on the eyes
-/datum/gear/coat/med
+/datum/gear/suit/coat/med
name = "Medical winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/medical
restricted_roles = list("Chief Medical Officer", "Medical Doctor") // Reserve it to Medical Doctors and their boss, the Chief Medical Officer
-/datum/gear/coat/paramedic
+/datum/gear/suit/coat/paramedic
name = "Paramedic winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/paramedic
restricted_roles = list("Chief Medical Officer", "Paramedic") // Reserve it to Paramedics and their boss, the Chief Medical Officer
-/datum/gear/coat/robotics
+/datum/gear/suit/coat/robotics
name = "Robotics winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/robotics
restricted_roles = list("Research Director", "Roboticist")
-/datum/gear/coat/sci
+/datum/gear/suit/coat/sci
name = "Science winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/science
restricted_roles = list("Research Director", "Scientist", "Roboticist") // Reserve it to the Science Departement
-/datum/gear/coat/eng
+/datum/gear/suit/coat/eng
name = "Engineering winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/engineering
restricted_roles = list("Chief Engineer", "Station Engineer") // Reserve it to Station Engineers and their boss, the Chief Engineer
-/datum/gear/coat/eng/atmos
+/datum/gear/suit/coat/eng/atmos
name = "Atmospherics winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos
restricted_roles = list("Chief Engineer", "Atmospheric Technician") // Reserve it to Atmos Techs and their boss, the Chief Engineer
-/datum/gear/coat/hydro
+/datum/gear/suit/coat/hydro
name = "Hydroponics winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/hydro
restricted_roles = list("Head of Personnel", "Botanist") // Reserve it to Botanists and their boss, the Head of Personnel
-/datum/gear/coat/bar
+/datum/gear/suit/coat/bar
name = "Bar winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/bar
restricted_roles = list("Bartender") // Reserve it to Bartenders and not the Head of Personnel because he doesnt deserve to look as fancy as them
-/datum/gear/coat/cargo
+/datum/gear/suit/coat/cargo
name = "Cargo winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/cargo
restricted_roles = list("Quartermaster", "Cargo Technician") // Reserve it to Cargo Techs and their boss, the Quartermaster
-/datum/gear/coat/miner
+/datum/gear/suit/coat/miner
name = "Mining winter coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/miner
restricted_roles = list("Quartermaster", "Shaft Miner") // Reserve it to Miners and their boss, the Quartermaster
-/datum/gear/militaryjacket
+/datum/gear/suit/militaryjacket
name = "Military Jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/jacket/miljacket
+ subcategory = SUBCATEGORY_SUIT_JACKETS
-/datum/gear/ianshirt
+/datum/gear/suit/ianshirt
name = "Ian Shirt"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/ianshirt
-/datum/gear/flakjack
+/datum/gear/suit/flakjack
name = "Flak Jacket"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/flakjack
+ subcategory = SUBCATEGORY_SUIT_JACKETS
cost = 2
-/datum/gear/trekds9_coat
+/datum/gear/suit/trekds9_coat
name = "DS9 Overcoat (use uniform)"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/storage/trek/ds9
+ subcategory = SUBCATEGORY_SUIT_JOBS
restricted_desc = "All, barring Service and Civilian"
restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster",
"Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Scientist", "Roboticist",
"Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer",
"Cargo Technician", "Shaft Miner") //everyone who actually deserves a job.
//Federation jackets from movies
-/datum/gear/trekcmdcap
+/datum/gear/suit/trekcmdcap
name = "Fed (movie) uniform, Black"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/storage/fluff/fedcoat/capt
+ subcategory = SUBCATEGORY_SUIT_JOBS
restricted_roles = list("Captain","Head of Personnel")
-/datum/gear/trekcmdmov
+/datum/gear/suit/trekcmdmov
name = "Fed (movie) uniform, Red"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/storage/fluff/fedcoat
+ subcategory = SUBCATEGORY_SUIT_JOBS
restricted_desc = "Heads of Staff and Security"
restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster","Warden","Detective","Security Officer")
-/datum/gear/trekmedscimov
+/datum/gear/suit/trekmedscimov
name = "Fed (movie) uniform, Blue"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/storage/fluff/fedcoat/medsci
+ subcategory = SUBCATEGORY_SUIT_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist")
-/datum/gear/trekengmov
+/datum/gear/suit/trekengmov
name = "Fed (movie) uniform, Yellow"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/storage/fluff/fedcoat/eng
+ subcategory = SUBCATEGORY_SUIT_JOBS
restricted_desc = "Engineering and Cargo"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Cargo Technician", "Shaft Miner", "Quartermaster")
-/datum/gear/trekcmdcapmod
+/datum/gear/suit/trekcmdcapmod
name = "Fed (Modern) uniform, White"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/storage/fluff/modernfedcoat
restricted_roles = list("Captain","Head of Personnel")
-/datum/gear/trekcmdmod
+/datum/gear/suit/trekcmdmod
name = "Fed (Modern) uniform, Red"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/storage/fluff/modernfedcoat/sec
+ subcategory = SUBCATEGORY_SUIT_JOBS
restricted_desc = "Heads of Staff and Security"
restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster","Warden","Detective","Security Officer")
-/datum/gear/trekmedscimod
+/datum/gear/suit/trekmedscimod
name = "Fed (Modern) uniform, Blue"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/storage/fluff/modernfedcoat/medsci
+ subcategory = SUBCATEGORY_SUIT_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist")
-/datum/gear/trekengmod
+/datum/gear/suit/trekengmod
name = "Fed (Modern) uniform, Yellow"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/storage/fluff/modernfedcoat/eng
+ subcategory = SUBCATEGORY_SUIT_JOBS
restricted_desc = "Engineering and Cargo"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Cargo Technician", "Shaft Miner", "Quartermaster")
-/datum/gear/christmascoatr
+/datum/gear/suit/christmascoatr
name = "Red Christmas Coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/christmascoatr
+ subcategory = SUBCATEGORY_SUIT_COATS
-/datum/gear/christmascoatg
+/datum/gear/suit/christmascoatg
name = "Green Christmas Coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/christmascoatg
+ subcategory = SUBCATEGORY_SUIT_COATS
-/datum/gear/christmascoatrg
+/datum/gear/suit/christmascoatrg
name = "Red and Green Christmas Coat"
- category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/christmascoatrg
+ subcategory = SUBCATEGORY_SUIT_COATS
+
+/datum/gear/suit/samurai
+ name = "Samurai outfit"
+ path = /obj/item/clothing/suit/samurai
diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm
index e667626968..e693f9d2f7 100644
--- a/modular_citadel/code/modules/client/loadout/uniform.dm
+++ b/modular_citadel/code/modules/client/loadout/uniform.dm
@@ -1,562 +1,542 @@
-/datum/gear/suitblack
- name = "Black suit"
- category = SLOT_W_UNIFORM
- path = /obj/item/clothing/under/suit/black
+/datum/gear/uniform
+ category = CATEGORY_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_GENERAL
+ slot = SLOT_W_UNIFORM
-/datum/gear/suitgreen
+/datum/gear/uniform/suit
+ name = "Black suit"
+ path = /obj/item/clothing/under/suit/black
+ subcategory = SUBCATEGORY_UNIFORM_SUITS
+
+/datum/gear/uniform/suit/green
name = "Green suit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/suit/green
-/datum/gear/suitred
+/datum/gear/uniform/suit/red
name = "Red suit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/suit/red
-/datum/gear/suitcharcoal
+/datum/gear/uniform/suit/charcoal
name = "Charcoal suit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/suit/charcoal
-/datum/gear/suitnavy
+/datum/gear/uniform/suit/navy
name = "Navy suit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/suit/navy
-/datum/gear/suitburgundy
+/datum/gear/uniform/suit/burgundy
name = "Burgundy suit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/suit/burgundy
-/datum/gear/suittan
+/datum/gear/uniform/suit/tan
name = "Tan suit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/suit/tan
-/datum/gear/suitwhite
+/datum/gear/uniform/suit/white
name = "White suit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/suit/white
-/datum/gear/assistantformal
+/datum/gear/uniform/assistantformal
name = "Assistant's formal uniform"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/assistantformal
-/datum/gear/maidcostume
+/datum/gear/uniform/maidcostume
name = "Maid costume"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/maid
-/datum/gear/mailmanuniform
+/datum/gear/uniform/mailmanuniform
name = "Mailman's jumpsuit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/mailman
-/datum/gear/skirtblack
+/datum/gear/uniform/skirt
name = "Black skirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/skirt
+ subcategory = SUBCATEGORY_UNIFORM_SKIRTS
-/datum/gear/skirtblue
+/datum/gear/uniform/skirt/blue
name = "Blue skirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/skirt/blue
-/datum/gear/skirtred
+/datum/gear/uniform/skirt/red
name = "Red skirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/skirt/red
-/datum/gear/skirtpurple
+/datum/gear/uniform/skirt/purple
name = "Purple skirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/skirt/purple
-/datum/gear/skirtplaid
+/datum/gear/uniform/skirt/plaid
name = "Plaid skirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/skirt/plaid
-/datum/gear/schoolgirlblue
+/datum/gear/uniform/schoolgirlblue
name = "Blue Schoolgirl Uniform"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/schoolgirl
-/datum/gear/schoolgirlred
+/datum/gear/uniform/schoolgirlred
name = "Red Schoolgirl Uniform"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/schoolgirl/red
-/datum/gear/schoolgirlgreen
+/datum/gear/uniform/schoolgirlgreen
name = "Green Schoolgirl Uniform"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/schoolgirl/green
-/datum/gear/schoolgirlorange
+/datum/gear/uniform/schoolgirlorange
name = "Orange Schoolgirl Uniform"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/schoolgirl/orange
-/datum/gear/stripeddress
+/datum/gear/uniform/dress
name = "Striped Dress"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/striped
+ subcategory = SUBCATEGORY_UNIFORM_DRESSES
-/datum/gear/sundresswhite
+/datum/gear/uniform/dress/sun/white
name = "White Sundress"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/sundress/white
-/datum/gear/sundress
+/datum/gear/uniform/dress/sun
name = "Sundress"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/sundress
-/datum/gear/greendress
+/datum/gear/uniform/dress/green
name = "Green Dress"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/green
-/datum/gear/pinkdress
+/datum/gear/uniform/dress/pink
name = "Pink Dress"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/pink
-/datum/gear/flowerdress
+
+/datum/gear/uniform/dress/orange
name = "Flower Dress"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/flower
-/datum/gear/sweptskirt
+/datum/gear/uniform/skirt/swept
name = "Swept skirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/skirt/swept
-/datum/gear/croptop
+/datum/gear/uniform/croptop
name = "Croptop"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/croptop
-/datum/gear/yoga
+/datum/gear/uniform/pants
name = "Yoga Pants"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/yoga
+ subcategory = SUBCATEGORY_UNIFORM_PANTS
-/datum/gear/kilt
+/datum/gear/uniform/kilt
name = "Kilt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/kilt
-/datum/gear/camoshorts
+/datum/gear/uniform/pants/camo
name = "Camo Pants"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/camo
-/datum/gear/athleticshorts
+/datum/gear/uniform/shorts
name = "Athletic Shorts"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/shorts/red
+ subcategory = SUBCATEGORY_UNIFORM_SHORTS
-/datum/gear/bjeans
+/datum/gear/uniform/pants/bjeans
name = "Black Jeans"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/blackjeans
-/datum/gear/cjeans
+/datum/gear/uniform/pants/cjeans
name = "Classic Jeans"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/classicjeans
-/datum/gear/khaki
+/datum/gear/uniform/pants/khaki
name = "Khaki Pants"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/khaki
-/datum/gear/wpants
+/datum/gear/uniform/pants/white
name = "White Pants"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/white
-/datum/gear/rpants
+/datum/gear/uniform/pants/red
name = "Red Pants"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/red
-/datum/gear/tpants
+/datum/gear/uniform/pants/tan
name = "Tan Pants"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/tan
-/datum/gear/trpants
+/datum/gear/uniform/pants/track
name = "Track Pants"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/track
-/datum/gear/rippedjeans
+/datum/gear/uniform/pants/ripped
name = "Ripped Jeans"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/jeanripped
-/datum/gear/jeanshort
+/datum/gear/uniform/shorts/jean
name = "Jean Shorts"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/jeanshort
-/datum/gear/denimskirt
+/datum/gear/uniform/skirt/denim
name = "Denim Skirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/pants/denimskirt
-/datum/gear/yoga
- name = "Yoga Pants"
- category = SLOT_W_UNIFORM
- path = /obj/item/clothing/under/pants/yoga
-
// Pantsless Sweaters
-/datum/gear/turtleneck
+/datum/gear/uniform/turtleneck
name = "Tactitool Turtleneck"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/syndicate/cosmetic
-/datum/gear/creamsweater
+/datum/gear/uniform/sweater
name = "Cream Commando Sweater"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/sweater
+ subcategory = SUBCATEGORY_UNIFORM_SWEATERS
-/datum/gear/blacksweater
+/datum/gear/uniform/sweater/black
name = "Black Commando Sweater"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/sweater/black
-/datum/gear/purpsweater
+/datum/gear/uniform/sweater/purple
name = "Purple Commando Sweater"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/sweater/purple
-/datum/gear/greensweater
+/datum/gear/uniform/sweater/green
name = "Green Commando Sweater"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/sweater/green
-/datum/gear/redsweater
+/datum/gear/uniform/sweater/red
name = "Red Commando Sweater"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/sweater/red
-/datum/gear/bluesweater
+/datum/gear/uniform/sweater/blue
name = "Navy Commando Sweater"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/sweater/blue
-/datum/gear/keyholesweater
+/datum/gear/uniform/sweater/keyhole
name = "Keyhole Sweater"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/keyholesweater
-/datum/gear/polyjump
+/datum/gear/uniform/polyjump
name = "Polychromic Jumpsuit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/polyjumpsuit
cost = 2
-
-/datum/gear/polyskirt
+
+/datum/gear/uniform/skirt/poly
name = "Polychromic Jumpskirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/skirt/polychromic
cost = 2
-/datum/gear/polysuit
+/datum/gear/uniform/suit/poly
name = "Polychromic Button-up Shirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/poly_shirt
cost = 3
-
-/datum/gear/polypleated
+
+/datum/gear/uniform/skirt/poly/pleated
name = "Polychromic Pleated Sweaterskirt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/dress/skirt/polychromic/pleated
cost = 3
-/datum/gear/polykilt
+/datum/gear/uniform/polykilt
name = "Polychromic Kilt"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/kilt/polychromic
cost = 3
-/datum/gear/polyshorts
+/datum/gear/uniform/shorts/poly
name = "Polychromic Shorts"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/polyshorts
cost = 3
-/datum/gear/polyshortpants
+/datum/gear/uniform/shorts/poly/athletic
name = "Polychromic Athletic Shorts"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/shorts/polychromic
cost = 2
// Trekie things
//TOS
-/datum/gear/trekcmdtos
+/datum/gear/uniform/trekcmdtos
name = "TOS uniform, cmd"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/command
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Heads of Staff"
restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster")
-/datum/gear/trekmedscitos
+/datum/gear/uniform/trekmedscitos
name = "TOS uniform, med/sci"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/medsci
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist")
-/datum/gear/trekengtos
+/datum/gear/uniform/trekengtos
name = "TOS uniform, ops/sec"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/engsec
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Engineering, Security, and Cargo"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
//TNG
-/datum/gear/trekcmdtng
+/datum/gear/uniform/trekcmdtng
name = "TNG uniform, cmd"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/command/next
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Heads of Staff"
restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster")
-/datum/gear/trekmedscitng
+/datum/gear/uniform/trekmedscitng
name = "TNG uniform, med/sci"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/medsci/next
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist")
-/datum/gear/trekengtng
+/datum/gear/uniform/trekengtng
name = "TNG uniform, ops/sec"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/engsec/next
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Engineering, Security, and Cargo"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
//VOY
-/datum/gear/trekcmdvoy
+/datum/gear/uniform/trekcmdvoy
name = "VOY uniform, cmd"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/command/voy
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Heads of Staff"
restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster")
-/datum/gear/trekmedscivoy
+/datum/gear/uniform/trekmedscivoy
name = "VOY uniform, med/sci"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/medsci/voy
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist")
-/datum/gear/trekengvoy
+/datum/gear/uniform/trekengvoy
name = "VOY uniform, ops/sec"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/engsec/voy
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Engineering, Security, and Cargo"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
//DS9
-/datum/gear/trekcmdds9
+/datum/gear/uniform/trekcmdds9
name = "DS9 uniform, cmd"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/command/ds9
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Heads of Staff"
restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster")
-/datum/gear/trekmedscids9
+/datum/gear/uniform/trekmedscids9
name = "DS9 uniform, med/sci"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/medsci/ds9
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist")
-/datum/gear/trekengds9
+/datum/gear/uniform/trekengds9
name = "DS9 uniform, ops/sec"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/engsec/ds9
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Engineering, Security, and Cargo"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
//ENT
-/datum/gear/trekcmdent
+/datum/gear/uniform/trekcmdent
name = "ENT uniform, cmd"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/command/ent
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Heads of Staff"
restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster")
-/datum/gear/trekmedscient
+/datum/gear/uniform/trekmedscient
name = "ENT uniform, med/sci"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/medsci/ent
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Research Director","Scientist", "Roboticist")
-/datum/gear/trekengent
+/datum/gear/uniform/trekengent
name = "ENT uniform, ops/sec"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/engsec/ent
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Engineering, Security, and Cargo"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
//TheMotionPicture
-/datum/gear/trekfedutil
+/datum/gear/uniform/trekfedutil
name = "TMP uniform"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/fedutil
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "All, barring Service and Civilian"
restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster",
"Medical Doctor","Chemist","Virologist","Paramedic","Geneticist","Scientist", "Roboticist",
"Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer",
"Cargo Technician", "Shaft Miner")
-/datum/gear/trekfedtrainee
+/datum/gear/uniform/trekfedtrainee
name = "TMP uniform, trainee"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/fedutil/trainee
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_roles = list("Assistant", "Janitor", "Cargo Technician")
-/datum/gear/trekfedservice
+/datum/gear/uniform/trekfedservice
name = "TMP uniform, service"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/fedutil/service
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Service and Civilian, barring Clown, Mime and Lawyer"
restricted_roles = list("Assistant", "Bartender", "Botanist", "Cook", "Curator", "Janitor", "Chaplain")
//Orvilike
-/datum/gear/orvcmd
+/datum/gear/uniform/orvcmd
name = "ORV uniform, cmd"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/command/orv
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Heads of Staff"
restricted_roles = list("Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Research Director", "Chief Medical Officer", "Quartermaster")
-/datum/gear/orvcmd_capt
+/datum/gear/uniform/orvcmd_capt
name = "ORV uniform, capt"
- category = SLOT_W_UNIFORM
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
path = /obj/item/clothing/under/trek/command/orv/captain
restricted_roles = list("Captain")
-/datum/gear/orvmedsci
+/datum/gear/uniform/orvmedsci
name = "ORV uniform, med/sci"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/medsci/orv
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Medical and Science"
restricted_roles = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Virologist", "Paramedic", "Geneticist", "Research Director", "Scientist", "Roboticist")
-/datum/gear/orvcmd_medsci
+/datum/gear/uniform/orvcmd_medsci
name = "ORV uniform, med/sci, cmd"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/command/orv/medsci
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_roles = list("Chief Medical Officer", "Research Director")
-/datum/gear/orvops
+/datum/gear/uniform/orvops
name = "ORV uniform, ops/sec"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/engsec/orv
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_desc = "Engineering, Security and Cargo"
restricted_roles = list("Chief Engineer", "Atmospheric Technician", "Station Engineer", "Warden", "Detective", "Security Officer", "Head of Security", "Cargo Technician", "Shaft Miner", "Quartermaster")
-/datum/gear/orvcmd_ops
+/datum/gear/uniform/orvcmd_ops
name = "ORV uniform, ops/sec, cmd"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/command/orv/engsec
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_roles = list("Chief Engineer", "Head of Security")
-/datum/gear/orvass
+/datum/gear/uniform/orvass
name = "ORV uniform, assistant"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/orv
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_roles = list("Assistant")
-/datum/gear/orvsrv
+/datum/gear/uniform/orvsrv
name = "ORV uniform, service"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trek/orv/service
+ subcategory = SUBCATEGORY_UNIFORM_JOBS
restricted_roles = list("Assistant", "Bartender", "Botanist", "Cook", "Curator", "Janitor", "Chaplain")
restricted_desc = "Service and Civilian, barring Clown, Mime and Lawyer"
//Memes
-/datum/gear/gear_harnesses
+/datum/gear/uniform/gear_harnesses
name = "Gear Harness"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/gear_harness
//Christmas
/*Commenting out Until next Christmas or made automatic
-/datum/gear/christmasmaler
+/datum/gear/uniform/christmasmaler
name = "Red Masculine Christmas Suit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/christmas
-/datum/gear/christmasmaleg
+/datum/gear/uniform/christmasmaleg
name = "Green Masculine Christmas Suit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/christmas/green
-/datum/gear/christmasfemaler
+/datum/gear/uniform/christmasfemaler
name = "Red Feminine Christmas Suit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/christmas/croptop
-/datum/gear/christmasfemaleg
+/datum/gear/uniform/christmasfemaleg
name = "Green Feminine Christmas Suit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/christmas/croptop/green
-/datum/gear/pinkstripper
+/datum/gear/uniform/pinkstripper
name = "Pink stripper outfit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/stripper
cost = 3
*/
-/datum/gear/greenstripper
+/datum/gear/uniform/greenstripper
name = "Green stripper outfit"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/misc/stripper/green
cost = 3
-/datum/gear/qipao
+/datum/gear/uniform/qipao
name = "Qipao, Black"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/qipao
+ subcategory = SUBCATEGORY_UNIFORM_DRESSES
cost = 3
-/datum/gear/qipao/white
+/datum/gear/uniform/qipao/white
name = "Qipao, White"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/qipao/white
+ subcategory = SUBCATEGORY_UNIFORM_DRESSES
cost = 3
-/datum/gear/qipao/red
+/datum/gear/uniform/qipao/red
name = "Qipao, Red"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/qipao/red
+ subcategory = SUBCATEGORY_UNIFORM_DRESSES
cost = 3
-/datum/gear/cheongsam
+/datum/gear/uniform/cheongsam
name = "Cheongsam, Black"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/cheongsam
+ subcategory = SUBCATEGORY_UNIFORM_DRESSES
cost = 3
-/datum/gear/cheongsam/white
+/datum/gear/uniform/cheongsam/white
name = "Cheongsam, White"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/cheongsam/white
+ subcategory = SUBCATEGORY_UNIFORM_DRESSES
cost = 3
-/datum/gear/cheongsam/red
+/datum/gear/uniform/cheongsam/red
name = "Cheongsam, Red"
- category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/costume/cheongsam/red
+ subcategory = SUBCATEGORY_UNIFORM_DRESSES
cost = 3
+
+/datum/gear/uniform/dress/black
+ name = "Black dress"
+ path = /obj/item/clothing/under/misc/black_dress
+
+/datum/gear/uniform/skirt/pinktutu
+ name = "Pink tutu"
+ path = /obj/item/clothing/under/misc/pinktutu
+
+/datum/gear/uniform/bathrobe
+ name = "Bathrobe"
+ path = /obj/item/clothing/under/misc/bathrobe
+
+/datum/gear/uniform/kimono
+ name = "Kimono"
+ path = /obj/item/clothing/under/costume/kimono
+
+/datum/gear/uniform/kimono/black
+ name = "Black kimono"
+ path = /obj/item/clothing/under/costume/kimono/black
+
+/datum/gear/uniform/kimono/kamishimo
+ name = "Kamishimo"
+ path = /obj/item/clothing/under/costume/kimono/kamishimo
+
+/datum/gear/uniform/kimono/fancy
+ name = "Fancy kimono"
+ path = /obj/item/clothing/under/costume/kimono/fancy
+
+/datum/gear/uniform/kimono/sakura
+ name = "Sakura kimono"
+ path = /obj/item/clothing/under/costume/kimono/sakura
\ No newline at end of file
diff --git a/sound/effects/blood1.ogg b/sound/effects/wounds/blood1.ogg
similarity index 100%
rename from sound/effects/blood1.ogg
rename to sound/effects/wounds/blood1.ogg
diff --git a/sound/effects/blood2.ogg b/sound/effects/wounds/blood2.ogg
similarity index 100%
rename from sound/effects/blood2.ogg
rename to sound/effects/wounds/blood2.ogg
diff --git a/sound/effects/blood3.ogg b/sound/effects/wounds/blood3.ogg
similarity index 100%
rename from sound/effects/blood3.ogg
rename to sound/effects/wounds/blood3.ogg
diff --git a/sound/effects/crack1.ogg b/sound/effects/wounds/crack1.ogg
similarity index 100%
rename from sound/effects/crack1.ogg
rename to sound/effects/wounds/crack1.ogg
diff --git a/sound/effects/crack2.ogg b/sound/effects/wounds/crack2.ogg
similarity index 100%
rename from sound/effects/crack2.ogg
rename to sound/effects/wounds/crack2.ogg
diff --git a/sound/effects/wounds/crackandbleed.ogg b/sound/effects/wounds/crackandbleed.ogg
new file mode 100644
index 0000000000..ea07f13d48
Binary files /dev/null and b/sound/effects/wounds/crackandbleed.ogg differ
diff --git a/sound/effects/wounds/pierce1.ogg b/sound/effects/wounds/pierce1.ogg
new file mode 100644
index 0000000000..cd7b7c3961
Binary files /dev/null and b/sound/effects/wounds/pierce1.ogg differ
diff --git a/sound/effects/wounds/pierce2.ogg b/sound/effects/wounds/pierce2.ogg
new file mode 100644
index 0000000000..4977cab299
Binary files /dev/null and b/sound/effects/wounds/pierce2.ogg differ
diff --git a/sound/effects/wounds/pierce3.ogg b/sound/effects/wounds/pierce3.ogg
new file mode 100644
index 0000000000..e81700b134
Binary files /dev/null and b/sound/effects/wounds/pierce3.ogg differ
diff --git a/sound/effects/sizzle1.ogg b/sound/effects/wounds/sizzle1.ogg
similarity index 100%
rename from sound/effects/sizzle1.ogg
rename to sound/effects/wounds/sizzle1.ogg
diff --git a/sound/effects/sizzle2.ogg b/sound/effects/wounds/sizzle2.ogg
similarity index 100%
rename from sound/effects/sizzle2.ogg
rename to sound/effects/wounds/sizzle2.ogg
diff --git a/sound/roundend/CitadelStationHasSeenBetterDays.ogg b/sound/roundend/CitadelStationHasSeenBetterDays.ogg
new file mode 100644
index 0000000000..2fa0c5b33c
Binary files /dev/null and b/sound/roundend/CitadelStationHasSeenBetterDays.ogg differ
diff --git a/sound/weapons/shot.ogg b/sound/weapons/shot.ogg
new file mode 100644
index 0000000000..6c57482973
Binary files /dev/null and b/sound/weapons/shot.ogg differ
diff --git a/strings/abductee_objectives.txt b/strings/abductee_objectives.txt
index 93fd946818..135bb7673b 100644
--- a/strings/abductee_objectives.txt
+++ b/strings/abductee_objectives.txt
@@ -31,7 +31,7 @@ Flood the station's powernet with as much electricity as you can.
Replace all the floor tiles with wood, carpeting, grass or bling.
You must escape the station! Get the shuttle called!
Don't allow anyone to be cloned.
-The oxygen is killing them all and they don't even know it. Make sure no oxygen is on the station.
+Their cold, mindless gaze pierce your soul. They see your every movements, it's merely a question of time before they try to control us further. Deactivate all cameras!
Your body must be improved. Ingest as many drugs as you can.
You are hungry. Eat as much food as you can find.
You see you see what they cannot you see the open door you seeE you SEeEe you SEe yOU seEee SHOW THEM ALL
diff --git a/strings/wounds/bone_scar_desc.json b/strings/wounds/bone_scar_desc.json
new file mode 100644
index 0000000000..3540547c4a
--- /dev/null
+++ b/strings/wounds/bone_scar_desc.json
@@ -0,0 +1,26 @@
+{
+ "generic": ["general disfigurement"],
+
+ "bluntmoderate": [
+ "the bone equivalent of a faded bruise",
+ "a series of tiny chip marks"
+ ],
+
+ "bluntsevere": [
+ "a series of faded hairline cracks",
+ "a small bone dent"
+ ],
+
+ "bluntcritical": [
+ "large streaks of refilled cracks",
+ "a fractal of reformed stress marks",
+ "a cluster of calluses"
+ ],
+
+ "dismember": [
+ "is slightly misaligned",
+ "has clearly been dropped recently",
+ "has a damaged socket"
+ ]
+
+}
\ No newline at end of file
diff --git a/strings/wounds/flesh_scar_desc.json b/strings/wounds/flesh_scar_desc.json
new file mode 100644
index 0000000000..fb2b927a30
--- /dev/null
+++ b/strings/wounds/flesh_scar_desc.json
@@ -0,0 +1,86 @@
+{
+ "generic": ["general disfigurement"],
+
+ "bluntmoderate": [
+ "light discoloring",
+ "a slight blue tint"
+ ],
+
+ "bluntsevere": [
+ "a faded, fist-sized bruise",
+ "a vaguely triangular peel scar"
+ ],
+
+ "bluntcritical": [
+ "a section of janky skin lines and badly healed scars",
+ "a large patch of uneven skin tone",
+ "a cluster of calluses"
+ ],
+
+
+
+ "slashmoderate": [
+ "light, faded lines",
+ "minor cut marks",
+ "a small faded slit",
+ "a series of small scars"
+ ],
+
+ "slashsevere": [
+ "a twisted line of faded gashes",
+ "a gnarled sickle-shaped slice scar"
+ ],
+
+ "slashcritical": [
+ "a winding path of very badly healed scar tissue",
+ "a series of peaks and valleys along a gruesome line of cut scar tissue",
+ "a grotesque snake of indentations and stitching scars"
+ ],
+
+
+
+ "piercemoderate": [
+ "a small, faded bruise",
+ "a small twist of reformed skin",
+ "a thumb-sized puncture scar"
+ ],
+
+ "piercesevere": [
+ "an ink-splat shaped pocket of scar tissue",
+ "a long-faded puncture wound",
+ "a tumbling puncture hole with evidence of faded stitching"
+ ],
+
+ "piercecritical": [
+ "a rippling shockwave of scar tissue",
+ "a wide, scattered cloud of shrapnel marks",
+ "a gruesome multi-pronged puncture scar"
+ ],
+
+
+
+ "burnmoderate": [
+ "small amoeba-shaped skinmarks",
+ "a faded streak of depressed skin"
+ ],
+
+ "burnsevere": [
+ "a large, jagged patch of faded skin",
+ "random spots of shiny, smooth skin",
+ "spots of taut, leathery skin"
+ ],
+
+ "burncritical": [
+ "massive, disfiguring keloid scars",
+ "several long streaks of badly discolored and malformed skin",
+ "unmistakeable splotches of dead tissue from serious burns"
+ ],
+
+
+ "dismember": [
+ "is several skintone shades paler than the rest of the body",
+ "is a gruesome patchwork of artificial flesh",
+ "has a large series of attachment scars at the articulation points"
+ ]
+
+}
\ No newline at end of file
diff --git a/strings/wounds/scar_loc.json b/strings/wounds/scar_loc.json
new file mode 100644
index 0000000000..f721294925
--- /dev/null
+++ b/strings/wounds/scar_loc.json
@@ -0,0 +1,52 @@
+{
+ "": ["general area"],
+
+ "head": [
+ "left eyebrow",
+ "cheekbone",
+ "neck",
+ "throat",
+ "jawline",
+ "entire face"
+ ],
+
+ "chest": [
+ "upper chest",
+ "lower abdomen",
+ "midsection",
+ "collarbone",
+ "lower back"
+ ],
+
+ "l_arm": [
+ "outer left forearm",
+ "inner left wrist",
+ "left elbow",
+ "left bicep",
+ "left shoulder"
+ ],
+
+ "r_arm": [
+ "outer right forearm",
+ "inner right wrist",
+ "right elbow",
+ "right bicep",
+ "right shoulder"
+ ],
+
+ "l_leg": [
+ "inner left thigh",
+ "outer left calf",
+ "outer left hip",
+ "left kneecap",
+ "lower left shin"
+ ],
+
+ "r_leg": [
+ "inner right thigh",
+ "outer right calf",
+ "outer right hip",
+ "right kneecap",
+ "lower right shin"
+ ]
+}
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index b33277b4c0..faa1ce990c 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -61,6 +61,7 @@
#include "code\__DEFINES\language.dm"
#include "code\__DEFINES\layers_planes.dm"
#include "code\__DEFINES\lighting.dm"
+#include "code\__DEFINES\loadout.dm"
#include "code\__DEFINES\logging.dm"
#include "code\__DEFINES\machines.dm"
#include "code\__DEFINES\maps.dm"
@@ -200,6 +201,7 @@
#include "code\_globalvars\lists\client.dm"
#include "code\_globalvars\lists\flavor_misc.dm"
#include "code\_globalvars\lists\keybindings.dm"
+#include "code\_globalvars\lists\loadout_categories.dm"
#include "code\_globalvars\lists\maintenance_loot.dm"
#include "code\_globalvars\lists\mapping.dm"
#include "code\_globalvars\lists\medals.dm"
@@ -432,6 +434,7 @@
#include "code\datums\components\igniter.dm"
#include "code\datums\components\infective.dm"
#include "code\datums\components\jousting.dm"
+#include "code\datums\components\killerqueen.dm"
#include "code\datums\components\knockback.dm"
#include "code\datums\components\knockoff.dm"
#include "code\datums\components\lifesteal.dm"
@@ -670,7 +673,9 @@
#include "code\datums\wounds\_wounds.dm"
#include "code\datums\wounds\bones.dm"
#include "code\datums\wounds\burns.dm"
-#include "code\datums\wounds\cuts.dm"
+#include "code\datums\wounds\loss.dm"
+#include "code\datums\wounds\pierce.dm"
+#include "code\datums\wounds\slash.dm"
#include "code\game\alternate_appearance.dm"
#include "code\game\atoms.dm"
#include "code\game\atoms_movable.dm"
@@ -1519,6 +1524,7 @@
#include "code\modules\antagonists\clockcult\clock_effects\servant_blocker.dm"
#include "code\modules\antagonists\clockcult\clock_effects\spatial_gateway.dm"
#include "code\modules\antagonists\clockcult\clock_helpers\clock_powerdrain.dm"
+#include "code\modules\antagonists\clockcult\clock_helpers\clock_rites.dm"
#include "code\modules\antagonists\clockcult\clock_helpers\component_helpers.dm"
#include "code\modules\antagonists\clockcult\clock_helpers\fabrication_helpers.dm"
#include "code\modules\antagonists\clockcult\clock_helpers\hierophant_network.dm"
@@ -1526,6 +1532,7 @@
#include "code\modules\antagonists\clockcult\clock_helpers\ratvarian_language.dm"
#include "code\modules\antagonists\clockcult\clock_helpers\scripture_checks.dm"
#include "code\modules\antagonists\clockcult\clock_helpers\slab_abilities.dm"
+#include "code\modules\antagonists\clockcult\clock_items\clock_augments.dm"
#include "code\modules\antagonists\clockcult\clock_items\clock_components.dm"
#include "code\modules\antagonists\clockcult\clock_items\clockwork_armor.dm"
#include "code\modules\antagonists\clockcult\clock_items\clockwork_slab.dm"
@@ -1537,6 +1544,7 @@
#include "code\modules\antagonists\clockcult\clock_items\soul_vessel.dm"
#include "code\modules\antagonists\clockcult\clock_items\wraith_spectacles.dm"
#include "code\modules\antagonists\clockcult\clock_items\clock_weapons\_call_weapon.dm"
+#include "code\modules\antagonists\clockcult\clock_items\clock_weapons\brass_claw.dm"
#include "code\modules\antagonists\clockcult\clock_items\clock_weapons\ratvarian_shield.dm"
#include "code\modules\antagonists\clockcult\clock_items\clock_weapons\ratvarian_spear.dm"
#include "code\modules\antagonists\clockcult\clock_mobs\_eminence.dm"
@@ -3307,6 +3315,7 @@
#include "code\modules\surgery\plastic_surgery.dm"
#include "code\modules\surgery\prosthetic_replacement.dm"
#include "code\modules\surgery\remove_embedded_object.dm"
+#include "code\modules\surgery\repair_puncture.dm"
#include "code\modules\surgery\surgery.dm"
#include "code\modules\surgery\surgery_step.dm"
#include "code\modules\surgery\tools.dm"
diff --git a/tgui/yarn.lock b/tgui/yarn.lock
index a2a23a7998..c2fc3a185f 100644
--- a/tgui/yarn.lock
+++ b/tgui/yarn.lock
@@ -1241,9 +1241,9 @@ bluebird@^3.5.5:
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
- version "4.11.8"
- resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
- integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
+ version "4.11.9"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
+ integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
body-parser@1.19.0:
version "1.19.0"
@@ -2203,9 +2203,9 @@ electron-to-chromium@^1.3.390:
integrity sha512-DbCBdwtARI0l3e3m6ZIxVaTNahb6dSsmGjuag/twiVcWuM4MSpL5IfsJsJSyqLqxosE/m0CXlZaBmxegQW/dAg==
elliptic@^6.0.0:
- version "6.5.2"
- resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762"
- integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==
+ version "6.5.3"
+ resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
+ integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==
dependencies:
bn.js "^4.4.0"
brorand "^1.0.1"