diff --git a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm index 5da534a08e..3e5c80253d 100644 --- a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm +++ b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm @@ -1453,7 +1453,7 @@ /area/ruin/space/has_grav/hotel/guestroom/room_2) "eu" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/wood, /area/ruin/space/has_grav/hotel/guestroom/room_2) "ev" = ( diff --git a/_maps/RandomZLevels/away_mission/research.dmm b/_maps/RandomZLevels/away_mission/research.dmm index cdb7cf680b..4710d9829b 100644 --- a/_maps/RandomZLevels/away_mission/research.dmm +++ b/_maps/RandomZLevels/away_mission/research.dmm @@ -5371,7 +5371,7 @@ /area/awaymission/research/interior/dorm) "kS" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/plasteel, /area/awaymission/research/interior/dorm) "kT" = ( diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 3a1ce84ba2..d91dd5b7c8 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -350,7 +350,7 @@ /area/security/prison) "aaV" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/plasteel, /area/security/prison) "aaW" = ( @@ -54870,7 +54870,7 @@ /area/engine/atmos) "hgO" = ( /obj/structure/table, -/obj/item/storage/pill_bottle/dice{ +/obj/item/storage/box/dice{ pixel_x = 4; pixel_y = 4 }, diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index ce7186f523..db191d5b2d 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -124,6 +124,45 @@ }, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) +"aaq" = ( +/obj/machinery/button/door{ + id = "cargounload"; + layer = 4; + name = "Loading Doors"; + pixel_x = 24; + pixel_y = 8 + }, +/obj/machinery/button/door{ + id = "cargoload"; + layer = 4; + name = "Loading Doors"; + pixel_x = 24; + pixel_y = -8 + }, +/obj/machinery/computer/cargo{ + dir = 8 + }, +/obj/machinery/camera{ + c_tag = "Cargo Bay - Starboard"; + dir = 8; + name = "cargo camera" + }, +/obj/effect/turf_decal/bot, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/quartermaster/storage) +"aar" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/central) "aas" = ( /obj/docking_port/stationary/random{ id = "pod_lavaland1"; @@ -143,10 +182,215 @@ /obj/effect/landmark/xeno_spawn, /turf/open/space, /area/solar/starboard/fore) +"aav" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/crew_quarters/fitness/recreation) +"aaw" = ( +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/crew_quarters/fitness/recreation) +"aax" = ( +/obj/machinery/light, +/obj/machinery/camera{ + c_tag = "Recreation - Aft"; + dir = 1; + name = "recreation camera" + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"aay" = ( +/turf/closed/wall, +/area/crew_quarters/fitness/pool) +"aaz" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/airlock/public/glass{ + name = "Pool" + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/pool) +"aaA" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/crew_quarters/fitness/pool) +"aaB" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"aaC" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/portable_atmospherics/canister/air, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"aaD" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/turf/open/floor/plating, +/area/crew_quarters/fitness/pool) "aaE" = ( /obj/structure/lattice/catwalk, /turf/open/space, /area/solar/starboard/fore) +"aaF" = ( +/obj/structure/closet/athletic_mixed, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/item/toy/poolnoodle/blue, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"aaG" = ( +/obj/structure/closet/athletic_mixed, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/item/toy/poolnoodle/red, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"aaH" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"aaI" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/table/glass, +/obj/structure/bedsheetbin/towel, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"aaJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/table/glass, +/obj/item/storage/firstaid/regular, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"aaK" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"aaL" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"aaM" = ( +/obj/structure/bed, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"aaN" = ( +/turf/open/pool, +/area/crew_quarters/fitness/pool) "aaO" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -154,9 +398,147 @@ "aaP" = ( /turf/closed/wall/mineral/plastitanium, /area/hallway/secondary/entry) +"aaQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/structure/sign/poster/official/walk{ + pixel_x = -32 + }, +/turf/open/floor/plasteel/yellowsiding/corner, +/area/crew_quarters/fitness/pool) +"aaR" = ( +/obj/machinery/space_heater, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) "aaS" = ( /turf/closed/wall/mineral/plastitanium, /area/construction/mining/aux_base) +"aaT" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"aaU" = ( +/obj/machinery/door/airlock/maintenance_hatch/abandoned{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"aaV" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/yellowsiding, +/area/crew_quarters/fitness/pool) +"aaW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"aaX" = ( +/obj/machinery/pool/controller, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/yellowsiding, +/area/crew_quarters/fitness/pool) +"aaY" = ( +/obj/structure/pool/Lboard, +/turf/open/pool, +/area/crew_quarters/fitness/pool) +"aaZ" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/yellowsiding/corner{ + icon_state = "yellowcornersiding"; + dir = 8 + }, +/area/crew_quarters/fitness/pool) +"aba" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -24; + pixel_y = 0 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 4 + }, +/area/crew_quarters/fitness/pool) +"abb" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"abc" = ( +/obj/machinery/door/airlock/maintenance_hatch/abandoned{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"abd" = ( +/obj/structure/pool/ladder{ + dir = 2; + pixel_y = 24 + }, +/turf/open/pool, +/area/crew_quarters/fitness/pool) "abe" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -166,6 +548,31 @@ "abf" = ( /turf/closed/wall, /area/hallway/secondary/entry) +"abg" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/rack, +/obj/item/weldingtool, +/obj/item/assembly/voice, +/obj/item/clothing/head/welding, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"abh" = ( +/obj/effect/landmark/blobstart, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) "abi" = ( /turf/closed/wall, /area/construction/mining/aux_base) @@ -173,6 +580,61 @@ /obj/structure/lattice/catwalk, /turf/open/space, /area/space/nearstation) +"abk" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/landmark/event_spawn, +/obj/structure/reagent_dispensers/watertank, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"abl" = ( +/obj/machinery/pool/filter{ + pixel_y = 16 + }, +/turf/open/pool, +/area/crew_quarters/fitness/pool) +"abm" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 8 + }, +/area/crew_quarters/fitness/pool) +"abn" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 4 + }, +/area/crew_quarters/fitness/pool) +"abo" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) "abp" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small{ @@ -196,6 +658,18 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) +"abr" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) "abs" = ( /obj/docking_port/stationary{ dwidth = 1; @@ -207,11 +681,94 @@ /obj/structure/fans/tiny/invisible, /turf/open/space/basic, /area/space) +"abt" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/crew_quarters/fitness/pool) +"abu" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/camera{ + c_tag = "Pool - Portside"; + dir = 4; + name = "pool camera" + }, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 4 + }, +/area/crew_quarters/fitness/pool) "abv" = ( /obj/item/stack/cable_coil, /obj/structure/lattice/catwalk, /turf/open/space, /area/solar/starboard/fore) +"abw" = ( +/obj/machinery/pool/drain, +/turf/open/pool, +/area/crew_quarters/fitness/pool) +"abx" = ( +/obj/structure/pool/Rboard, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 8 + }, +/area/crew_quarters/fitness/pool) +"aby" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Pool - Starboard"; + dir = 8; + name = "pool camera" + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"abz" = ( +/obj/structure/closet/firecloset, +/turf/open/floor/plating, +/area/hallway/secondary/construction) +"abA" = ( +/obj/structure/dresser, +/turf/open/floor/wood, +/area/maintenance/starboard/aft) +"abB" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 4 + }, +/area/crew_quarters/fitness/pool) "abC" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -262,6 +819,95 @@ }, /turf/open/floor/plasteel, /area/construction/mining/aux_base) +"abI" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/starboard/aft) +"abJ" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/effect/landmark/xeno_spawn, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/starboard/aft) +"abK" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/reagent_dispensers/fueltank, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/maintenance/starboard/aft) +"abL" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"abM" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/closet/emcloset, +/obj/item/clothing/mask/breath, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"abN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/machinery/portable_atmospherics/canister/air, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) +"abO" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 4 + }, +/area/crew_quarters/fitness/pool) "abP" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock/external{ @@ -306,6 +952,71 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/construction/mining/aux_base) +"abU" = ( +/obj/structure/pool/ladder{ + dir = 1; + pixel_y = -24 + }, +/turf/open/pool, +/area/crew_quarters/fitness/pool) +"abV" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_x = -26 + }, +/turf/open/floor/plasteel/yellowsiding/corner{ + icon_state = "yellowcornersiding"; + dir = 4 + }, +/area/crew_quarters/fitness/pool) +"abW" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"abX" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/yellowsiding/corner{ + icon_state = "yellowcornersiding"; + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"abY" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/closet/secure_closet/personal, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/item/toy/poolnoodle/yellow, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) "abZ" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/stripes/line, @@ -365,6 +1076,117 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) +"acg" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/closet/secure_closet/personal, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/item/toy/poolnoodle/red, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"ach" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"aci" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"acj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"ack" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"acl" = ( +/obj/structure/table/wood, +/obj/item/clothing/suit/toggle/owlwings, +/obj/item/clothing/under/costume/owl, +/obj/item/clothing/mask/gas/owl_mask, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/starboard/aft) +"acm" = ( +/obj/structure/table/wood, +/obj/item/storage/secure/briefcase, +/obj/item/restraints/handcuffs, +/obj/item/grenade/smokebomb, +/turf/open/floor/wood, +/area/maintenance/starboard/aft) +"acn" = ( +/obj/structure/table/wood, +/obj/item/modular_computer/tablet/preset/cheap, +/turf/open/floor/wood, +/area/maintenance/starboard/aft) "aco" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -452,6 +1274,43 @@ }, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) +"acw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/closet/secure_closet/personal, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/item/toy/poolnoodle/blue, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) +"acx" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/light, +/obj/structure/closet/secure_closet/personal, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/item/toy/poolnoodle/blue, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/pool) "acF" = ( /obj/docking_port/stationary{ dir = 2; @@ -13899,32 +14758,6 @@ }, /turf/open/floor/plasteel, /area/quartermaster/storage) -"aEg" = ( -/obj/machinery/button/door{ - id = "cargounload"; - layer = 4; - name = "Loading Doors"; - pixel_x = 24; - pixel_y = 8 - }, -/obj/machinery/button/door{ - id = "cargoload"; - layer = 4; - name = "Loading Doors"; - pixel_x = 24; - pixel_y = -8 - }, -/obj/machinery/computer/cargo{ - dir = 8 - }, -/obj/machinery/camera{ - c_tag = "Cargo Bay - Starboard"; - dir = 8; - name = "cargo camera" - }, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/quartermaster/storage) "aEi" = ( /obj/structure/cable/white{ icon_state = "0-2" @@ -19546,7 +20379,7 @@ /area/security/prison) "aND" = ( /obj/structure/table, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -20242,7 +21075,7 @@ /area/crew_quarters/bar/atrium) "aOJ" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -72671,7 +73504,7 @@ /area/library) "ctL" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -32 }, @@ -94052,27 +94885,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) -"ddw" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel{ - heat_capacity = 1e+006 - }, -/area/crew_quarters/fitness/recreation) -"ddx" = ( -/obj/machinery/light, -/obj/machinery/camera{ - c_tag = "Recreation - Aft"; - dir = 1; - name = "recreation camera" - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/crew_quarters/fitness/recreation) "ddy" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/tile/neutral, @@ -94698,7 +95510,7 @@ /area/medical/medbay/central) "deG" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /obj/structure/sign/poster/official/help_others{ pixel_x = -32 }, @@ -97387,28 +98199,6 @@ }, /turf/open/floor/plasteel, /area/maintenance/starboard/aft) -"diX" = ( -/obj/effect/decal/cleanable/cobweb, -/obj/structure/dresser, -/turf/open/floor/wood, -/area/maintenance/starboard/aft) -"diY" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table/wood, -/obj/item/clothing/suit/toggle/owlwings, -/obj/item/clothing/under/costume/owl, -/obj/item/clothing/mask/gas/owl_mask, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) -"diZ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/table/wood, -/obj/item/storage/secure/briefcase, -/obj/item/restraints/handcuffs, -/obj/item/grenade/smokebomb, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "dja" = ( /obj/machinery/vending/assist, /obj/machinery/newscaster{ @@ -98421,20 +99211,6 @@ }, /turf/open/floor/plasteel/dark, /area/medical/abandoned) -"dkO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/space_heater, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) -"dkP" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/maintenance/starboard/aft) "dkQ" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock/maintenance_hatch/abandoned{ @@ -98452,30 +99228,6 @@ }, /turf/open/floor/plasteel, /area/maintenance/starboard/aft) -"dkR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/xeno_spawn, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken2" - }, -/area/maintenance/starboard/aft) -"dkS" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/chair/office/dark{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/starboard/aft) -"dkT" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/table/wood, -/obj/item/modular_computer/tablet/preset/cheap, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "dkU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, @@ -99878,41 +100630,6 @@ }, /turf/open/floor/plasteel, /area/maintenance/starboard/aft) -"dnV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/maintenance/starboard/aft) -"dnW" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/maintenance/starboard/aft) -"dnX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/xeno_spawn, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) -"dnY" = ( -/obj/machinery/portable_atmospherics/canister/air, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/maintenance/starboard/aft) "dnZ" = ( /obj/machinery/light/small{ dir = 8 @@ -100843,29 +101560,6 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/construction) -"dpJ" = ( -/obj/effect/landmark/blobstart, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) -"dpK" = ( -/obj/structure/closet/emcloset, -/obj/item/clothing/mask/breath, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) -"dpL" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/maintenance/starboard/aft) -"dpM" = ( -/obj/machinery/portable_atmospherics/canister/air, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "dpN" = ( /obj/structure/table/wood/poker, /obj/item/clothing/glasses/sunglasses/big, @@ -101733,11 +102427,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/hallway/secondary/construction) -"drr" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/landmark/event_spawn, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "drs" = ( /obj/structure/chair/stool/bar, /obj/machinery/light/small{ @@ -104149,36 +104838,6 @@ }, /turf/open/floor/plasteel, /area/maintenance/starboard/aft) -"dvQ" = ( -/obj/structure/rack, -/obj/effect/decal/cleanable/dirt, -/obj/item/weldingtool, -/obj/item/assembly/voice, -/obj/item/clothing/head/welding, -/obj/effect/spawner/lootdrop/maintenance, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/maintenance/starboard/aft) -"dvR" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/oil, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/starboard/aft) -"dvS" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/structure/reagent_dispensers/fueltank, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "dvT" = ( /obj/structure/table/wood, /obj/machinery/newscaster{ @@ -105139,22 +105798,6 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"dxz" = ( -/obj/effect/landmark/xeno_spawn, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/maintenance/starboard/aft) -"dxA" = ( -/obj/structure/closet/firecloset, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/maintenance/starboard/aft) "dxB" = ( /obj/structure/chair/wood/normal{ dir = 1 @@ -105990,13 +106633,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/hallway/secondary/construction) -"dyT" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "dyU" = ( /turf/closed/wall/r_wall, /area/maintenance/solars/starboard/aft) @@ -107606,16 +108242,6 @@ heat_capacity = 1e+006 }, /area/maintenance/starboard/aft) -"dBE" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "dBF" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -108377,12 +109003,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/maintenance/starboard/aft) -"dDa" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "dDb" = ( /obj/structure/sign/warning/electricshock, /turf/closed/wall/r_wall, @@ -116328,7 +116948,7 @@ /area/library/abandoned) "dQx" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/carpet, /area/library/abandoned) "dQy" = ( @@ -122570,7 +123190,7 @@ /area/hallway/secondary/exit/departure_lounge) "ecH" = ( /obj/structure/table, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) @@ -161323,7 +161943,7 @@ bvL cjw bYU bvL -bvL +aar bvL bun bvL @@ -172835,7 +173455,7 @@ ayD ayD hdH azD -aEg +aaq azD kam aHV @@ -178579,7 +179199,7 @@ dnR dpG dpG dpG -dpG +abz dpG dxu dyQ @@ -179098,7 +179718,7 @@ dvO dxw dyS dmh -dBz +abK dCV dEk dFt @@ -179598,22 +180218,22 @@ cZX dbD ddt ddt -dfV +aaB dbD diW -dkO +aaR dbA dnU -dbD -drr -diW +abg +abk +abo due dbD dbD -dyT diW -dBE -dCV +diW +abL +abM dEk dFv dGN @@ -179855,22 +180475,22 @@ cZY dbE cRr cRr -dfW +aaC dhB -cRr -dkP -dbE -dnV -dpJ dfW -dhB +aaT +aaW +abb +abh +dfW +abr dhB dvP dxx dfW dvP dBF -dDa +abN dEk dFw dGO @@ -180111,17 +180731,17 @@ cYp cZZ cIX ddu -cHU -dfX -cHU -cHU -dkQ -cHU -dkQ -cHU -cHU -dfX -cHU +aay +aaD +aay +aay +aaU +aay +abc +aay +aay +abt +aay cHU dkQ dyU @@ -180368,19 +180988,19 @@ cYq daa cuL cuL -cuL -aad -cHU -diX -dkR -cHU -dnW -dpK -cHU -aad -cHU -dvQ -dxy +aay +aaF +aaQ +aba +abn +abu +abB +abO +abV +abY +aay +abA +abI dyU dAl dBH @@ -180625,19 +181245,19 @@ cYr dab dbF ddv -cuL -aaa -dhC -diY -dkS -cHU -dnX -dpL -dfX -aaa -dfX -dvR -dxz +aay +aaG +aaV +aaN +aaN +aaN +aaN +aaN +abW +acg +aay +acl +abJ dyU dAm dBI @@ -180881,20 +181501,20 @@ cWD cAz dac cxy -ddw -cuM -aad -dhC -diZ -dkT -cHU -dnY -dpM -dfX -aad -dfX -dvS -dxA +aav +aaz +aaH +aaV +aaN +aaN +aaN +aaN +aaN +abW +acw +aay +acm +acn dyU dAn dBJ @@ -181138,19 +181758,19 @@ cWE cYs dad cTe -ddw -cuM -aaa +aav +aaz +aaH +aaV +aaN +aaN +aaN +aaN +aaN +abW +abY +aay dhC -dhC -cHU -cHU -cHU -dfX -dfX -aaa -dfX -dfX cHU dyV dyV @@ -181395,18 +182015,18 @@ cTe cYt dae dbG -ddw -cuM -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +aaw +aaA +aaH +aaV +abd +aaN +aaN +aaN +abU +abW +acg +aay aad aad aad @@ -181652,18 +182272,18 @@ cxy cYt daf dbH -ddx -cuM -aad -aaa -ajr -ajr -ajr -ajr -ajr -aaa -ajr -aaa +aax +aaA +aaI +aaV +aaN +aaN +abw +aaN +aaN +abW +acx +aay ajr ajr aad @@ -181909,18 +182529,18 @@ cWF cYu dag dbI -cDL -cuM -aad -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +dbJ +aaA +aaJ +aaV +aaN +aaN +aaN +aaN +aaN +abW +ach +aaA aaa aaa aad @@ -182167,17 +182787,17 @@ cYv dah cTe dbJ -cuM -aad -ajr -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aaA +aaH +aaV +aaN +aaN +aaN +aaN +aaN +abW +aci +aaA aaa aaa ajr @@ -182424,19 +183044,19 @@ cYw czl cxy dbJ -cuM -aad -ajr -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aaA +aaH +aaX +aaN +aaN +aaN +aaN +aaN +abW +acj +aaA +qgU +qgU aad aaa dBO @@ -182681,17 +183301,17 @@ cQa dai dbJ ddy -cuM -aad -aaa -aaa -aaa -hZh -hZh -hZh -hZh -hZh -hZh +aaA +aaK +aaV +abl +aaN +aaY +aaN +aaN +abW +ack +aaA aaa aaa ajr @@ -182938,17 +183558,17 @@ cuM daj dbK ddz -cuM -aad -ajr -aaa -aaa -hZh -hZh -hZh -hZh -hZh -hZh +aaA +aaL +aaZ +abm +abm +abx +abm +abm +abX +aaL +aaA aaa aaa ajr @@ -183195,17 +183815,17 @@ cuM dak dbL ddA -cuM -aad -ajr -aaa -aaa -hZh -hZh -hZh -hZh -hZh -hZh +aaA +aaM +aaM +aaM +aaM +aby +aaM +aaM +aaM +aaM +aaA aaa aaa ajr @@ -183452,19 +184072,19 @@ cuL cuM cuM cuM -cuL -aad -aaa -aaa -aaa -hZh -hZh -hZh -hZh -hZh -hZh -aaa -aaa +aay +aaA +aaA +aaA +aaA +aay +aaA +aaA +aaA +aaA +aay +qgU +qgU aad aaa dBO @@ -183711,18 +184331,18 @@ aad aad aad aad -ajr +aad +qgU aaa aaa -hZh -hZh -hZh -hZh -hZh -hZh aaa aaa -ajr +qgU +aaa +aaa +aaa +aaa +aad aad dBO dDf @@ -183969,16 +184589,16 @@ aaa ajr ajr ajr -aaa -aaa -hZh -hZh -hZh -hZh -hZh -hZh -aaa -aaa +qgU +ajr +ajr +ajr +ajr +qgU +ajr +ajr +ajr +qgU ajr aaa aaa @@ -184228,12 +184848,12 @@ aaa aaa aaa aaa -hZh -hZh -hZh -hZh -hZh -hZh +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa ajr @@ -184485,12 +185105,12 @@ aaa aaa aaa aaa -hZh -hZh -hZh -hZh -hZh -hZh +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -184742,12 +185362,12 @@ aaa aaa aaa aaa -hZh -hZh -hZh -hZh -hZh -hZh +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -184999,12 +185619,12 @@ aaa aaa aaa aaa -hZh -hZh -hZh -hZh -hZh -hZh +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -185256,12 +185876,12 @@ aaa aaa aaa aaa -hZh -hZh -hZh -hZh -hZh -hZh +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -185513,12 +186133,12 @@ aaa aaa aab aaa -hZh -hZh -hZh -hZh -hZh -hZh +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 794f05498d..d6e413f1de 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -922,7 +922,7 @@ /area/security/prison) "acb" = ( /obj/structure/table, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/plasteel, /area/security/prison) "acc" = ( @@ -15603,7 +15603,7 @@ /area/crew_quarters/dorms) "aDZ" = ( /obj/structure/table, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aEa" = ( @@ -21182,7 +21182,7 @@ /area/crew_quarters/locker) "aPI" = ( /obj/structure/table, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aPJ" = ( @@ -42467,7 +42467,7 @@ dir = 10 }, /obj/structure/table/wood/poker, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/wood, /area/crew_quarters/bar) "bFt" = ( diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 79d665b63c..f3b1b2afb6 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -5281,16 +5281,8 @@ /turf/open/floor/plating, /area/asteroid/nearstation) "ail" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/landmark/start/chief_medical_officer, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) +/turf/closed/wall, +/area/medical/genetics) "aim" = ( /obj/structure/chair/office/dark{ dir = 8 @@ -5559,21 +5551,28 @@ /turf/open/floor/plasteel, /area/quartermaster/storage) "aiJ" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/yellow{ +/obj/machinery/light{ dir = 1 }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 +/obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/medical/chemistry"; + dir = 1; + name = "Chemistry Lab APC"; + pixel_y = 25 + }, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/item/kirbyplants{ + icon_state = "plant-21" + }, +/obj/machinery/camera{ + c_tag = "Chemistry" }, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/obj/effect/landmark/start/chemist, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/medical/chemistry) "aiK" = ( /obj/structure/closet/crate/bin, @@ -5659,23 +5658,20 @@ /turf/open/floor/plasteel/white, /area/science/research) "aiQ" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/blue{ +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 +/obj/structure/cable/white{ + icon_state = "2-4" }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 }, -/obj/effect/landmark/start/paramedic, /turf/open/floor/plasteel, -/area/medical/medbay/zone3) +/area/hallway/primary/port/aft) "aiR" = ( /obj/machinery/suit_storage_unit/security, /obj/machinery/firealarm{ @@ -6168,21 +6164,8 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "ajG" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/landmark/start/chief_medical_officer, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/turf/closed/wall/r_wall, +/area/crew_quarters/heads/cmo) "ajH" = ( /obj/structure/plasticflaps/opaque, /obj/effect/turf_decal/delivery, @@ -10485,21 +10468,8 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "aqo" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/door/airlock/external{ - name = "External Airlock"; - req_access_txt = "13" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) +/turf/closed/wall/r_wall, +/area/maintenance/port/aft) "aqp" = ( /obj/machinery/autolathe, /obj/structure/extinguisher_cabinet{ @@ -10587,17 +10557,15 @@ /turf/open/floor/plating, /area/crew_quarters/heads/hos) "aqx" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 +/obj/structure/cable/white{ + icon_state = "2-4" }, -/obj/effect/landmark/xeno_spawn, -/obj/structure/sign/warning/vacuum{ - pixel_x = -32; - pixel_y = 32 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/maintenance/port) +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aqy" = ( /obj/structure/cable/white, /obj/effect/spawner/structure/window/reinforced, @@ -12702,24 +12670,14 @@ /turf/open/floor/wood, /area/security/detectives_office) "atE" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/structure/cable/white{ + icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/external{ - name = "External Airlock"; - req_access_txt = "13" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) +/turf/open/floor/plating, +/area/maintenance/port/aft) "atF" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -14003,15 +13961,16 @@ /turf/open/floor/wood, /area/security/detectives_office) "avB" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/structure/sign/warning/vacuum{ - pixel_x = -32; - pixel_y = 32 +/turf/open/floor/plating{ + icon_state = "panelscorched" }, -/turf/open/floor/plating, -/area/maintenance/port) +/area/maintenance/port/aft) "avC" = ( /obj/structure/sign/poster/ripped, /turf/closed/wall/rust, @@ -14668,11 +14627,16 @@ /turf/open/floor/engine/o2, /area/engine/atmos) "awB" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/port) +/turf/open/floor/plating{ + icon_state = "platingdmg1" + }, +/area/maintenance/port/aft) "awC" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 @@ -14708,27 +14672,46 @@ /area/maintenance/starboard/aft) "awE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 }, /turf/open/floor/plating, -/area/maintenance/port) +/area/maintenance/port/aft) "awF" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/atmos) "awG" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/maintenance/port) -"awH" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"awH" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/machinery/light/small, -/obj/structure/closet/emcloset/anchored, -/turf/open/floor/plasteel, -/area/maintenance/port) +/turf/closed/wall/r_wall, +/area/maintenance/port/aft) "awI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 5 @@ -14756,11 +14739,15 @@ /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "awL" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, /turf/open/floor/plating, -/area/maintenance/port) +/area/maintenance/port/aft) "awM" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -15023,69 +15010,72 @@ /turf/open/floor/plasteel, /area/maintenance/starboard) "axh" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/structure/closet, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plating/airless, -/area/maintenance/port) +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "axi" = ( /obj/machinery/air_sensor/atmos/oxygen_tank, /turf/open/floor/engine/o2, /area/engine/atmos) "axj" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, -/turf/open/floor/plasteel, -/area/maintenance/port) +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/library) "axk" = ( +/obj/structure/girder, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"axl" = ( +/obj/structure/closet/firecloset, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/structure/closet/crate, -/obj/item/stack/ore/silver, -/obj/item/stack/ore/iron, -/obj/item/stack/ore/iron, -/obj/item/stack/ore/iron, -/obj/item/pickaxe/emergency, /turf/open/floor/plasteel, -/area/maintenance/port) -"axl" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) +/area/maintenance/port/aft) "axm" = ( /obj/machinery/atmospherics/components/unary/thermomachine/freezer, /turf/open/floor/plasteel, /area/engine/atmos) "axn" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/rack, +/obj/item/reagent_containers/food/drinks/bottle/whiskey, +/obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/light/small, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ dir = 1 }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "axo" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/stripes/line{ @@ -15362,22 +15352,20 @@ /turf/open/floor/carpet, /area/crew_quarters/dorms) "axL" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" +/obj/structure/rack, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 + dir = 1 }, /turf/open/floor/plasteel, -/area/maintenance/port) +/area/maintenance/port/aft) "axM" = ( /obj/structure/table/wood, /obj/item/lipstick/random{ @@ -15527,12 +15515,11 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/bar/atrium) "axU" = ( -/obj/structure/table/wood, -/obj/item/paper_bin, -/obj/item/pen, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/maintenance/port/aft) "axV" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/newscaster{ @@ -15549,19 +15536,17 @@ /turf/closed/wall, /area/hallway/secondary/exit) "axX" = ( -/obj/effect/landmark/xeno_spawn, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/wood, -/area/maintenance/port) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall/r_wall/rust, +/area/maintenance/port/aft) "axY" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/structure/cable/white{ + icon_state = "1-2" }, -/obj/item/cigbutt, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/landmark/event_spawn, /turf/open/floor/plating, -/area/maintenance/port) +/area/maintenance/port/aft) "axZ" = ( /turf/closed/wall/r_wall/rust, /area/security/prison) @@ -17489,6 +17474,13 @@ }, /turf/open/floor/plasteel, /area/security/prison) +"aBn" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/library) "aBo" = ( /obj/structure/cable/white{ icon_state = "2-4" @@ -18182,6 +18174,12 @@ /obj/machinery/atmospherics/miner/nitrogen, /turf/open/floor/engine/n2, /area/engine/atmos) +"aCx" = ( +/turf/open/floor/wood, +/area/library) +"aCy" = ( +/turf/closed/wall, +/area/crew_quarters/heads/cmo) "aCz" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 @@ -18205,6 +18203,15 @@ }, /turf/open/floor/plasteel/white/corner, /area/engine/atmos) +"aCB" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/wood, +/area/library) "aCC" = ( /obj/machinery/firealarm{ dir = 1; @@ -18606,6 +18613,13 @@ dir = 1 }, /area/hallway/secondary/exit) +"aDf" = ( +/obj/effect/landmark/barthpot, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/wood, +/area/library) "aDg" = ( /obj/structure/cable/white{ icon_state = "1-8" @@ -18648,12 +18662,90 @@ }, /turf/open/space/basic, /area/space) +"aDk" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/port/aft) "aDl" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 }, /turf/open/floor/plasteel, /area/engine/atmos) +"aDm" = ( +/obj/structure/bookcase/random/fiction, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/library) +"aDn" = ( +/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 + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/library) +"aDo" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/library) +"aDp" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/port/aft) +"aDq" = ( +/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 + }, +/obj/structure/closet/crate/bin, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel/dark, +/area/library) "aDr" = ( /obj/structure/sign/warning/nosmoking, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ @@ -19129,6 +19221,106 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/hallway/secondary/exit) +"aEg" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall/r_wall, +/area/maintenance/port/aft) +"aEh" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = 26 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/camera{ + c_tag = "Aft Primary Hallway 4" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/port/aft) +"aEi" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 24 + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/port/aft) +"aEj" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating{ + icon_state = "platingdmg2" + }, +/area/maintenance/port/aft) +"aEk" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/power/apc{ + areastring = "/area/hallway/primary/port/aft"; + dir = 1; + name = "Port Quarter Hallway APC"; + pixel_y = 24 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/port/aft) +"aEl" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/port/aft) +"aEm" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/port/aft) "aEn" = ( /obj/machinery/shieldgen, /obj/structure/sign/warning/nosmoking{ @@ -19786,6 +19978,17 @@ /obj/effect/landmark/blobstart, /turf/open/floor/plating, /area/maintenance/starboard/central) +"aFh" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/hallway/primary/port/aft) "aFi" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -19796,6 +19999,21 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"aFj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/hallway/primary/port/aft) "aFk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -19819,6 +20037,10 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) +"aFm" = ( +/obj/machinery/status_display, +/turf/closed/wall, +/area/medical/genetics) "aFn" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 @@ -19838,6 +20060,25 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) +"aFo" = ( +/turf/closed/wall/rust, +/area/medical/genetics) +"aFp" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) "aFq" = ( /obj/machinery/power/emitter, /obj/machinery/light/small, @@ -20192,6 +20433,13 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) +"aFM" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aFN" = ( /obj/structure/extinguisher_cabinet{ pixel_x = -26 @@ -20347,6 +20595,10 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"aFZ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, +/area/crew_quarters/heads/cmo) "aGa" = ( /obj/effect/landmark/event_spawn, /obj/item/beacon, @@ -20380,9 +20632,28 @@ }, /turf/open/floor/plating, /area/hallway/secondary/exit) +"aGd" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/hallway/primary/port/aft) "aGe" = ( /turf/closed/wall/r_wall, /area/engine/gravity_generator) +"aGf" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "geneticsbot"; + name = "Genetics Privacy Shutters" + }, +/turf/open/floor/plating, +/area/medical/genetics) "aGg" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -20439,6 +20710,29 @@ }, /turf/open/floor/plasteel, /area/engine/engineering) +"aGl" = ( +/obj/machinery/door/firedoor, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/table/reinforced, +/obj/machinery/door/window/southleft{ + name = "Genetics Desk"; + req_access_txt = "5; 9; 68" + }, +/obj/item/folder/yellow, +/obj/item/pen, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "geneticsbot"; + name = "Genetics Privacy Shutters" + }, +/turf/open/floor/plasteel, +/area/medical/genetics) "aGm" = ( /obj/structure/sign/warning/radiation, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -20604,6 +20898,19 @@ }, /turf/open/floor/plasteel, /area/maintenance/port/central) +"aGC" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) "aGD" = ( /obj/machinery/power/apc/highcap/five_k{ areastring = "/area/maintenance/port/central"; @@ -20631,6 +20938,24 @@ }, /turf/open/floor/plating, /area/maintenance/port/central) +"aGF" = ( +/obj/structure/mirror{ + pixel_x = -28 + }, +/obj/machinery/shower{ + dir = 4; + name = "emergency shower" + }, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/machinery/door/window/southleft, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/medical/genetics) "aGG" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -20909,6 +21234,97 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"aGY" = ( +/obj/structure/bed/dogbed/runtime, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/obj/structure/sign/poster/official/medical_green_cross{ + pixel_x = -32 + }, +/obj/machinery/camera{ + c_tag = "CMO's Office"; + dir = 4 + }, +/mob/living/simple_animal/pet/cat/Runtime, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/heads/cmo) +"aGZ" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/loading_area, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) +"aHa" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/obj/structure/table/glass, +/obj/item/storage/firstaid/brute{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/storage/firstaid/brute{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/regular, +/obj/item/storage/firstaid/brute{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/structure/window/reinforced/spawner/east, +/obj/structure/window/reinforced/spawner/north, +/turf/open/floor/plasteel, +/area/medical/medbay/zone3) +"aHb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, +/area/medical/morgue) +"aHc" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/door/window/southright, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 26 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/medical/genetics) +"aHd" = ( +/obj/structure/window/reinforced, +/obj/machinery/clonepod, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/medical/genetics) "aHe" = ( /obj/effect/turf_decal/bot_white/right, /obj/effect/turf_decal/tile/neutral{ @@ -20923,6 +21339,15 @@ }, /turf/open/floor/plasteel/dark, /area/engine/gravity_generator) +"aHf" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "geneticsbot"; + name = "Genetics Privacy Shutters" + }, +/turf/open/floor/plating, +/area/medical/genetics) "aHg" = ( /obj/machinery/camera{ c_tag = "Gravity Generator Room"; @@ -20945,6 +21370,17 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, /area/engine/engineering) +"aHi" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/grunge{ + name = "Morgue"; + req_access_txt = "5" + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) "aHj" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -21078,6 +21514,11 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"aHs" = ( +/obj/effect/turf_decal/tile/blue, +/obj/machinery/vending/medical, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) "aHt" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -21281,6 +21722,37 @@ }, /turf/open/floor/plating, /area/maintenance/port/central) +"aHG" = ( +/obj/machinery/power/apc{ + areastring = "/area/medical/genetics"; + dir = 8; + name = "Genetics Lab APC"; + pixel_x = -26; + pixel_y = 3 + }, +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/structure/table, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/button/door{ + id = "geneticsbot"; + name = "Genetics Shutter Control"; + pixel_x = -24; + pixel_y = -8; + req_access_txt = "5; 9; 68" + }, +/obj/item/clothing/gloves/color/latex, +/obj/item/storage/box/disks{ + pixel_x = -2; + pixel_y = 4 + }, +/obj/item/storage/box/rxglasses, +/turf/open/floor/plasteel/dark, +/area/medical/genetics) "aHH" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -21308,6 +21780,25 @@ }, /turf/open/floor/plating, /area/maintenance/port/central) +"aHJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/chair/office/light{ + dir = 4 + }, +/obj/effect/landmark/start/geneticist, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/medical/genetics) +"aHK" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/medical/morgue) "aHL" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, @@ -21444,6 +21935,23 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/kitchen) +"aHX" = ( +/obj/structure/sign/warning/nosmoking{ + pixel_x = 32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/computer/scan_consolenew{ + dir = 8 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/medical/genetics) "aHY" = ( /obj/structure/table, /obj/item/paper_bin, @@ -22059,7 +22567,7 @@ /area/hallway/primary/starboard) "aJa" = ( /obj/structure/table, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /obj/machinery/firealarm{ dir = 4; pixel_x = -24 @@ -22083,6 +22591,66 @@ }, /turf/open/floor/plasteel/white/corner, /area/hallway/secondary/exit) +"aJd" = ( +/obj/machinery/computer/cloning{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aJe" = ( +/obj/structure/table, +/obj/machinery/airalarm/unlocked{ + dir = 4; + pixel_x = -23 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/item/clipboard, +/obj/item/folder/white, +/obj/item/storage/pill_bottle/mutadone{ + pixel_x = -8; + pixel_y = 8 + }, +/obj/item/storage/pill_bottle/mannitol{ + pixel_x = -8; + pixel_y = 2 + }, +/obj/item/radio/headset/headset_medsci, +/turf/open/floor/plasteel/dark, +/area/medical/genetics) +"aJf" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/medical/genetics) +"aJg" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/dna_scannernew, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/delivery, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24 + }, +/turf/open/floor/plasteel/dark, +/area/medical/genetics) "aJh" = ( /obj/machinery/light{ dir = 8 @@ -22190,6 +22758,20 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) +"aJo" = ( +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_x = -26 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/vending/wardrobe/gene_wardrobe, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) "aJp" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -22236,6 +22818,20 @@ /obj/machinery/atmospherics/pipe/simple/green/visible, /turf/closed/wall/r_wall, /area/engine/supermatter) +"aJv" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/landmark/start/geneticist, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) "aJw" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 1; @@ -22244,6 +22840,17 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/dark, /area/engine/engineering) +"aJx" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) "aJy" = ( /obj/structure/cable{ icon_state = "1-2" @@ -22266,6 +22873,22 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"aJA" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/requests_console{ + department = "Genetics"; + name = "Genetics RC"; + pixel_x = 28; + pixel_y = 0 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) "aJB" = ( /obj/structure/table/reinforced, /obj/item/stack/sheet/metal/fifty, @@ -22482,6 +23105,28 @@ }, /turf/open/floor/plasteel, /area/hydroponics) +"aJN" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/landmark/blobstart, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aJO" = ( +/obj/machinery/camera{ + c_tag = "Genetics Cloning"; + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) "aJP" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -22719,6 +23364,59 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/secondary/exit) +"aKk" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aKl" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/port/aft) +"aKm" = ( +/turf/closed/wall, +/area/maintenance/port/aft) +"aKn" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall, +/area/maintenance/port/aft) +"aKo" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/door/airlock/external{ + name = "External Airlock"; + req_access_txt = "13" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aKp" = ( /obj/machinery/airalarm{ dir = 4; @@ -22755,6 +23453,18 @@ }, /turf/open/floor/plasteel/dark, /area/engine/gravity_generator) +"aKr" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/landmark/xeno_spawn, +/obj/structure/sign/warning/vacuum{ + pixel_x = -32; + pixel_y = 32 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aKs" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/command/glass{ @@ -22897,6 +23607,25 @@ }, /turf/open/floor/engine, /area/engine/supermatter) +"aKB" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/external{ + name = "External Airlock"; + req_access_txt = "13" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aKC" = ( /obj/machinery/atmospherics/components/binary/pump{ name = "Gas to Chamber" @@ -22915,6 +23644,16 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel/dark, /area/engine/engineering) +"aKF" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/sign/warning/vacuum{ + pixel_x = -32; + pixel_y = 32 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aKG" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -22962,6 +23701,12 @@ }, /turf/open/floor/plasteel, /area/engine/engineering) +"aKJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aKK" = ( /obj/structure/table/reinforced, /obj/structure/cable/white{ @@ -23177,6 +23922,9 @@ }, /turf/open/floor/plasteel, /area/hydroponics) +"aKV" = ( +/turf/closed/wall/r_wall, +/area/medical/virology) "aKW" = ( /obj/machinery/seed_extractor, /obj/effect/turf_decal/bot, @@ -23431,6 +24179,56 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"aLn" = ( +/obj/machinery/smartfridge/chemistry/virology/preloaded, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aLo" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/obj/structure/disposalpipe/trunk, +/obj/effect/turf_decal/stripes/red/full, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/disposal/bin{ + name = "corpse disposal unit" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aLp" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aLq" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aLr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aLs" = ( +/turf/closed/wall/r_wall/rust, +/area/maintenance/port/aft) "aLt" = ( /obj/effect/turf_decal/tile/brown{ dir = 1 @@ -23441,6 +24239,77 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) +"aLu" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/window/reinforced/spawner/north, +/obj/machinery/door/window/eastright{ + name = "Monkey Pen"; + req_access_txt = "5; 9; 68" + }, +/turf/open/floor/plasteel/freezer, +/area/medical/genetics) +"aLv" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aLw" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/medical/virology) +"aLx" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aLy" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/port/aft) +"aLz" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light/small, +/obj/structure/closet/emcloset/anchored, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"aLA" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/tile/purple, +/obj/structure/chair/office/light, +/obj/effect/landmark/start/geneticist, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aLB" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aLC" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/item/cigbutt, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aLD" = ( /obj/machinery/power/port_gen/pacman, /obj/effect/turf_decal/stripes/line{ @@ -23538,6 +24407,12 @@ /obj/item/clothing/glasses/meson/engine, /turf/open/floor/plasteel, /area/engine/gravity_generator) +"aLL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plating/airless, +/area/maintenance/port/aft) "aLM" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -23632,6 +24507,11 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"aLX" = ( +/obj/structure/table/wood, +/obj/item/gun/ballistic/automatic/toy/pistol/unrestricted, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aLY" = ( /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -23812,6 +24692,12 @@ }, /turf/open/floor/plasteel, /area/hydroponics) +"aMl" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/window/reinforced/spawner/east, +/obj/item/storage/box/monkeycubes, +/turf/open/floor/plasteel/freezer, +/area/medical/genetics) "aMm" = ( /obj/structure/cable/white{ icon_state = "2-4" @@ -23931,6 +24817,48 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/bar/atrium) +"aMv" = ( +/obj/structure/table/wood, +/obj/item/clothing/gloves/color/black, +/obj/item/taperecorder, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/sign/poster/contraband/random{ + pixel_y = 32 + }, +/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/maintenance/port/aft) +"aMw" = ( +/obj/structure/rack, +/obj/item/storage/briefcase{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/secure/briefcase, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/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/maintenance/port/aft) "aMx" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 @@ -23993,6 +24921,56 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) +"aMD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/sign/poster/contraband/random, +/turf/closed/wall, +/area/maintenance/port/aft) +"aME" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"aMF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/closet/crate, +/obj/item/stack/ore/silver, +/obj/item/stack/ore/iron, +/obj/item/stack/ore/iron, +/obj/item/stack/ore/iron, +/obj/item/pickaxe/emergency, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"aMG" = ( +/obj/structure/girder, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aMH" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"aMI" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) "aMJ" = ( /turf/closed/wall/r_wall, /area/tcommsat/server) @@ -24057,6 +25035,22 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"aMQ" = ( +/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 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) "aMR" = ( /obj/machinery/camera{ c_tag = "Supermatter Chamber"; @@ -24115,6 +25109,17 @@ }, /turf/open/floor/engine, /area/engine/supermatter) +"aMY" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/dna_scannernew, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/dark, +/area/medical/genetics) "aMZ" = ( /obj/structure/cable{ icon_state = "1-8" @@ -24297,6 +25302,43 @@ }, /turf/open/floor/plasteel/dark, /area/hydroponics) +"aNo" = ( +/obj/machinery/light_switch{ + pixel_x = -24; + pixel_y = -38 + }, +/obj/machinery/button/door{ + desc = "A remote control switch for the medbay foyer."; + id = "cloningfoyer"; + name = "Cloning Doors Control"; + normaldoorcontrol = 1; + pixel_x = -24; + pixel_y = -24 + }, +/obj/structure/closet/crate/freezer/surplus_limbs, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aNp" = ( +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/door/airlock/medical/glass{ + name = "Genetics"; + req_access_txt = "5; 9; 68" + }, +/turf/open/floor/plasteel, +/area/medical/genetics) "aNq" = ( /obj/machinery/hydroponics/constructable, /obj/structure/cable/white, @@ -24514,6 +25556,94 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/secondary/exit) +"aNL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aNM" = ( +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/effect/landmark/start/geneticist, +/turf/open/floor/plasteel, +/area/medical/genetics) +"aNN" = ( +/obj/machinery/dna_scannernew, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aNO" = ( +/obj/machinery/camera{ + c_tag = "Genetics Lab"; + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/computer/scan_consolenew{ + icon_state = "computer"; + dir = 1 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/medical/genetics) +"aNP" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/medical/genetics) +"aNQ" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical/glass{ + id_tag = "cloningfoyer"; + name = "Cloning Lab"; + req_access_txt = "5" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/medical/genetics) +"aNR" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/medical/genetics) +"aNS" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/effect/landmark/start/paramedic, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) "aNT" = ( /obj/machinery/announcement_system, /obj/machinery/status_display/ai{ @@ -24606,6 +25736,42 @@ /obj/machinery/power/supermatter_crystal/shard/engine, /turf/open/floor/engine, /area/engine/supermatter) +"aOb" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Chief Medical Officer's Desk"; + departmentType = 5; + name = "Chief Medical Officer RC"; + pixel_y = 28 + }, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/heads/cmo) +"aOc" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aOd" = ( /obj/machinery/power/apc{ areastring = "/area/engine/engineering"; @@ -24619,6 +25785,29 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"aOe" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/command{ + name = "Chief Medical Officer's Office"; + req_access_txt = "40" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/crew_quarters/heads/cmo) "aOf" = ( /obj/machinery/door/airlock{ name = "Custodial Closet"; @@ -24634,6 +25823,24 @@ }, /turf/open/floor/plasteel, /area/janitor) +"aOg" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) "aOh" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -24660,6 +25867,19 @@ /obj/structure/sign/departments/botany, /turf/closed/wall, /area/hydroponics) +"aOl" = ( +/obj/structure/closet/secure_closet/CMO, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/heads/cmo) "aOm" = ( /obj/item/kirbyplants{ icon_state = "plant-21" @@ -24733,6 +25953,13 @@ }, /turf/closed/wall, /area/hallway/primary/central) +"aOs" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/rack, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aOt" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, @@ -24823,6 +26050,24 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"aOA" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/medical/genetics) +"aOB" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) "aOC" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 5 @@ -24849,6 +26094,22 @@ }, /turf/open/floor/circuit/green, /area/engine/supermatter) +"aOE" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) "aOF" = ( /obj/structure/cable{ icon_state = "1-8" @@ -24870,60 +26131,101 @@ /turf/open/floor/engine, /area/engine/engineering) "aOH" = ( -/turf/closed/wall/r_wall, -/area/maintenance/port) -"aOI" = ( /obj/structure/cable/white{ - icon_state = "2-4" + icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/obj/effect/decal/cleanable/cobweb, -/turf/open/floor/plating, -/area/maintenance/port) -"aOL" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/port) -"aOM" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"aON" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/stripes/line{ +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aOI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aOJ" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/blue{ dir = 4 }, -/turf/open/floor/plasteel, -/area/maintenance/port) +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) +"aOK" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/computer/card/minor/cmo{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/keycard_auth{ + pixel_x = 24; + pixel_y = -24 + }, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24; + pixel_y = -6 + }, +/obj/machinery/computer/security/telescreen/cmo{ + dir = 1; + icon_state = "telescreen"; + pixel_y = -32 + }, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/heads/cmo) +"aOL" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aOM" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) +"aON" = ( +/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 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) "aOO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -24962,49 +26264,49 @@ heat_capacity = 1e+006 }, /area/hallway/primary/port/aft) -"aOR" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/structure/cable/white{ - icon_state = "2-4" - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, +"aOQ" = ( +/obj/machinery/suit_storage_unit/cmo, /obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/port/aft) -"aOS" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/port/aft) -"aOT" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/heads/cmo) +"aOR" = ( +/obj/structure/table/glass, +/obj/item/storage/box/bodybags{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/box/bodybags, +/obj/item/pen, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"aOS" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/maintenance/port/aft) +"aOT" = ( /obj/structure/cable/white{ - icon_state = "1-8" + icon_state = "1-4" }, -/obj/structure/cable/white{ - icon_state = "4-8" +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/port/aft) +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aOU" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, @@ -25023,92 +26325,77 @@ /turf/open/floor/plasteel, /area/hallway/primary/port/aft) "aOV" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/structure/extinguisher_cabinet{ - pixel_y = 26 +/obj/effect/landmark/blobstart, +/turf/open/floor/plating{ + icon_state = "panelscorched" }, -/obj/structure/cable/white{ - icon_state = "4-8" +/area/maintenance/port/aft) +"aOW" = ( +/obj/structure/disposalpipe/segment, +/turf/closed/wall, +/area/medical/genetics) +"aOX" = ( +/obj/machinery/requests_console{ + department = "Medbay"; + departmentType = 1; + name = "Medbay RC"; + pixel_x = -30 }, /obj/machinery/camera{ - c_tag = "Aft Primary Hallway 4" - }, -/obj/effect/turf_decal/tile/green{ - dir = 1 + c_tag = "Medbay Storage" }, +/obj/machinery/rnd/production/techfab/department/medical, +/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/stripes/box, +/obj/structure/disposalpipe/segment, /turf/open/floor/plasteel, -/area/hallway/primary/port/aft) -"aOW" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_y = 24 - }, +/area/medical/medbay/zone3) +"aOY" = ( /obj/structure/cable/white{ - icon_state = "2-8" + icon_state = "1-2" }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/purple{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/landmark/start/medical_doctor, /turf/open/floor/plasteel, -/area/hallway/primary/port/aft) -"aOX" = ( +/area/medical/medbay/zone3) +"aOZ" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable/white{ + icon_state = "0-4" + }, /obj/machinery/power/apc{ - areastring = "/area/hallway/primary/port/aft"; + areastring = "/area/crew_quarters/heads/cmo"; dir = 1; - name = "Port Quarter Hallway APC"; - pixel_y = 24 + name = "CMO's Office APC"; + pixel_y = 26 }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/structure/cable/white{ - icon_state = "0-8" - }, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/port/aft) -"aOY" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/structure/cable/white{ - icon_state = "1-8" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/port/aft) -"aOZ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/port/aft) +/obj/effect/landmark/start/chief_medical_officer, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/heads/cmo) "aPa" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -25191,6 +26478,21 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"aPg" = ( +/obj/item/kirbyplants{ + icon_state = "plant-22" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) "aPh" = ( /obj/machinery/light{ dir = 1 @@ -25394,6 +26696,34 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"aPv" = ( +/obj/structure/table/glass, +/obj/item/storage/firstaid/o2{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/storage/firstaid/o2{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/regular, +/obj/item/storage/firstaid/o2{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/structure/cable/white, +/obj/effect/turf_decal/delivery, +/obj/machinery/power/apc{ + areastring = "/area/medical/medbay/zone3"; + name = "Medbay APC"; + pixel_y = -26 + }, +/obj/machinery/door/window/northleft{ + name = "First-Aid Supplies"; + req_access_txt = "5" + }, +/turf/open/floor/plasteel, +/area/medical/medbay/zone3) "aPw" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -25432,10 +26762,141 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) +"aPz" = ( +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced/spawner/west, +/obj/structure/window/reinforced/spawner/north, +/obj/structure/table/glass, +/obj/item/storage/firstaid/toxin{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/storage/firstaid/toxin{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/regular, +/obj/item/storage/firstaid/toxin{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/medical/medbay/zone3) +"aPA" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/grunge{ + name = "Morgue"; + req_access_txt = "5" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"aPB" = ( +/obj/structure/disposalpipe/segment, +/turf/closed/wall, +/area/medical/morgue) +"aPC" = ( +/obj/machinery/computer/security/telescreen/entertainment, +/obj/structure/bodycontainer/morgue{ + icon_state = "morgue1"; + dir = 2 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"aPD" = ( +/obj/machinery/light, +/obj/structure/noticeboard{ + dir = 1; + pixel_y = -32 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/obj/effect/turf_decal/delivery, +/obj/structure/table/glass, +/obj/item/storage/firstaid/fire{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/storage/firstaid/fire{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/regular, +/obj/item/storage/firstaid/fire{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/machinery/door/window/northright{ + name = "First-Aid Supplies"; + req_access_txt = "5" + }, +/turf/open/floor/plasteel, +/area/medical/medbay/zone3) +"aPE" = ( +/obj/structure/bodycontainer/morgue{ + icon_state = "morgue1"; + dir = 2 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"aPF" = ( +/obj/structure/chair/office/light{ + dir = 4 + }, +/obj/effect/landmark/start/chief_medical_officer, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/heads/cmo) "aPG" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/tcommsat/server) +"aPH" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24 + }, +/obj/structure/disposaloutlet{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) "aPI" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -25497,89 +26958,69 @@ /turf/open/floor/engine, /area/engine/engineering) "aPO" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/turf/closed/wall/r_wall, -/area/maintenance/port) +/obj/effect/turf_decal/stripes/line, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aPP" = ( /obj/structure/cable/white{ - icon_state = "1-2" + icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"aPQ" = ( -/obj/structure/closet, -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 3; - name = "3maintenance loot spawner" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/stripes/line{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"aPR" = ( -/obj/structure/girder, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /turf/open/floor/plating, -/area/maintenance/port) +/area/maintenance/port/aft) +"aPQ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aPR" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/maintenance/port/aft) "aPS" = ( -/obj/structure/closet/firecloset, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/stripes/line{ +/obj/effect/landmark/xeno_spawn, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/turf/open/floor/plasteel, -/area/maintenance/port) +/turf/open/floor/wood, +/area/maintenance/port/aft) "aPT" = ( -/obj/structure/rack, -/obj/item/reagent_containers/food/drinks/bottle/whiskey, -/obj/effect/spawner/lootdrop/maintenance, -/obj/machinery/light/small, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/turf/open/floor/wood{ + icon_state = "wood-broken6" }, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) +/area/maintenance/port/aft) "aPU" = ( -/obj/structure/rack, -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 2; - name = "2maintenance loot spawner" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"aPV" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 + dir = 5 }, /turf/closed/wall, -/area/maintenance/port) +/area/maintenance/port/aft) +"aPV" = ( +/obj/structure/barricade/wooden, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aPW" = ( /obj/machinery/vending/snack/random, /obj/machinery/firealarm{ @@ -25696,16 +27137,18 @@ }, /area/hallway/primary/port/aft) "aQe" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue{ dir = 8 }, -/turf/open/floor/plasteel{ - heat_capacity = 1e+006 +/obj/effect/turf_decal/tile/blue{ + dir = 4 }, -/area/hallway/primary/port/aft) +/obj/item/paper_bin, +/obj/item/pen, +/obj/item/stamp/cmo, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/heads/cmo) "aQf" = ( /obj/machinery/firealarm{ dir = 1; @@ -25730,6 +27173,39 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"aQh" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"aQi" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) "aQj" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/yellow{ @@ -25912,6 +27388,94 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) +"aQB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/sign/poster/contraband/random, +/turf/closed/wall, +/area/maintenance/port/aft) +"aQC" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"aQD" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/effect/landmark/blobstart, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"aQE" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/obj/structure/table/wood, +/obj/item/storage/box/bodybags{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/box/bodybags, +/obj/machinery/power/apc{ + areastring = "/area/medical/morgue"; + dir = 4; + name = "Morgue APC"; + pixel_x = 26 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Morgue"; + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"aQF" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall/rust, +/area/maintenance/port/aft) "aQG" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 6 @@ -25950,6 +27514,19 @@ }, /turf/open/floor/plasteel/grimy, /area/tcommsat/server) +"aQI" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) "aQJ" = ( /obj/machinery/meter, /obj/effect/turf_decal/stripes/corner{ @@ -25969,6 +27546,17 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"aQL" = ( +/obj/structure/table/wood, +/obj/item/clothing/gloves/color/latex, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) "aQM" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -26010,6 +27598,14 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"aQQ" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/barricade/wooden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aQR" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -26038,9 +27634,39 @@ /turf/open/floor/engine, /area/engine/engineering) "aQU" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall/r_wall, -/area/maintenance/port) +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"aQV" = ( +/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 + }, +/obj/machinery/computer/arcade{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) "aQW" = ( /turf/closed/wall, /area/library) @@ -26083,30 +27709,17 @@ /turf/closed/wall, /area/medical/morgue) "aRc" = ( -/obj/effect/spawner/structure/window/reinforced/tinted, -/turf/open/floor/plating, -/area/medical/morgue) +/obj/structure/chair/stool/bar, +/turf/open/floor/wood, +/area/maintenance/port/aft) "aRd" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/grunge{ - name = "Morgue"; - req_access_txt = "5" - }, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/medical/morgue) +/obj/effect/decal/cleanable/blood/splatter, +/turf/open/floor/wood, +/area/maintenance/port/aft) "aRe" = ( -/obj/effect/spawner/structure/window/reinforced/tinted, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/medical/morgue) +/turf/closed/wall/r_wall, +/area/medical/virology) "aRf" = ( /turf/closed/wall, /area/medical/chemistry) @@ -26138,6 +27751,11 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/medical/chemistry) +"aRj" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/maintenance/port/aft) "aRk" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/camera{ @@ -26153,6 +27771,44 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"aRl" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/white, +/turf/open/floor/plating, +/area/crew_quarters/heads/cmo) +"aRm" = ( +/turf/open/floor/wood, +/area/maintenance/port/aft) +"aRn" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aRo" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/newscaster{ + pixel_y = -32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/holopad, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/heads/cmo) +"aRp" = ( +/obj/structure/bodycontainer/morgue{ + icon_state = "morgue1"; + dir = 2 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) "aRq" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/purple, @@ -26214,6 +27870,20 @@ }, /turf/open/floor/plasteel, /area/science/research) +"aRw" = ( +/obj/structure/bodycontainer/morgue{ + icon_state = "morgue1"; + dir = 2 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) "aRx" = ( /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; @@ -26236,6 +27906,38 @@ "aRz" = ( /turf/closed/wall, /area/maintenance/starboard) +"aRA" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/structure/reagent_dispensers/virusfood{ + pixel_x = -32 + }, +/obj/item/storage/box/beakers{ + pixel_x = -6; + pixel_y = 8 + }, +/obj/item/storage/box/monkeycubes{ + pixel_x = 4; + pixel_y = 6 + }, +/obj/item/storage/box/syringes{ + pixel_x = -3; + pixel_y = 2 + }, +/obj/item/reagent_containers/dropper{ + pixel_y = -8 + }, +/obj/item/reagent_containers/syringe/antiviral{ + pixel_x = 2; + pixel_y = -10 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) "aRB" = ( /obj/effect/turf_decal/bot, /obj/structure/table, @@ -26248,6 +27950,10 @@ }, /turf/open/floor/plasteel/dark, /area/tcommsat/server) +"aRC" = ( +/obj/machinery/computer/slot_machine, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aRD" = ( /obj/structure/cable{ icon_state = "1-2" @@ -26391,14 +28097,12 @@ /turf/open/floor/engine, /area/engine/engineering) "aRS" = ( -/obj/structure/cable/white{ - icon_state = "1-2" +/obj/machinery/vending/cigarette, +/obj/machinery/newscaster{ + pixel_x = -32 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating{ - icon_state = "platingdmg2" - }, -/area/maintenance/port) +/turf/open/floor/plating, +/area/maintenance/port/aft) "aRT" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, @@ -26427,6 +28131,23 @@ }, /turf/open/floor/plasteel/dark, /area/library) +"aRV" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/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 + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) "aRW" = ( /obj/structure/chair/office/dark{ dir = 4 @@ -26518,44 +28239,31 @@ /turf/open/floor/plasteel/dark, /area/library) "aSe" = ( -/obj/structure/bodycontainer/morgue, -/obj/effect/decal/cleanable/cobweb, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/vending/wallmed{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/green{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/holopad, +/turf/open/floor/plasteel/white, +/area/medical/virology) "aSf" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aSg" = ( -/obj/structure/sign/warning/nosmoking{ - pixel_x = 32 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) +/obj/item/cigbutt, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aSh" = ( /turf/closed/wall, /area/medical/medbay/zone3) @@ -26582,26 +28290,11 @@ /turf/open/floor/plasteel, /area/medical/chemistry) "aSk" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/power/apc/highcap/five_k{ - areastring = "/area/medical/chemistry"; - dir = 1; - name = "Chemistry Lab APC"; - pixel_y = 25 - }, /obj/structure/cable/white{ - icon_state = "0-2" - }, -/obj/item/kirbyplants{ - icon_state = "plant-21" - }, -/obj/machinery/camera{ - c_tag = "Chemistry" + icon_state = "1-2" }, /obj/effect/turf_decal/tile/yellow{ - dir = 1 + dir = 8 }, /turf/open/floor/plasteel/white, /area/medical/chemistry) @@ -26615,6 +28308,19 @@ /obj/item/storage/pill_bottle/mutadone, /turf/open/floor/plasteel, /area/medical/chemistry) +"aSm" = ( +/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/maintenance/port/aft) "aSn" = ( /obj/machinery/chem_dispenser, /obj/machinery/button/door{ @@ -26629,6 +28335,54 @@ }, /turf/open/floor/plasteel, /area/medical/chemistry) +"aSo" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"aSp" = ( +/obj/structure/table/glass, +/obj/machinery/reagentgrinder{ + pixel_y = 5 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/item/reagent_containers/spray/cleaner{ + pixel_x = -8; + pixel_y = 2 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aSq" = ( +/obj/structure/table/wood, +/obj/item/storage/briefcase, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aSr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aSs" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/wood{ + icon_state = "wood-broken" + }, +/area/maintenance/port/aft) "aSt" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -26761,10 +28515,43 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/maintenance/starboard/aft) +"aSG" = ( +/turf/open/floor/plating, +/area/maintenance/port/aft) "aSH" = ( /obj/structure/sign/poster/contraband/random, /turf/closed/wall, /area/maintenance/starboard) +"aSI" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/maintenance/port/aft) +"aSJ" = ( +/obj/structure/chair/office/light, +/obj/effect/landmark/start/virologist, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aSK" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aSL" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/maintenance/port/aft) "aSM" = ( /obj/machinery/door/airlock/command{ name = "Telecomms Server Room"; @@ -26810,6 +28597,22 @@ /obj/machinery/vending/wardrobe/engi_wardrobe, /turf/open/floor/engine, /area/engine/engineering) +"aSQ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aSR" = ( /obj/structure/table/reinforced, /obj/item/tank/internals/plasma, @@ -26909,12 +28712,15 @@ /turf/open/floor/engine, /area/engine/engineering) "aTb" = ( -/obj/structure/cable/white{ - icon_state = "1-2" +/obj/structure/table/wood, +/obj/item/toy/cards/deck/syndicate{ + pixel_y = 6 + }, +/obj/machinery/light/small{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, -/area/maintenance/port) +/area/maintenance/port/aft) "aTc" = ( /obj/structure/chair/office/dark{ dir = 8 @@ -26945,7 +28751,7 @@ "aTf" = ( /obj/structure/table/wood, /obj/item/clipboard, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -26988,96 +28794,90 @@ /turf/open/floor/plasteel/dark, /area/library) "aTj" = ( -/obj/structure/table, -/obj/item/storage/box/bodybags{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/box/bodybags, -/obj/machinery/airalarm/unlocked{ - dir = 4; - pixel_x = -23 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aTk" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ +/obj/effect/turf_decal/tile/green{ dir = 4 }, -/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/medical/morgue) -"aTl" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) -"aTm" = ( -/obj/structure/mirror{ - pixel_x = -28 - }, -/obj/machinery/shower{ - dir = 4; - name = "emergency shower" - }, -/obj/machinery/newscaster{ - pixel_y = 32 - }, -/obj/machinery/door/window/southleft, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/medical/medbay/zone3) -"aTn" = ( /obj/machinery/light{ dir = 1 }, -/obj/machinery/door/window/southright, -/obj/item/radio/intercom{ - name = "Station Intercom"; +/obj/structure/closet/secure_closet/medical1, +/obj/item/radio/headset/headset_med, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aTl" = ( +/obj/machinery/vending/wardrobe/viro_wardrobe, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ pixel_y = 26 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/medical/virology) +"aTm" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/green{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/medical/medbay/zone3) +/obj/effect/turf_decal/tile/green, +/obj/item/paper_bin, +/obj/item/pen, +/obj/item/book/manual/wiki/infections{ + pixel_x = -15; + pixel_y = 2 + }, +/obj/item/stack/sheet/mineral/plasma{ + pixel_x = -12 + }, +/obj/item/stack/sheet/mineral/plasma{ + pixel_x = -14; + pixel_y = 3 + }, +/obj/item/hand_labeler, +/obj/item/clothing/gloves/color/latex, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aTn" = ( +/obj/effect/landmark/start/virologist, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/medical/virology"; + dir = 1; + name = "Virology APC"; + pixel_y = 24 + }, +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/machinery/camera{ + c_tag = "Virology" + }, +/turf/open/floor/plasteel, +/area/medical/virology) "aTo" = ( -/obj/structure/window/reinforced, -/obj/machinery/clonepod, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/medical/medbay/zone3) +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/medical/virology) "aTp" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -27092,11 +28892,12 @@ /area/medical/chemistry) "aTr" = ( /obj/structure/cable/white{ - icon_state = "1-2" + icon_state = "1-4" }, /obj/effect/turf_decal/tile/yellow{ - dir = 1 + dir = 8 }, +/obj/effect/landmark/start/chemist, /turf/open/floor/plasteel/white, /area/medical/chemistry) "aTs" = ( @@ -27117,6 +28918,19 @@ /obj/machinery/chem_master, /turf/open/floor/plasteel, /area/medical/chemistry) +"aTv" = ( +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) "aTw" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/blue{ @@ -27325,6 +29139,12 @@ icon_state = "platingdmg1" }, /area/maintenance/starboard/aft) +"aTQ" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/closed/wall/r_wall, +/area/medical/virology) "aTR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -27359,6 +29179,40 @@ icon_state = "panelscorched" }, /area/maintenance/starboard/aft) +"aTU" = ( +/obj/structure/sign/poster/contraband/random, +/turf/closed/wall/rust, +/area/maintenance/port/aft) +"aTV" = ( +/obj/structure/table/wood, +/obj/item/wrench, +/obj/item/storage/secure/briefcase{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/briefcase, +/obj/machinery/light/small{ + dir = 8 + }, +/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/maintenance/port/aft) +"aTW" = ( +/obj/structure/bed, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) "aTX" = ( /obj/machinery/light{ dir = 8 @@ -27421,13 +29275,23 @@ /turf/closed/wall/r_wall/rust, /area/engine/engineering) "aUb" = ( +/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 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/landmark/event_spawn, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/landmark/blobstart, -/turf/open/floor/plating, -/area/maintenance/port) +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) "aUc" = ( /obj/machinery/power/apc{ areastring = "/area/library"; @@ -27478,74 +29342,114 @@ /turf/open/floor/wood, /area/library) "aUh" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/structure/cable/white{ - icon_state = "1-8" - }, -/turf/open/floor/wood, -/area/library) +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/closed/wall/r_wall, +/area/medical/virology) "aUi" = ( -/obj/structure/cable/white{ - icon_state = "2-8" - }, -/turf/open/floor/wood, -/area/library) +/turf/closed/wall/rust, +/area/maintenance/port/aft) "aUj" = ( /obj/machinery/photocopier, /turf/open/floor/plasteel/dark, /area/library) "aUk" = ( -/obj/structure/bodycontainer/morgue, -/obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_x = -26 +/obj/structure/table/wood, +/obj/item/storage/pill_bottle, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aUl" = ( +/obj/machinery/computer/slot_machine, +/obj/machinery/light/small, +/obj/structure/sign/poster/contraband/random{ + pixel_y = -32 + }, +/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/medical/morgue) +/area/maintenance/port/aft) +"aUm" = ( +/obj/machinery/computer/slot_machine, +/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/maintenance/port/aft) "aUn" = ( /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/medical/medbay/zone3) "aUo" = ( -/obj/machinery/camera{ - c_tag = "Genetics Cloning"; - dir = 4 +/obj/structure/table/wood, +/obj/item/coin/iron{ + icon_state = "coin_bananium_heads"; + name = "arcade coin"; + pixel_x = 6 }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 +/obj/item/coin/iron{ + icon_state = "coin_bananium_heads"; + name = "arcade coin"; + pixel_x = -6 }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 +/obj/item/coin/iron{ + icon_state = "coin_bananium_heads"; + name = "arcade coin"; + pixel_y = 6 }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/obj/item/instrument/guitar, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aUp" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/blue{ +/obj/structure/table/wood, +/obj/item/reagent_containers/blood/random, +/obj/item/reagent_containers/syringe{ + pixel_y = 5 + }, +/obj/item/reagent_containers/syringe, +/obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/obj/effect/turf_decal/tile/blue{ +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) -"aUq" = ( -/obj/machinery/computer/cloning{ +/obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) +"aUq" = ( +/obj/structure/table/wood, +/obj/item/clipboard, +/obj/item/toy/syndicateballoon, +/obj/item/newspaper, +/obj/item/clothing/head/bowler, +/obj/machinery/power/apc{ + areastring = "/area/maintenance/port/aft"; + dir = 8; + name = "Port Quarter Maintenance APC"; + pixel_x = -26; + pixel_y = 3 }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aUr" = ( /obj/machinery/status_display, /turf/closed/wall, @@ -27563,27 +29467,41 @@ /turf/open/floor/plasteel/dark, /area/medical/chemistry) "aUt" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/holopad, /obj/structure/cable/white{ - icon_state = "1-4" + icon_state = "4-8" }, -/obj/effect/turf_decal/tile/yellow{ +/turf/open/floor/plasteel, +/area/medical/chemistry) +"aUu" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/turf/open/floor/plasteel/white, -/area/medical/chemistry) +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aUv" = ( -/obj/machinery/holopad, /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/landmark/start/chemist, +/turf/open/floor/plasteel/white, /area/medical/chemistry) "aUw" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/structure/closet/crate/bin, /turf/open/floor/plasteel/white, /area/medical/chemistry) "aUx" = ( @@ -27722,6 +29640,73 @@ }, /turf/closed/wall/r_wall, /area/science/research) +"aUJ" = ( +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = -32 + }, +/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 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) +"aUK" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/door/airlock/virology{ + name = "Virology Access"; + req_access_txt = "39" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/medical/virology) +"aUL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aUM" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Medbay Maintenance"; + req_access_txt = "5" + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"aUN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aUO" = ( /obj/structure/cable{ icon_state = "4-8" @@ -27824,18 +29809,22 @@ /turf/open/floor/wood, /area/library) "aUZ" = ( -/obj/effect/landmark/barthpot, -/turf/open/floor/wood, -/area/library) -"aVa" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 + dir = 4 }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aVa" = ( /obj/structure/cable/white{ - icon_state = "1-2" + icon_state = "1-4" }, -/turf/open/floor/wood, -/area/library) +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aVb" = ( /obj/structure/table/wood, /obj/item/storage/crayons, @@ -27860,117 +29849,109 @@ /turf/open/floor/plasteel/dark, /area/library) "aVc" = ( -/obj/structure/bodycontainer/morgue, -/obj/machinery/light{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) -"aVd" = ( /obj/structure/cable/white{ - icon_state = "1-2" + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "2-4" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, -/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/stripes/line, +/turf/open/floor/plating{ + icon_state = "panelscorched" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/area/maintenance/port/aft) +"aVd" = ( +/obj/structure/cable/white{ + icon_state = "4-8" }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aVe" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) +/turf/open/floor/plating, +/area/maintenance/port/aft) "aVf" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/grunge{ - name = "Morgue"; - req_access_txt = "5" +/obj/structure/cable/white{ + icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/structure/cable/white{ + icon_state = "1-8" }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/medical/medbay/zone3) -"aVg" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aVg" = ( +/obj/structure/cable/white{ + icon_state = "4-8" }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/port/aft) "aVh" = ( -/obj/machinery/holopad, -/obj/effect/landmark/start/medical_doctor, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 +/obj/structure/cable/white{ + icon_state = "2-8" }, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/medical/medbay/zone3) +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aVi" = ( -/obj/machinery/dna_scannernew, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 +/turf/open/floor/plating{ + icon_state = "panelscorched" }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/area/maintenance/port/aft) "aVj" = ( -/obj/structure/table/glass, -/obj/item/stack/sheet/mineral/plasma, -/obj/item/stack/sheet/mineral/plasma, -/obj/item/stack/sheet/mineral/plasma, -/obj/item/reagent_containers/glass/bottle/charcoal{ - pixel_x = 6 +/obj/machinery/chem_master, +/obj/effect/turf_decal/stripes/line{ + dir = 9 }, -/obj/item/reagent_containers/glass/bottle/epinephrine, -/obj/item/reagent_containers/dropper, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/medical/chemistry) -"aVl" = ( -/obj/effect/turf_decal/tile/yellow{ - dir = 8 +"aVk" = ( +/obj/structure/closet/emcloset, +/obj/effect/turf_decal/stripes/line{ + dir = 10 }, -/turf/open/floor/plasteel/white, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"aVl" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, /area/medical/chemistry) "aVm" = ( /obj/structure/cable/white{ @@ -27981,16 +29962,11 @@ /turf/open/floor/plasteel/white, /area/medical/chemistry) "aVn" = ( -/obj/structure/closet/crate/bin, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/requests_console{ - department = "Chemistry Lab"; - name = "Chemistry RC"; - pixel_x = 32; - receive_ore_updates = 1 +/obj/effect/turf_decal/stripes/line{ + dir = 5 }, -/obj/effect/turf_decal/tile/yellow, -/turf/open/floor/plasteel/white, +/obj/machinery/chem_heater, +/turf/open/floor/plasteel, /area/medical/chemistry) "aVo" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -28179,6 +30155,39 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, /area/science/research) +"aVF" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aVG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aVH" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aVI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aVJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aVK" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 6 @@ -28194,14 +30203,14 @@ /turf/open/space, /area/asteroid/nearstation) "aVM" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, /obj/structure/cable/white{ - icon_state = "1-2" + icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/port) +/turf/open/floor/plating, +/area/maintenance/port/aft) "aVN" = ( /obj/structure/table/wood, /obj/item/storage/bag/books, @@ -28245,9 +30254,15 @@ /turf/open/floor/plasteel/dark, /area/library) "aVR" = ( -/obj/structure/bookcase/random/fiction, -/turf/open/floor/plasteel/dark, -/area/library) +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/reagent_dispensers/watertank, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aVS" = ( /obj/structure/bookcase/random/fiction, /obj/effect/turf_decal/tile/neutral{ @@ -28287,22 +30302,15 @@ /turf/open/floor/plasteel/dark, /area/library) "aVW" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/rack, +/obj/item/storage/toolbox/mechanical, +/obj/item/clothing/head/welding, +/obj/machinery/light/small, +/obj/effect/turf_decal/stripes/line{ 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/library) +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aVX" = ( /obj/structure/easel, /obj/item/canvas/twentythreeXnineteen, @@ -28314,24 +30322,18 @@ /turf/open/floor/plasteel/dark, /area/library) "aVY" = ( -/obj/structure/table, -/obj/item/clothing/gloves/color/latex, -/obj/structure/extinguisher_cabinet{ - pixel_x = -26 +/obj/machinery/door/airlock/grunge{ + name = "Crematorium"; + req_access_txt = "27" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) -"aVZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -28343,19 +30345,39 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/medical/morgue) -"aWa" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 +/area/maintenance/port/aft) +"aVZ" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aWa" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) +/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/item/storage/backpack, +/obj/item/crowbar, +/obj/item/wrench, +/obj/structure/rack, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aWb" = ( /obj/effect/spawner/structure/window/reinforced/tinted, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -28364,123 +30386,78 @@ /turf/open/floor/plating, /area/medical/medbay/zone3) "aWc" = ( -/obj/machinery/light_switch{ - pixel_x = -24; - pixel_y = -38 +/obj/structure/cable/white{ + icon_state = "1-4" }, -/obj/machinery/button/door{ - desc = "A remote control switch for the medbay foyer."; - id = "cloningfoyer"; - name = "Cloning Doors Control"; - normaldoorcontrol = 1; - pixel_x = -24; - pixel_y = -24 +/obj/structure/cable/white{ + icon_state = "1-2" }, -/obj/structure/closet/crate/freezer/surplus_limbs, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) -"aWd" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/effect/landmark/blobstart, +/turf/open/floor/plating{ + icon_state = "platingdmg1" + }, +/area/maintenance/port/aft) +"aWd" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/landmark/event_spawn, +/obj/item/tank/internals/oxygen/red, +/obj/item/clothing/mask/gas, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aWe" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/turf/open/floor/plating{ + icon_state = "panelscorched" }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) -"aWe" = ( -/obj/structure/table/glass, -/obj/item/storage/box/bodybags{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/box/bodybags, -/obj/item/pen, -/obj/machinery/firealarm{ - dir = 8; - pixel_x = 24 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, -/obj/effect/turf_decal/tile/blue, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/area/maintenance/port/aft) "aWf" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/requests_console{ + department = "Chemistry Lab"; + name = "Chemistry RC"; + pixel_x = 32; + receive_ore_updates = 1 + }, +/obj/effect/turf_decal/tile/yellow, /obj/structure/table/glass, -/obj/item/folder/white, -/obj/item/reagent_containers/glass/beaker/large{ - pixel_x = -3 - }, -/obj/item/reagent_containers/glass/beaker{ - pixel_x = 3 +/obj/item/stack/sheet/mineral/plasma, +/obj/item/stack/sheet/mineral/plasma, +/obj/item/stack/sheet/mineral/plasma, +/obj/item/reagent_containers/glass/bottle/charcoal{ + pixel_x = 6 }, +/obj/item/reagent_containers/glass/bottle/epinephrine, /obj/item/reagent_containers/dropper, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel/dark, +/obj/item/reagent_containers/dropper, +/turf/open/floor/plasteel/white, /area/medical/chemistry) "aWg" = ( -/obj/structure/table/glass, -/obj/item/assembly/igniter, -/obj/item/assembly/igniter, -/obj/item/assembly/igniter, -/obj/item/assembly/timer{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/assembly/timer{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/assembly/timer{ - pixel_x = 3; - pixel_y = 3 +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, +/obj/machinery/chem_dispenser, +/turf/open/floor/plasteel, +/area/medical/chemistry) +"aWh" = ( /obj/machinery/firealarm{ dir = 1; pixel_y = -24 }, /obj/machinery/light, +/obj/structure/chair/office/light{ + dir = 8 + }, +/obj/effect/landmark/start/chemist, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/medical/chemistry) -"aWh" = ( -/obj/structure/table/glass, -/obj/item/clothing/glasses/science{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/clothing/glasses/science, -/obj/item/stack/cable_coil/white{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/stack/cable_coil/white, -/obj/item/grenade/chem_grenade, -/obj/item/grenade/chem_grenade, -/obj/item/grenade/chem_grenade, -/obj/item/grenade/chem_grenade, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/medical/chemistry) "aWi" = ( /obj/structure/cable/white{ @@ -28498,21 +30475,39 @@ /area/medical/chemistry) "aWj" = ( /obj/structure/table/glass, -/obj/item/clipboard, -/obj/item/toy/figure/chemist, -/obj/machinery/light_switch{ - pixel_x = 24; - pixel_y = -24 +/obj/item/clothing/glasses/science{ + pixel_x = 3; + pixel_y = 3 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/item/clothing/glasses/science, +/obj/item/stack/cable_coil/white{ + pixel_x = 3; + pixel_y = 3 }, -/obj/effect/turf_decal/tile/neutral{ +/obj/item/stack/cable_coil/white, +/obj/item/grenade/chem_grenade, +/obj/item/grenade/chem_grenade, +/obj/item/grenade/chem_grenade, +/obj/item/grenade/chem_grenade, +/obj/item/assembly/igniter, +/obj/item/assembly/igniter, +/obj/item/assembly/igniter, +/obj/item/assembly/timer{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/assembly/timer{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/assembly/timer{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/effect/turf_decal/stripes/line{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/medical/chemistry) "aWk" = ( /obj/structure/table, @@ -28627,6 +30622,46 @@ }, /turf/open/floor/circuit/green/telecomms/mainframe, /area/science/research) +"aWv" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aWw" = ( +/obj/structure/sign/warning/biohazard{ + pixel_x = -32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aWx" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/landmark/blobstart, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aWy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/portable_atmospherics/canister/oxygen, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aWz" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /obj/structure/lattice, @@ -28689,12 +30724,13 @@ /turf/open/floor/plasteel/dark, /area/library) "aWF" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/dark, -/area/library) +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aWG" = ( /obj/machinery/bookbinder, /obj/machinery/status_display{ @@ -28713,68 +30749,72 @@ /turf/open/floor/plasteel/dark, /area/library) "aWH" = ( -/obj/structure/bodycontainer/morgue, -/obj/machinery/power/apc{ - areastring = "/area/medical/morgue"; - name = "Morgue APC"; - pixel_y = -26 - }, -/obj/structure/cable/white{ - icon_state = "0-4" - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) -"aWI" = ( -/obj/effect/decal/cleanable/blood/old, -/obj/structure/cable/white{ - icon_state = "1-8" - }, -/turf/open/floor/plating, -/area/medical/morgue) -"aWJ" = ( -/obj/structure/closet/crate/bin, -/obj/machinery/camera{ - c_tag = "Medbay Morgue"; - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/closet/firecloset, +/obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"aWI" = ( +/obj/structure/cable/white{ + icon_state = "4-8" }, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aWJ" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) "aWK" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/medical/medbay/zone3) "aWL" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "cloningfoyer"; - name = "Cloning Lab"; - req_access_txt = "5" +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/unres{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/newscaster{ + pixel_x = 32 }, /turf/open/floor/plasteel, -/area/medical/medbay/zone3) +/area/medical/virology) "aWM" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/medical/medbay/zone3) +/obj/machinery/door/airlock/virology{ + name = "Virology Access"; + req_access_txt = "39" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) "aWN" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/medical/glass{ @@ -28942,6 +30982,27 @@ /obj/structure/lattice/catwalk, /turf/open/space, /area/asteroid/nearstation) +"aXd" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/light/small, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aXe" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aXf" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, @@ -28966,13 +31027,19 @@ /turf/open/floor/plasteel/dark, /area/library) "aXi" = ( -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 +/obj/structure/bonfire, +/obj/item/reagent_containers/food/drinks/bottle/orangejuice{ + desc = "For the weary spacemen on their quest to rekindle the first plasma fire."; + name = "Carton of Estus" }, -/obj/structure/closet/crate/bin, -/turf/open/floor/plasteel/dark, -/area/library) +/obj/item/nullrod/claymore/glowing{ + desc = "Don't tell anyone you put any points into dex, though."; + force = 10; + name = "moonlight greatsword" + }, +/obj/effect/decal/remains/human, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aXj" = ( /obj/structure/bookcase/random/reference, /obj/effect/turf_decal/tile/neutral{ @@ -29103,6 +31170,21 @@ }, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) +"aXv" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aXw" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -29187,6 +31269,19 @@ }, /turf/open/floor/plasteel/white, /area/science/research) +"aXD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -26 + }, +/turf/open/floor/plasteel, +/area/medical/virology) "aXE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -29313,53 +31408,21 @@ /turf/open/floor/wood, /area/library) "aXN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/white{ - icon_state = "1-2" - }, /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/turf/open/floor/plating, -/area/maintenance/port) -"aXO" = ( -/obj/structure/table/glass, -/obj/item/storage/firstaid/toxin{ - pixel_x = 6; - pixel_y = 6 - }, -/obj/item/storage/firstaid/toxin{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/firstaid/regular, -/obj/item/storage/firstaid/toxin{ - pixel_x = -3; - pixel_y = -3 - }, -/obj/machinery/requests_console{ - department = "Medbay"; - departmentType = 1; - name = "Medbay RC"; - pixel_x = -30 - }, -/obj/machinery/camera{ - c_tag = "Medbay Storage" - }, -/obj/effect/turf_decal/delivery, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 1 - }, /turf/open/floor/plasteel, -/area/medical/medbay/zone3) +/area/maintenance/port/aft) +"aXO" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/wood, +/area/maintenance/port/aft) "aXP" = ( /obj/structure/extinguisher_cabinet{ pixel_y = 32 @@ -29456,6 +31519,12 @@ }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) +"aXY" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/closed/wall/r_wall, +/area/medical/virology) "aXZ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/closet/crate/bin, @@ -29802,85 +31871,77 @@ /turf/open/floor/wood, /area/library) "aYz" = ( -/obj/structure/cable/white{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/turf/open/floor/plating{ - icon_state = "platingdmg3" - }, -/area/maintenance/port) -"aYA" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plating{ - icon_state = "platingdmg1" - }, -/area/maintenance/port) -"aYC" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, -/area/maintenance/port) -"aYE" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/structure/cable/white{ - icon_state = "1-8" +/obj/structure/closet/l3closet/virology, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 }, /obj/effect/turf_decal/stripes/line{ - dir = 1 + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aYA" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 10 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/airalarm{ + pixel_y = 23 }, /turf/open/floor/plating, -/area/maintenance/port) -"aYF" = ( -/obj/structure/cable/white{ - icon_state = "2-8" +/area/maintenance/port/aft) +"aYB" = ( +/obj/machinery/shower{ + desc = "From what you understand it was put in rather recently, but the design looks right out of the 2510's. Weird."; + dir = 1; + icon_state = "shower"; + name = "Emergency Shower" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/camera{ + c_tag = "Virology Access"; + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aYC" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/landmark/event_spawn, +/turf/open/floor/wood, +/area/maintenance/port/aft) +"aYD" = ( +/obj/machinery/atmospherics/components/unary/tank/air, +/obj/effect/turf_decal/stripes/line{ dir = 10 }, /turf/open/floor/plating, -/area/maintenance/port) +/area/maintenance/port/aft) +"aYE" = ( +/obj/machinery/computer/pandemic, +/obj/effect/turf_decal/tile/green, +/obj/item/healthanalyzer, +/obj/machinery/requests_console{ + department = "Virology"; + name = "Virology RC"; + pixel_x = 0; + pixel_y = -32; + receive_ore_updates = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aYF" = ( +/obj/structure/chair/comfy/black, +/turf/open/floor/wood, +/area/maintenance/port/aft) "aYG" = ( -/obj/structure/table/glass, -/obj/item/storage/firstaid/fire{ - pixel_x = 6; - pixel_y = 6 - }, -/obj/item/storage/firstaid/fire{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/firstaid/regular, -/obj/item/storage/firstaid/fire{ - pixel_x = -3; - pixel_y = -3 - }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 - }, -/obj/effect/turf_decal/delivery, -/obj/machinery/door/window/eastleft{ - name = "First-Aid Supplies"; - req_access_txt = "5" - }, -/turf/open/floor/plasteel, -/area/medical/medbay/zone3) +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/chair/comfy/black, +/turf/open/floor/wood, +/area/maintenance/port/aft) "aYH" = ( /obj/effect/landmark/start/medical_doctor, /obj/effect/turf_decal/tile/blue{ @@ -30089,6 +32150,14 @@ heat_capacity = 1e+006 }, /area/hallway/primary/aft) +"aYX" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/window/reinforced/spawner/north, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aYY" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -30188,62 +32257,80 @@ }, /turf/closed/wall/r_wall/rust, /area/science/robotics/lab) +"aZn" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/window/reinforced/spawner/north, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/landmark/xeno_spawn, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aZo" = ( -/obj/structure/girder, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/door/window/northright{ + name = "Theatre Stage" + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aZp" = ( -/obj/structure/table/wood, -/obj/item/gun/ballistic/automatic/toy/pistol/unrestricted, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aZq" = ( -/obj/structure/table/wood, -/obj/item/clothing/gloves/color/black, -/obj/item/taperecorder, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) +"aZr" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, /obj/machinery/light/small{ dir = 1 }, -/obj/structure/sign/poster/contraband/random{ - pixel_y = 32 - }, -/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/maintenance/port) -"aZr" = ( -/obj/structure/rack, -/obj/item/storage/briefcase{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/storage/secure/briefcase, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/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/maintenance/port) +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aZs" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/sign/poster/contraband/random, -/turf/closed/wall, -/area/maintenance/port) +/obj/machinery/vending/autodrobe, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) +"aZt" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/item/clothing/suit/syndicatefake, +/obj/item/clothing/head/syndicatefake, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) "aZu" = ( /obj/machinery/status_display{ pixel_y = -32 @@ -30284,88 +32371,119 @@ }, /turf/open/floor/wood, /area/library) -"aZy" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, -/turf/closed/wall/rust, -/area/maintenance/port) -"aZz" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +"aZx" = ( +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/structure/sign/poster/contraband/random, -/turf/closed/wall, -/area/maintenance/port) -"aZA" = ( -/obj/structure/barricade/wooden, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"aZB" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, -/turf/closed/wall, -/area/maintenance/port) -"aZC" = ( -/obj/structure/table/glass, -/obj/item/storage/firstaid/brute{ - pixel_x = 6; - pixel_y = 6 - }, -/obj/item/storage/firstaid/brute{ +/obj/machinery/light/small, +/obj/structure/table/wood, +/obj/item/lipstick/random{ pixel_x = 3; pixel_y = 3 }, -/obj/item/storage/firstaid/regular, -/obj/item/storage/firstaid/brute{ +/obj/item/lipstick/random{ pixel_x = -3; pixel_y = -3 }, -/obj/machinery/newscaster{ - pixel_x = -32 - }, -/obj/structure/cable/white{ - icon_state = "2-4" - }, -/obj/effect/turf_decal/delivery, -/obj/machinery/door/window/eastright{ - name = "First-Aid Supplies"; - req_access_txt = "5" - }, -/turf/open/floor/plasteel, -/area/medical/medbay/zone3) -"aZD" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/loading_area{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ +/obj/item/lipstick/random, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) +"aZy" = ( +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/effect/turf_decal/tile/blue{ +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/item/clothing/suit/justice, +/obj/item/clothing/head/helmet/justice/escape{ + name = "justice helmet" + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) +"aZz" = ( +/obj/structure/dresser, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) +"aZA" = ( +/obj/structure/table/glass, +/obj/item/clipboard, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/item/folder/white, +/obj/item/toy/figure/chemist, +/obj/item/reagent_containers/glass/beaker/large{ + pixel_x = -3; + pixel_y = 6 + }, +/obj/item/reagent_containers/glass/beaker{ + pixel_x = 3; + pixel_y = 6 + }, +/turf/open/floor/plasteel/dark, +/area/medical/chemistry) +"aZB" = ( +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/airlock/virology/glass{ + name = "Isolation Room"; + req_access_txt = "39" + }, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) +"aZC" = ( +/obj/structure/table/wood, +/obj/structure/sign/poster/random{ + pixel_x = 32 + }, +/turf/open/floor/wood, +/area/maintenance/port/aft) +"aZD" = ( +/obj/machinery/atmospherics/components/binary/valve/on{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"aZE" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/atmos/abandoned{ + name = "Atmospherics Maintenance"; + req_access_txt = "12;24" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/maintenance/port/aft) "aZF" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/medical/glass{ @@ -30426,6 +32544,21 @@ }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) +"aZJ" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/structure/sign/warning/nosmoking{ + pixel_y = -32 + }, +/obj/structure/sign/warning/fire{ + pixel_x = 32 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "aZK" = ( /obj/machinery/holopad, /obj/structure/cable/white{ @@ -30774,113 +32907,6 @@ icon_state = "platingdmg1" }, /area/maintenance/starboard) -"baj" = ( -/turf/closed/wall, -/area/maintenance/port) -"bam" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) -"bao" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"bap" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/port) -"baq" = ( -/obj/structure/table/wood, -/obj/item/clothing/suit/syndicatefake, -/obj/item/clothing/head/syndicatefake, -/obj/effect/decal/cleanable/cobweb, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) -"bar" = ( -/turf/open/floor/plating, -/area/maintenance/port) -"bas" = ( -/obj/structure/dresser, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) -"bat" = ( -/obj/structure/table/glass, -/obj/item/storage/firstaid/o2{ - pixel_x = 6; - pixel_y = 6 - }, -/obj/item/storage/firstaid/o2{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/firstaid/regular, -/obj/item/storage/firstaid/o2{ - pixel_x = -3; - pixel_y = -3 - }, -/obj/machinery/power/apc{ - areastring = "/area/medical/medbay/zone3"; - dir = 8; - name = "Medbay APC"; - pixel_x = -26 - }, -/obj/structure/cable/white, -/obj/effect/turf_decal/delivery, -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/medical/medbay/zone3) -"bau" = ( -/obj/machinery/light, -/obj/structure/noticeboard{ - dir = 1; - pixel_y = -32 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/stripes/box, -/obj/machinery/rnd/production/techfab/department/medical, -/turf/open/floor/plasteel, -/area/medical/medbay/zone3) -"bav" = ( -/obj/machinery/vending/medical, -/obj/machinery/firealarm{ - dir = 1; - pixel_y = -24 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/medical/medbay/zone3) "baw" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/departments/medbay/alt, @@ -31278,101 +33304,6 @@ }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) -"bbc" = ( -/obj/structure/table/wood, -/obj/item/flashlight/lamp, -/turf/open/floor/plating, -/area/maintenance/port) -"bbe" = ( -/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/maintenance/port) -"bbf" = ( -/obj/structure/cable/white{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, -/area/maintenance/port) -"bbg" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"bbh" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/landmark/blobstart, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/port) -"bbj" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, -/area/maintenance/port) -"bbk" = ( -/obj/structure/cable/white{ - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"bbl" = ( -/obj/structure/table/wood, -/obj/item/clipboard, -/obj/item/toy/syndicateballoon, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) -"bbm" = ( -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"bbn" = ( -/obj/machinery/vending/autodrobe, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) "bbp" = ( /obj/machinery/light{ dir = 8 @@ -31686,92 +33617,6 @@ }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) -"bbQ" = ( -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/port) -"bbR" = ( -/turf/open/floor/wood, -/area/maintenance/port) -"bbS" = ( -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/port) -"bbT" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/turf/closed/wall, -/area/maintenance/port) -"bbV" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/barricade/wooden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"bbW" = ( -/obj/structure/barricade/wooden, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"bbX" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/closed/wall, -/area/maintenance/port) -"bbY" = ( -/obj/machinery/computer/security/telescreen/entertainment, -/turf/closed/wall, -/area/maintenance/port) -"bbZ" = ( -/obj/structure/barricade/wooden, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"bca" = ( -/obj/structure/sign/poster/contraband/random, -/turf/closed/wall, -/area/maintenance/port) -"bcb" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating{ - icon_state = "platingdmg1" - }, -/area/maintenance/port) -"bcc" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) "bcd" = ( /obj/item/retractor, /obj/item/hemostat, @@ -32096,129 +33941,6 @@ }, /turf/open/floor/plasteel, /area/science/mixing) -"bcF" = ( -/obj/machinery/computer/slot_machine, -/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/maintenance/port) -"bcG" = ( -/obj/structure/chair/stool/bar, -/turf/open/floor/wood, -/area/maintenance/port) -"bcH" = ( -/obj/effect/decal/cleanable/blood/splatter, -/turf/open/floor/wood, -/area/maintenance/port) -"bcI" = ( -/turf/open/floor/wood{ - icon_state = "wood-broken2" - }, -/area/maintenance/port) -"bcJ" = ( -/obj/structure/chair/stool/bar, -/turf/open/floor/plating, -/area/maintenance/port) -"bcK" = ( -/obj/machinery/computer/slot_machine, -/turf/open/floor/plating, -/area/maintenance/port) -"bcL" = ( -/obj/machinery/vending/cigarette, -/obj/machinery/newscaster{ - pixel_x = -32 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"bcM" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/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/maintenance/port) -"bcN" = ( -/obj/structure/chair/comfy/black{ - dir = 4 - }, -/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/maintenance/port) -"bcO" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/structure/sign/warning/nosmoking{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"bcR" = ( -/obj/structure/table/wood, -/obj/item/instrument/guitar, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/turf/open/floor/plating, -/area/maintenance/port) -"bcS" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/structure/cable/white{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/landmark/blobstart, -/turf/open/floor/plating, -/area/maintenance/port) -"bcT" = ( -/obj/structure/rack, -/obj/item/storage/toolbox/mechanical, -/obj/item/clothing/head/welding, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "0-8" - }, -/obj/machinery/power/apc{ - areastring = "/area/maintenance/port"; - dir = 4; - name = "Port Maintenance APC"; - pixel_x = 26 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) "bcU" = ( /obj/item/circular_saw, /obj/item/surgicaldrill{ @@ -32670,160 +34392,6 @@ /obj/structure/sign/warning/fire, /turf/closed/wall, /area/science/mixing) -"bdD" = ( -/obj/structure/table/wood, -/obj/item/storage/briefcase, -/turf/open/floor/plating, -/area/maintenance/port) -"bdE" = ( -/obj/structure/chair/stool/bar, -/turf/open/floor/wood{ - icon_state = "wood-broken" - }, -/area/maintenance/port) -"bdF" = ( -/obj/structure/chair/stool/bar, -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/port) -"bdG" = ( -/obj/structure/chair/stool/bar, -/turf/open/floor/wood{ - icon_state = "wood-broken2" - }, -/area/maintenance/port) -"bdH" = ( -/obj/structure/table/wood, -/obj/item/toy/cards/deck/syndicate{ - pixel_y = 6 - }, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"bdI" = ( -/obj/structure/table/wood, -/obj/item/wrench, -/obj/item/storage/secure/briefcase{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/briefcase, -/obj/machinery/light/small{ - dir = 8 - }, -/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/maintenance/port) -"bdJ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/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/maintenance/port) -"bdK" = ( -/obj/structure/chair/comfy/black{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/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/maintenance/port) -"bdL" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"bdM" = ( -/obj/effect/landmark/xeno_spawn, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"bdN" = ( -/obj/structure/table/wood, -/obj/item/clothing/suit/justice, -/obj/item/clothing/head/helmet/justice/escape{ - name = "justice helmet" - }, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/structure/sign/poster/contraband/random{ - pixel_x = 32 - }, -/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/maintenance/port) -"bdO" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, -/area/maintenance/port) -"bdP" = ( -/obj/structure/reagent_dispensers/fueltank, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) "bdQ" = ( /obj/structure/closet/secure_closet/medical2, /obj/machinery/airalarm{ @@ -33234,148 +34802,10 @@ /obj/machinery/door/poddoor/incinerator_toxmix, /turf/open/floor/engine/vacuum, /area/science/mixing) -"beu" = ( -/obj/structure/table/wood, -/obj/item/storage/pill_bottle, -/turf/open/floor/plating, -/area/maintenance/port) -"bev" = ( -/obj/machinery/computer/slot_machine, -/obj/machinery/light/small, -/obj/structure/sign/poster/contraband/random{ - pixel_y = -32 - }, -/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/maintenance/port) -"bew" = ( -/obj/structure/table/wood, -/obj/item/coin/iron{ - icon_state = "coin_bananium_heads"; - name = "arcade coin"; - pixel_x = 6 - }, -/obj/item/coin/iron{ - icon_state = "coin_bananium_heads"; - name = "arcade coin"; - pixel_x = -6 - }, -/obj/item/coin/iron{ - icon_state = "coin_bananium_heads"; - name = "arcade coin"; - pixel_y = 6 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"bex" = ( -/obj/structure/table/wood, -/obj/item/reagent_containers/blood/random, -/obj/item/reagent_containers/syringe{ - pixel_y = 5 - }, -/obj/item/reagent_containers/syringe, -/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/maintenance/port) -"bey" = ( -/obj/structure/table/wood, -/obj/item/newspaper, -/obj/item/clothing/head/bowler, -/turf/open/floor/plating, -/area/maintenance/port) -"bez" = ( -/obj/structure/sign/poster/contraband/random{ - pixel_y = -32 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"beA" = ( -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = -32 - }, -/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/maintenance/port) -"beB" = ( -/obj/machinery/door/window{ - dir = 8; - name = "Theatre Stage" - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) -"beC" = ( -/obj/structure/table/wood, -/obj/item/lipstick/random{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/lipstick/random{ - pixel_x = -3; - pixel_y = -3 - }, -/obj/item/lipstick/random, -/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/maintenance/port) "beE" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/medical/medbay/zone3) -"beF" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Medbay Maintenance"; - req_access_txt = "5" - }, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) "beG" = ( /obj/structure/sign/departments/medbay/alt, /turf/closed/wall, @@ -33512,93 +34942,6 @@ }, /turf/closed/wall/r_wall, /area/science/robotics/lab) -"beR" = ( -/obj/structure/cable/white{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"beS" = ( -/obj/structure/cable/white{ - icon_state = "2-8" - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/structure/cable/white{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/port) -"beV" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/structure/cable/white{ - icon_state = "2-4" - }, -/obj/structure/cable/white{ - icon_state = "2-8" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, -/area/maintenance/port) -"beZ" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/maintenance/port) -"bfa" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/structure/cable/white{ - icon_state = "1-8" - }, -/obj/structure/cable/white{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plating, -/area/maintenance/port) -"bfb" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plating{ - icon_state = "platingdmg3" - }, -/area/maintenance/port) -"bfd" = ( -/obj/structure/closet/emcloset, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) "bfe" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/airalarm/unlocked{ @@ -33732,22 +35075,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel/white, /area/chapel/main) -"bfw" = ( -/obj/structure/bonfire, -/obj/item/reagent_containers/food/drinks/bottle/orangejuice{ - desc = "For the weary spacemen on their quest to rekindle the first plasma fire."; - name = "Carton of Estus" - }, -/obj/item/nullrod/claymore/glowing{ - desc = "Don't tell anyone you put any points into dex, though."; - force = 10; - name = "moonlight greatsword" - }, -/obj/effect/decal/remains/human, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/chapel/main) "bfx" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 @@ -33760,122 +35087,16 @@ }, /turf/closed/wall, /area/chapel/main) -"bfz" = ( -/obj/machinery/door/airlock/grunge{ - name = "Crematorium"; - req_access_txt = "27" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/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/maintenance/port) "bfA" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/chapel/main) -"bfB" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plating, -/area/maintenance/port) "bfC" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/closed/wall/rust, /area/chapel/main) -"bfD" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/item/storage/backpack, -/obj/item/crowbar, -/obj/item/wrench, -/obj/structure/rack, -/turf/open/floor/plasteel, -/area/maintenance/port) -"bfE" = ( -/obj/structure/cable/white{ - icon_state = "1-4" - }, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/landmark/blobstart, -/turf/open/floor/plating{ - icon_state = "platingdmg1" - }, -/area/maintenance/port) -"bfF" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/landmark/event_spawn, -/obj/item/tank/internals/oxygen/red, -/obj/item/clothing/mask/gas, -/turf/open/floor/plating, -/area/maintenance/port) -"bfG" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/port) -"bfH" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/port) "bfI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ @@ -34158,22 +35379,6 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/main) -"bgc" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/portable_atmospherics/canister/oxygen, -/turf/open/floor/plasteel, -/area/maintenance/port) -"bgd" = ( -/obj/structure/closet/firecloset, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) "bge" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 @@ -34500,21 +35705,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/hallway/secondary/entry) -"bgO" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port) "bgP" = ( /turf/closed/wall, /area/hallway/secondary/entry) @@ -37915,14 +39105,6 @@ heat_capacity = 1e+006 }, /area/hallway/primary/port/aft) -"bxR" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/landmark/event_spawn, -/turf/open/floor/plating, -/area/maintenance/port) "bxS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -38346,22 +39528,6 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) -"dEa" = ( -/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 - }, -/obj/machinery/computer/arcade{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port) "dFV" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 @@ -40085,9 +41251,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/hallway/primary/starboard/fore) -"nxA" = ( -/turf/closed/wall, -/area/hallway/primary/port/aft) "nFG" = ( /obj/machinery/atmospherics/pipe/manifold/yellow/visible{ dir = 8 @@ -41063,12 +42226,6 @@ /obj/structure/sign/warning/vacuum, /turf/closed/wall/rust, /area/maintenance/starboard) -"sCb" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall, -/area/medical/medbay/zone3) "sCr" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -41902,10 +43059,6 @@ "sJG" = ( /turf/closed/wall/r_wall/rust, /area/engine/supermatter) -"sJH" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall/r_wall/rust, -/area/maintenance/port) "sJI" = ( /turf/closed/wall/rust, /area/library) @@ -41966,9 +43119,6 @@ icon_state = "wood-broken7" }, /area/library) -"sJT" = ( -/turf/closed/wall/rust, -/area/medical/morgue) "sJV" = ( /turf/closed/wall/r_wall/rust, /area/tcommsat/server) @@ -42046,33 +43196,13 @@ "sKp" = ( /turf/closed/wall/rust, /area/medical/medbay/zone3) -"sKx" = ( -/turf/closed/wall/r_wall/rust, -/area/maintenance/port) "sKB" = ( /turf/closed/wall/rust, /area/security/checkpoint) -"sKE" = ( -/turf/closed/wall/rust, -/area/maintenance/port) -"sKH" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall/rust, -/area/maintenance/port) -"sKI" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall/rust, -/area/maintenance/port) "sKJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall/rust, /area/science/robotics/lab) -"sKL" = ( -/obj/structure/sign/poster/contraband/random, -/turf/closed/wall/rust, -/area/maintenance/port) "sKP" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -42085,11 +43215,6 @@ }, /turf/closed/wall/r_wall/rust, /area/science/robotics/lab) -"sKW" = ( -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/port) "sKZ" = ( /turf/closed/wall/r_wall/rust, /area/science/xenobiology) @@ -72661,10 +73786,10 @@ aad aad aad aad -baj -aqo -baj -baj +aKm +aKo +aKm +aKm aaa aaa aaa @@ -72919,9 +74044,9 @@ aMJ aMJ sJV aMJ -aqx -awH -baj +aKr +aLz +aKm aaa aaa aaa @@ -73176,9 +74301,9 @@ buJ buO sKn aMJ -atE -sKx -baj +aKB +aLs +aKm aac aaa aaa @@ -73433,8 +74558,8 @@ buK sKj buR aMJ -avB -aOH +aKF +aqo aad aac aaa @@ -73690,8 +74815,8 @@ buL buP buS aMJ -awB -baj +aKJ +aKm aad aad aaa @@ -73947,8 +75072,8 @@ buK sKj buR aMJ -awB -baj +aKJ +aKm aad aad aaa @@ -74204,8 +75329,8 @@ buN buQ buU sJV -awB -aOH +aKJ +aqo aad aaa aaa @@ -74461,9 +75586,9 @@ sJV aMJ aMJ sJV -awB -aOH -sKx +aKJ +aqo +aLs aac aaa aaa @@ -74717,10 +75842,10 @@ bvo aad bvo aad -baj -awE -awL -baj +aKm +aLp +aLB +aKm aac aac aac @@ -74974,10 +76099,10 @@ aUQ aVK aUQ aXc -baj -aOH -axY -awG +aKm +aqo +aLC +aLv aac aac aac @@ -75232,9 +76357,9 @@ aVL aUR aUQ bvo -sKx -awB -baj +aLs +aKJ +aKm aac aad aac @@ -75489,9 +76614,9 @@ aUU aWz aVL bvo -aOH -axh -baj +aqo +aLL +aKm aad aad aad @@ -75746,10 +76871,10 @@ aUU aWz aUQ bvg -baj -awB -baj -baj +aKm +aKJ +aKm +aKm aad aad aad @@ -76003,10 +77128,10 @@ aUU aWz aVL bvg -awG -awB -axj -baj +aLv +aKJ +aME +aKm aad aad aad @@ -76260,17 +77385,17 @@ aUU aUU aUQ bvg -baj -awB -axk -baj -aad -aad -aad -aad -aad -aad +aKm +aKJ +aMF +aKm +aac +aac aad +aKm +aKm +aKm +aKm aad aad aaa @@ -76517,21 +77642,21 @@ aUU aWz aVL bvg -baj -awB -aZo -baj -aad -aad -aad -aad -aad -aad -aad -aad -aac -aac -aaa +aKm +aKJ +aMG +aKm +aKm +aKm +aKm +aKm +aOs +aSf +aKV +aKV +aKV +aLw +aLw aaa aaa aaa @@ -76774,21 +77899,21 @@ aUU aWz aUQ bvo -baj -awE -awL -baj -aad -aad -aad -aad -aad -aad -aad -aad -aad -aac -aac +aKm +aLp +aLB +aOI +aPQ +aPQ +aPQ +aPQ +aPQ +aVF +aKV +aLn +aRA +aSp +aLw aaa aaa aaa @@ -77031,21 +78156,21 @@ aUU aWz aVL bvo -aOH -baj -axl -sKE -baj -aZo -aZo -sKE -baj -aad -aad -aad -aad -aad -aac +aqo +aKm +aMH +axU +aKm +aMG +aMG +aUi +aKm +aVG +aKV +aSe +aSJ +aTm +aLw aaa aaa aaa @@ -77288,21 +78413,21 @@ aUU aWz aUQ aad -sKx -aZp -bam -bbc -bbQ -dEa -bdD -beu -sKE -aad -aad -aad -aad -aad -aac +aLs +aLX +aMI +aOL +aPR +aQV +aSq +aUk +aUi +aVG +aKV +aTk +aSK +aYE +aKV aad aaa aaa @@ -77545,23 +78670,23 @@ aUU aUU aVL aad -aOH -aZq -axn -axU -axX -bcG -bdE -bev -baj -aad -aad -aad -aad -aad -aad -aad -aad +aqo +aMv +aMQ +aOM +aPS +aRc +aSs +aUl +aKm +aVG +aKV +aTl +aXD +aKV +aKV +aKV +aKV aaa aaa aaa @@ -77802,23 +78927,23 @@ bvg bvg bvo bvo -aOH -aZr -bam -bbe -bbS -bcH -bcG -bcF -baj -aad -aad -aad -aad -aad -aad -aad -aad +aqo +aMw +aMI +aON +aPT +aRd +aRc +aUm +aKm +aVH +aRe +aTn +aWL +aZB +aTv +aTW +aLw aac aaa aaa @@ -78048,34 +79173,34 @@ aKH acB aEt aEt -aOH -aPO -sJH -aQU -aQU -sJH -sJH -aQU -aQU -sJH -aQU -aQU -aZs -axL -bap -bbT -bcI -bar -bew -aZo -aad -aad -aad -aad -aad -aad -aad -aad +aqo +awH +axX +aEg +aEg +axX +axX +aEg +aEg +axX +aEg +aEg +aMD +aOc +aOS +aPU +aRj +aSG +aUo +aMG +aSg +aKV +aUK +aXY +aTo +aTQ +aUh +aKV aac aac aaa @@ -78305,34 +79430,34 @@ aKI aLY aNa aEt -aOI -aPP -bxR -aRS -aTb -aUb -aVM -aVM -aTb -aTb -aTb -aVM -aTb -bao -bbf -aZA -bbR -bdF -bcK -baj -aad -aad -aad -aad -aad -aad -aad -aad +aqx +awL +axY +aEj +aFM +aJN +aKl +aKl +aFM +aFM +aFM +aKl +aFM +aOH +aOT +aPV +aRm +aSI +aRC +aKm +aSr +aKV +aWI +aYz +aKV +aZD +aYD +aKm aad aac aac @@ -78562,8 +79687,8 @@ apt aLZ aNb aEt -bbg -aPQ +atE +axh aQW aQW aQW @@ -78576,20 +79701,20 @@ sJI aQW sJI aQW -bbg -aZz -bcJ -bdG -bev -baj -aad -aad -aad -aad -aad -aad -aad -aad +atE +aQB +aRn +aSL +aUl +aKm +aSQ +aKV +aWJ +aYB +aKV +aYA +aZJ +aKm aad aad aac @@ -78819,8 +79944,8 @@ aKK aMa aNc aEt -bbg -aPR +atE +axk aQW aRT aRU @@ -78833,23 +79958,23 @@ jnK aYw aZu aQW -aYA -sKH -bcK -bdH -bex -sKE -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +awB +aQF +aRC +aTb +aUp +aUi +aTj +aKV +aWM +aKV +aKV +aZE +aKm +aKm +aKm +aKm +aKm aad aad aad @@ -79076,8 +80201,8 @@ aKL aMb aNd sHV -aOL -aPS +avB +axl sJI aSc aTc @@ -79090,23 +80215,23 @@ aXL aYx aZv aQW -bbh -aPV -baj -sKL -baj -aZo -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +aOV +axU +aKm +aTU +aKm +aMG +aVI +aWw +aXd +aKm +aRm +aRm +aYF +aYX +aZp +aZt +aKm aad aad aad @@ -79333,8 +80458,8 @@ aKM aMa aNe aEt -aYA -aPT +awB +axn aQW amH aTd @@ -79347,23 +80472,23 @@ aXM aYy aZw aQW -bbg -bbV -bcL -bdI -bey -aZo -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +atE +aQQ +aRS +aTV +aUq +aMG +aVJ +aWx +aXe +aXN +aXO +aYC +aYG +aZn +aZp +aZx +aKm aad aad aad @@ -79590,8 +80715,8 @@ aKN aMc aNf aEt -aOM -aPU +awE +axL aQW aRW aTe @@ -79604,23 +80729,23 @@ aQW aQW aQW sJI -bbj -bbW -bcM -bdJ -bez -baj -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +aPO +aQU +aRV +aUb +aUu +aUN +aVM +aKm +aKm +aKm +aZC +aRm +aRm +aZo +aZp +aZy +aKm aad aad aac @@ -79847,37 +80972,37 @@ aKO aMd aNg aEt -aON -aPV +awG +axU aQW aRX aTf -sJX -aUX +axj +aCB +aDm +aDn +aDo +aKn +aLy +aFM +aFM +aPP +aQQ +aSm +aSm +aUJ +aKm aVR -aVQ -aXg -aQW -aYz -aTb -aTb -bbk -bbV -bcN -bdK -beA -baj -aad -aad -aad +aKm +aXi bfu bfu sLf bfu bfu -aad -aad -aad +aZq +aKm +aKm aac aac aaa @@ -80114,16 +81239,16 @@ bxS aVS aWE aXh -aQW -bbg -aZy -bap -bap -bbX -bcO -bdL -beB -sKE +ajG +ajG +ajG +ajG +ajG +aHK +aRb +aRb +aUL +sLf bfu bfu sLf @@ -80132,9 +81257,9 @@ bhZ biF bjf bfu -aad -aad -aac +aZr +aZp +aLv aac aaa aaa @@ -80370,17 +81495,17 @@ sJX aUY aVT aVQ -aXi -aQW -bbg -aZz -baq -bbl -bbY -bbm -bdM -bbm -sKE +aXg +ajG +aGY +aOl +aOQ +aCy +aPC +aQh +aRb +aKJ +sLf bfv bfS bgB @@ -80389,9 +81514,9 @@ bia biG bjg bfu -aad -aad -aac +aZs +aZz +aKm aaa aaa aaa @@ -80628,16 +81753,16 @@ sKe aVU aWE aXj -sJI -aYC -aZA -bar -bbm -bbZ -bbm -bbm -bbm -baj +ajG +aOb +aPF +aRo +aFZ +aRp +aQi +aRb +aKJ +bfu bfu bfu bfu @@ -80648,7 +81773,7 @@ bjh bfu sLf bfu -aac +aKm aaa aaa aaa @@ -80875,27 +82000,27 @@ aIB aIB aIB aIB -aOR +aiQ aPZ aQZ aSb sJS -aUh -aUZ +aBn +aDf aVV aVQ aXk -aQW -bbg -aPV -bas -bbn -bca -bcR -bdN -beC -baj -bfw +ajG +aOZ +aQe +aOK +aCy +aPE +aSo +aRb +aLp +aLB +aVW bfu bgC bhp @@ -81132,26 +82257,26 @@ aKP aMe aNj aIB -aOS +aDk aQa aQX aSc aTi -aUi -aVa -aVW -aWF -aVW -aXN -aYE -aZB -bap -bap -sKI -bap -bap -bap -bap +aCx +aCx +aVQ +aWE +aDq +ajG +aOe +aRl +aCy +aCy +aRw +aQC +aHb +aHb +aUZ bfx bfu bfu @@ -81389,7 +82514,7 @@ aKQ aMf aNk aOf -aOT +aDp aQb aRa aSd @@ -81399,16 +82524,16 @@ aVb aVX aWG aXl -aQW -aYF -bxR -aRS -aTb -bcb -bcS -aTb -aVM -beR +aSh +aOg +aGC +aGC +aPA +aJx +aQD +aQI +aHi +aVa bfy bfT bgD @@ -81648,25 +82773,25 @@ aNl aID aOU aQc -aRb -aRb -sJT -aRb -aRb -aRb -aRb +ail +ail +aFo +ail +ail +ail +ail +ail aSh -aSh -aSh -aSh -aSh -sKp -bcc -bcT -bdP -aZo -beS -bfz +aPg +aNS +aPz +aPB +aPH +aQE +aQL +aRb +aVc +aVY bfU bgE bhr @@ -81903,26 +83028,26 @@ aKS aMh aNm aIB -aOV -aQd -aRc -aSe -aTj -aUk -aVc -aVY -aWH -sKp -aXO -aYG -aZC -bat +aEh +aFh +aGf +aHG +aJe +aJo +aLo +aLu +aMl +aOW +aOX +aGZ +aOE +aPv aSh aSh aSh aSh aSh -bbg +atE bfA bfu bgF @@ -82160,26 +83285,26 @@ aIB sIK aIB aIB -aOW -aPZ -aRd -aSf -aTk -aSf -aVd -aVZ -aWI -aSh +aEi +aFj +aGl +aHJ +aJf +aJv +aLq +aLx +aMY +ail aXP aYH -aZD -bau +aFp +aPD aSh bcd bcU bdQ aSh -bbg +atE bfA bfV bgG @@ -82417,27 +83542,27 @@ aKT aMi aNn aHM -aOX -aQe -aRe -aSg -aTl +aEk +aGd +aHf +aHX +aJg +aJA +aLr +aLA +aNO ail -aVe -aWa -aWJ -aSh aXQ aYI -ajG -bav +aOJ +aHa aSh bce bcV bdR sKp -beV -bfB +aVd +aVZ bfW bgH bht @@ -82674,16 +83799,16 @@ aKU aMj aNt csX -aOY +aEl aQf -nxA -aSh -aSh -aSh -aVf -sCb -aSh -aSh +ail +ail +ail +ail +aNp +aOA +ail +ail aXR aYJ aZF @@ -82693,7 +83818,7 @@ bcf bcW blt ooX -aOL +avB bfA bfX bgI @@ -82931,15 +84056,15 @@ aKX lyp bIJ aOj -aOZ +aEm bxQ sJJ -aSh -aTm -aUo -aVg -aWc -aWK +ail +aGF +aJO +aNL +aNo +aNP aXm aXS aYK @@ -82950,7 +84075,7 @@ bcg bcX bdS aSh -aOL +avB bfy bfY bgJ @@ -83191,12 +84316,12 @@ aHM aPa aQb aKg -aSh -aTn -aUp -aVh -aWd -aWL +ail +aHc +aKk +aNM +aOB +aNQ aXn bxT aYL @@ -83207,7 +84332,7 @@ aUn aWb bdT aSh -bbg +atE bfA bfZ bgK @@ -83448,12 +84573,12 @@ aOh vsL aQd sJK -aSi -aTo -aUq -aVi -aWe -aWM +aFm +aHd +aJd +aNN +aOR +aNR aXo aXT aYM @@ -83464,7 +84589,7 @@ bch bcY bdU beE -beZ +aVe bfC bga bgL @@ -83720,8 +84845,8 @@ bbq bbq bbq bdV -beF -bfa +aUM +aVf bfA bgb bgM @@ -83966,7 +85091,7 @@ aSj aTq aUs aVj -aWf +aWg aTp aXq aXV @@ -83978,7 +85103,7 @@ bci bcZ bdW aSh -bbg +atE bfA bfu bfu @@ -84219,25 +85344,25 @@ aHM aPd aQc aRf +aiJ aSk aTr -aUt aVl -aWg +aWh aRf aXr aXW aYP aZL baC -bbs +aHs aSi aWK aWK aSh -bfb -bfD -bgc +aVg +aWa +aWy bgN bhz bip @@ -84478,24 +85603,24 @@ aQg aRh aSl aTs -aiJ -aVl -aWh +aUt +aVn +aWj aRh aXs aXX aYQ aZM baD -bbr +bbs aWK bda bdX aSh -aYF -bfE -bdO -bgO +aVh +aWc +aWF +aXv bhA biq biV @@ -84740,7 +85865,7 @@ aVm aWi aWN aXt -aiQ +aOY aYR aZN ajO @@ -84749,9 +85874,9 @@ bcj bdb bdY aSh -sKW -bfF -aZo +aVi +aWd +aMG bgP bhB bir @@ -84993,8 +86118,8 @@ aRg aSn aTu aUw -aVn -aWj +aWf +aZA aWO aXu aXZ @@ -85006,9 +86131,9 @@ bck bdc bdZ aSh -bfd -bfG -bgd +aVk +aWe +aWH bgP bhC bis @@ -85263,9 +86388,9 @@ aSh aWK bea beG -sKE -bfH -baj +aUi +aWv +aKm bgQ bhD bit diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index ca155d6e94..f11815b537 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -2190,7 +2190,7 @@ /turf/open/floor/plasteel/dark, /area/security/prison) "afp" = ( -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /obj/structure/table, /turf/open/floor/plasteel/dark, /area/security/prison) @@ -10736,7 +10736,7 @@ /area/crew_quarters/dorms) "ayo" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/carpet, /area/crew_quarters/dorms) "ayq" = ( @@ -22136,6 +22136,9 @@ /obj/item/kirbyplants{ icon_state = "plant-05" }, +/obj/machinery/light/small{ + dir = 1 + }, /turf/open/floor/plasteel/dark, /area/crew_quarters/bar) "aYZ" = ( diff --git a/_maps/map_files/Snaxi/Snaxi.dmm b/_maps/map_files/Snaxi/Snaxi.dmm index c8b76b4922..edd3cfd0fb 100644 --- a/_maps/map_files/Snaxi/Snaxi.dmm +++ b/_maps/map_files/Snaxi/Snaxi.dmm @@ -1548,7 +1548,7 @@ /turf/open/floor/plasteel/white, /area/science/lab) "ayu" = ( -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-16" }, /obj/effect/turf_decal/tile/purple{ @@ -7757,7 +7757,7 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-10" }, /turf/open/floor/carpet, @@ -9031,7 +9031,7 @@ /obj/structure/cable{ icon_state = "2-8" }, -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-10" }, /turf/open/floor/plasteel/dark, @@ -9409,7 +9409,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "dij" = ( -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-10" }, /turf/open/floor/carpet, @@ -11361,7 +11361,7 @@ /turf/open/floor/plasteel, /area/janitor) "eue" = ( -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-04" }, /obj/effect/turf_decal/tile/blue{ @@ -17394,7 +17394,7 @@ /obj/machinery/light{ dir = 4 }, -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-10" }, /turf/open/floor/wood, @@ -22642,7 +22642,7 @@ /turf/open/floor/engine, /area/engine/engineering) "lfs" = ( -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-08" }, /turf/open/floor/plasteel, @@ -27858,7 +27858,7 @@ /turf/open/floor/carpet, /area/quartermaster/miningoffice) "old" = ( -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "applebush" }, /turf/open/floor/wood, @@ -28531,7 +28531,7 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/hop) "oGU" = ( -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-10" }, /turf/open/floor/wood, @@ -29602,7 +29602,7 @@ c_tag = "Courtroom East"; dir = 8 }, -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "applebush" }, /turf/open/floor/wood, @@ -32153,7 +32153,7 @@ /turf/open/floor/carpet, /area/crew_quarters/dorms) "qHO" = ( -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-21" }, /turf/open/floor/plasteel, @@ -32961,7 +32961,7 @@ dir = 4 }, /obj/effect/turf_decal/tile/neutral, -/obj//obj/item/kirbyplants, +/obj/item/kirbyplants, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "rhX" = ( @@ -34346,7 +34346,7 @@ /area/engine/engineering) "saN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-10" }, /turf/open/floor/plasteel, @@ -34837,7 +34837,7 @@ dir = 8 }, /obj/effect/turf_decal/tile/blue, -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-10" }, /turf/open/floor/plasteel/dark, @@ -36237,7 +36237,7 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-10" }, /turf/open/floor/plasteel/dark, @@ -43182,7 +43182,7 @@ /obj/structure/cable{ icon_state = "0-4" }, -/obj//obj/item/kirbyplants{ +/obj/item/kirbyplants{ icon_state = "plant-10" }, /obj/machinery/power/apc{ diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index ba1711d0ed..5a14eb9041 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -8429,7 +8429,7 @@ /area/centcom/ferry) "tx" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /turf/open/floor/plasteel/grimy, /area/centcom/ferry) "ty" = ( @@ -10217,7 +10217,7 @@ /area/wizard_station) "xy" = ( /obj/structure/table/wood/fancy, -/obj/item/storage/pill_bottle/dice{ +/obj/item/storage/box/dice{ icon_state = "magicdicebag" }, /turf/open/floor/carpet, diff --git a/_maps/shuttles/arrival_delta.dmm b/_maps/shuttles/arrival_delta.dmm index 16fc34e62b..c7d331e368 100644 --- a/_maps/shuttles/arrival_delta.dmm +++ b/_maps/shuttles/arrival_delta.dmm @@ -307,7 +307,7 @@ "D" = ( /obj/structure/table/reinforced, /obj/item/folder, -/obj/item/storage/pill_bottle/dice, +/obj/item/storage/box/dice, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/shuttle/arrival) diff --git a/_maps/shuttles/arrival_omega.dmm b/_maps/shuttles/arrival_omega.dmm index decb5f9d52..9285a4a716 100644 --- a/_maps/shuttles/arrival_omega.dmm +++ b/_maps/shuttles/arrival_omega.dmm @@ -237,7 +237,7 @@ /area/shuttle/arrival) "C" = ( /obj/structure/table/reinforced, -/obj/item/storage/pill_bottle/dice{ +/obj/item/storage/box/dice{ pixel_x = -2; pixel_y = 8 }, diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 2af331b777..d1c1d309cd 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -142,6 +142,7 @@ #define CUSTOM_SKINTONE 24 //adds a "_g" suffix to bodypart overlays icon states if a custom skintone is used. #define HORNCOLOR 25 #define WINGCOLOR 26 +#define CAN_SCAR 27 // If this species can be scarred (fleshy) //organ slots #define ORGAN_SLOT_BRAIN "brain" diff --git a/code/__DEFINES/_flags/_flags.dm b/code/__DEFINES/_flags/_flags.dm index 7daf9fa8a3..3a31eebb19 100644 --- a/code/__DEFINES/_flags/_flags.dm +++ b/code/__DEFINES/_flags/_flags.dm @@ -142,6 +142,10 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 /// The attack is from a parry counterattack. #define ATTACKCHAIN_PARRY_COUNTERATTACK (1<<0) +// UnarmedAttack() flags +/// Attack is from a parry counterattack +#define UNARMED_ATTACK_PARRY (1<<0) + /// If the thing can reflect light (lasers/energy) #define RICOCHET_SHINY (1<<0) /// If the thing can reflect matter (bullets/bomb shrapnel) diff --git a/code/__DEFINES/flags/do_after.dm b/code/__DEFINES/_flags/do_after.dm similarity index 100% rename from code/__DEFINES/flags/do_after.dm rename to code/__DEFINES/_flags/do_after.dm diff --git a/code/__DEFINES/_flags/obj_flags.dm b/code/__DEFINES/_flags/obj_flags.dm index ebb9b4bda0..a936a5cef5 100644 --- a/code/__DEFINES/_flags/obj_flags.dm +++ b/code/__DEFINES/_flags/obj_flags.dm @@ -12,4 +12,9 @@ #define SHOVABLE_ONTO (1<<9) //called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check. #define BLOCK_Z_FALL (1<<10) +/// Integrity defines for clothing (not flags but close enough) +#define CLOTHING_PRISTINE 0 // We have no damage on the clothing +#define CLOTHING_DAMAGED 1 // There's some damage on the clothing but it still has at least one functioning bodypart and can be equipped +#define CLOTHING_SHREDDED 2 // The clothing is useless and cannot be equipped unless repaired first + // If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support diff --git a/code/__DEFINES/flags/shields.dm b/code/__DEFINES/_flags/shields.dm similarity index 100% rename from code/__DEFINES/flags/shields.dm rename to code/__DEFINES/_flags/shields.dm diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 22e5be3523..198356f804 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -75,7 +75,11 @@ #define ADMIN_PUNISHMENT_PIE "Cream Pie" #define ADMIN_PUNISHMENT_CUSTOM_PIE "Custom Cream Pie" #define ADMIN_PUNISHMENT_SHOES "Knot Shoes" +#define ADMIN_PUNISHMENT_CRACK ":B:oneless" +#define ADMIN_PUNISHMENT_BLEED ":B:loodless" +#define ADMIN_PUNISHMENT_SCARIFY "Scarify" #define ADMIN_PUNISHMENT_PICKLE "Pickle-ify" +#define ADMIN_PUNISHMENT_FRY "Fry" #define AHELP_ACTIVE 1 #define AHELP_CLOSED 2 diff --git a/code/__DEFINES/admin/keybindings.dm b/code/__DEFINES/admin/keybindings.dm index 3efc26c7d5..fcfe7c5e58 100644 --- a/code/__DEFINES/admin/keybindings.dm +++ b/code/__DEFINES/admin/keybindings.dm @@ -1,6 +1,6 @@ // Defines for managed input/keybinding system. /// Max length of a keypress command before it's considered to be a forged packet/bogus command -#define MAX_KEYPRESS_COMMANDLENGTH 16 +#define MAX_KEYPRESS_COMMANDLENGTH 32 /// Maximum keys that can be bound to one button #define MAX_COMMANDS_PER_KEY 5 /// Maximum keys per keybind diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 1882effe38..5b8a4d5fc3 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -252,7 +252,14 @@ #define COMPONENT_INTERRUPT_LIFE_BIOLOGICAL 1 // interrupt biological processes #define COMPONENT_INTERRUPT_LIFE_PHYSICAL 2 // interrupt physical handling -// /mob/living/carbon signals +// /mob/living/carbon physiology signals +#define COMSIG_CARBON_GAIN_WOUND "carbon_gain_wound" //from /datum/wound/proc/apply_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L) +#define COMSIG_CARBON_LOSE_WOUND "carbon_lose_wound" //from /datum/wound/proc/remove_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L) +///from base of /obj/item/bodypart/proc/attach_limb(): (new_limb, special) allows you to fail limb attachment +#define COMSIG_CARBON_ATTACH_LIMB "carbon_attach_limb" + #define COMPONENT_NO_ATTACH (1<<0) +#define COMSIG_CARBON_REMOVE_LIMB "carbon_remove_limb" //from base of /obj/item/bodypart/proc/drop_limb(special, dismembered) + #define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) #define COMSIG_CARBON_IDENTITY_TRANSFERRED_TO "carbon_id_transferred_to" //from datum/dna/transfer_identity(): (datum/dna, transfer_SE) #define COMSIG_CARBON_TACKLED "carbon_tackled" //sends from tackle.dm on tackle completion @@ -352,7 +359,7 @@ #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_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/projectile/proc/fire(): () +#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 #define COMSIG_EMBED_TRY_FORCE "item_try_embed" // sent when trying to force an embed (mainly for projectiles, only used in the embed element) #define COMSIG_PROJECTILE_PREHIT "com_proj_prehit" ///sent to targets during the process_hit proc of projectiles @@ -362,6 +369,7 @@ // /mob/living/carbon/human signals #define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) #define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) +#define COMSIG_HUMAN_EARLY_UNARMED_ATTACK "human_early_unarmed_attack" #define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted) #define COMSIG_HUMAN_PREFS_COPIED_TO "human_prefs_copied_to" //from datum/preferences/copy_to(): (datum/preferences, icon_updates, roundstart_checks) #define COMSIG_HUMAN_HARDSET_DNA "human_hardset_dna" //from mob/living/carbon/human/hardset_dna(): (ui, list/mutation_index, newreal_name, newblood_type, datum/species, newfeatures) diff --git a/code/__DEFINES/integrated_electronics.dm b/code/__DEFINES/integrated_electronics.dm index 727314abc6..71bdfb37ea 100644 --- a/code/__DEFINES/integrated_electronics.dm +++ b/code/__DEFINES/integrated_electronics.dm @@ -7,10 +7,10 @@ #define PULSE_CHANNEL "pulse channel" // Methods of obtaining a circuit. -#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box and able to be printed in the IC printer. +#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box and is able to be printed in the IC printer. #define IC_SPAWN_RESEARCH 2 // If the circuit design will be available in the IC printer after upgrading it. -// Categories that help differentiate circuits that can do different tipes of actions +// Categories that help differentiate circuits that can do different types of actions #define IC_ACTION_MOVEMENT (1<<0) // If the circuit can move the assembly #define IC_ACTION_COMBAT (1<<1) // If the circuit can cause harm #define IC_ACTION_LONG_RANGE (1<<2) // If the circuit communicate with something outside of the assembly diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 90c7c34f8d..a9d9bda00c 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -216,7 +216,7 @@ GLOBAL_LIST_INIT(pointed_types, typecacheof(list( #define isgun(A) (istype(A, /obj/item/gun)) -#define isfood(A) (istype(A, /obj/item/reagent_containers/food)) +#define isfood(A) (istype(A, /obj/item/reagent_containers/food/snacks)) //Assemblies #define isassembly(O) (istype(O, /obj/item/assembly)) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 0801da6911..52657e9104 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -12,6 +12,8 @@ #define MOVE_INTENT_RUN "run" //Blood levels +#define BLOOD_VOLUME_MAX_LETHAL 2150 +#define BLOOD_VOLUME_EXCESS 2100 #define BLOOD_VOLUME_MAXIMUM 2000 #define BLOOD_VOLUME_SLIME_SPLIT 1120 #define BLOOD_VOLUME_NORMAL 560 @@ -57,6 +59,7 @@ #define BODYPART_NOT_DISABLED 0 #define BODYPART_DISABLED_DAMAGE 1 #define BODYPART_DISABLED_PARALYSIS 2 +#define BODYPART_DISABLED_WOUND 3 #define DEFAULT_BODYPART_ICON 'icons/mob/human_parts.dmi' #define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi' @@ -103,12 +106,14 @@ #define TRAUMA_RESILIENCE_BASIC 1 //Curable with chems #define TRAUMA_RESILIENCE_SURGERY 2 //Curable with brain surgery #define TRAUMA_RESILIENCE_LOBOTOMY 3 //Curable with lobotomy -#define TRAUMA_RESILIENCE_MAGIC 4 //Curable only with magic -#define TRAUMA_RESILIENCE_ABSOLUTE 5 //This is here to stay +#define TRAUMA_RESILIENCE_WOUND 4 //Curable by healing the head wound +#define TRAUMA_RESILIENCE_MAGIC 5 //Curable only with magic +#define TRAUMA_RESILIENCE_ABSOLUTE 6 //This is here to stay //Limit of traumas for each resilience tier #define TRAUMA_LIMIT_BASIC 3 #define TRAUMA_LIMIT_SURGERY 2 +#define TRAUMA_LIMIT_WOUND 2 #define TRAUMA_LIMIT_LOBOTOMY 3 #define TRAUMA_LIMIT_MAGIC 3 #define TRAUMA_LIMIT_ABSOLUTE INFINITY @@ -316,4 +321,4 @@ #define EYE_CONTACT_RANGE 5 /// If you examine the same atom twice in this timeframe, we call examine_more() instead of examine() -#define EXAMINE_MORE_TIME 1 SECONDS \ No newline at end of file +#define EXAMINE_MORE_TIME 1 SECONDS diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 4225581018..14cc7c9e5e 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -36,6 +36,8 @@ #define STATUS_EFFECT_REGENERATIVE_CORE /datum/status_effect/regenerative_core //removes damage slowdown while giving a slow regenerating effect +#define STATUS_EFFECT_DETERMINED /datum/status_effect/determined //currently in a combat high from being seriously wounded + ///////////// // DEBUFFS // ///////////// @@ -107,6 +109,8 @@ #define STATUS_EFFECT_ELECTROSTAFF /datum/status_effect/electrostaff //slows down victim +#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 + ///////////// // NEUTRAL // ///////////// diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index bf76f8a523..a6bd7a1c8e 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -152,14 +152,17 @@ var/list/po = A.priority_overlays;\ if(LAZYLEN(rm)){\ A.overlays -= rm;\ - rm.Cut();\ + A.remove_overlays = null;\ }\ if(LAZYLEN(ad)){\ A.overlays |= ad;\ - ad.Cut();\ + A.add_overlays = null;\ }\ if(LAZYLEN(po)){\ A.overlays |= po;\ }\ + else{\ + A.priority_overlays = null;\ + }\ A.flags_1 &= ~OVERLAY_QUEUED_1;\ } diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm index 7e391caaed..a472e83795 100644 --- a/code/__DEFINES/tools.dm +++ b/code/__DEFINES/tools.dm @@ -17,6 +17,7 @@ //Glasswork Tools #define TOOL_BLOW "blowing_rod" #define TOOL_GLASS_CUT "glasskit" +#define TOOL_BONESET "bonesetter" // If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY, // tool sound is only played when op is started. If not, it's played twice. diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index eb86c52301..3e5b27d376 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -228,7 +228,7 @@ #define TRAIT_SPRINT_LOCKED "sprint_locked" //non-mob traits -#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it +#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it #define VEHICLE_TRAIT "vehicle" // inherited from riding vehicles #define INNATE_TRAIT "innate" diff --git a/code/__DEFINES/wounds.dm b/code/__DEFINES/wounds.dm new file mode 100644 index 0000000000..b993429961 --- /dev/null +++ b/code/__DEFINES/wounds.dm @@ -0,0 +1,43 @@ +#define WOUND_DAMAGE_EXPONENT 1.4 + +#define WOUND_SEVERITY_TRIVIAL 0 // for jokey/meme wounds like stubbed toe, no standard messages/sounds or second winds +#define WOUND_SEVERITY_MODERATE 1 +#define WOUND_SEVERITY_SEVERE 2 +#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 + +// 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_MAX 10 + +// 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) + +// 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 +// 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) + +// 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 diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 84709a78b1..733cbcfd8d 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -81,6 +81,10 @@ if (CONFIG_GET(flag/log_attack)) WRITE_LOG(GLOB.world_attack_log, "ATTACK: [text]") +/proc/log_wounded(text) + if (CONFIG_GET(flag/log_attack)) + WRITE_LOG(GLOB.world_attack_log, "WOUND: [text]") + /proc/log_manifest(ckey, datum/mind/mind,mob/body, latejoin = FALSE) if (CONFIG_GET(flag/log_manifest)) WRITE_LOG(GLOB.world_manifest_log, "[ckey] \\ [body.real_name] \\ [mind.assigned_role] \\ [mind.special_role ? mind.special_role : "NONE"] \\ [latejoin ? "LATEJOIN":"ROUNDSTART"]") diff --git a/code/__HELPERS/do_after.dm b/code/__HELPERS/do_after.dm index b2202ec9ae..49e506ee90 100644 --- a/code/__HELPERS/do_after.dm +++ b/code/__HELPERS/do_after.dm @@ -186,6 +186,9 @@ break if(uninterruptible) continue + if(!(target in user.do_afters)) + . = FALSE + break if(!(target in user.do_afters)) . = FALSE @@ -198,7 +201,7 @@ if((!drifting && user.loc != user_loc) || target.loc != target_loc || (!ignorehelditem && user.get_active_held_item() != holding) || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke())) . = 0 break - if (progress) + if(progress) qdel(progbar) if(!QDELETED(target)) @@ -275,7 +278,7 @@ break if(target && !(target in user.do_afters)) - . = 0 + . = FALSE break if(needhand) @@ -288,8 +291,10 @@ if(user.get_active_held_item() != holding) . = 0 break - if (progress) + if(progress) qdel(progbar) + if(!QDELETED(target)) + LAZYREMOVE(user.do_afters, target) if(!QDELETED(target)) LAZYREMOVE(user.do_afters, target) @@ -345,7 +350,6 @@ break mainloop if(progbar) qdel(progbar) - for(var/thing in targets) var/atom/target = thing if(!QDELETED(target)) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index f8f6bca31a..ca12567b59 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -145,9 +145,9 @@ continue if(!S.ckeys_allowed) snowflake_ipc_antenna_list[S.name] = mspath - var/color1 = random_short_color() - var/color2 = random_short_color() - var/color3 = random_short_color() + var/color1 = random_color() + var/color2 = random_color() + var/color3 = random_color() var/body_model = MALE switch(intended_gender) diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm index cbe1817233..0441e0bcb7 100644 --- a/code/__HELPERS/sanitize_values.dm +++ b/code/__HELPERS/sanitize_values.dm @@ -51,40 +51,111 @@ return default return default -/proc/sanitize_hexcolor(color, desired_format=3, include_crunch=0, default) +#define RGB_FORMAT_INVALID 0 +#define RGB_FORMAT_SHORT 1 +#define RGB_FORMAT_LONG 2 + +/** + * Sanitizes a hexadecimal color. Always outputs lowercase. + * + * @params + * * color - input color, 3 or 6 characters without the #. + * * desired_format - 3 or 6 characters without the potential #. can only put in 3 or 6 here. + * * include_crunch - do we put a # at the start + * * default - default color. must be 3 or 6 characters with or without #. + * * default_replacement - what we replace broken letters with. + */ +/proc/sanitize_hexcolor(color, desired_format = 3, include_crunch = 0, default = rgb(218, 72, 255), default_replacement = "f") + if(!istext(default) || (length(default) < 3)) + CRASH("Default should be a text string of RGB format, with or without the crunch, 3 or 6 characters. Default was instead [default]") + if(!istext(default_replacement) || (length(default_replacement) != 1)) + CRASH("Invalid default_replacement: [default_replacement]") + default_replacement = lowertext(default_replacement) + switch(text2ascii(default_replacement)) + if(48 to 57) + if(97 to 102) + if(65 to 70) + else // yeah yeah i know 3 empty if's.. + CRASH("Invalid default_replacement: [default_replacement]") var/crunch = include_crunch ? "#" : "" if(!istext(color)) - color = "" + color = default - var/start = 1 + (text2ascii(color, 1) == 35) var/len = length(color) - var/char = "" - // RRGGBB -> RGB but awful - var/convert_to_shorthand = desired_format == 3 && length_char(color) > 3 + // get rid of crunch + if(len && color[1] == "#") + if(len >= 2) + color = copytext(color, 2) + else + color = "" + len = length(color) - . = "" - var/i = start - while(i <= len) + switch(desired_format) + if(3) + desired_format = RGB_FORMAT_SHORT + if(6) + desired_format = RGB_FORMAT_LONG + else + CRASH("Invalid desired_format: [desired_format]. Must be 3 or 6.") + var/current_format = RGB_FORMAT_INVALID + switch(length(color)) + if(3) + current_format = RGB_FORMAT_SHORT + if(6) + current_format = RGB_FORMAT_LONG + else + current_format = RGB_FORMAT_INVALID + + if(current_format == RGB_FORMAT_INVALID) // nah + color = default // process default + if(color[1] == "#") // we checked default was at least 3 chars long earlier + color = copytext(color, 2) + len = length(color) + switch(len) + if(3) + current_format = RGB_FORMAT_SHORT + if(6) + current_format = RGB_FORMAT_LONG + else + CRASH("Default was not 3 or 6 RGB hexadecimal characters: [default]") + + var/sanitized = "" + var/char = "" + // first, sanitize hex + for(var/i in 1 to len) char = color[i] switch(text2ascii(char)) - if(48 to 57) //numbers 0 to 9 - . += char - if(97 to 102) //letters a to f - . += char - if(65 to 70) //letters A to F - . += lowertext(char) + if(48 to 57) // 0 to 9 + sanitized += char + if(97 to 102) // a to f + sanitized += char + if(65 to 70) // A to F (capitalized!) + sanitized += lowertext(char) else - break - i += length(char) - if(convert_to_shorthand && i <= len) //skip next one - i += length(color[i]) + sanitized += default_replacement + // do we need to convert? + if(desired_format == current_format) + return crunch + sanitized // no + // yes + if((desired_format == RGB_FORMAT_SHORT) && (current_format == RGB_FORMAT_LONG)) // downconvert + var/temp = "" + // we could do some math but we're lazy and in practice floor()ing this. + for(var/i in 1 to 6 step 2) + temp += sanitized[i] + sanitized = temp + else if((desired_format == RGB_FORMAT_LONG) && (current_format == RGB_FORMAT_SHORT)) // upconvert + var/temp = "" + for(var/i in 1 to 3) + temp += sanitized[i] + temp += sanitized[i] + sanitized = temp + else + CRASH("Invalid desired_format and current_format pair: [desired_format], [current_format]. Could not determine which way to convert.") + return crunch + sanitized - if(length_char(.) != desired_format) - if(default) - return default - return crunch + repeat_string(desired_format, "0") - - return crunch + . +#undef RGB_FORMAT_INVALID +#undef RGB_FORMAT_SHORT +#undef RGB_FORMAT_LONG /proc/sanitize_ooccolor(color) if(length(color) != length_char(color)) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 2c8497d5ed..7a18d2ce01 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -339,10 +339,24 @@ /proc/isLeap(y) return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) - +/// For finding out what body parts a body zone covers, the inverse of the below basically +/proc/zone2body_parts_covered(def_zone) + switch(def_zone) + if(BODY_ZONE_CHEST) + return list(CHEST, GROIN) + if(BODY_ZONE_HEAD) + return list(HEAD) + if(BODY_ZONE_L_ARM) + return list(ARM_LEFT, HAND_LEFT) + if(BODY_ZONE_R_ARM) + return list(ARM_RIGHT, HAND_RIGHT) + if(BODY_ZONE_L_LEG) + return list(LEG_LEFT, FOOT_LEFT) + if(BODY_ZONE_R_LEG) + return list(LEG_RIGHT, FOOT_RIGHT) //Turns a Body_parts_covered bitfield into a list of organ/limb names. -//(I challenge you to find a use for this) +//(I challenge you to find a use for this) -I found a use for it!! /proc/body_parts_covered2organ_names(bpc) var/list/covered_parts = list() diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index cbe004ed90..4addae3ac4 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1437,7 +1437,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) /obj/item/reagent_containers/food/snacks/grown, /obj/item/reagent_containers/food/snacks/grown/mushroom, /obj/item/reagent_containers/food/snacks/grown/nettle, // base type - /obj/item/reagent_containers/food/snacks/deepfryholder, /obj/item/reagent_containers/food/snacks/grown/shell, /obj/item/reagent_containers/food/snacks/clothing, /obj/item/reagent_containers/food/snacks/store/bread diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 4c912b9c1e..a25381f266 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -116,15 +116,16 @@ GLOBAL_LIST_INIT(ai_core_display_screens, list( GLOBAL_LIST_INIT(security_depts_prefs, list(SEC_DEPT_RANDOM, SEC_DEPT_NONE, SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, SEC_DEPT_SCIENCE, SEC_DEPT_SUPPLY)) - //Backpacks -#define GBACKPACK "Grey Backpack" -#define GSATCHEL "Grey Satchel" -#define GDUFFELBAG "Grey Duffel Bag" -#define LSATCHEL "Leather Satchel" +//Backpacks #define DBACKPACK "Department Backpack" #define DSATCHEL "Department Satchel" #define DDUFFELBAG "Department Duffel Bag" -GLOBAL_LIST_INIT(backbaglist, list(DBACKPACK, DSATCHEL, DDUFFELBAG, GBACKPACK, GSATCHEL, GDUFFELBAG, LSATCHEL)) +GLOBAL_LIST_INIT(backbaglist, list(DBACKPACK, DSATCHEL, DDUFFELBAG, //everything after this point is a non-department backpack + "Grey Backpack" = /obj/item/storage/backpack, + "Grey Satchel" = /obj/item/storage/backpack/satchel, + "Grey Duffel Bag" = /obj/item/storage/backpack/duffelbag, + "Leather Satchel" = /obj/item/storage/backpack/satchel/leather, + "Snail Shell" = /obj/item/storage/backpack/snail)) //Suit/Skirt #define PREF_SUIT "Jumpsuit" diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 02cbd6bea5..7b40c96a6d 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -94,8 +94,9 @@ The below is only really for safety, or you can alter the way it functions and re-insert it above. */ -/mob/living/silicon/ai/UnarmedAttack(atom/A) +/mob/living/silicon/ai/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) A.attack_ai(src) + /mob/living/silicon/ai/RangedAttack(atom/A) A.attack_ai(src) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 01261677d9..8a63339081 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -269,10 +269,9 @@ proximity_flag is not currently passed to attack_hand, and is instead used in human click code to allow glove touches only at melee range. */ -/mob/proc/UnarmedAttack(atom/A, proximity_flag) +/mob/proc/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(ismob(A)) changeNext_move(CLICK_CD_MELEE) - return /* Ranged unarmed attack: diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 9fcccedf1a..82288ee0d1 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -175,8 +175,9 @@ clicks, you can do so here, but you will have to change attack_robot() above to the proper function */ -/mob/living/silicon/robot/UnarmedAttack(atom/A) +/mob/living/silicon/robot/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) A.attack_robot(src) + /mob/living/silicon/robot/RangedAttack(atom/A) A.attack_robot(src) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index d8ef1c525a..94374c5cb6 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -128,7 +128,7 @@ deltimer(C.parallax_animate_timer) var/datum/callback/CB = CALLBACK(src, .proc/update_parallax_motionblur, C, animatedir, new_parallax_movedir, newtransform) if(skip_windups) - CB.Invoke() + CB.InvokeAsync() else C.parallax_animate_timer = addtimer(CB, min(shortesttimer, PARALLAX_LOOP_TIME), TIMER_CLIENT_TIME|TIMER_STOPPABLE) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 059f9d518e..48b652b6f3 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -4,12 +4,18 @@ Otherwise pretty standard. */ -/mob/living/carbon/human/UnarmedAttack(atom/A, proximity) + +/mob/living/carbon/human/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(!has_active_hand()) //can't attack without a hand. to_chat(src, "You look at your arm and sigh.") return + var/obj/item/bodypart/check_arm = get_active_hand() + if(check_arm && check_arm.is_disabled() == BODYPART_DISABLED_WOUND) + to_chat(src, "The damage in your [check_arm.name] is preventing you from using it! Get it fixed, or at least splinted!") + return + // Special glove functions: // If the gloves do anything, have them return 1 to stop // normal attack_hand() here. @@ -20,16 +26,16 @@ var/override = 0 for(var/datum/mutation/human/HM in dna.mutations) - override += HM.on_attack_hand(A, proximity) + override += HM.on_attack_hand(A, proximity, intent, flags) if(override) return SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) - A.attack_hand(src) + A.attack_hand(src, intent, flags) //Return TRUE to cancel other attack hand effects that respect it. -/atom/proc/attack_hand(mob/user) +/atom/proc/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = FALSE if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND)) add_fingerprint(user) @@ -104,8 +110,8 @@ /* Animals & All Unspecified */ -/mob/living/UnarmedAttack(atom/A) - A.attack_animal(src) +/mob/living/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) + A.attack_animal(src, intent, flags) /atom/proc/attack_animal(mob/user) SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_ANIMAL, user) @@ -116,8 +122,8 @@ /* Monkeys */ -/mob/living/carbon/monkey/UnarmedAttack(atom/A) - A.attack_paw(src) +/mob/living/carbon/monkey/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) + A.attack_paw(src, intent, flags) /atom/proc/attack_paw(mob/user) if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND) @@ -162,8 +168,8 @@ Aliens Defaults to same as monkey in most places */ -/mob/living/carbon/alien/UnarmedAttack(atom/A) - A.attack_alien(src) +/mob/living/carbon/alien/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) + A.attack_alien(src, intent, flags) /atom/proc/attack_alien(mob/living/carbon/alien/user) attack_paw(user) @@ -173,29 +179,29 @@ return // Babby aliens -/mob/living/carbon/alien/larva/UnarmedAttack(atom/A) - A.attack_larva(src) +/mob/living/carbon/alien/larva/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) + A.attack_larva(src, intent, flags) + /atom/proc/attack_larva(mob/user) return - /* Slimes Nothing happening here */ -/mob/living/simple_animal/slime/UnarmedAttack(atom/A) - A.attack_slime(src) +/mob/living/simple_animal/slime/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) + A.attack_slime(src, intent, flags) + /atom/proc/attack_slime(mob/user) return /mob/living/simple_animal/slime/RestrainedClickOn(atom/A) return - /* Drones */ -/mob/living/simple_animal/drone/UnarmedAttack(atom/A) - A.attack_drone(src) +/mob/living/simple_animal/drone/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) + A.attack_drone(src, intent, flags) /atom/proc/attack_drone(mob/living/simple_animal/drone/user) attack_hand(user) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans. @@ -203,55 +209,44 @@ /mob/living/simple_animal/slime/RestrainedClickOn(atom/A) return - /* True Devil */ - -/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity) +/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) A.attack_hand(src) /* Brain */ - -/mob/living/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default +/mob/living/brain/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) return - /* pAI */ - -/mob/living/silicon/pai/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default +/mob/living/silicon/pai/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) return - /* Simple animals */ - -/mob/living/simple_animal/UnarmedAttack(atom/A, proximity) +/mob/living/simple_animal/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(!dextrous) return ..() if(!ismob(A)) - A.attack_hand(src) + A.attack_hand(src, intent, flags) update_inv_hands() - /* Hostile animals */ - -/mob/living/simple_animal/hostile/UnarmedAttack(atom/A) +/mob/living/simple_animal/hostile/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) target = A if(dextrous && !ismob(A)) ..() else AttackingTarget() - - /* New Players: Have no reason to click on anything at all. diff --git a/code/controllers/subsystem/chat.dm b/code/controllers/subsystem/chat.dm index bbeb0683f0..ba2794d00f 100644 --- a/code/controllers/subsystem/chat.dm +++ b/code/controllers/subsystem/chat.dm @@ -31,19 +31,13 @@ SUBSYSTEM_DEF(chat) //Some macros remain in the string even after parsing and fuck up the eventual output var/original_message = message - message = replacetext(message, "\improper", "") - message = replacetext(message, "\proper", "") - if(handle_whitespace) - message = replacetext(message, "\n", "
") - message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]") - if (trailing_newline) - message += "
" //url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. //Do the double-encoding here to save nanoseconds - var/twiceEncoded = url_encode(url_encode(message)) + var/twiceEncoded if(islist(target)) + var/sanitized_message = FALSE for(var/I in target) var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible @@ -55,6 +49,17 @@ SUBSYSTEM_DEF(chat) if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file. continue + + if(!sanitized_message) + message = replacetext(message, "\improper", "") + message = replacetext(message, "\proper", "") + if(handle_whitespace) + message = replacetext(message, "\n", "
") + message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]") + if (trailing_newline) + message += "
" + twiceEncoded = url_encode(url_encode(message)) + sanitized_message = TRUE if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue C.chatOutput.messageQueue += message @@ -74,6 +79,15 @@ SUBSYSTEM_DEF(chat) if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file. return + message = replacetext(message, "\improper", "") + message = replacetext(message, "\proper", "") + if(handle_whitespace) + message = replacetext(message, "\n", "
") + message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]") + if (trailing_newline) + message += "
" + twiceEncoded = url_encode(url_encode(message)) + if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue C.chatOutput.messageQueue += message return diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index cd577e4ac6..b4a162c982 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -268,6 +268,7 @@ SUBSYSTEM_DEF(persistence) SaveRandomizedRecipes() SavePanicBunker() SavePaintings() + SaveScars() /datum/controller/subsystem/persistence/proc/LoadPanicBunker() var/bunker_path = file("data/bunker_passthrough.json") @@ -547,3 +548,24 @@ SUBSYSTEM_DEF(persistence) var/json_file = file("data/paintings.json") fdel(json_file) WRITE_FILE(json_file, json_encode(paintings)) + +/datum/controller/subsystem/persistence/proc/SaveScars() + for(var/i in GLOB.joined_player_list) + var/mob/living/carbon/human/ending_human = get_mob_by_ckey(i) + if(!istype(ending_human) || !ending_human.mind || !ending_human.client || !ending_human.client.prefs || !ending_human.client.prefs.persistent_scars) + continue + + var/mob/living/carbon/human/original_human = ending_human.mind.original_character + if(!original_human || original_human.stat == DEAD || !original_human.all_scars || !(original_human == ending_human)) + if(ending_human.client) // i was told if i don't check this every step of the way byond might decide a client ceases to exist mid proc so here we go + 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 + if(!ending_human.client) + return + ending_human.client.prefs.scars_list["[ending_human.client.prefs.scars_index]"] = ending_human.format_scars() + if(!ending_human.client) + return + ending_human.client.prefs.save_character() diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 97a5ec2c2b..a93aff7d2b 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -15,6 +15,8 @@ SUBSYSTEM_DEF(vote) var/vote_system = PLURALITY_VOTING var/question = null var/list/choices = list() + /// List of choice = object for statclick objects for statpanel voting + var/list/choice_statclicks = list() var/list/scores = list() var/list/choice_descs = list() // optional descriptions var/list/voted = list() @@ -47,7 +49,33 @@ SUBSYSTEM_DEF(vote) client_popup.open(0) next_pop = world.time+VOTE_COOLDOWN - +/** + * Renders a statpanel. Directly uses statpanel/stat calls since this is called from base of mob/Stat(). + */ +/datum/controller/subsystem/vote/proc/render_statpanel(mob/M) + if(!mode) // check if vote is running + return + if(!statpanel("Status")) // don't bother if they're not focused on this panel + return + var/static/list/supported = list(PLURALITY_VOTING, APPROVAL_VOTING) + stat("Vote active!", "There is currently a vote running. Question: [question]") + if(!(vote_system in supported)) + stat("", "The current vote system is not supported by statpanel rendering. Please vote manually by opening the vote popup using the action button or chat link.") + return + stat("Time Left:", "[round(end_time - world.time)] seconds") + stat(null, null) + stat("Choices:", null) + stat(null, null) + for(var/i in 1 to choice_statclicks.len) + var/choice = choice_statclicks[i] + var/ivotedforthis = FALSE + switch(vote_system) + if(APPROVAL_VOTING) + ivotedforthis = voted[usr.ckey] && (i in voted[usr.ckey]) + if(PLURALITY_VOTING) + ivotedforthis = voted[usr.ckey] == i + stat(ivotedforthis? "\[X\]" : "\[ \]", choice_statclicks[choice]) + stat(null, null) /datum/controller/subsystem/vote/proc/reset() initiator = null @@ -59,9 +87,26 @@ SUBSYSTEM_DEF(vote) voted.Cut() voting.Cut() scores.Cut() + cleanup_statclicks() display_votes = initial(display_votes) //CIT CHANGE - obfuscated votes remove_action_buttons() +/datum/controller/subsystem/vote/proc/cleanup_statclicks() + for(var/choice in choice_statclicks) + qdel(choice_statclicks[choice]) + choice_statclicks = list() + +/obj/effect/statclick/vote + name = "ERROR" + var/choice + +/obj/effect/statclick/vote/Click() + SSvote.submit_vote(choice) + +/obj/effect/statclick/vote/New(loc, choice, name) + src.choice = choice + src.name = name + /datum/controller/subsystem/vote/proc/get_result() //get the highest number of votes var/greatest_votes = 0 @@ -536,6 +581,12 @@ SUBSYSTEM_DEF(vote) vp = CONFIG_GET(number/vote_period) to_chat(world, "\n[text]\nType vote or click here to place your votes.\nYou have [DisplayTimeText(vp)] to vote.") end_time = started_time+vp + // generate statclick list + cleanup_statclicks() + for(var/i in 1 to choices.len) + var/choice = choices[i] + choice_statclicks[choice] = new /obj/effect/statclick/vote(null, i, choice) + // for(var/c in GLOB.clients) SEND_SOUND(c, sound('sound/misc/server-ready.ogg')) var/client/C = c diff --git a/code/datums/armor.dm b/code/datums/armor.dm index 85915395f8..88170541c6 100644 --- a/code/datums/armor.dm +++ b/code/datums/armor.dm @@ -1,9 +1,9 @@ -#define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]" +#define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]-[wound]" -/proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0) +/proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0) . = locate(ARMORID) if (!.) - . = new /datum/armor(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic) + . = new /datum/armor(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic, wound) /datum/armor datum_flags = DF_USE_TAG @@ -17,8 +17,9 @@ var/fire var/acid var/magic + var/wound -/datum/armor/New(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0) +/datum/armor/New(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0) src.melee = melee src.bullet = bullet src.laser = laser @@ -29,15 +30,16 @@ src.fire = fire src.acid = acid src.magic = magic + src.wound = wound tag = ARMORID -/datum/armor/proc/modifyRating(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0) - return getArmor(src.melee+melee, src.bullet+bullet, src.laser+laser, src.energy+energy, src.bomb+bomb, src.bio+bio, src.rad+rad, src.fire+fire, src.acid+acid, src.magic+magic) +/datum/armor/proc/modifyRating(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0) + return getArmor(src.melee+melee, src.bullet+bullet, src.laser+laser, src.energy+energy, src.bomb+bomb, src.bio+bio, src.rad+rad, src.fire+fire, src.acid+acid, src.magic+magic, src.wound+wound) /datum/armor/proc/modifyAllRatings(modifier = 0) - return getArmor(melee+modifier, bullet+modifier, laser+modifier, energy+modifier, bomb+modifier, bio+modifier, rad+modifier, fire+modifier, acid+modifier, magic+modifier) + return getArmor(melee+modifier, bullet+modifier, laser+modifier, energy+modifier, bomb+modifier, bio+modifier, rad+modifier, fire+modifier, acid+modifier, magic+modifier, wound+modifier) -/datum/armor/proc/setRating(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic) +/datum/armor/proc/setRating(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic, wound) return getArmor((isnull(melee) ? src.melee : melee),\ (isnull(bullet) ? src.bullet : bullet),\ (isnull(laser) ? src.laser : laser),\ @@ -47,19 +49,20 @@ (isnull(rad) ? src.rad : rad),\ (isnull(fire) ? src.fire : fire),\ (isnull(acid) ? src.acid : acid),\ - (isnull(magic) ? src.magic : magic)) + (isnull(magic) ? src.magic : magic),\ + (isnull(wound) ? src.wound : wound)) /datum/armor/proc/getRating(rating) return vars[rating] /datum/armor/proc/getList() - return list("melee" = melee, "bullet" = bullet, "laser" = laser, "energy" = energy, "bomb" = bomb, "bio" = bio, "rad" = rad, "fire" = fire, "acid" = acid, "magic" = magic) + return list("melee" = melee, "bullet" = bullet, "laser" = laser, "energy" = energy, "bomb" = bomb, "bio" = bio, "rad" = rad, "fire" = fire, "acid" = acid, "magic" = magic, "wound" = wound) /datum/armor/proc/attachArmor(datum/armor/AA) - return getArmor(melee+AA.melee, bullet+AA.bullet, laser+AA.laser, energy+AA.energy, bomb+AA.bomb, bio+AA.bio, rad+AA.rad, fire+AA.fire, acid+AA.acid, magic+AA.magic) + return getArmor(melee+AA.melee, bullet+AA.bullet, laser+AA.laser, energy+AA.energy, bomb+AA.bomb, bio+AA.bio, rad+AA.rad, fire+AA.fire, acid+AA.acid, magic+AA.magic, wound+AA.wound) /datum/armor/proc/detachArmor(datum/armor/AA) - return getArmor(melee-AA.melee, bullet-AA.bullet, laser-AA.laser, energy-AA.energy, bomb-AA.bomb, bio-AA.bio, rad-AA.rad, fire-AA.fire, acid-AA.acid, magic-AA.magic) + return getArmor(melee-AA.melee, bullet-AA.bullet, laser-AA.laser, energy-AA.energy, bomb-AA.bomb, bio-AA.bio, rad-AA.rad, fire-AA.fire, acid-AA.acid, magic-AA.magic, wound-AA.wound) /datum/armor/vv_edit_var(var_name, var_value) if (var_name == NAMEOF(src, tag)) diff --git a/code/datums/beepsky_fashion.dm b/code/datums/beepsky_fashion.dm new file mode 100644 index 0000000000..1156822c93 --- /dev/null +++ b/code/datums/beepsky_fashion.dm @@ -0,0 +1,221 @@ +//similar to dog_fashion, but for beepsky, who has far more refined fashion tastes +/datum/beepsky_fashion + var/name //not setting the name and desc makes them go to the default + var/desc + + var/icon_file = 'icons/mob/secbot_accessories.dmi' //we sell secbots and secbot accessories + var/obj_icon_state + var/obj_alpha + var/obj_color + + var/list/stun_sounds //sound that replaces the stun attack when set + var/ignore_sound = FALSE //whether to ignore sounds entirely or not + + //emotes (don't set them if you want the default value) + var/death_emote //what is said when beepsky dies + var/capture_one //what is said when cuffing someone + var/capture_two //what is said when cuffing someone, directly to the person being cuffed + var/infraction //the level of threat detected + var/taunt // beepsky pointing at a criminal + var/attack_one //text when attacking criminal + var/attack_two //text when attacking criminal, but directly to the criminal + var/patrol_emote //engaging patrol text + var/patrol_fail_emote //failing to engage patrol text + var/list/arrest_texts //first is for not-cuffing, second is for cuffing + var/arrest_emote //text stating that you're cuffing some criminal C with a threat of level X in location Y + + //for reference, the following words are replaced when processed before speech: + //LOCATION = the location passed, if any (this is only used by arrest_emote) + //CRIMINAL = the name of the criminal (this is used by everything but patrol_emote and infraction) + //BOT = the name of the bot (this can be used on any of the emotes) + //THREAT_LEVEL = the level of the threat detected (can be used on arrest_emote and infraction) + +/datum/beepsky_fashion/proc/get_overlay(var/dir) + if(icon_file && obj_icon_state) + var/image/beepsky_overlay = image(icon_file, obj_icon_state, dir = dir) + beepsky_overlay.alpha = obj_alpha + beepsky_overlay.color = obj_color + return beepsky_overlay + +/datum/beepsky_fashion/proc/stun_attack(mob/living/carbon/C) //fired when beepsky does a stun attack with the fashion worn, for sounds/overlays/etc + return + +//actual fashions from here on out +/datum/beepsky_fashion/wizard + obj_icon_state = "wizard" + name = "Archmage Beepsky" + desc = "A secbot stolen from the wizard federation." + death_emote = "BOT casts EI NATH on themselves!" + capture_one = "BOT is casting cable ties on CRIMINAL!" + capture_two = "BOT is casting cable ties on you!" + infraction = "Magical disturbance of magnitude THREAT_LEVEL detected!" + taunt = "BOT points his staff towards CRIMINAL!" + attack_one = "BOT casts magic missile on CRIMINAL!" + attack_two = "BOT casts magic missile on you!" + patrol_emote = "Beginning search for magical disturbances." + patrol_fail_emote = "Failure to find magical disturbances. Recallibrating." + arrest_emote = "ARREST_TYPE level THREAT_LEVEL magical practitioner CRIMINAL in LOCATION." + stun_sounds = list('sound/magic/lightningbolt.ogg', + 'sound/magic/fireball.ogg', + 'sound/weapons/zapbang.ogg', + 'sound/magic/knock.ogg', + 'sound/magic/fleshtostone.ogg', + 'sound/effects/magic.ogg', + 'sound/magic/disintegrate.ogg') + +/datum/beepsky_fashion/cowboy + obj_icon_state = "cowboy" + name = "Sheriff Beepsky" + desc = "The sheriff of this here station." + capture_one = "BOT is tying CRIMINAL up!" + capture_two = "BOT is tying you up!" + infraction = "Outlaws with a bounty of THREAT_LEVEL000 space dollars detected!" + taunt = "BOT aims his revolver towards CRIMINAL!" + attack_one = "BOT unloads his revolver onto CRIMINAL!" + attack_two = "BOT unloads his revolver onto you!" + patrol_emote = "Engaging bounty hunting protocols." + patrol_fail_emote = "Unable to find any bounties due to error. Rebooting." + arrest_emote = "ARREST_TYPE outlaw CRIMINAL with a bounty of THREAT_LEVEL000 in LOCATION." + stun_sounds = list('sound/weapons/Gunshot.ogg', + 'sound/weapons/Gunshot2.ogg', + 'sound/weapons/Gunshot3.ogg', + 'sound/weapons/Gunshot4.ogg') + +/datum/beepsky_fashion/chef + obj_icon_state = "chef" + name = "Chef Beepsky" + desc = "Cooking up the finest foods the station has ever seen." + death_emote = "Mamma-mia!" + infraction = "Grade THREAT_LEVEL prosciutto detected!" + taunt = "BOT glares at CRIMINAL." + attack_one = "BOT CQCs CRIMINAL!" + attack_two = "BOT CQCs you!" + patrol_emote = "Beginning search for the bad prosciutto." + patrol_fail_emote = "All prosciutto is stale. Rebooting." + arrest_texts = list("Frying", "Grilling") //any good secoff knows the difference + arrest_emote = "ARREST_TYPE grade THREAT_LEVEL prosciutto CRIMINAL in LOCATION." + stun_sounds = list('sound/weapons/cqchit1.ogg', + 'sound/weapons/cqchit2.ogg') + +/datum/beepsky_fashion/cat + obj_icon_state = "cat" + name = "OwOfficer Bweepskwee" + desc = "A beepsky unit with cat ears. Catgirl science has gone too far." + death_emote = "Nya!" + capture_one = "BOT is tying CRIMINAL up!!" + capture_two = "BOT is tying you up!" + infraction = "Wevel THREAT_LEVEL infwactwion awert!!!" + taunt = "BOT points at CRIMINAL and nyas!" + attack_one = "BOT shoves CRIMINAL onto a table!" + attack_two = "BOT shoves you onto a table!" + patrol_emote = "Enwgagwing patwol mwodies.." + patrol_fail_emote = "Unawbwle two stwawt patwollies. Nya." + arrest_texts = list("Dwetwaining", "Awwesting") + arrest_emote = "ARREST_TYPE wevel THREAT_LEVEL scwumbwag CRIMINAL in LOCATION. Nya." + ignore_sound = TRUE //we instead make the stunned person fire the nya emote + +/datum/beepsky_fashion/cat/stun_attack(var/mob/living/carbon/C) //makes a fake table under you on hit, makes cat people nya when hit + if(iscatperson(C)) + C.emote("nya") + var/turf/target_turf = get_turf(C) + if(target_turf) //slams you on a fake table + playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1) + var/obj/effect/overlay_holder = new(target_turf) + overlay_holder.name = "Catboy Table" + overlay_holder.desc = "Where bad catboys go." + var/image/table_overlay = image('icons/obj/smooth_structures/table.dmi', "table") + overlay_holder.add_overlay(table_overlay) + QDEL_IN(overlay_holder, 10) + +/datum/beepsky_fashion/cake //nothing else. it's just beepsky. with a cake on his head. + obj_icon_state = "cake" + name = "Cakesky" + desc = "It's a secbot, wearing a cake on his head!" + +/datum/beepsky_fashion/captain + obj_icon_state = "captain" + name = "Captainsky" + desc = "The real captain of this station." + capture_one = "BOT is lecturing CRIMINAL on why he is the captain!" + capture_two = "BOT is lecturing you on why he is the captain!" + infraction = "Level THREAT_LEVEL greytider detected." + attack_one = "BOT beats CRIMINAL with the chain of command!" + attack_two = "BOT beats you with the chain of command!" + patrol_emote = "Uselessness protocols engaged." + patrol_fail_emote = "Unit has been found as useless. Rebooting." + arrest_texts = list("Demoting", "Firing") + arrest_emote = "ARREST_TYPE level THREAT_LEVEL lesser crewmember CRIMINAL in LOCATION." + stun_sounds = list('sound/weapons/chainhit.ogg') + +/datum/beepsky_fashion/king + obj_icon_state = "king" + name = "King Beepsky" + desc = "He who has ascended to bare the right of king, sits atop the throne." + capture_one = "BOT is calling the guards onto CRIMINAL!" + capture_two = "BOT is calling the guards onto you!" + infraction = "Treason of level THREAT_LEVEL detected!" + attack_one = "BOT strikes CRIMINAL with his kingly authority!" + attack_two = "BOT strikes you with his kingly authority!" + patrol_emote = "Searching for peasants to beat up." + patrol_fail_emote = "Peasants are using dark magic. Recallibrating." + arrest_texts = list("Knighting", "Executing") + arrest_emote = "ARREST_TYPE level THREAT_LEVEL peasant CRIMINAL in LOCATION." + stun_sounds = list('sound/weapons/punch1.ogg', + 'sound/weapons/punch2.ogg', + 'sound/weapons/punch3.ogg', + 'sound/weapons/punch4.ogg') + +/datum/beepsky_fashion/pirate + obj_icon_state = "pirate" + name = "Beepsbeard the Pirate" + desc = "Sailor of the seven seas, all sea-faring bots fear the one known as Beepsbeard." + capture_one = "BOT is making CRIMINAL walk the plank!" + capture_two = "BOT is making you walk the plank!" + infraction = "Enemy vessel spotted with threat level THREAT_LEVEL!" + attack_one = "BOT strikes CRIMINAL with his cutlass!" + attack_two = "BOT strikes you with his cutlass!" + patrol_emote = "Searching for enemy vessels to board." + patrol_fail_emote = "No way to engage enemy vessels. Rebooting." + arrest_texts = list("Boarding", "Sinking") + arrest_emote = "ARREST_TYPE level THREAT_LEVEL vessel CRIMINAL in LOCATION." + stun_sounds = list('sound/weapons/bladeslice.ogg') + +/datum/beepsky_fashion/engineer + obj_icon_state = "engineer" + name = "Chief Engineer Beepsky" + desc = "He fixes criminals with a wrench to the face." + capture_one = "BOT is tying CRIMINAL up!" + capture_two = "BOT is tying you up!" + infraction = "Structural integrity issue spotted with threat level THREAT_LEVEL" + attack_one = "BOT strikes CRIMINAL with his wrench!" + attack_two = "BOT strikes you with his wrench!" + arrest_texts = list("Fixing", "Repairing") + arrest_emote = "ARREST_TYPE level THREAT_LEVEL structural issue in LOCATION" + stun_sounds = list('sound/weapons/genhit.ogg') + +/datum/beepsky_fashion/tophat + obj_icon_state = "tophat" + name = "Fancy Beepsky" + desc = "It's a secbot, wearing a top hat! How fancy." + +/datum/beepsky_fashion/fedora + obj_icon_state = "fedora" + name = "Fedorasky" + desc = "It's a secbot, wearing a fedora!" + +/datum/beepsky_fashion/sombrero + obj_icon_state = "sombrero" + name = "Sombrerosky" + desc = "A secbot wearing a sombrero. Truly, a hombre to all." + +/datum/beepsky_fashion/santa + obj_icon_state = "santa" + name = "Saint Beepsky" + desc = "Have you been a level 7 infraction this holiday season?" + capture_one = "BOT is tying CRIMINAL up with fairy lights!" + capture_two = "BOT is tying you up with fairy lights!" + infraction = "Level THREAT_LEVEL threat to holiday cheer spotted!" + attack_one = "BOT crushes CRIMINAL with their holiday spirit!" + attack_two = "BOT crushes you with their holiday spirit!" + arrest_emote = "ARREST_TYPE level THREAT_LEVEL threat to holiday cheer in LOCATION" + diff --git a/code/datums/brain_damage/magic.dm b/code/datums/brain_damage/magic.dm index ff04ceead9..a00b341b82 100644 --- a/code/datums/brain_damage/magic.dm +++ b/code/datums/brain_damage/magic.dm @@ -94,7 +94,7 @@ if(get_dist(owner, stalker) <= 1) playsound(owner, 'sound/magic/demon_attack1.ogg', 50) owner.visible_message("[owner] is torn apart by invisible claws!", "Ghostly claws tear your body apart!") - owner.take_bodypart_damage(rand(20, 45)) + owner.take_bodypart_damage(rand(20, 45), wound_bonus=CANT_WOUND) else if(prob(50)) stalker.forceMove(get_step_towards(stalker, owner)) if(get_dist(owner, stalker) <= 8) diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm index bc1f566f23..13cf2add97 100644 --- a/code/datums/brain_damage/special.dm +++ b/code/datums/brain_damage/special.dm @@ -104,7 +104,7 @@ QDEL_IN(src, 300) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/hallucination/simple/bluespace_stream/attack_hand(mob/user) +/obj/effect/hallucination/simple/bluespace_stream/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user != seer || !linked_to) return var/slip_in_message = pick("slides sideways in an odd way, and disappears", "jumps into an unseen dimension",\ diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm index 441a161428..b5b8849155 100644 --- a/code/datums/components/butchering.dm +++ b/code/datums/components/butchering.dm @@ -2,7 +2,7 @@ var/speed = 80 //time in deciseconds taken to butcher something var/effectiveness = 100 //percentage effectiveness; numbers above 100 yield extra drops var/bonus_modifier = 0 //percentage increase to bonus item chance - var/butcher_sound = 'sound/weapons/slice.ogg' //sound played when butchering + var/butcher_sound = 'sound/effects/butcher.ogg' //sound played when butchering var/butchering_enabled = TRUE var/can_be_blunt = FALSE @@ -64,8 +64,11 @@ H.visible_message("[user] slits [H]'s throat!", \ "[user] slits your throat...") log_combat(user, H, "finishes slicing the throat of") - H.apply_damage(source.force, BRUTE, BODY_ZONE_HEAD) - H.bleed_rate = clamp(H.bleed_rate + 20, 0, 30) + 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 + screaming_through_a_slit_throat.apply_wound(slit_throat) H.apply_status_effect(/datum/status_effect/neck_slice) /datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat) diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm index 863d55ccab..d138cf1971 100644 --- a/code/datums/components/caltrop.dm +++ b/code/datums/components/caltrop.dm @@ -48,7 +48,7 @@ var/damage = rand(min_damage, max_damage) if(HAS_TRAIT(H, TRAIT_LIGHT_STEP)) damage *= 0.75 - H.apply_damage(damage, BRUTE, picked_def_zone) + H.apply_damage(damage, BRUTE, picked_def_zone, wound_bonus = CANT_WOUND) if(cooldown < world.time - 10) //cooldown to avoid message spam. if(!H.incapacitated(ignore_restraints = TRUE)) diff --git a/code/datums/components/edible.dm b/code/datums/components/edible.dm index 47e60a1ee1..dc2e490fe4 100644 --- a/code/datums/components/edible.dm +++ b/code/datums/components/edible.dm @@ -51,7 +51,8 @@ Behavior that's still missing from this component that original food items had t var/atom/owner = parent - owner.create_reagents(volume, INJECTABLE) + if(!owner.reagents) //we don't want to override what's in the item if it possibly contains reagents already + owner.create_reagents(volume, INJECTABLE) if(initial_reagents) for(var/rid in initial_reagents) diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index 137a1bb864..ce124646f4 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -147,7 +147,7 @@ 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) + limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus=-30, sharpness = TRUE) 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) @@ -163,7 +163,7 @@ if(harmful && prob(chance)) var/damage = weapon.w_class * jostle_pain_mult - limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage) + 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!") @@ -173,7 +173,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) + limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND) victim.visible_message("[weapon] falls out of [victim.name]'s [limb.name]!", ignored_mobs=victim) to_chat(victim, "[weapon] falls out of your [limb.name]!") else @@ -199,7 +199,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) //It hurts to rip it out, get surgery you dingus. + 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. 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 @@ -276,7 +276,7 @@ damage *= 0.7 if(harmful && prob(chance)) - limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage) + 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)) diff --git a/code/datums/components/fried.dm b/code/datums/components/fried.dm new file mode 100644 index 0000000000..4e21962778 --- /dev/null +++ b/code/datums/components/fried.dm @@ -0,0 +1,107 @@ +/*! + This component essentially encapsulates frying and utilizes the edible component + This means fried items can work like regular ones, and generally the code is far less messy +*/ +/datum/component/fried + var/fry_power //how powerfully was this item fried + var/atom/owner //the atom it is owned by + var/stored_name //name of the owner when the component was first added + var/frying_examine_text = "the coders messed frying code up, report this!" + +/datum/component/fried/Initialize(frying_power) + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) + RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/restore) //basically, unfry people who are being cleaned (badmemes fried someone) + + fry_power = frying_power + owner = parent + stored_name = owner.name + + setup_fried_item() + +//some stuff to do with the contents of fried junk +GLOBAL_VAR_INIT(frying_hardmode, TRUE) +GLOBAL_VAR_INIT(frying_bad_chem_add_volume, TRUE) +GLOBAL_LIST_INIT(frying_bad_chems, list( +/datum/reagent/toxin/bad_food = 1, +/datum/reagent/toxin = 1, +/datum/reagent/lithium = 1, +/datum/reagent/mercury = 1, +)) + +/datum/component/fried/proc/examine(datum/source, mob/user, list/examine_list) + examine_list += "[parent] has been [frying_examine_text]" + +/datum/component/fried/proc/setup_fried_item() //sets the name, colour and examine text and edibility up + //first we do some checks depending on the type of item being fried + var/list/fried_tastes = list("crispy") + var/fried_foodtypes = FRIED + var/fried_junk = FALSE + + if(!isfood(owner) && GLOB.frying_hardmode && GLOB.frying_bad_chems.len && !owner.reagents) //you fried some junk, it's not gonna taste great + fried_junk = TRUE + fried_foodtypes |= TOXIC // junk tastes toxic too + else + if(isfood(owner)) + var/obj/item/reagent_containers/food/snacks/food_item = owner + fried_tastes += food_item.tastes + fried_foodtypes |= food_item.foodtype + + var/fried_eat_time = 0 + if(isturf(owner)) + fried_eat_time = 30 //we want turfs to be eaten slowly + + var/colour_priority = FIXED_COLOUR_PRIORITY + if(ismob(owner)) + colour_priority = WASHABLE_COLOUR_PRIORITY //badmins fried someone and we want to let them wash the fry colour off + //lets heavily hint at how to undo their frying + to_chat(owner, "You've been coated in hot cooking oil! You should probably go wash it off at the showers.") + else + owner.AddComponent(/datum/component/edible, foodtypes = fried_tastes, tastes = fried_tastes, eat_time = fried_eat_time) //we don't want mobs to get the edible component + + switch(fry_power) + if(0 to 15) + owner.name = "lightly fried [owner.name]" + owner.add_atom_colour(rgb(166,103,54), colour_priority) + frying_examine_text = "lightly fried" + if(16 to 49) + owner.name = "fried [owner.name]" + owner.add_atom_colour(rgb(103,63,24), colour_priority) + frying_examine_text = "moderately fried" + if(50 to 59) + owner.name = "deep fried [owner.name]" + owner.add_atom_colour(rgb(63,23,4), colour_priority) + frying_examine_text = "deeply fried" + else + owner.name = "the physical manifestation of fried foods" + owner.add_atom_colour(rgb(33,19,9), colour_priority) + frying_examine_text = "incomprehensibly fried to a crisp" + + //adding the edible component gives it reagents meaning we can now add the bad frying reagents if it's junk + if(fried_junk && owner.reagents) //check again just incase + var/R = rand(1, GLOB.frying_bad_chems.len) + var/bad_chem = GLOB.frying_bad_chems[R] + var/bad_chem_amount = max(4,GLOB.frying_bad_chems[bad_chem] * (fry_power/12.5)) //4u of bad chem reached when deeply fried + owner.reagents.add_reagent(bad_chem, bad_chem_amount) + +/datum/component/fried/proc/restore_name() //restore somethings name + //we do string manipulation and not restoring their name to real_name because some things hide your real_name and we want to maintain that + if(copytext(owner.name,1,14) == "lightly fried ") + owner.name = copytext(owner.name,15) + else + if(copytext(owner.name,1,6) == "fried ") + owner.name = copytext(owner.name,7) + else + if(copytext(owner.name,1,11) == "deep fried ") + owner.name = copytext(owner.name, 12) + else + if(owner.name == "the physical manifestation of fried foods") //if the name is still this, their name hasn't changed, so we can safely restore their stored name + owner.name = stored_name + +/datum/component/fried/proc/restore() //restore a fried mob to being not-fried + if(ismob(owner)) + //restore the name, the colour should wash off itself, and then remove the component + restore_name() + RemoveComponent() diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index bd12ecc092..a5f9271f4b 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -62,6 +62,7 @@ ///Store the thrownthing datum for later use /datum/component/tackler/proc/registerTackle(mob/living/carbon/user, datum/thrownthing/TT) tackle = TT + tackle.thrower = user ///See if we can tackle or not. If we can, leap! /datum/component/tackler/proc/checkTackle(mob/living/carbon/user, atom/A, params) diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index 46ba5dc93b..a269e24974 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -301,7 +301,7 @@ GLOBAL_LIST_EMPTY(uplinks) else if(istype(parent,/obj/item/radio)) unlock_note = "Radio Frequency: [format_frequency(unlock_code)] ([P.name])." else if(istype(parent,/obj/item/pen)) - unlock_note = "Uplink Degrees: [english_list(unlock_code)] ([P.name])." + unlock_note = "Uplink Degrees: [unlock_code] ([P.name])." /datum/component/uplink/proc/generate_code() if(istype(parent,/obj/item/pda)) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 94940b3855..cf942f077f 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -78,6 +78,8 @@ /datum/datacore/proc/manifest() for(var/mob/dead/new_player/N in GLOB.player_list) + if(!N?.client) + continue if(N.new_character) log_manifest(N.ckey,N.new_character.mind,N.new_character) if(ishuman(N.new_character)) diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm index 774d97202e..0fad819e8e 100644 --- a/code/datums/diseases/advance/symptoms/flesh_eating.dm +++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm @@ -64,7 +64,8 @@ Bonus if(bleed) if(ishuman(M)) var/mob/living/carbon/human/H = M - H.bleed_rate += 5 * power + var/obj/item/bodypart/random_part = pick(H.bodyparts) + random_part.generic_bleedstacks += 5 * power return 1 /* diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 23b6704080..8d80bc3f36 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -131,9 +131,9 @@ L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color) L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len) L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color) - L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"]) - L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"]) - L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"]) + L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"], 6) + L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"], 6) + L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"], 6) if(!GLOB.mam_tails_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) L[DNA_MUTANTTAIL_BLOCK] = construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) @@ -239,11 +239,11 @@ if(DNA_HAIR_STYLE_BLOCK) setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len)) if(DNA_COLOR_ONE_BLOCK) - sanitize_hexcolor(features["mcolor"]) + sanitize_hexcolor(features["mcolor"], 6) if(DNA_COLOR_TWO_BLOCK) - sanitize_hexcolor(features["mcolor2"]) + sanitize_hexcolor(features["mcolor2"], 6) if(DNA_COLOR_THREE_BLOCK) - sanitize_hexcolor(features["mcolor3"]) + sanitize_hexcolor(features["mcolor3"], 6) if(DNA_MUTANTTAIL_BLOCK) construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) if(DNA_MUTANTEAR_BLOCK) diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm index 744f57c391..2e80feac67 100644 --- a/code/datums/dog_fashion.dm +++ b/code/datums/dog_fashion.dm @@ -38,7 +38,6 @@ corgI.color = obj_color return corgI - /datum/dog_fashion/head icon_file = 'icons/mob/corgi_head.dmi' @@ -53,7 +52,6 @@ name = "Sous chef REAL_NAME" desc = "Your food will be taste-tested. All of it." - /datum/dog_fashion/head/captain name = "Captain REAL_NAME" desc = "Probably better than the last captain." diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index c2fe24a20d..3691b2fccc 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -223,8 +223,8 @@ /obj/item/clothing/gloves/krav_maga/combatglovesplus name = "combat gloves plus" desc = "These tactical gloves are fireproof and shock resistant, and using nanochip technology it teaches you the powers of krav maga." - icon_state = "combat" - item_state = "blackgloves" + icon_state = "fightglovesblack" + item_state = "fightglovesblack" siemens_coefficient = 0 permeability_coefficient = 0.05 strip_delay = 80 diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index a2a9e376e1..7d884344f1 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -44,7 +44,7 @@ else playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, TRUE, -1) log_combat(A, D, "strong punched (Sleeping Carp)")//so as to not double up on logging - D.apply_damage((damage + 15) + crit_damage, BRUTE, affecting) + D.apply_damage((damage + 15) + crit_damage, BRUTE, affecting, wound_bonus = CANT_WOUND) return TRUE ///Crashing Wave Kick: Harm Disarm combo, throws people seven tiles backwards @@ -56,7 +56,7 @@ playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, TRUE, -1) var/atom/throw_target = get_edge_target_turf(D, A.dir) D.throw_at(throw_target, 7, 14, A) - D.apply_damage(damage, BRUTE, BODY_ZONE_CHEST) + D.apply_damage(damage, BRUTE, BODY_ZONE_CHEST, wound_bonus = CANT_WOUND, wound_bonus = CANT_WOUND) log_combat(A, D, "launchkicked (Sleeping Carp)") return TRUE @@ -66,14 +66,14 @@ A.do_attack_animation(D, ATTACK_EFFECT_KICK) playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, TRUE, -1) if((D.mobility_flags & MOBILITY_STAND)) - D.apply_damage(damage, BRUTE, BODY_ZONE_HEAD) + D.apply_damage(damage, BRUTE, BODY_ZONE_HEAD, wound_bonus = CANT_WOUND) D.DefaultCombatKnockdown(50, override_hardstun = 0.01, override_stamdmg = 0) - D.apply_damage(damage + 35, STAMINA, BODY_ZONE_HEAD) //A cit specific change form the tg port to really punish anyone who tries to stand up + D.apply_damage(damage + 35, STAMINA, BODY_ZONE_HEAD, wound_bonus = CANT_WOUND) //A cit specific change form the tg port to really punish anyone who tries to stand up D.visible_message("[A] kicks [D] in the head, sending them face first into the floor!", \ "You are kicked in the head by [A], sending you crashing to the floor!", "You hear a sickening sound of flesh hitting flesh!", COMBAT_MESSAGE_RANGE, A) else - D.apply_damage(damage*0.5, BRUTE, BODY_ZONE_HEAD) - D.apply_damage(damage + 35, STAMINA, BODY_ZONE_HEAD) + D.apply_damage(damage*0.5, BRUTE, BODY_ZONE_HEAD, wound_bonus = CANT_WOUND) + D.apply_damage(damage + 35, STAMINA, BODY_ZONE_HEAD, wound_bonus = CANT_WOUND) D.drop_all_held_items() D.visible_message("[A] kicks [D] in the head!", \ "You are kicked in the head by [A]!", "You hear a sickening sound of flesh hitting flesh!", COMBAT_MESSAGE_RANGE, A) @@ -99,7 +99,7 @@ D.visible_message("[A] [atk_verb]s [D]!", \ "[A] [atk_verb]s you!", null, null, A) to_chat(A, "You [atk_verb] [D]!") - D.apply_damage(damage, BRUTE, affecting) + D.apply_damage(damage, BRUTE, affecting, wound_bonus = CANT_WOUND) playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, TRUE, -1) if(CHECK_MOBILITY(D, MOBILITY_STAND) && damage >= stunthreshold) to_chat(D, "You stumble and fall!") diff --git a/code/datums/martial/wrestling.dm b/code/datums/martial/wrestling.dm index 18fd8e7b18..8dc1afba81 100644 --- a/code/datums/martial/wrestling.dm +++ b/code/datums/martial/wrestling.dm @@ -215,11 +215,17 @@ /datum/martial_art/wrestling/proc/FlipAnimation(mob/living/carbon/human/D) set waitfor = FALSE + var/transform_before + var/laying_before if (D) + transform_before = D.transform + laying_before = D.lying animate(D, transform = matrix(180, MATRIX_ROTATE), time = 1, loop = 0) sleep(15) if (D) - animate(D, transform = null, time = 1, loop = 0) + if(transform_before && laying_before == D.lying) //animate calls sleep so this should be fine and stop a bug with transforms + D.transform = transform_before + animate(D, transform = null, time = 1, loop = 0) /datum/martial_art/wrestling/proc/slam(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!D) @@ -415,11 +421,17 @@ to_chat(A, "You can't drop onto [D] from here!") return FALSE + var/transform_before + var/laying_before if(A) + transform_before = A.transform + laying_before = A.lying animate(A, transform = matrix(90, MATRIX_ROTATE), time = 1, loop = 0) sleep(10) if(A) - animate(A, transform = null, time = 1, loop = 0) + if(transform_before && laying_before == A.lying) //if they suddenly dropped to the floor between this period, don't revert their animation + animate(A, transform = null, time = 1, loop = 0) + A.transform = transform_before A.forceMove(D.loc) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index d02249fb38..cb99fdc5a3 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -66,6 +66,9 @@ /// Our skill holder. var/datum/skill_holder/skill_holder + ///What character we spawned in as- either at roundstart or latejoin, so we know for persistent scars if we ended as the same person or not + var/mob/original_character + /datum/mind/New(var/key) skill_holder = new(src) src.key = key diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 73d59aa0de..787d6375a7 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -77,10 +77,14 @@ description = "Pull it out!\n" mood_change = -7 -/datum/mood_event/table - description = "Someone threw me on a table!\n" - mood_change = -2 - timeout = 2 MINUTES +/datum/mood_event/table_limbsmash + description = "That fucking table, man that hurts...\n" + mood_change = -3 + timeout = 3 MINUTES + +/datum/mood_event/table_limbsmash/add_effects(obj/item/bodypart/banged_limb) + if(banged_limb) + description = "My fucking [banged_limb.name], man that hurts...\n" /datum/mood_event/table/add_effects() if(ishuman(owner)) diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm index 36fbe449b8..fb5f6ed5f6 100644 --- a/code/datums/mutations/_mutations.dm +++ b/code/datums/mutations/_mutations.dm @@ -91,7 +91,7 @@ /datum/mutation/human/proc/get_visual_indicator() return -/datum/mutation/human/proc/on_attack_hand(atom/target, proximity) +/datum/mutation/human/proc/on_attack_hand(atom/target, proximity, act_intent, unarmed_attack_flags) return /datum/mutation/human/proc/on_ranged_attack(atom/target, mouseparams) diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm index 4f8cd6b25e..2df2b20cbc 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -19,8 +19,8 @@ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "hulk", /datum/mood_event/hulk) RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) -/datum/mutation/human/hulk/on_attack_hand(atom/target, proximity) - if(proximity) //no telekinetic hulk attack +/datum/mutation/human/hulk/on_attack_hand(atom/target, proximity, act_intent, unarmed_attack_flags) + if(proximity && (act_intent == INTENT_HARM)) //no telekinetic hulk attack return target.attack_hulk(owner) /datum/mutation/human/hulk/on_life() diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index e080e597a3..179ed765c5 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -441,6 +441,10 @@ owner.adjustBruteLoss(-10, FALSE) owner.adjustFireLoss(-5, FALSE) owner.adjustOxyLoss(-10) + if(!iscarbon(owner)) + return + var/mob/living/carbon/C = owner + QDEL_LIST(C.all_scars) /obj/screen/alert/status_effect/fleshmend name = "Fleshmend" diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index faed65e9c4..561329f02a 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -430,10 +430,19 @@ /datum/status_effect/neck_slice/tick() var/mob/living/carbon/human/H = owner - if(H.stat == DEAD || H.bleed_rate <= 8) + var/obj/item/bodypart/throat = H.get_bodypart(BODY_ZONE_HEAD) + if(H.stat == DEAD || !throat) H.remove_status_effect(/datum/status_effect/neck_slice) if(prob(10)) H.emote(pick("gasp", "gag", "choke")) + 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) + still_bleeding = TRUE + break + if(!still_bleeding) + H.remove_status_effect(/datum/status_effect/neck_slice) /mob/living/proc/apply_necropolis_curse(set_curse, duration = 10 MINUTES) var/datum/status_effect/necropolis_curse/C = has_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE) diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm index 12c223f500..dd5fef61d7 100644 --- a/code/datums/status_effects/status_effect.dm +++ b/code/datums/status_effects/status_effect.dm @@ -279,3 +279,7 @@ /datum/status_effect/grouped/before_remove(source) sources -= source return !length(sources) + +//do_after modifier! +/datum/status_effect/proc/interact_speed_modifier() + return 1 diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm new file mode 100644 index 0000000000..2c0c030425 --- /dev/null +++ b/code/datums/status_effects/wound_effects.dm @@ -0,0 +1,188 @@ + +// The shattered remnants of your broken limbs fill you with determination! +/obj/screen/alert/status_effect/determined + name = "Determined" + desc = "The serious wounds you've sustained have put your body into fight-or-flight mode! Now's the time to look for an exit!" + icon_state = "regenerative_core" + +/datum/status_effect/determined + id = "determined" + alert_type = /obj/screen/alert/status_effect/determined + +/datum/status_effect/determined/on_apply() + . = ..() + owner.visible_message("[owner] grits [owner.p_their()] teeth in pain!", "Your senses sharpen as your body tenses up from the wounds you've sustained!", vision_distance=COMBAT_MESSAGE_RANGE) + +/datum/status_effect/determined/on_remove() + owner.visible_message("[owner]'s body slackens noticeably!", "Your adrenaline rush dies off, and the pain from your wounds come aching back in...", vision_distance=COMBAT_MESSAGE_RANGE) + return ..() + +/datum/status_effect/limp + id = "limp" + status_type = STATUS_EFFECT_REPLACE + tick_interval = 10 + alert_type = /obj/screen/alert/status_effect/limp + var/msg_stage = 0//so you dont get the most intense messages immediately + /// The left leg of the limping person + var/obj/item/bodypart/l_leg/left + /// The right leg of the limping person + var/obj/item/bodypart/r_leg/right + /// Which leg we're limping with next + var/obj/item/bodypart/next_leg + /// How many deciseconds we limp for on the left leg + var/slowdown_left = 0 + /// How many deciseconds we limp for on the right leg + var/slowdown_right = 0 + +/datum/status_effect/limp/on_apply() + if(!iscarbon(owner)) + return FALSE + var/mob/living/carbon/C = owner + left = C.get_bodypart(BODY_ZONE_L_LEG) + right = C.get_bodypart(BODY_ZONE_R_LEG) + update_limp() + RegisterSignal(C, COMSIG_MOVABLE_MOVED, .proc/check_step) + RegisterSignal(C, list(COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_LOSE_WOUND, COMSIG_CARBON_ATTACH_LIMB, COMSIG_CARBON_REMOVE_LIMB), .proc/update_limp) + return ..() + +/datum/status_effect/limp/on_remove() + UnregisterSignal(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_LOSE_WOUND, COMSIG_CARBON_ATTACH_LIMB, COMSIG_CARBON_REMOVE_LIMB)) + return ..() + +/obj/screen/alert/status_effect/limp + name = "Limping" + desc = "One or more of your legs has been wounded, slowing down steps with that leg! Get it fixed, or at least splinted!" + +/datum/status_effect/limp/proc/check_step(mob/whocares, OldLoc, Dir, forced) + if(!owner.client || !(owner.mobility_flags & MOBILITY_STAND) || !owner.has_gravity() || (owner.movement_type & FLYING) || forced) + return + var/determined_mod = 1 + if(owner.has_status_effect(STATUS_EFFECT_DETERMINED)) + determined_mod = 0.25 + if(next_leg == left) + owner.client.move_delay += slowdown_left * determined_mod + next_leg = right + else + owner.client.move_delay += slowdown_right * determined_mod + next_leg = left + +/datum/status_effect/limp/proc/update_limp() + var/mob/living/carbon/C = owner + left = C.get_bodypart(BODY_ZONE_L_LEG) + right = C.get_bodypart(BODY_ZONE_R_LEG) + + if(!left && !right) + C.remove_status_effect(src) + return + + slowdown_left = 0 + slowdown_right = 0 + + if(left) + for(var/thing in left.wounds) + var/datum/wound/W = thing + slowdown_left += W.limp_slowdown + + if(right) + for(var/thing in right.wounds) + var/datum/wound/W = thing + slowdown_right += W.limp_slowdown + + // this handles losing your leg with the limp and the other one being in good shape as well + if(!slowdown_left && !slowdown_right) + C.remove_status_effect(src) + return + + +///////////////////////// +//////// WOUNDS ///////// +///////////////////////// + +// wound alert +/obj/screen/alert/status_effect/wound + name = "Wounded" + desc = "Your body has sustained serious damage, click here to inspect yourself." + +/obj/screen/alert/status_effect/wound/Click() + var/mob/living/carbon/C = usr + C.check_self_for_injuries() + +// wound status effect base +/datum/status_effect/wound + id = "wound" + status_type = STATUS_EFFECT_MULTIPLE + var/obj/item/bodypart/linked_limb + var/datum/wound/linked_wound + alert_type = NONE + +/datum/status_effect/wound/on_creation(mob/living/new_owner, incoming_wound) + . = ..() + var/datum/wound/W = incoming_wound + linked_wound = W + linked_limb = linked_wound.limb + +/datum/status_effect/wound/on_remove() + linked_wound = null + linked_limb = null + UnregisterSignal(owner, COMSIG_CARBON_LOSE_WOUND) + return ..() + +/datum/status_effect/wound/on_apply() + if(!iscarbon(owner)) + return FALSE + RegisterSignal(owner, COMSIG_CARBON_LOSE_WOUND, .proc/check_remove) + return ..() + +/// check if the wound getting removed is the wound we're tied to +/datum/status_effect/wound/proc/check_remove(mob/living/L, datum/wound/W) + if(W == linked_wound) + qdel(src) + + +// bones +/datum/status_effect/wound/bone + +/datum/status_effect/wound/bone/interact_speed_modifier() + var/mob/living/carbon/C = owner + + if(C.get_active_hand() == linked_limb) + to_chat(C, "The [lowertext(linked_wound)] in your [linked_limb.name] slows your progress!") + return linked_wound.interaction_efficiency_penalty + + return 1 + +/datum/status_effect/wound/bone/nextmove_modifier() + var/mob/living/carbon/C = owner + + if(C.get_active_hand() == linked_limb) + return linked_wound.interaction_efficiency_penalty + + return 1 + +/datum/status_effect/wound/bone/moderate + id = "disjoint" +/datum/status_effect/wound/bone/severe + id = "hairline" + +/datum/status_effect/wound/bone/critical + id = "compound" + +// cuts +/datum/status_effect/wound/cut/moderate + id = "abrasion" + +/datum/status_effect/wound/cut/severe + id = "laceration" + +/datum/status_effect/wound/cut/critical + id = "avulsion" + +// burns +/datum/status_effect/wound/burn/moderate + id = "seconddeg" + +/datum/status_effect/wound/burn/severe + id = "thirddeg" + +/datum/status_effect/wound/burn/critical + id = "fourthdeg" diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index 40b71eec0a..95e02c5a94 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -452,3 +452,21 @@ GLOBAL_LIST_EMPTY(family_heirlooms) mob_trait = TRAIT_COLDBLOODED gain_text = "You feel cold-blooded." lose_text = "You feel more warm-blooded." + +/datum/quirk/monophobia + name = "Monophobia" + desc = "You will become increasingly stressed when not in company of others, triggering panic reactions ranging from sickness to heart attacks." + value = -3 // Might change it to 4. + gain_text = "You feel really lonely..." + lose_text = "You feel like you could be safe on your own." + medical_record_text = "Patient feels sick and distressed when not around other people, leading to potentially lethal levels of stress." + +/datum/quirk/monophobia/post_add() + . = ..() + var/mob/living/carbon/human/H = quirk_holder + H.gain_trauma(/datum/brain_trauma/severe/monophobia, TRAUMA_RESILIENCE_ABSOLUTE) + +/datum/quirk/monophobia/remove() + . = ..() + var/mob/living/carbon/human/H = quirk_holder + H?.cure_trauma_type(/datum/brain_trauma/severe/monophobia, TRAUMA_RESILIENCE_ABSOLUTE) diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm index 4b039aa1b5..e92564a3b4 100644 --- a/code/datums/traits/neutral.dm +++ b/code/datums/traits/neutral.dm @@ -122,3 +122,19 @@ if(H) var/datum/species/species = H.dna.species species.disliked_food &= ~ALCOHOL + +/datum/quirk/longtimer + name = "Longtimer" + desc = "You've been around for a long time and seen more than your fair share of action, suffering some pretty nasty scars along the way. For whatever reason, you've declined to get them removed or augmented." + value = 0 + gain_text = "Your body has seen better days." + lose_text = "Your sins may wash away, but those scars are here to stay..." + medical_record_text = "Patient has withstood significant physical trauma and declined plastic surgery procedures to heal scarring." + /// the minimum amount of scars we can generate + var/min_scars = 3 + /// the maximum amount of scars we can generate + var/max_scars = 7 + +/datum/quirk/longtimer/on_spawn() + var/mob/living/carbon/C = quirk_holder + C.generate_fake_scars(rand(min_scars, max_scars)) diff --git a/code/datums/wounds/_scars.dm b/code/datums/wounds/_scars.dm new file mode 100644 index 0000000000..bfbaab835e --- /dev/null +++ b/code/datums/wounds/_scars.dm @@ -0,0 +1,134 @@ +/** + * scars are cosmetic datums that are assigned to bodyparts once they recover from wounds. Each wound type and severity have their own descriptions for what the scars + * look like, and then each body part has a list of "specific locations" like your elbow or wrist or wherever the scar can appear, to make it more interesting than "right arm" + * + * + * Arguments: + * * + */ +/datum/scar + var/obj/item/bodypart/limb + var/mob/living/carbon/victim + var/severity + var/description + var/precise_location + + /// Scars from the longtimer quirk are "fake" and won't be saved with persistent scarring, since it makes you spawn with a lot by default + var/fake=FALSE + + /// How many tiles away someone can see this scar, goes up with severity. Clothes covering this limb will decrease visibility by 1 each, except for the head/face which is a binary "is mask obscuring face" check + var/visibility = 2 + /// Whether this scar can actually be covered up by clothing + var/coverable = TRUE + /// What zones this scar can be applied to + var/list/applicable_zones = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_ARM, BODY_ZONE_R_LEG) + +/datum/scar/Destroy(force, ...) + if(limb) + LAZYREMOVE(limb.scars, src) + if(victim) + LAZYREMOVE(victim.all_scars, src) + . = ..() + +/** + * generate() is used to actually fill out the info for a scar, according to the limb and wound it is provided. + * + * After creating a scar, call this on it while targeting the scarred bodypart with a given wound to apply the scar. + * + * Arguments: + * * BP- The bodypart being targeted + * * W- The wound being used to generate the severity and description info + * * add_to_scars- Should always be TRUE unless you're just storing a scar for later usage, like how cuts want to store a scar for the highest severity of cut, rather than the severity when the wound is fully healed (probably demoted to moderate) + */ +/datum/scar/proc/generate(obj/item/bodypart/BP, datum/wound/W, add_to_scars=TRUE) + if(!(BP.body_zone in applicable_zones)) + qdel(src) + return + limb = BP + severity = W.severity + if(limb.owner) + victim = limb.owner + if(add_to_scars) + LAZYADD(limb.scars, src) + if(victim) + LAZYADD(victim.all_scars, src) + + description = pick(W.scarring_descriptions) + precise_location = pick(limb.specific_locations) + switch(W.severity) + if(WOUND_SEVERITY_MODERATE) + visibility = 2 + if(WOUND_SEVERITY_SEVERE) + visibility = 3 + if(WOUND_SEVERITY_CRITICAL) + visibility = 5 + +/// Used when we finalize a scar from a healing cut +/datum/scar/proc/lazy_attach(obj/item/bodypart/BP, datum/wound/W) + LAZYADD(BP.scars, src) + if(BP.owner) + victim = BP.owner + 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)) + qdel(src) + return + limb = BP + src.severity = severity + LAZYADD(limb.scars, src) + if(BP.owner) + victim = BP.owner + LAZYADD(victim.all_scars, src) + src.description = description + precise_location = specific_location + switch(severity) + if(WOUND_SEVERITY_MODERATE) + visibility = 2 + if(WOUND_SEVERITY_SEVERE) + visibility = 3 + if(WOUND_SEVERITY_CRITICAL) + visibility = 5 + return TRUE + +/// What will show up in examine_more() if this scar is visible +/datum/scar/proc/get_examine_description(mob/viewer) + if(!victim || !is_visible(viewer)) + return + + var/msg = "[victim.p_they(TRUE)] [victim.p_have()] [description] on [victim.p_their()] [precise_location]." + switch(severity) + if(WOUND_SEVERITY_MODERATE) + msg = "[msg]" + if(WOUND_SEVERITY_SEVERE) + msg = "[msg]" + if(WOUND_SEVERITY_CRITICAL) + msg = "[msg]" + return "\t[msg]" + +/// Whether a scar can currently be seen by the viewer +/datum/scar/proc/is_visible(mob/viewer) + if(!victim || !viewer) + return + if(get_dist(viewer, victim) > visibility) + return + + if(!ishuman(victim) || isobserver(viewer) || victim == viewer) + return TRUE + + var/mob/living/carbon/human/H = 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))) + return FALSE + else if(limb.scars_covered_by_clothes) + var/num_covers = LAZYLEN(H.clothingonpart(limb)) + if(num_covers + get_dist(viewer, victim) >= visibility) + return FALSE + + return TRUE + +/// 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]" diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm new file mode 100644 index 0000000000..b1ba49b7ab --- /dev/null +++ b/code/datums/wounds/_wounds.dm @@ -0,0 +1,318 @@ +/* + Wounds are specific medical complications that can arise and be applied to (currently) carbons, with a focus on humans. All of the code for and related to this is heavily WIP, + and the documentation will be slanted towards explaining what each part/piece is leading up to, until such a time as I finish the core implementations. The original design doc + can be found at https://hackmd.io/@Ryll/r1lb4SOwU + + Wounds are datums that operate like a mix of diseases, brain traumas, and components, and are applied to a /obj/item/bodypart (preferably attached to a carbon) when they take large spikes of damage + or under other certain conditions (thrown hard against a wall, sustained exposure to plasma fire, etc). Wounds are categorized by the three following criteria: + 1. Severity: Either MODERATE, SEVERE, or CRITICAL. See the hackmd for more details + 2. Viable zones: What body parts the wound is applicable to. Generic wounds like broken bones and severe burns can apply to every zone, but you may want to add special wounds for certain limbs + like a twisted ankle for legs only, or open air exposure of the organs for particularly gruesome chest wounds. Wounds should be able to function for every zone they are marked viable for. + 3. Damage type: Currently either BRUTE or BURN. Again, see the hackmd for a breakdown of my plans for each type. + + When a body part suffers enough damage to get a wound, the severity (determined by a roll or something, worse damage leading to worse wounds), affected limb, and damage type sustained are factored into + deciding what specific wound will be applied. I'd like to have a few different types of wounds for at least some of the choices, but I'm just doing rough generals for now. Expect polishing +*/ + +/datum/wound + /// What it's named + var/name = "ouchie" + /// The description shown on the scanners + var/desc = "" + /// The basic treatment suggested by health analyzers + var/treat_text = "" + /// What the limb looks like on a cursory examine + var/examine_desc = "is badly hurt" + + /// needed for "your arm has a compound fracture" vs "your arm has some third degree burns" + var/a_or_from = "a" + /// The visible message when this happens + var/occur_text = "" + /// This sound will be played upon the wound being applied + var/sound_effect + + /// 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 + 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 + + /// Specific items such as bandages or sutures that can try directly treating this wound + var/list/treatable_by + /// Specific items such as bandages or sutures that can try directly treating this wound only if the user has the victim in an aggressive grab or higher + 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 + + /// Using this limb in a do_after interaction will multiply the length by this duration (arms) + var/interaction_efficiency_penalty = 1 + /// Incoming damage on this limb will be multiplied by this, to simulate tenderness and vulnerability (mostly burns). + var/damage_mulitplier_penalty = 1 + /// If set and this wound is applied to a leg, we take this many deciseconds extra per step on this leg + var/limp_slowdown + /// 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 + 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 + + /// What status effect we assign on application + var/status_effect_type + /// The status effect we're linked to + var/datum/status_effect/linked_status_effect + /// If we're operating on this wound and it gets healed, we'll nix the surgery too + var/datum/surgery/attached_surgery + /// if you're a lazy git and just throw them in cryo, the wound will go away after accumulating severity * 25 power + var/cryo_progress + + /// What kind of scars this wound will create description wise once healed + var/list/scarring_descriptions = list("general disfigurement") + /// 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 + +/datum/wound/Destroy() + if(attached_surgery) + QDEL_NULL(attached_surgery) + if(limb?.wounds && (src in limb.wounds)) // destroy can call remove_wound() and remove_wound() calls qdel, so we check to make sure there's anything to remove first + remove_wound() + limb = null + victim = null + return ..() + +/** + * apply_wound() is used once a wound type is instantiated to assign it to a bodypart, and actually come into play. + * + * + * Arguments: + * * L: The bodypart we're wounding, we don't care about the person, we can get them through the limb + * * silent: Not actually necessary I don't think, was originally used for demoting wounds so they wouldn't make new messages, but I believe old_wound took over that, I may remove this shortly + * * old_wound: If our new wound is a replacement for one of the same time (promotion or demotion), we can reference the old one just before it's removed to copy over necessary vars + * * 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)) + 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())) + qdel(src) + return + + // we accept promotions and demotions, but no point in redundancy. This should have already been checked wherever the wound was rolled and applied for (see: bodypart damage code), but we do an extra check + // in case we ever directly add wounds + for(var/i in L.wounds) + var/datum/wound/preexisting_wound = i + if((preexisting_wound.type == type) && (preexisting_wound != old_wound)) + qdel(src) + return + + victim = L.owner + limb = L + LAZYADD(victim.all_wounds, src) + LAZYADD(limb.wounds, src) + limb.update_wounds() + if(status_effect_type) + linked_status_effect = victim.apply_status_effect(status_effect_type, src) + SEND_SIGNAL(victim, COMSIG_CARBON_GAIN_WOUND, src, limb) + if(!victim.alerts["wound"]) // only one alert is shared between all of the wounds + victim.throw_alert("wound", /obj/screen/alert/status_effect/wound) + + var/demoted + if(old_wound) + demoted = (severity <= old_wound.severity) + + if(severity == WOUND_SEVERITY_TRIVIAL) + return + + if(!(silent || demoted)) + var/msg = "[victim]'s [limb.name] [occur_text]!" + var/vis_dist = COMBAT_MESSAGE_RANGE + + if(severity != WOUND_SEVERITY_MODERATE) + msg = "[msg]" + vis_dist = DEFAULT_MESSAGE_RANGE + + 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) + + if(!demoted) + wound_injury(old_wound) + second_wind() + +/// Remove the wound from whatever it's afflicting, and cleans up whateverstatus effects it had or modifiers it had on interaction times. ignore_limb is used for detachments where we only want to forget the victim +/datum/wound/proc/remove_wound(ignore_limb, replaced = FALSE) + //TODO: have better way to tell if we're getting removed without replacement (full heal) scar stuff + if(limb && !already_scarred && !replaced) + already_scarred = TRUE + var/datum/scar/new_scar = new + new_scar.generate(limb, src) + if(victim) + LAZYREMOVE(victim.all_wounds, src) + if(!victim.all_wounds) + victim.clear_alert("wound") + SEND_SIGNAL(victim, COMSIG_CARBON_LOSE_WOUND, src, limb) + if(limb && !ignore_limb) + LAZYREMOVE(limb.wounds, src) + limb.update_wounds() + +/** + * 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) + * + * 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 + * * 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) + var/datum/wound/new_wound = new new_type + already_scarred = TRUE + remove_wound(replaced=TRUE) + new_wound.apply_wound(limb, old_wound = src, smited = smited) + qdel(src) + return new_wound + +/// The immediate negative effects faced as a result of the wound +/datum/wound/proc/wound_injury(datum/wound/old_wound = null) + return + +/// 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) + if(WOUND_SEVERITY_SEVERE) + victim.reagents.add_reagent(/datum/reagent/determination, WOUND_DETERMINATION_SEVERE) + if(WOUND_SEVERITY_CRITICAL) + victim.reagents.add_reagent(/datum/reagent/determination, WOUND_DETERMINATION_CRITICAL) + +/** + * 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. + * + * 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: + * * I: The item we're trying to use + * * user: The mob trying to use it on us + */ +/datum/wound/proc/try_treating(obj/item/I, mob/user) + // first we weed out if we're not dealing with our wound's bodypart, or if it might be an attack + if(!I || limb.body_zone != user.zone_selected || (I.force && user.a_intent != INTENT_HELP)) + return FALSE + + var/allowed = FALSE + + // check if we have a valid treatable tool (or, if cauteries are allowed, if we have something hot) + if((I.tool_behaviour == treatable_tool) || (treatable_tool == TOOL_CAUTERY && I.get_temperature())) + allowed = TRUE + // failing that, see if we're aggro grabbing them and if we have an item that works for aggro grabs only + else if(user.pulling == victim && user.grab_state >= GRAB_AGGRESSIVE && check_grab_treatments(I, user)) + allowed = TRUE + // failing THAT, we check if we have a generally allowed item + else + for(var/allowed_type in treatable_by) + if(istype(I, allowed_type)) + allowed = TRUE + break + + // if none of those apply, we return false to avoid interrupting + if(!allowed) + return FALSE + + // now that we've determined we have a valid attempt at treating, we can stomp on their dreams if we're already interacting with the patient + if(INTERACTING_WITH(user, victim)) + to_chat(user, "You're already interacting with [victim]!") + return TRUE + + // lastly, treat them + 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()] +/datum/wound/proc/check_grab_treatments(obj/item/I, mob/user) + return FALSE + +/// Like try_treating() but for unhanded interactions from humans, used by joint dislocations for manual bodypart chiropractice for example. +/datum/wound/proc/try_handling(mob/living/carbon/human/user) + return FALSE + +/// Someone is using something that might be used for treating the wound on this limb +/datum/wound/proc/treat(obj/item/I, mob/user) + return + +/// If var/processing is TRUE, this is run on each life tick +/datum/wound/proc/handle_process() + return + +/// For use in do_after callback checks +/datum/wound/proc/still_exists() + return (!QDELETED(src) && limb) + +/// When our parent bodypart is hurt +/datum/wound/proc/receive_damage(wounding_type, wounding_dmg, wound_bonus) + return + +/// Called from cryoxadone and pyroxadone when they're proc'ing. Wounds will slowly be fixed separately from other methods when these are in effect. crappy name but eh +/datum/wound/proc/on_xadone(power) + cryo_progress += power + if(cryo_progress > 33 * severity) + qdel(src) + +/// Called when we're crushed in an airlock or firedoor, for one of the improvised joint dislocation fixes +/datum/wound/proc/crush() + 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. + * + * Return the full string line you want to show, note that we're already dealing with the 'warning' span at this point, and that \n is already appended for you in the place this is called from + * + * Arguments: + * * 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]!" + +/datum/wound/proc/get_scanner_description(mob/user) + return "Type: [name]\nSeverity: [severity_text()]\nDescription: [desc]\nRecommended Treatment: [treat_text]" + +/datum/wound/proc/severity_text() + switch(severity) + if(WOUND_SEVERITY_TRIVIAL) + return "Trivial" + if(WOUND_SEVERITY_MODERATE) + return "Moderate" + if(WOUND_SEVERITY_SEVERE) + return "Severe" + if(WOUND_SEVERITY_CRITICAL) + return "Critical" diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm new file mode 100644 index 0000000000..80d922cba3 --- /dev/null +++ b/code/datums/wounds/bones.dm @@ -0,0 +1,453 @@ + +/* + Bones +*/ +// TODO: well, a lot really, but i'd kill to get overlays and a bonebreaking effect like Blitz: The League, similar to electric shock skeletons + +/* + 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 + + /// Have we been taped? + var/taped + /// Have we been bone gel'd? + var/gelled + /// If we did the gel + surgical tape healing method for fractures, how many regen points we need + var/regen_points_needed + /// Our current counter for gel + surgical tape regeneration + var/regen_points_current + /// If we suffer severe head booboos, we can get brain traumas tied to them + var/datum/brain_trauma/active_trauma + /// What brain trauma group, if any, we can draw from for head wounds + var/brain_trauma_group + /// If we deal brain traumas, when is the next one due? + var/next_trauma_cycle + /// 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 + +/* + Overwriting of base procs +*/ +/datum/wound/brute/bone/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) + next_trauma_cycle = world.time + (rand(100-WOUND_BONE_HEAD_TIME_VARIANCE, 100+WOUND_BONE_HEAD_TIME_VARIANCE) * 0.01 * trauma_cycle_cooldown) + + RegisterSignal(victim, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, .proc/attack_with_hurt_hand) + if(limb.held_index && victim.get_item_for_held_index(limb.held_index) && (disabling || prob(30 * severity))) + var/obj/item/I = victim.get_item_for_held_index(limb.held_index) + if(istype(I, /obj/item/offhand)) + I = victim.get_inactive_held_item() + + if(I && victim.dropItemToGround(I)) + victim.visible_message("[victim] drops [I] in shock!", "The force on your [limb.name] causes you to drop [I]!", vision_distance=COMBAT_MESSAGE_RANGE) + + update_inefficiencies() + +/datum/wound/brute/bone/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() + . = ..() + if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle) + if(active_trauma) + QDEL_NULL(active_trauma) + else + active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND) + next_trauma_cycle = world.time + (rand(100-WOUND_BONE_HEAD_TIME_VARIANCE, 100+WOUND_BONE_HEAD_TIME_VARIANCE) * 0.01 * trauma_cycle_cooldown) + + if(!regen_points_needed) + return + + regen_points_current++ + if(prob(severity * 2)) + victim.take_bodypart_damage(rand(2, severity * 2), stamina=rand(2, severity * 2.5), wound_bonus=CANT_WOUND) + if(prob(33)) + to_chat(victim, "You feel a sharp pain in your body as your bones are reforming!") + + if(regen_points_current > regen_points_needed) + if(!victim || !limb) + qdel(src) + return + to_chat(victim, "Your [limb.name] has recovered from your fracture!") + 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) + if(victim.get_active_hand() != limb || victim.a_intent == INTENT_HELP || !ismob(target) || severity <= WOUND_SEVERITY_MODERATE) + return + + // With a severe or critical wound, you have a 15% or 30% chance to proc pain on hit + if(prob((severity - 1) * 15)) + // And you have a 70% or 50% chance to actually land the blow, respectively + if(prob(70 - 20 * (severity - 1))) + to_chat(victim, "The fracture in your [limb.name] shoots with pain as you strike [target]!") + limb.receive_damage(brute=rand(1,5)) + else + victim.visible_message("[victim] weakly strikes [target] with [victim.p_their()] broken [limb.name], recoiling from pain!", \ + "You fail to strike [target] as the fracture in your [limb.name] lights up in unbearable pain!", vision_distance=COMBAT_MESSAGE_RANGE) + victim.emote("scream") + victim.Stun(0.5 SECONDS) + 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) + return + + if(limb.body_zone == BODY_ZONE_CHEST && victim.blood_volume && prob(chance_internal_bleeding + 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.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!") + 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.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) + return ..() + + var/msg = "" + if(!splinted) + msg = "[victim.p_their(TRUE)] [limb.name] [examine_desc]" + else + var/splint_condition = "" + // how much life we have left in these bandages + switch(splinted.obj_integrity / splinted.max_integrity * 100) + if(0 to 25) + splint_condition = "just barely " + if(25 to 50) + splint_condition = "loosely " + if(50 to 75) + splint_condition = "mostly " + if(75 to INFINITY) + splint_condition = "tightly " + + msg = "[victim.p_their(TRUE)] [limb.name] is [splint_condition] fastened in a splint of [splinted.name]" + + if(taped) + msg += ", and appears to be reforming itself under some surgical tape!" + else if(gelled) + msg += ", with fizzing flecks of blue bone gel sparking off the bone!" + else + msg += "!" + return "[msg]" + +/* + New common procs for /datum/wound/brute/bone/ +*/ + +/datum/wound/brute/bone/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 + 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) + else + interaction_efficiency_penalty = interaction_efficiency_penalty + + if(initial(disabling) && splinted) + disabling = FALSE + else if(initial(disabling)) + disabling = TRUE + + 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 + 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." + examine_desc = "is awkwardly jammed out of place" + occur_text = "jerks violently and becomes unseated" + 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 + 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") + +/datum/wound/brute/bone/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) + if(user.pulling != victim || user.zone_selected != limb.body_zone || user.a_intent == INTENT_GRAB) + return FALSE + + if(user.grab_state == GRAB_PASSIVE) + to_chat(user, "You must have [victim] in an aggressive grab to manipulate [victim.p_their()] [lowertext(name)]!") + return TRUE + + if(user.grab_state >= GRAB_AGGRESSIVE) + user.visible_message("[user] begins twisting and straining [victim]'s dislocated [limb.name]!", "You begin twisting and straining [victim]'s dislocated [limb.name]...", ignored_mobs=victim) + to_chat(victim, "[user] begins twisting and straining your dislocated [limb.name]!") + if(user.a_intent == INTENT_HELP) + chiropractice(user) + else + malpractice(user) + 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) + var/time = base_treat_time + + if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + + if(prob(65)) + user.visible_message("[user] snaps [victim]'s dislocated [limb.name] back into place!", "You snap [victim]'s dislocated [limb.name] back into place!", ignored_mobs=victim) + to_chat(victim, "[user] snaps your dislocated [limb.name] back into place!") + victim.emote("scream") + limb.receive_damage(brute=20, wound_bonus=CANT_WOUND) + qdel(src) + else + user.visible_message("[user] wrenches [victim]'s dislocated [limb.name] around painfully!", "You wrench [victim]'s dislocated [limb.name] around painfully!", ignored_mobs=victim) + to_chat(victim, "[user] wrenches your dislocated [limb.name] around painfully!") + limb.receive_damage(brute=10, wound_bonus=CANT_WOUND) + 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) + var/time = base_treat_time + + if(!do_after(user, time, target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + + if(prob(65)) + user.visible_message("[user] snaps [victim]'s dislocated [limb.name] with a sickening crack!", "You snap [victim]'s dislocated [limb.name] with a sickening crack!", ignored_mobs=victim) + to_chat(victim, "[user] snaps your dislocated [limb.name] with a sickening crack!") + victim.emote("scream") + limb.receive_damage(brute=25, wound_bonus=30) + else + user.visible_message("[user] wrenches [victim]'s dislocated [limb.name] around painfully!", "You wrench [victim]'s dislocated [limb.name] around painfully!", ignored_mobs=victim) + to_chat(victim, "[user] wrenches your dislocated [limb.name] around painfully!") + limb.receive_damage(brute=10, wound_bonus=CANT_WOUND) + malpractice(user) + + +/datum/wound/brute/bone/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 + user.visible_message("[user] begins resetting [victim]'s [limb.name] with [I].", "You begin resetting [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 + + if(victim == user) + limb.receive_damage(brute=15, wound_bonus=CANT_WOUND) + victim.visible_message("[user] finishes resetting [victim.p_their()] [limb.name]!", "You reset your [limb.name]!") + else + limb.receive_damage(brute=10, wound_bonus=CANT_WOUND) + user.visible_message("[user] finishes resetting [victim]'s [limb.name]!", "You finish resetting [victim]'s [limb.name]!", victim) + to_chat(victim, "[user] resets your [limb.name]!") + + victim.emote("scream") + qdel(src) + +/* + Severe (Hairline Fracture) +*/ + +/datum/wound/brute/bone/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" + + 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 + 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") + brain_trauma_group = BRAIN_TRAUMA_MILD + trauma_cycle_cooldown = 1.5 MINUTES + chance_internal_bleeding = 40 + +/datum/wound/brute/bone/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" + 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 + 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") + brain_trauma_group = BRAIN_TRAUMA_SEVERE + trauma_cycle_cooldown = 2.5 MINUTES + chance_internal_bleeding = 60 + +// 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) + 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) + if(gelled) + to_chat(user, "[user == victim ? "Your" : "[victim]'s"] [limb.name] is already coated with bone gel!") + return + + user.visible_message("[user] begins hastily applying [I] to [victim]'s' [limb.name]...", "You begin hastily applying [I] to [user == victim ? "your" : "[victim]'s"] [limb.name], disregarding the warning label...") + + if(!do_after(user, base_treat_time * 1.5 * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, .proc/still_exists))) + return + + I.use(1) + victim.emote("scream") + if(user != victim) + user.visible_message("[user] finishes applying [I] to [victim]'s [limb.name], emitting a fizzing noise!", "You finish applying [I] to [victim]'s [limb.name]!", ignored_mobs=victim) + to_chat(victim, "[user] finishes applying [I] to your [limb.name], and you can feel the bones exploding with pain as they begin melting and reforming!") + else + var/painkiller_bonus = 0 + if(victim.drunkenness) + painkiller_bonus += 5 + if(victim.reagents && victim.reagents.has_reagent(/datum/reagent/medicine/morphine)) + painkiller_bonus += 10 + if(victim.reagents && 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 + 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 + victim.visible_message("[victim] finishes applying [I] to [victim.p_their()] [limb.name], grimacing from the pain!", "You finish applying [I] to your [limb.name], and your bones explode in pain!") + + limb.receive_damage(30, stamina=100, wound_bonus=CANT_WOUND) + if(!gelled) + 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) + if(!gelled) + to_chat(user, "[user == victim ? "Your" : "[victim]'s"] [limb.name] must be coated with bone gel to perform this emergency operation!") + return + if(taped) + to_chat(user, "[user == victim ? "Your" : "[victim]'s"] [limb.name] is already wrapped in [I.name] and reforming!") + return + + 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, base_treat_time * (user == victim ? 1.5 : 1), target = victim, extra_checks=CALLBACK(src, .proc/still_exists))) + return + + regen_points_current = 0 + regen_points_needed = 30 SECONDS * (user == victim ? 1.5 : 1) * (severity - 1) + I.use(1) + if(user != victim) + user.visible_message("[user] finishes applying [I] to [victim]'s [limb.name], emitting a fizzing noise!", "You finish applying [I] to [victim]'s [limb.name]!", ignored_mobs=victim) + to_chat(victim, "[user] finishes applying [I] to your [limb.name], you immediately begin to feel your bones start to reform!") + else + victim.visible_message("[victim] finishes applying [I] to [victim.p_their()] [limb.name], !", "You finish applying [I] to your [limb.name], and you immediately begin to feel your bones start to reform!") + + taped = TRUE + processes = TRUE + +/datum/wound/brute/bone/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) + . = ..() + + . += "
" + + if(!gelled) + . += "Alternative Treatment: Apply bone gel directly to injured limb, then apply surgical tape to begin bone regeneration. This is both excruciatingly painful and slow, and only recommended in dire circumstances.\n" + 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" + + 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." + else if(limb.body_zone == BODY_ZONE_CHEST && victim.blood_volume) + . += "Ribcage Trauma Detected: Further trauma to chest is likely to worsen internal bleeding until bone is repaired." + . += "
" diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm new file mode 100644 index 0000000000..6a6629a0c9 --- /dev/null +++ b/code/datums/wounds/burns.dm @@ -0,0 +1,323 @@ + + + +// 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 + processes = TRUE + sound_effect = 'sound/effects/sizzle1.ogg' + + 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 + + // Flesh damage vars + /// How much damage to our flesh we currently have. Once both this and infestation reach 0, the wound is considered healed + var/flesh_damage = 5 + /// Our current counter for how much flesh regeneration we have stacked from regenerative mesh/synthflesh/whatever, decrements each tick and lowers flesh_damage + var/flesh_healing = 0 + + // Infestation vars (only for severe and critical) + /// How quickly infection breeds on this burn if we don't have disinfectant + var/infestation_rate = 0 + /// Our current level of infection + var/infestation = 0 + /// Our current level of sanitization/anti-infection, from disinfectants/alcohol/UV lights. While positive, totally pauses and slowly reverses infestation effects each tick + var/sanitization = 0 + + /// 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() + . = ..() + if(strikes_to_lose_limb == 0) + victim.adjustToxLoss(0.5) + if(prob(1)) + victim.visible_message("The infection on the remnants of [victim]'s [limb.name] shift and bubble nauseatingly!", "You can feel the infection on the remnants of your [limb.name] coursing through your veins!") + return + + if(victim.reagents) + if(victim.reagents.has_reagent(/datum/reagent/medicine/spaceacillin)) + sanitization += 0.9 + if(victim.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine/)) + sanitization += 0.9 + if(victim.reagents.has_reagent(/datum/reagent/medicine/mine_salve)) + 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(flesh_healing > 0) + var/bandage_factor = (current_bandage ? current_bandage.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 + + // here's the check to see if we're cleared up + if((flesh_damage <= 0) && (infestation <= 1)) + to_chat(victim, "The burns on your [limb.name] have cleared up!") + qdel(src) + return + + // 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) + infestation = max(0, infestation - WOUND_BURN_SANITIZATION_RATE) + sanitization = max(0, sanitization - (WOUND_BURN_SANITIZATION_RATE * bandage_factor)) + return + + infestation += infestation_rate + + switch(infestation) + if(0 to WOUND_INFECTION_MODERATE) + if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE) + if(prob(30)) + victim.adjustToxLoss(0.2) + if(prob(6)) + to_chat(victim, "The blisters on your [limb.name] ooze a strange pus...") + if(WOUND_INFECTION_SEVERE to WOUND_INFECTION_CRITICAL) + if(!disabling && prob(2)) + to_chat(victim, "Your [limb.name] completely locks up, as you struggle for control against the infection!") + disabling = TRUE + else if(disabling && prob(8)) + to_chat(victim, "You regain sensation in your [limb.name], but it's still in terrible shape!") + disabling = FALSE + else if(prob(20)) + victim.adjustToxLoss(0.5) + if(WOUND_INFECTION_CRITICAL to WOUND_INFECTION_SEPTIC) + if(!disabling && prob(3)) + to_chat(victim, "You suddenly lose all sensation of the festering infection in your [limb.name]!") + disabling = TRUE + else if(disabling && prob(3)) + to_chat(victim, "You can barely feel your [limb.name] again, and you have to strain to retain motor control!") + disabling = FALSE + else if(prob(1)) + to_chat(victim, "You contemplate life without your [limb.name]...") + victim.adjustToxLoss(0.75) + else if(prob(4)) + victim.adjustToxLoss(1) + if(WOUND_INFECTION_SEPTIC to INFINITY) + if(prob(infestation)) + switch(strikes_to_lose_limb) + if(3 to INFINITY) + to_chat(victim, "The skin on your [limb.name] is literally dripping off, you feel awful!") + if(2) + to_chat(victim, "The infection in your [limb.name] is literally dripping off, you feel horrible!") + if(1) + to_chat(victim, "Infection has just about completely claimed your [limb.name]!") + if(0) + to_chat(victim, "The last of the nerve endings in your [limb.name] wither away, as the infection completely paralyzes your joint connector.") + threshold_penalty = 120 // piss easy to destroy + var/datum/brain_trauma/severe/paralysis/sepsis = new (limb.body_zone) + victim.gain_trauma(sepsis) + strikes_to_lose_limb-- + +/datum/wound/burn/get_examine_description(mob/user) + 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/bandage_condition + switch(current_bandage.absorption_capacity) + if(0 to 1.25) + bandage_condition = "nearly ruined " + if(1.25 to 2.75) + bandage_condition = "badly worn " + if(2.75 to 4) + bandage_condition = "slightly pus-stained " + if(4 to INFINITY) + bandage_condition = "clean " + + condition += " underneath a dressing of [bandage_condition] [current_bandage.name]" + else + switch(infestation) + if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE) + condition += ", with small spots of discoloration along the nearby veins!" + if(WOUND_INFECTION_SEVERE to WOUND_INFECTION_CRITICAL) + condition += ", with dark clouds spreading outwards under the skin!" + if(WOUND_INFECTION_CRITICAL to WOUND_INFECTION_SEPTIC) + condition += ", with streaks of rotten infection pulsating outward!" + if(WOUND_INFECTION_SEPTIC to INFINITY) + return "[victim.p_their(TRUE)] [limb.name] is a mess of char and rot, skin literally dripping off the bone with infection!" + else + condition += "!" + + return "[victim.p_their(TRUE)] [limb.name] [examine_desc][condition]" + +/datum/wound/burn/get_scanner_description(mob/user) + if(strikes_to_lose_limb == 0) + var/oopsie = "Type: [name]\nSeverity: [severity_text()]" + oopsie += "
Infection Level: The infection is total. The bodypart is lost. Amputate or augment limb immediately.
" + return oopsie + + . = ..() + . += "
" + + if(infestation <= sanitization && flesh_damage <= flesh_healing) + . += "No further treatment required: Burns will heal shortly." + else + switch(infestation) + if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE) + . += "Infection Level: Moderate\n" + if(WOUND_INFECTION_SEVERE to WOUND_INFECTION_CRITICAL) + . += "Infection Level: Severe\n" + if(WOUND_INFECTION_CRITICAL to WOUND_INFECTION_SEPTIC) + . += "Infection Level: CRITICAL\n" + if(WOUND_INFECTION_SEPTIC to INFINITY) + . += "Infection Level: LOSS IMMINENT\n" + if(infestation > sanitization) + . += "\tSurgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n" + + if(flesh_damage > 0) + . += "Flesh damage detected: Please apply ointment or regenerative mesh to allow recovery.\n" + . += "
" + +/* + new burn common procs +*/ + +/// 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)) + return + + limb.heal_damage(I.heal_brute, I.heal_burn) + user.visible_message("[user] applies [I] to [victim].", "You apply [I] to [user == victim ? "your" : "[victim]'s"] [limb.name].") + I.use(1) + sanitization += I.sanitization + flesh_healing += I.flesh_regeneration + + if((infestation <= 0 || sanitization >= infestation) && (flesh_damage <= 0 || flesh_healing > flesh_damage)) + to_chat(user, "You've done all you can with [I], now you must wait for the flesh on [victim]'s [limb.name] to recover.") + 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]...") + if(!do_after(user, (user == victim ? I.self_delay : I.other_delay), target=victim, extra_checks = CALLBACK(src, .proc/still_exists))) + return + + limb.heal_damage(I.heal_brute, I.heal_burn) + user.visible_message("[user] applies [I] to [victim].", "You apply [I] to [user == victim ? "your" : "[victim]'s"] [limb.name].") + I.use(1) + sanitization += I.sanitization + flesh_healing += I.flesh_regeneration + + if(sanitization >= infestation && flesh_healing > flesh_damage) + to_chat(user, "You've done all you can with [I], now you must wait for the flesh on [victim]'s [limb.name] to recover.") + else + try_treating(I, user) + +/// Paramedic UV penlights +/datum/wound/burn/proc/uv(obj/item/flashlight/pen/paramedic/I, mob/user) + if(I.uv_cooldown > world.time) + to_chat(user, "[I] is still recharging!") + return + if(infestation <= 0 || infestation < sanitization) + to_chat(user, "There's no infection to treat on [victim]'s [limb.name]!") + return + + 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 + +/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)) + 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) + flesh_healing += amount * 0.5 // 20u patch will heal 10 flesh standard + +// we don't even care about first degree burns, straight to second +/datum/wound/burn/moderate + name = "Second Degree Burns" + desc = "Patient is suffering considerable burns with mild skin penetration, weakening limb integrity and increased burning sensations." + treat_text = "Recommended application of topical ointment or regenerative mesh to affected region." + 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 + 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") + +/datum/wound/burn/severe + name = "Third Degree Burns" + desc = "Patient is suffering extreme burns with full skin penetration, creating serious risk of infection and greatly reduced limb integrity." + treat_text = "Recommended immediate disinfection and excision of any infected skin, followed by bandaging and ointment." + 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 + 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) + 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") + +/datum/wound/burn/critical + name = "Catastrophic Burns" + desc = "Patient is suffering near complete loss of tissue and significantly charred muscle and bone, creating life-threatening risk of infection and negligible limb integrity." + treat_text = "Immediate surgical debriding of any infected skin, followed by potent tissue regeneration formula and bandaging." + 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 + 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) + 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") diff --git a/code/datums/wounds/cuts.dm b/code/datums/wounds/cuts.dm new file mode 100644 index 0000000000..0ab3bbd5f8 --- /dev/null +++ b/code/datums/wounds/cuts.dm @@ -0,0 +1,309 @@ + +/* + Cuts +*/ + +/datum/wound/brute/cut + 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) + treatable_by_grabbed = list(/obj/item/gun/energy/laser) + treatable_tool = TOOL_CAUTERY + treat_priority = TRUE + base_treat_time = 3 SECONDS + + /// How much blood we start losing when this wound is first applied + var/initial_flow + /// When we have less than this amount of flow, either from treatment or clotting, we demote to a lower cut or are healed of the wound + var/minimum_flow + /// How fast our blood flow will naturally decrease per tick, not only do larger cuts bleed more faster, they clot slower + var/clot_rate + + /// Once the blood flow drops below minimum_flow, we demote it to this type of wound. If there's none, we're all better + var/demotes_to + + /// How much staunching per type (cautery, suturing, bandaging) you can have before that type is no longer effective for this cut NOT IMPLEMENTED + 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) + 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) + 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) + return ..() + + var/bandage_condition = "" + // how much life we have left in these bandages + switch(current_bandage.absorption_capacity) + if(0 to 1.25) + bandage_condition = "nearly ruined " + if(1.25 to 2.75) + bandage_condition = "badly worn " + if(2.75 to 4) + bandage_condition = "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]!" + +/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 + blood_flow += 0.05 * wounding_dmg + +/datum/wound/brute/cut/handle_process() + blood_flow = min(blood_flow, WOUND_CUT_MAX_BLOODFLOW) + + if(victim.reagents && 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(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 + else + blood_flow -= clot_rate + + if(blood_flow > highest_flow) + highest_flow = blood_flow + + if(blood_flow < minimum_flow) + if(demotes_to) + replace_wound(demotes_to) + else + to_chat(victim, "The cut on your [limb.name] has stopped bleeding!") + 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) + if(istype(I, /obj/item/gun/energy/laser)) + return TRUE + +/datum/wound/brute/cut/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) + 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) + if(INTERACTING_WITH(user, victim)) + to_chat(user, "You're already interacting with [victim]!") + return + + 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].[user] licks the wounds on [victim]'s [limb.name].", "You lick some of the wounds on [victim]'s [limb.name]", ignored_mobs=victim) + to_chat(victim, "[user] licks the wounds on your [limb.name]! minimum_flow) + try_handling(user) + else if(demotes_to) + to_chat(user, "You successfully lower the severity of [victim]'s cuts.") + +/datum/wound/brute/cut/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 + +/// 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) + 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))) + return + var/damage = lasgun.chambered.BB.damage + lasgun.chambered.BB.wound_bonus -= 30 + lasgun.chambered.BB.damage *= self_penalty_mult + if(!lasgun.process_fire(victim, victim, TRUE, null, limb.body_zone)) + 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) + 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) + blood_flow -= blood_cauterized + cauterized += blood_cauterized + + if(blood_flow > minimum_flow) + try_treating(I, user) + else if(demotes_to) + 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) + 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) + try_treating(I, user) + 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 + 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' + severity = WOUND_SEVERITY_MODERATE + initial_flow = 2 + minimum_flow = 0.5 + max_per_type = 3 + clot_rate = 0.15 + threshold_minimum = 20 + 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") + +/datum/wound/brute/cut/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' + severity = WOUND_SEVERITY_SEVERE + initial_flow = 3.25 + minimum_flow = 2.75 + clot_rate = 0.07 + max_per_type = 4 + threshold_minimum = 50 + 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") + +/datum/wound/brute/cut/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" + occur_text = "is torn open, spraying blood wildly" + sound_effect = 'sound/effects/blood3.ogg' + severity = WOUND_SEVERITY_CRITICAL + initial_flow = 4.25 + minimum_flow = 4 + clot_rate = -0.05 // critical cuts actively get worse instead of better + max_per_type = 5 + threshold_minimum = 80 + 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) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index dabbe93bec..f87f7a757c 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -516,7 +516,7 @@ GLOBAL_LIST_EMPTY(teleportlocs) used_environ += amount -/area/Entered(atom/movable/M) +/area/Entered(atom/movable/M, atom/OldLoc) set waitfor = FALSE SEND_SIGNAL(src, COMSIG_AREA_ENTERED, M) SEND_SIGNAL(M, COMSIG_ENTER_AREA, src) //The atom that enters the area @@ -524,6 +524,11 @@ GLOBAL_LIST_EMPTY(teleportlocs) return var/mob/living/L = M + var/turf/oldTurf = get_turf(OldLoc) + var/area/A = oldTurf?.loc + if(A && (A.has_gravity != has_gravity)) + L.update_gravity(L.mob_has_gravity()) + if(!L.ckey) return diff --git a/code/game/atoms.dm b/code/game/atoms.dm index a5bc419de6..f9763cc863 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -994,6 +994,39 @@ Proc for attack log creation, because really why not var/reverse_message = "has been [what_done] by [ssource][postfix]" target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE) +/** + * log_wound() is for when someone is *attacked* and suffers a wound. Note that this only captures wounds from damage, so smites/forced wounds aren't logged, as well as demotions like cuts scabbing over + * + * Note that this has no info on the attack that dealt the wound: information about where damage came from isn't passed to the bodypart's damaged proc. When in doubt, check the attack log for attacks at that same time + * TODO later: Add logging for healed wounds, though that will require some rewriting of healing code to prevent admin heals from spamming the logs. Not high priority + * + * Arguments: + * * victim- The guy who got wounded + * * suffered_wound- The wound, already applied, that we're logging. It has to already be attached so we can get the limb from it + * * dealt_damage- How much damage is associated with the attack that dealt with this wound. + * * dealt_wound_bonus- The wound_bonus, if one was specified, of the wounding attack + * * dealt_bare_wound_bonus- The bare_wound_bonus, if one was specified *and applied*, of the wounding attack. Not shown if armor was present + * * base_roll- Base wounding ability of an attack is a random number from 1 to (dealt_damage ** WOUND_DAMAGE_EXPONENT). This is the number that was rolled in there, before mods + */ +/proc/log_wound(atom/victim, datum/wound/suffered_wound, dealt_damage, dealt_wound_bonus, dealt_bare_wound_bonus, base_roll) + if(QDELETED(victim) || !suffered_wound) + return + var/message = "has suffered: [suffered_wound][suffered_wound.limb ? " to [suffered_wound.limb.name]" : null]"// maybe indicate if it's a promote/demote? + + if(dealt_damage) + message += " | Damage: [dealt_damage]" + // The base roll is useful since it can show how lucky someone got with the given attack. For example, dealing a cut + if(base_roll) + message += " (rolled [base_roll]/[dealt_damage ** WOUND_DAMAGE_EXPONENT])" + + if(dealt_wound_bonus) + message += " | WB: [dealt_wound_bonus]" + + if(dealt_bare_wound_bonus) + message += " | BWB: [dealt_bare_wound_bonus]" + + victim.log_message(message, LOG_ATTACK, color="blue") + // Filter stuff /atom/proc/add_filter(name,priority,list/params) LAZYINITLIST(filter_data) diff --git a/code/game/atoms_movement.dm b/code/game/atoms_movement.dm index 68db17f076..db9424d983 100644 --- a/code/game/atoms_movement.dm +++ b/code/game/atoms_movement.dm @@ -6,6 +6,7 @@ // To be removed on step_ conversion // All this work to prevent a second bump /atom/movable/Move(atom/newloc, direct=0) + set waitfor = FALSE //n o . = FALSE if(!newloc || newloc == loc) return @@ -52,6 +53,7 @@ //////////////////////////////////////// /atom/movable/Move(atom/newloc, direct) + set waitfor = FALSE //n o var/atom/movable/pullee = pulling var/turf/T = loc if(!moving_from_pull) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index a7ccada9f2..3d7eeb7a8a 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -543,6 +543,8 @@ /datum/game_mode/proc/get_remaining_days(client/C) if(!C) return 0 + if(C.prefs?.db_flags & DB_FLAG_EXEMPT) + return 0 if(!CONFIG_GET(flag/use_age_restriction_for_jobs)) return 0 if(!isnum(C.player_age)) diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm index db145ffacc..b4028dc0fd 100644 --- a/code/game/gamemodes/gangs/dominator.dm +++ b/code/game/gamemodes/gangs/dominator.dm @@ -149,7 +149,7 @@ add_fingerprint(user) return ..() -/obj/machinery/dominator/attack_hand(mob/user) +/obj/machinery/dominator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(operating || (stat & BROKEN)) examine(user) return diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 6312dc08a4..10b92d9655 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -845,6 +845,37 @@ GLOBAL_LIST_EMPTY(possible_items_special) /datum/objective/destroy/internal var/stolen = FALSE //Have we already eliminated this target? +/datum/objective/steal_five_of_type + name = "steal five of" + explanation_text = "Steal at least five items!" + var/list/wanted_items = list(/obj/item) + +/datum/objective/steal_five_of_type/New() + ..() + wanted_items = typecacheof(wanted_items) + +/datum/objective/steal_five_of_type/summon_guns + name = "steal guns" + explanation_text = "Steal at least five guns!" + wanted_items = list(/obj/item/gun) + +/datum/objective/steal_five_of_type/summon_magic + name = "steal magic" + explanation_text = "Steal at least five magical artefacts!" + wanted_items = list(/obj/item/spellbook, /obj/item/gun/magic, /obj/item/clothing/suit/space/hardsuit/wizard, /obj/item/scrying, /obj/item/antag_spawner/contract, /obj/item/necromantic_stone) + +/datum/objective/steal_five_of_type/check_completion() + var/list/datum/mind/owners = get_owners() + var/stolen_count = 0 + for(var/datum/mind/M in owners) + if(!isliving(M.current)) + continue + var/list/all_items = M.current.GetAllContents() //this should get things in cheesewheels, books, etc. + for(var/obj/I in all_items) //Check for wanted items + if(is_type_in_typecache(I, wanted_items)) + stolen_count++ + return stolen_count >= 5 + //Created by admin tools /datum/objective/custom name = "custom" diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 88dc0ebb56..634ed2da48 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -107,7 +107,7 @@ stat |= BROKEN update_icon() -/obj/machinery/pdapainter/attack_hand(mob/user) +/obj/machinery/pdapainter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 557adf488b..31fdf675ca 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -122,7 +122,7 @@ else icon_state = "airlock_sensor_off" -/obj/machinery/airlock_sensor/attack_hand(mob/user) +/obj/machinery/airlock_sensor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -161,4 +161,4 @@ /obj/machinery/airlock_sensor/Destroy() SSradio.remove_object(src,frequency) - return ..() \ No newline at end of file + return ..() diff --git a/code/game/machinery/aug_manipulator.dm b/code/game/machinery/aug_manipulator.dm index b95e3149ea..d13c167a22 100644 --- a/code/game/machinery/aug_manipulator.dm +++ b/code/game/machinery/aug_manipulator.dm @@ -100,7 +100,7 @@ stat |= BROKEN update_icon() -/obj/machinery/aug_manipulator/attack_hand(mob/user) +/obj/machinery/aug_manipulator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 83b0c0ee2d..01f73a3c75 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -79,7 +79,7 @@ charging = null update_icon() -/obj/machinery/cell_charger/attack_hand(mob/user) +/obj/machinery/cell_charger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -103,8 +103,18 @@ removecell() /obj/machinery/cell_charger/attack_ai(mob/user) + if(!charging) + return + + charging.forceMove(loc) + to_chat(user, "You remotely disconnect the battery port and eject [charging] from [src].") + + removecell() return +/obj/machinery/cell_charger/attack_robot(mob/user) + attack_ai(user) + /obj/machinery/cell_charger/emp_act(severity) . = ..() diff --git a/code/game/machinery/computer/arcade/misc_arcade.dm b/code/game/machinery/computer/arcade/misc_arcade.dm index 78b4a6863c..9b7d3d3f6f 100644 --- a/code/game/machinery/computer/arcade/misc_arcade.dm +++ b/code/game/machinery/computer/arcade/misc_arcade.dm @@ -8,7 +8,7 @@ icon_state = "arcade" circuit = /obj/item/circuitboard/computer/arcade/amputation -/obj/machinery/computer/arcade/amputation/attack_hand(mob/user) +/obj/machinery/computer/arcade/amputation/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!iscarbon(user)) return var/mob/living/carbon/c_user = user @@ -28,4 +28,4 @@ for(var/i=1; i<=rand(3,5); i++) prizevend(user) else - to_chat(c_user, "You (wisely) decide against putting your hand in the machine.") \ No newline at end of file + to_chat(c_user, "You (wisely) decide against putting your hand in the machine.") diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 797a32c2db..9f1390c69b 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -103,7 +103,7 @@ return FALSE return ..() -/obj/machinery/computer/camera_advanced/attack_hand(mob/user) +/obj/machinery/computer/camera_advanced/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 25f4237439..5c280eeace 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -662,7 +662,7 @@ What a mess.*/ GLOB.data_core.removeMajorCrime(active1.fields["id"], href_list["cdataid"]) if("notes") if(istype(active2, /datum/data/record)) - var/t1 = stripped_input(usr, "Please summarize notes:", "Secure. records", active2.fields["notes"], null) + var/t1 = stripped_multiline_input(usr, "Please summarize notes:", "Secure records", active2.fields["notes"], 8192) if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) return active2.fields["notes"] = t1 diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm index 5c13bfdf5d..f91fd66fb5 100644 --- a/code/game/machinery/defibrillator_mount.dm +++ b/code/game/machinery/defibrillator_mount.dm @@ -59,7 +59,7 @@ return defib.get_cell() //defib interaction -/obj/machinery/defibrillator_mount/attack_hand(mob/living/user) +/obj/machinery/defibrillator_mount/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!defib) to_chat(user, "There's no defibrillator unit loaded!") return diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm index 31e6a3cfeb..5bf16d4638 100644 --- a/code/game/machinery/dish_drive.dm +++ b/code/game/machinery/dish_drive.dm @@ -31,7 +31,7 @@ if(user.Adjacent(src)) . += "Alt-click it to beam its contents to any nearby disposal bins." -/obj/machinery/dish_drive/attack_hand(mob/living/user) +/obj/machinery/dish_drive/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!contents.len) to_chat(user, "There's nothing in [src]!") return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 83f370802d..a950cb7e7d 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -763,7 +763,7 @@ /obj/machinery/door/airlock/attack_paw(mob/user) return attack_hand(user) -/obj/machinery/door/airlock/attack_hand(mob/user) +/obj/machinery/door/airlock/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index b73e6a57ff..fd1a8690df 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -140,7 +140,7 @@ do_animate("deny") return -/obj/machinery/door/attack_hand(mob/user) +/obj/machinery/door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -343,6 +343,10 @@ /obj/machinery/door/proc/crush() for(var/mob/living/L in get_turf(src)) 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) + 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. L.emote("roar") diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index e359c6331f..4855280b86 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -88,7 +88,7 @@ else stat |= NOPOWER -/obj/machinery/door/firedoor/attack_hand(mob/user) +/obj/machinery/door/firedoor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 0b23e650d7..4c68d0b0b5 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -141,7 +141,7 @@ if(user) log_game("[user] reset a fire alarm at [COORD(src)]") -/obj/machinery/firealarm/attack_hand(mob/user) +/obj/machinery/firealarm/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(buildstage != 2) return ..() add_fingerprint(user) diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 141f261688..8cb7ca1e8d 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -50,7 +50,7 @@ harvesting = FALSE warming_up = FALSE -/obj/machinery/harvester/attack_hand(mob/user) +/obj/machinery/harvester/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(state_open) close_machine() else if(!harvesting) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 621e486e90..f43114f7cb 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(network_holopads) new_disk.forceMove(src) disk = new_disk -/obj/machinery/holopad/tutorial/attack_hand(mob/user) +/obj/machinery/holopad/tutorial/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!istype(user)) return if(user.incapacitated() || !is_operational()) diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 6d49ba88e7..7cf21ed767 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -26,7 +26,7 @@ on = TRUE icon_state = "igniter1" -/obj/machinery/igniter/attack_hand(mob/user) +/obj/machinery/igniter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index cd9e9dc83f..7bb08fdbc1 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -158,12 +158,10 @@ attached.transfer_blood_to(beaker, amount) update_icon() -/obj/machinery/iv_drip/attack_hand(mob/user) +/obj/machinery/iv_drip/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return - if(!ishuman(user)) - return if(attached) visible_message("[attached] is detached from [src]") attached = null @@ -174,7 +172,11 @@ else toggle_mode() -/obj/machinery/iv_drip/verb/eject_beaker() +/obj/machinery/iv_drip/attack_robot(mob/user) + if(Adjacent(user)) + attack_hand(user) + +/obj/machinery/iv_drip/verb/eject_beaker(mob/user) set category = "Object" set name = "Remove IV Container" set src in view(1) @@ -189,6 +191,8 @@ if(usr && Adjacent(usr) && usr.can_hold_items()) if(!usr.put_in_hands(beaker)) beaker.forceMove(drop_location()) + if(iscyborg(user)) + beaker.forceMove(drop_location()) beaker = null update_icon() diff --git a/code/game/machinery/porta_turret/portable_turret_construct.dm b/code/game/machinery/porta_turret/portable_turret_construct.dm index 9d86e3792d..bf70ee8a9d 100644 --- a/code/game/machinery/porta_turret/portable_turret_construct.dm +++ b/code/game/machinery/porta_turret/portable_turret_construct.dm @@ -168,7 +168,7 @@ return ..() -/obj/machinery/porta_turret_construct/attack_hand(mob/user) +/obj/machinery/porta_turret_construct/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm index 7fdb9b38be..3899f07685 100644 --- a/code/game/machinery/porta_turret/portable_turret_cover.dm +++ b/code/game/machinery/porta_turret/portable_turret_cover.dm @@ -31,7 +31,7 @@ return parent_turret.attack_ai(user) -/obj/machinery/porta_turret_cover/attack_hand(mob/user) +/obj/machinery/porta_turret_cover/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 426c818ccb..5d0d39e3a4 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -108,7 +108,7 @@ return ..() -/obj/machinery/recharger/attack_hand(mob/user) +/obj/machinery/recharger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index e300afe6b9..8b9aa64c58 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -68,7 +68,7 @@ GLOBAL_VAR_INIT(singularity_counter, 0) /obj/machinery/power/singularity_beacon/attack_ai(mob/user) return -/obj/machinery/power/singularity_beacon/attack_hand(mob/user) +/obj/machinery/power/singularity_beacon/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/machinery/turnstile.dm b/code/game/machinery/turnstile.dm index 9bc5193bbb..f30ef22dd7 100644 --- a/code/game/machinery/turnstile.dm +++ b/code/game/machinery/turnstile.dm @@ -18,9 +18,6 @@ /obj/machinery/turnstile/CanAtmosPass(turf/T) return TRUE -/obj/machinery/turnstile/bullet_act(obj/item/projectile/P, def_zone) - return BULLET_ACT_FORCE_PIERCE //Pass through! - /obj/machinery/turnstile/proc/allowed_access(var/mob/B) if(B.pulledby && ismob(B.pulledby)) return allowed(B.pulledby) | allowed(B) @@ -28,6 +25,8 @@ return allowed(B) /obj/machinery/turnstile/CanPass(atom/movable/AM, turf/T) + if(istype(AM, /obj/item/projectile)) + return TRUE if(ismob(AM)) var/mob/B = AM if(isliving(AM)) @@ -60,6 +59,8 @@ return FALSE /obj/machinery/turnstile/CheckExit(atom/movable/AM as mob|obj, target) + if(istype(AM, /obj/item/projectile)) + return TRUE if(isliving(AM)) var/mob/living/M = AM var/outdir = dir @@ -81,4 +82,4 @@ M.last_bumped = world.time return canexit else - return TRUE \ No newline at end of file + return TRUE diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 26220d4d89..9e277b9d8e 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -297,7 +297,7 @@ GLOBAL_LIST_INIT(dye_registry, list( else return ..() -/obj/machinery/washing_machine/attack_hand(mob/user) +/obj/machinery/washing_machine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index 395ac810f4..dedbef1906 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -54,7 +54,7 @@ . *= booster_damage_modifier -/obj/mecha/attack_hand(mob/living/user) +/obj/mecha/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index bacb8c6669..eabbdfad88 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -9,7 +9,7 @@ var/buckle_prevents_pull = FALSE //Interaction -/atom/movable/attack_hand(mob/living/user) +/atom/movable/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm index faab0df6e9..e4f1c854d0 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -101,7 +101,7 @@ to_chat(user, "You carefully remove the poster from the wall.") roll_and_drop(user.loc) -/obj/structure/sign/poster/attack_hand(mob/user) +/obj/structure/sign/poster/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 2e45bbfca5..01f0b6f957 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -137,7 +137,7 @@ random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4") beauty = -150 -/obj/effect/decal/cleanable/vomit/attack_hand(mob/user) +/obj/effect/decal/cleanable/vomit/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 23c5822727..0cf95ea263 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -284,7 +284,7 @@ /obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) -/obj/structure/foamedmetal/attack_hand(mob/user) +/obj/structure/foamedmetal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index 504b931685..e363529c46 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -60,7 +60,7 @@ /obj/effect/portal/attack_tk(mob/user) return -/obj/effect/portal/attack_hand(mob/user) +/obj/effect/portal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 44164ed86c..8944b55cc4 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -466,7 +466,7 @@ /obj/effect/spawner/lootdrop/cigars_cases/no_turf = 2, /obj/effect/spawner/lootdrop/space_cash/no_turf = 5, /obj/item/reagent_containers/food/snacks/grown/cannabis = 5, - /obj/item/storage/pill_bottle/dice = 5, + /obj/item/storage/box/dice = 5, /obj/item/toy/cards/deck = 5, /obj/effect/spawner/lootdrop/druggie_pill/no_turf = 5 ) @@ -485,7 +485,7 @@ /obj/effect/spawner/lootdrop/cig_packs/no_turf = 10, /obj/effect/spawner/lootdrop/cigars_cases/no_turf = 5, /obj/item/reagent_containers/food/snacks/grown/cannabis = 5, - /obj/item/storage/pill_bottle/dice = 5, + /obj/item/storage/box/dice = 5, /obj/item/toy/cards/deck = 5, /obj/effect/spawner/lootdrop/druggie_pill/no_turf = 5, /obj/item/kitchen/knife = 5, diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 14b3c4e73e..745b281d2a 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -69,6 +69,7 @@ if(prob(50)) to_chat(mover, "You get stuck in \the [src] for a moment.") return FALSE + return TRUE else if(istype(mover, /obj/item/projectile)) return prob(30) @@ -152,7 +153,7 @@ else ..() -/obj/structure/spider/spiderling/attack_hand(mob/user) +/obj/structure/spider/spiderling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(user.a_intent != INTENT_HELP) user.changeNext_move(CLICK_CD_MELEE) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 90e232938c..a3bbf95413 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -313,7 +313,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb add_fingerprint(usr) return ..() -/obj/item/attack_hand(mob/user) +/obj/item/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -1113,4 +1113,4 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb jostle_pain_mult = (!isnull(embedding["jostle_pain_mult"]) ? embedding["jostle_pain_mult"] : EMBEDDED_JOSTLE_PAIN_MULTIPLIER),\ pain_stam_pct = (!isnull(embedding["pain_stam_pct"]) ? embedding["pain_stam_pct"] : EMBEDDED_PAIN_STAM_PCT),\ embed_chance_turf_mod = (!isnull(embedding["embed_chance_turf_mod"]) ? embedding["embed_chance_turf_mod"] : EMBED_CHANCE_TURF_MOD)) - return TRUE \ No newline at end of file + return TRUE diff --git a/code/game/objects/items/RSF.dm b/code/game/objects/items/RSF.dm index 01b351edd0..8fd2ed2377 100644 --- a/code/game/objects/items/RSF.dm +++ b/code/game/objects/items/RSF.dm @@ -26,6 +26,7 @@ RSF /obj/item/rsf/cyborg matter = 30 + /obj/item/rsf/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/rcd_ammo)) if((matter + 10) > 30) @@ -64,15 +65,16 @@ RSF return if (!(istype(A, /obj/structure/table) || isfloorturf(A))) return - - if(matter < 1) - to_chat(user, "\The [src] doesn't have enough matter left.") - return if(iscyborg(user)) + matter = 30 //borgs dont actually use the matter so this is mostly just so it doesnt fail the next check incase of shennanigans var/mob/living/silicon/robot/R = user if(!R.cell || R.cell.charge < 200) to_chat(user, "You do not have enough power to use [src].") return + if(matter < 1) + to_chat(user, "\The [src] doesn't have enough matter left.") + return + var/turf/T = get_turf(A) playsound(src.loc, 'sound/machines/click.ogg', 10, 1) @@ -91,7 +93,7 @@ RSF use_matter(50, user) if(4) to_chat(user, "Dispensing Dice Pack...") - new /obj/item/storage/pill_bottle/dice(T) + new /obj/item/storage/box/dice(T) use_matter(200, user) if(5) to_chat(user, "Dispensing Cigarette...") diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index c9a31a48c2..4f3761f899 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -183,7 +183,7 @@ /obj/item/airlock_painter/decal/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "decal_painter", name, 500, 400, master_ui, state) + ui = new(user, src, ui_key, "DecalPainter", name, 500, 400, master_ui, state) ui.open() /obj/item/airlock_painter/decal/ui_data(mob/user) @@ -233,4 +233,4 @@ /obj/item/airlock_painter/decal/debug/Initialize() . = ..() - ink = new /obj/item/toner/extreme(src) \ No newline at end of file + ink = new /obj/item/toner/extreme(src) diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm index 6648db46c4..3d444b7eca 100644 --- a/code/game/objects/items/cardboard_cutouts.dm +++ b/code/game/objects/items/cardboard_cutouts.dm @@ -44,7 +44,7 @@ )) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/cardboard_cutout/attack_hand(mob/living/user) +/obj/item/cardboard_cutout/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.a_intent == INTENT_HELP || pushed_over) return ..() user.visible_message("[user] pushes over [src]!", "You push over [src]!") diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index bcae1d750f..e15dc72838 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -78,7 +78,7 @@ toggle_paddles() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/defibrillator/attack_hand(mob/user) +/obj/item/defibrillator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user) if(slot_flags == ITEM_SLOT_BACK) if(user.get_item_by_slot(SLOT_BACK) == src) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index fdc3aa30af..75024aec26 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -183,9 +183,21 @@ var/T = get_turf(target) if(locate(/mob/living) in T) new /obj/effect/temp_visual/medical_holosign(T,user) //produce a holographic glow - holo_cooldown = world.time + 100 + holo_cooldown = world.time + 10 SECONDS return +// see: [/datum/wound/burn/proc/uv()] +/obj/item/flashlight/pen/paramedic + name = "paramedic penlight" + desc = "A high-powered UV penlight intended to help stave off infection in the field on serious burned patients. Probably really bad to look into." + icon_state = "penlight_surgical" + /// Our current UV cooldown + var/uv_cooldown = 0 + /// How long between UV fryings + var/uv_cooldown_length = 1 MINUTES + /// How much sanitization to apply to the burn wound + var/uv_power = 1 + /obj/effect/temp_visual/medical_holosign name = "medical holosign" desc = "A small holographic glow that indicates a medic is coming to treat a patient." diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm index 5cab9e33de..f5d3014d35 100644 --- a/code/game/objects/items/devices/geiger_counter.dm +++ b/code/game/objects/items/devices/geiger_counter.dm @@ -18,6 +18,7 @@ righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' w_class = WEIGHT_CLASS_SMALL slot_flags = ITEM_SLOT_BELT + rad_flags = RAD_NO_CONTAMINATE custom_materials = list(/datum/material/iron = 150, /datum/material/glass = 150) var/grace = RAD_GRACE_PERIOD diff --git a/code/game/objects/items/devices/polycircuit.dm b/code/game/objects/items/devices/polycircuit.dm index fb15ce45dc..a9f7cd46c8 100644 --- a/code/game/objects/items/devices/polycircuit.dm +++ b/code/game/objects/items/devices/polycircuit.dm @@ -11,7 +11,7 @@ /obj/item/stack/circuit_stack/attack_self(mob/user)// Prevents the crafting menu, and tells you how to use it. to_chat(user, "You can't use [src] by itself, you'll have to try and remove one of these circuits by hand... carefully.") -/obj/item/stack/circuit_stack/attack_hand(mob/user) +/obj/item/stack/circuit_stack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/mob/living/carbon/human/H = user if(!user.get_inactive_held_item() == src) return ..() diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 5802909201..ec59009794 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -97,7 +97,7 @@ GLOBAL_LIST_EMPTY(power_sinks) /obj/item/powersink/attack_ai() return -/obj/item/powersink/attack_hand(mob/user) +/obj/item/powersink/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 47542eb495..cdb8c09527 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -32,7 +32,7 @@ . = ..() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/electropack/attack_hand(mob/user) +/obj/item/electropack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/C = user if(src == C.back) @@ -162,7 +162,7 @@ materials = list(/datum/material/iron = 5000, /datum/material/glass =2000) category = list("hacked", "Misc") -/obj/item/electropack/shockcollar/attack_hand(mob/user) +/obj/item/electropack/shockcollar/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.get_item_by_slot(SLOT_NECK)) to_chat(user, "The collar is fastened tight! You'll need help taking this off!") return diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index f4c317c8ba..ec19c0c05e 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -86,7 +86,7 @@ /obj/item/radio/intercom/attack_ai(mob/user) interact(user) -/obj/item/radio/intercom/attack_hand(mob/user) +/obj/item/radio/intercom/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/items/devices/reverse_bear_trap.dm b/code/game/objects/items/devices/reverse_bear_trap.dm index 20107373d3..46b9547e9d 100644 --- a/code/game/objects/items/devices/reverse_bear_trap.dm +++ b/code/game/objects/items/devices/reverse_bear_trap.dm @@ -45,7 +45,7 @@ to_chat(loc, "*ding*") addtimer(CALLBACK(src, .proc/snap), 2) -/obj/item/reverse_bear_trap/attack_hand(mob/user) +/obj/item/reverse_bear_trap/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/C = user if(C.get_item_by_slot(SLOT_HEAD) == src) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index bc6a721d13..2011943bfb 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -10,6 +10,14 @@ NANITE SCANNER GENETICS SCANNER */ + +// Describes the three modes of scanning available for health analyzers +#define SCANMODE_HEALTH 0 +#define SCANMODE_CHEMICAL 1 +#define SCANMODE_WOUND 2 +#define SCANNER_CONDENSED 0 +#define SCANNER_VERBOSE 1 + /obj/item/t_scanner name = "\improper T-ray scanner" desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." @@ -80,7 +88,7 @@ GENETICS SCANNER throw_range = 7 custom_materials = list(/datum/material/iron=200) var/mode = 1 - var/scanmode = 0 + var/scanmode = SCANMODE_HEALTH var/advanced = FALSE /obj/item/healthanalyzer/suicide_act(mob/living/carbon/user) @@ -88,37 +96,40 @@ GENETICS SCANNER return BRUTELOSS /obj/item/healthanalyzer/attack_self(mob/user) - if(!scanmode) - to_chat(user, "You switch the health analyzer to scan chemical contents.") - scanmode = 1 - else - to_chat(user, "You switch the health analyzer to check physical health.") - scanmode = 0 + scanmode = (scanmode + 1) % 3 + switch(scanmode) + if(SCANMODE_HEALTH) + to_chat(user, "You switch the health analyzer to check physical health.") + if(SCANMODE_CHEMICAL) + to_chat(user, "You switch the health analyzer to scan chemical contents.") + if(SCANMODE_WOUND) + to_chat(user, "You switch the health analyzer to report extra info on wounds.") /obj/item/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user) + flick("[icon_state]-scan", src) //makes it so that it plays the scan animation upon scanning, including clumsy scanning // Clumsiness/brain damage check if ((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50)) - to_chat(user, "You stupidly try to analyze the floor's vitals!") - user.visible_message("[user] has analyzed the floor's vitals!") - var/msg = "*---------*\nAnalyzing results for The floor:\n\tOverall status: Healthy\n" - msg += "Key: Suffocation/Toxin/Burn/Brute\n" - msg += "\tDamage specifics: 0-0-0-0\n" - msg += "Body temperature: ???\n" - msg += "*---------*" - to_chat(user, msg) + user.visible_message("[user] analyzes the floor's vitals!", \ + "You stupidly try to analyze the floor's vitals!") + to_chat(user, "Analyzing results for The floor:\n\tOverall status: Healthy\ + \nKey: Suffocation/Toxin/Burn/Brute\ + \n\tDamage specifics: 0-0-0-0\ + \nBody temperature: ???") return - user.visible_message("[user] has analyzed [M]'s vitals.") + user.visible_message("[user] analyzes [M]'s vitals.", \ + "You analyze [M]'s vitals.") - if(scanmode == 0) + if(scanmode == SCANMODE_HEALTH) healthscan(user, M, mode, advanced) - else if(scanmode == 1) + else if(scanmode == SCANMODE_CHEMICAL) chemscan(user, M) + else + woundscan(user, M, src) add_fingerprint(user) - // Used by the PDA medical scanner too /proc/healthscan(mob/user, mob/living/M, mode = 1, advanced = FALSE) if(isliving(user) && (user.incapacitated() || user.eye_blind)) @@ -402,6 +413,17 @@ GENETICS SCANNER msg += " Intervention recommended.\n" else msg += "\n" + // Wounds + if(iscarbon(M)) + var/mob/living/carbon/C = M + var/list/wounded_parts = C.get_wounded_bodyparts() + for(var/i in wounded_parts) + var/obj/item/bodypart/wounded_part = i + msg += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]" + for(var/k in wounded_part.wounds) + var/datum/wound/W = k + msg += "
Type: [W.name]\nSeverity: [W.severity_text()]\nRecommended Treatment: [W.treat_text]
\n" // less lines than in woundscan() so we don't overload people trying to get basic med info + msg += "
\n" for(var/thing in M.diseases) var/datum/disease/D = thing @@ -414,7 +436,7 @@ GENETICS SCANNER var/blood_typepath = C.get_blood_id() if(blood_typepath) if(ishuman(C)) - if(H.bleed_rate) + if(H.is_bleeding()) msg += "Subject is bleeding!\n" var/blood_percent = round((C.scan_blood_volume() / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100) var/blood_type = C.dna.blood_type @@ -505,6 +527,67 @@ GENETICS SCANNER desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy." advanced = TRUE +/// Displays wounds with extended information on their status vs medscanners +/proc/woundscan(mob/user, mob/living/carbon/patient, obj/item/healthanalyzer/wound/scanner) + if(!istype(patient)) + return + + var/render_list = "" + for(var/i in patient.get_wounded_bodyparts()) + var/obj/item/bodypart/wounded_part = i + render_list += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]" + for(var/k in wounded_part.wounds) + var/datum/wound/W = k + render_list += "
[W.get_scanner_description()]
\n" + render_list += "
" + + if(render_list == "") + if(istype(scanner)) + // Only emit the cheerful scanner message if this scan came from a scanner + playsound(scanner, 'sound/machines/ping.ogg', 50, FALSE) + to_chat(user, "\The [scanner] makes a happy ping and briefly displays a smiley face with several exclamation points! It's really excited to report that [patient] has no wounds!") + else + to_chat(user, "No wounds detected in subject.") + else + to_chat(user, jointext(render_list, "")) + +/obj/item/healthanalyzer/wound + name = "first aid analyzer" + icon_state = "adv_spectrometer" + desc = "A prototype MeLo-Tech medical scanner used to diagnose injuries and recommend treatment for serious wounds, but offers no further insight into the patient's health. You hope the final version is less annoying to read!" + var/next_encouragement + var/greedy + +/obj/item/healthanalyzer/wound/attack_self(mob/user) + if(next_encouragement < world.time) + playsound(src, 'sound/machines/ping.ogg', 50, FALSE) + var/list/encouragements = list("briefly displays a happy face, gazing emptily at you", "briefly displays a spinning cartoon heart", "displays an encouraging message about eating healthy and exercising", \ + "reminds you that everyone is doing their best", "displays a message wishing you well", "displays a sincere thank-you for your interest in first-aid", "formally absolves you of all your sins") + to_chat(user, "\The [src] makes a happy ping and [pick(encouragements)]!") + next_encouragement = world.time + 10 SECONDS + greedy = FALSE + else if(!greedy) + to_chat(user, "\The [src] displays an eerily high-definition frowny face, chastizing you for asking it for too much encouragement.") + greedy = TRUE + else + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + if(isliving(user)) + var/mob/living/L = user + to_chat(L, "\The [src] makes a disappointed buzz and pricks your finger for being greedy. Ow!") + L.adjustBruteLoss(4) + L.dropItemToGround(src) + +/obj/item/healthanalyzer/wound/attack(mob/living/carbon/patient, mob/living/carbon/human/user) + add_fingerprint(user) + user.visible_message("[user] scans [patient] for serious injuries.", "You scan [patient] for serious injuries.") + + if(!istype(patient)) + playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) + to_chat(user, "\The [src] makes a sad buzz and briefly displays a frowny face, indicating it can't scan [patient].") + return + + woundscan(user, patient, src) + /obj/item/analyzer desc = "A hand-held environmental scanner which reports current gas levels. Alt-Click to use the built in barometer function." name = "analyzer" @@ -878,3 +961,9 @@ GENETICS SCANNER return "[HM.name] ([HM.alias])" else return HM.alias + +#undef SCANMODE_HEALTH +#undef SCANMODE_CHEMICAL +#undef SCANMODE_WOUND +#undef SCANNER_CONDENSED +#undef SCANNER_VERBOSE diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 78a1a3bfda..5765ac71f1 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -55,7 +55,7 @@ ..() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/taperecorder/attack_hand(mob/user) +/obj/item/taperecorder/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user) if(mytape) if(!user.is_holding(src)) diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index 4fdb862288..2fe4c67362 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -1,10 +1,10 @@ -/obj/item/storage/pill_bottle/dice +/obj/item/storage/box/dice name = "bag of dice" desc = "Contains all the luck you'll ever need." icon = 'icons/obj/dice.dmi' icon_state = "dicebag" -/obj/item/storage/pill_bottle/dice/Initialize() +/obj/item/storage/box/dice/Initialize() . = ..() var/special_die = pick("1","2","fudge","space","00","8bd20","4dd6","100") if(special_die == "1") @@ -30,7 +30,7 @@ if(special_die == "100") new /obj/item/dice/d100(src) -/obj/item/storage/pill_bottle/dice/suicide_act(mob/user) +/obj/item/storage/box/dice/suicide_act(mob/user) user.visible_message("[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!") return (OXYLOSS) diff --git a/code/game/objects/items/dualsaber.dm b/code/game/objects/items/dualsaber.dm index 8c7049c713..08460993ee 100644 --- a/code/game/objects/items/dualsaber.dm +++ b/code/game/objects/items/dualsaber.dm @@ -23,6 +23,8 @@ max_integrity = 200 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) resistance_flags = FIRE_PROOF + wound_bonus = -110 + bare_wound_bonus = 20 block_parry_data = /datum/block_parry_data/dual_esword var/hacked = FALSE /// Can this reflect all energy projectiles? diff --git a/code/game/objects/items/fireaxe.dm b/code/game/objects/items/fireaxe.dm index 41c1cbe915..7cb22d5eb0 100644 --- a/code/game/objects/items/fireaxe.dm +++ b/code/game/objects/items/fireaxe.dm @@ -17,6 +17,7 @@ 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 var/wielded = FALSE // track wielded status on item /obj/item/fireaxe/Initialize() diff --git a/code/game/objects/items/grenades/flashbang.dm b/code/game/objects/items/grenades/flashbang.dm index f51db9fa4c..bd25169fe4 100644 --- a/code/game/objects/items/grenades/flashbang.dm +++ b/code/game/objects/items/grenades/flashbang.dm @@ -60,6 +60,14 @@ shrapnel_type = /obj/item/projectile/bullet/pellet/stingball/mega shrapnel_radius = 12 +/obj/item/grenade/stingbang/breaker + name = "breakbang" + shrapnel_type = /obj/item/projectile/bullet/pellet/stingball/breaker + +/obj/item/grenade/stingbang/shred + name = "shredbang" + shrapnel_type = /obj/item/projectile/bullet/pellet/stingball/shred + /obj/item/grenade/stingbang/prime(mob/living/lanced_by) if(iscarbon(loc)) var/mob/living/carbon/C = loc diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index c7c9fa37a9..e3388b12eb 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -320,7 +320,7 @@ do_sparks(1, TRUE, src) qdel(src) -/obj/item/restraints/legcuffs/beartrap/energy/attack_hand(mob/user) +/obj/item/restraints/legcuffs/beartrap/energy/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) Crossed(user) //honk . = ..() diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index d6396f9902..691b4c4228 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -225,6 +225,7 @@ throwforce = 10 w_class = WEIGHT_CLASS_TINY obj_flags = UNIQUE_RENAME + wound_bonus = -10 var/chaplain_spawnable = TRUE total_mass = TOTAL_MASS_MEDIEVAL_WEAPON @@ -657,6 +658,8 @@ item_flags = ABSTRACT w_class = WEIGHT_CLASS_HUGE sharpness = IS_SHARP + wound_bonus = -20 + bare_wound_bonus = 25 total_mass = TOTAL_MASS_HAND_REPLACEMENT /obj/item/nullrod/armblade/Initialize() diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 2c00265ce8..8f274c04aa 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -79,6 +79,8 @@ sharpness = IS_SHARP_ACCURATE 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 + bare_wound_bonus = 10 custom_price = PRICE_NORMAL /obj/item/kitchen/knife/Initialize() diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm index 6c01e68a48..0673e1d489 100644 --- a/code/game/objects/items/manuals.dm +++ b/code/game/objects/items/manuals.dm @@ -506,7 +506,9 @@ if(prob(50)) step(W, pick(GLOB.alldirs)) ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC) - H.bleed_rate = 5 + for(var/i in H.bodyparts) + var/obj/item/bodypart/BP = i + BP.generic_bleedstacks += 5 H.gib_animation() sleep(3) H.adjustBruteLoss(1000) //to make the body super-bloody diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index c6aa9f7bf4..ee24579e9a 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -19,6 +19,8 @@ slot_flags = ITEM_SLOT_BELT force = 14 throwforce = 10 + wound_bonus = 15 + bare_wound_bonus = 10 reach = 2 w_class = WEIGHT_CLASS_NORMAL attack_verb = list("flogged", "whipped", "lashed", "disciplined") @@ -268,6 +270,8 @@ var/force_off // Damage when off - not stunning var/weight_class_on // What is the new size class when turned on + wound_bonus = 15 + /obj/item/melee/classic_baton/Initialize() . = ..() @@ -393,6 +397,7 @@ force_off = 0 weight_class_on = WEIGHT_CLASS_BULKY total_mass = TOTAL_MASS_NORMAL_ITEM + bare_wound_bonus = 5 /obj/item/melee/classic_baton/telescopic/suicide_act(mob/user) var/mob/living/carbon/human/H = user @@ -621,7 +626,7 @@ to_chat(user, "[target] doesn't seem to want to get on [src]!") update_icon() -/obj/item/melee/roastingstick/attack_hand(mob/user) +/obj/item/melee/roastingstick/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) ..() if (held_sausage) user.put_in_hands(held_sausage) diff --git a/code/game/objects/items/miscellaneous.dm b/code/game/objects/items/miscellaneous.dm index 7237a1788f..a7f7e3152c 100644 --- a/code/game/objects/items/miscellaneous.dm +++ b/code/game/objects/items/miscellaneous.dm @@ -18,6 +18,8 @@ icon = 'icons/obj/device.dmi' icon_state = "gangtool-blue" item_state = "radio" + var/list/stored_options + var/force_refresh = FALSE //if set to true, the beacon will recalculate its display options whenever opened /obj/item/choice_beacon/attack_self(mob/user) if(canUseBeacon(user)) @@ -34,14 +36,15 @@ return FALSE /obj/item/choice_beacon/proc/generate_options(mob/living/M) - var/list/display_names = generate_display_names() - if(!display_names.len) + if(!stored_options || force_refresh) + stored_options = generate_display_names() + if(!stored_options.len) return - var/choice = input(M,"Which item would you like to order?","Select an Item") as null|anything in display_names + var/choice = input(M,"Which item would you like to order?","Select an Item") as null|anything in stored_options if(!choice || !M.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return - spawn_option(display_names[choice],M) + spawn_option(stored_options[choice],M) qdel(src) /obj/item/choice_beacon/proc/spawn_option(obj/choice,mob/living/M) @@ -153,6 +156,51 @@ new choice(get_turf(M)) to_chat(M, "You hear something crackle from the beacon for a moment before a voice speaks. \"Please stand by for a message from S.E.L.F. Message as follows: Item request received. Your package has been transported, use the autosurgeon supplied to apply the upgrade. Message ends.\"") +/obj/item/choice_beacon/box + name = "choice box (default)" + desc = "Think really hard about what you want, and then rip it open!" + icon = 'icons/obj/storage.dmi' + icon_state = "deliverypackage3" + item_state = "deliverypackage3" + +/obj/item/choice_beacon/box/spawn_option(obj/choice,mob/living/M) + to_chat(M, "The box opens, revealing the [choice]!") + playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1) + M.temporarilyRemoveItemFromInventory(src, TRUE) + M.put_in_hands(new choice) + qdel(src) + +/obj/item/choice_beacon/box/plushie + name = "choice box (plushie)" + desc = "Using the power of quantum entanglement, this box contains every plush, until the moment it is opened!" + icon = 'icons/obj/plushes.dmi' + icon_state = "box" + item_state = "box" + +/obj/item/choice_beacon/box/spawn_option(choice,mob/living/M) + if(ispath(choice, /obj/item/toy/plush)) + ..() //regular plush, spawn it naturally + else + //snowflake plush + var/obj/item/toy/plush/snowflake_plushie = new(get_turf(M)) + snowflake_plushie.set_snowflake_from_config(choice) + M.temporarilyRemoveItemFromInventory(src, TRUE) + M.put_in_hands(new choice) + qdel(src) + +/obj/item/choice_beacon/box/plushie/generate_display_names() + var/list/plushie_list = list() + //plushie set 1: just subtypes of /obj/item/toy/plush + var/list/plushies_set_one = subtypesof(/obj/item/toy/plush) - list(/obj/item/toy/plush/narplush, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random_snowflake, /obj/item/toy/plush/random) //don't allow these special ones (you can still get narplush/hugbox) + for(var/V in plushies_set_one) + var/atom/A = V + plushie_list[initial(A.name)] = A + //plushie set 2: snowflake plushies + var/list/plushies_set_two = CONFIG_GET(keyed_list/snowflake_plushies) + for(var/V in plushies_set_two) + plushie_list[V] = V //easiest way to do this which works with how selecting options works, despite being snowflakey to have the key equal the value + return plushie_list + /obj/item/skub desc = "It's skub." name = "skub" diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index b7e2d22d2f..52f4b3462e 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -98,7 +98,7 @@ target.visible_message("[user]'s powerfist lets out a weak hiss as [user.p_they()] punch[user.p_es()] [target.name]!", \ "[user]'s punch strikes with force!") return - target.apply_damage(totalitemdamage * fisto_setting, BRUTE) + target.apply_damage(totalitemdamage * fisto_setting, BRUTE, wound_bonus = -25*fisto_setting**2) target.visible_message("[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!", \ "You cry out in pain as [user]'s punch flings you backwards!") new /obj/effect/temp_visual/kinetic_blast(target.loc) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 1f69cdae2e..6513b53e1d 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -746,8 +746,8 @@ ***********************************************************************/ /obj/item/weapon/gripper - name = "circuit gripper" - desc = "A simple grasping tool for inserting circuitboards into machinary." + name = "engineering gripper" + desc = "A simple grasping tool for interacting with various engineering related items, such as circuits, gas tanks, conveyer belts and more. Alt click to drop instead of use." icon = 'icons/obj/device.dmi' icon_state = "gripper" @@ -755,18 +755,36 @@ //Has a list of items that it can hold. var/list/can_hold = list( - /obj/item/circuitboard + /obj/item/circuitboard, + /obj/item/light, + /obj/item/electronics, + /obj/item/tank, + /obj/item/conveyor_switch_construct, + /obj/item/stack/conveyor, + /obj/item/wallframe, + /obj/item/vending_refill, + /obj/item/stack/sheet, + /obj/item/stack/tile, + /obj/item/stack/rods, + /obj/item/stock_parts + ) + //Basically a blacklist for any subtypes above we dont want + var/list/cannot_hold = list( + /obj/item/stack/sheet/mineral/plasma, + /obj/item/stack/sheet/plasteel ) var/obj/item/wrapped = null // Item currently being held. -/obj/item/weapon/gripper/attack_self() +//Used to interact with UI's of held items, such as gas tanks and airlock electronics. +/obj/item/weapon/gripper/AltClick(mob/user) if(wrapped) wrapped.forceMove(get_turf(wrapped)) + to_chat(user, "You drop the [wrapped].") wrapped = null return ..() -/obj/item/weapon/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params) +/obj/item/weapon/gripper/pre_attack(var/atom/target, var/mob/living/silicon/robot/user, proximity, params) if(!proximity) return @@ -792,18 +810,21 @@ return else if(istype(target,/obj/item)) - var/obj/item/I = target - var/grab = 0 + for(var/typepath in can_hold) if(istype(I,typepath)) grab = 1 - break + for(var/badpath in cannot_hold) + if(istype(I,badpath)) + if(!user.emagged) + grab = 0 + continue //We can grab the item, finally. if(grab) - to_chat(user, "You collect \the [I].") + to_chat(user, "You collect \the [I].") I.loc = src wrapped = I return @@ -812,18 +833,24 @@ /obj/item/weapon/gripper/mining name = "shelter capsule deployer" - desc = "A simple grasping tool for carrying and deploying shelter capsules." + desc = "A simple grasping tool for carrying and deploying shelter capsules. Alt click to drop instead of use." icon_state = "gripper_mining" can_hold = list( /obj/item/survivalcapsule ) -/obj/item/weapon/gripper/mining/attack_self() - if(wrapped) - wrapped.forceMove(get_turf(wrapped)) - wrapped.attack_self() - wrapped = null - return +/obj/item/weapon/gripper/medical + name = "medical gripper" + desc = "A simple grasping tool for interacting with medical equipment, such as beakers, blood bags, chem bags and more. Alt click to drop instead of use." + icon_state = "gripper_medical" + can_hold = list( + /obj/item/storage/bag/bio, + /obj/item/storage/bag/chemistry, + /obj/item/storage/pill_bottle, + /obj/item/reagent_containers/glass, + /obj/item/reagent_containers/pill, + /obj/item/reagent_containers/blood + ) /obj/item/gun/energy/plasmacutter/cyborg name = "cyborg plasma cutter" @@ -907,6 +934,9 @@ icon_state = "data_1" +/********************************************************************** + Dogborg stuff +***********************************************************************/ ///Mere cosmetic dogborg items, remnants of what were once the most annoying cyborg modules. /obj/item/dogborg_tongue name = "synthetic tongue" diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 154714b13f..992c173d3b 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -446,6 +446,12 @@ obj/item/shield/riot/bullet_proof return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT return ..() +/obj/item/shield/energy/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction) + if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object)) + block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT + return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT + return ..() + /obj/item/shield/energy/attack_self(mob/living/carbon/human/user) if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) to_chat(user, "You beat yourself in the head with [src]!") diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index 2f40604719..7fd37053b1 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -31,7 +31,7 @@ to_chat(user, "You slice off [src]'s uneven chunks of aluminium and scorch marks.") return TRUE -/obj/item/target/attack_hand(mob/user) +/obj/item/target/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/items/shrapnel.dm b/code/game/objects/items/shrapnel.dm index 7108080ecc..b74b0563b7 100644 --- a/code/game/objects/items/shrapnel.dm +++ b/code/game/objects/items/shrapnel.dm @@ -7,11 +7,13 @@ icon_state = "large" w_class = WEIGHT_CLASS_TINY item_flags = DROPDEL + sharpness = TRUE /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 /obj/item/shrapnel/bullet // bullets name = "bullet" @@ -28,7 +30,7 @@ /obj/item/projectile/bullet/shrapnel name = "flying shrapnel shard" - damage = 9 + damage = 8 range = 10 armour_penetration = -30 dismemberment = 5 @@ -36,6 +38,8 @@ ricochet_chance = 40 shrapnel_type = /obj/item/shrapnel ricochet_incidence_leeway = 60 + sharpness = TRUE + wound_bonus = 30 /obj/item/projectile/bullet/shrapnel/mega name = "flying shrapnel hunk" @@ -62,3 +66,15 @@ name = "megastingball pellet" ricochets_max = 6 ricochet_chance = 110 + +/obj/item/projectile/bullet/pellet/stingball/breaker + name = "breakbang pellet" + damage = 10 + wound_bonus = 40 + sharpness = FALSE + +/obj/item/projectile/bullet/pellet/stingball/shred + name = "shredbang pellet" + damage = 10 + wound_bonus = 30 + sharpness = TRUE diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index 376362d7c3..41cb68559b 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -22,6 +22,8 @@ var/war_cry = "AAAAARGH!!!" var/icon_prefix = "spearglass" var/wielded = FALSE // track wielded status on item + wound_bonus = -25 + bare_wound_bonus = 15 /obj/item/spear/Initialize() . = ..() diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 00e48fd12a..c142db6530 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -75,7 +75,7 @@ to_chat(user, "You cannot crush the polycrystal in-hand, try breaking one off.") //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/stack/sheet/bluespace_crystal/attack_hand(mob/user) +/obj/item/stack/sheet/bluespace_crystal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.get_inactive_held_item() == src) if(zero_amount()) return diff --git a/code/game/objects/items/stacks/cash.dm b/code/game/objects/items/stacks/cash.dm index ce0bc6591a..954950f5e6 100644 --- a/code/game/objects/items/stacks/cash.dm +++ b/code/game/objects/items/stacks/cash.dm @@ -11,6 +11,7 @@ w_class = WEIGHT_CLASS_TINY full_w_class = WEIGHT_CLASS_TINY resistance_flags = FLAMMABLE + grind_results = list(/datum/reagent/cellulose = 10) var/value = 0 /obj/item/stack/spacecash/Initialize() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index e6403e83cc..b358608ee4 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -15,6 +15,16 @@ var/self_delay = 50 var/other_delay = 0 var/repeating = FALSE + /// How much brute we heal per application + var/heal_brute + /// How much burn we heal per application + var/heal_burn + /// How much we reduce bleeding per application on cut wounds + var/stop_bleeding + /// How much sanitization to apply to burns on application + var/sanitization + /// How much we add to flesh_healing for burn wounds on application + var/flesh_regeneration /obj/item/stack/medical/attack(mob/living/M, mob/user) . = ..() @@ -70,8 +80,9 @@ icon_state = "brutepack" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - var/heal_brute = 20 - self_delay = 20 + heal_brute = 40 + self_delay = 40 + other_delay = 20 grind_results = list(/datum/reagent/medicine/styptic_powder = 10) /obj/item/stack/medical/bruise_pack/one @@ -95,7 +106,8 @@ M.heal_bodypart_damage((heal_brute/2)) return TRUE if(iscarbon(M)) - return heal_carbon(M, user, heal_brute, 0) + return heal_carbon(M, user, heal_brute, heal_burn) + to_chat(user, "You can't heal [M] with \the [src]!") to_chat(user, "You can't heal [M] with the \the [src]!") /obj/item/stack/medical/bruise_pack/suicide_act(mob/user) @@ -104,24 +116,27 @@ /obj/item/stack/medical/gauze name = "medical gauze" - desc = "A roll of elastic cloth that is extremely effective at stopping bleeding, heals minor wounds." + desc = "A roll of elastic cloth, perfect for stabilizing all kinds of wounds, from cuts and burns, to broken bones. " gender = PLURAL singular_name = "medical gauze" icon_state = "gauze" - var/stop_bleeding = 1800 - var/heal_brute = 5 - self_delay = 10 + heal_brute = 5 + self_delay = 50 + other_delay = 20 + amount = 6 + absorption_rate = 0.25 + absorption_capacity = 5 + splint_factor = 0.35 custom_price = PRICE_REALLY_CHEAP -/obj/item/stack/medical/gauze/heal(mob/living/M, mob/user) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!H.bleedsuppress && H.bleed_rate) //so you can't stack bleed suppression - H.suppress_bloodloss(stop_bleeding) - to_chat(user, "You stop the bleeding of [M]!") - H.adjustBruteLoss(-(heal_brute)) - return TRUE - to_chat(user, "You can not use \the [src] on [M]!") +// 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]") /obj/item/stack/medical/gauze/attackby(obj/item/I, mob/user, params) if(I.tool_behaviour == TOOL_WIRECUTTER || I.get_sharpness()) @@ -143,9 +158,12 @@ /obj/item/stack/medical/gauze/improvised name = "improvised gauze" singular_name = "improvised gauze" - desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds." - stop_bleeding = 900 heal_brute = 0 + desc = "A roll of cloth roughly cut from something that does a decent job of stabilizing wounds, but less efficiently so than real medical gauze." + self_delay = 60 + other_delay = 30 + absorption_rate = 0.15 + absorption_capacity = 4 /obj/item/stack/medical/gauze/adv name = "sterilized medical gauze" @@ -161,49 +179,38 @@ is_cyborg = 1 cost = 250 -/obj/item/stack/medical/ointment - name = "ointment" - desc = "Used to treat those nasty burn wounds." - gender = PLURAL - singular_name = "ointment" - icon_state = "ointment" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - var/heal_burn = 20 - self_delay = 20 - grind_results = list(/datum/reagent/medicine/silver_sulfadiazine = 10) - -/obj/item/stack/medical/ointment/one - amount = 1 - -/obj/item/stack/medical/ointment/heal(mob/living/M, mob/user) - if(M.stat == DEAD) - to_chat(user, " [M] is dead. You can not help [M.p_them()]!") - return - if(iscarbon(M)) - return heal_carbon(M, user, 0, heal_burn) - if(AmBloodsucker(M)) - return - to_chat(user, "You can't heal [M] with the \the [src]!") - -/obj/item/stack/medical/ointment/suicide_act(mob/living/user) - user.visible_message("[user] is squeezing \the [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?") - return TOXLOSS - /obj/item/stack/medical/suture name = "suture" - desc = "Sterile sutures used to seal up cuts and lacerations." + desc = "Basic sterile sutures used to seal up cuts and lacerations and stop bleeding." gender = PLURAL singular_name = "suture" icon_state = "suture" self_delay = 30 other_delay = 10 - amount = 15 - max_amount = 15 + amount = 10 + max_amount = 10 repeating = TRUE - var/heal_brute = 10 + heal_brute = 10 + stop_bleeding = 0.6 grind_results = list(/datum/reagent/medicine/spaceacillin = 2) +/obj/item/stack/medical/suture/emergency + name = "emergency suture" + desc = "A value pack of cheap sutures, not very good at repairing damage, but still decent at stopping bleeding." + heal_brute = 5 + amount = 5 + max_amount = 5 + +/obj/item/stack/medical/suture/one + amount = 1 + +/obj/item/stack/medical/suture/medicated + name = "medicated suture" + icon_state = "suture_purp" + desc = "A suture infused with drugs that speed up wound healing of the treated laceration." + heal_brute = 15 + grind_results = list(/datum/reagent/medicine/polypyr = 2) + /obj/item/stack/medical/suture/one amount = 1 @@ -223,10 +230,39 @@ to_chat(user, "[M] is at full health.") return FALSE user.visible_message("[user] applies \the [src] on [M].", "You apply \the [src] on [M].") - M.heal_bodypart_damage(heal_brute) - return TRUE + return heal_carbon(M, user, heal_brute, heal_burn) - to_chat(user, "You can't heal [M] with the \the [src]!") + to_chat(user, "You can't heal [M] with \the [src]!") + +/obj/item/stack/medical/ointment + name = "ointment" + desc = "Basic burn ointment, rated effective for second degree burns with proper bandaging, though it's still an effective stabilizer for worse burns. Not terribly good at outright healing burns though." + gender = PLURAL + singular_name = "ointment" + icon_state = "ointment" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + amount = 10 + max_amount = 10 + self_delay = 40 + other_delay = 20 + + heal_burn = 5 + flesh_regeneration = 2.5 + sanitization = 0.3 + grind_results = list(/datum/reagent/medicine/kelotane = 10) + +/obj/item/stack/medical/ointment/heal(mob/living/M, mob/user) + if(M.stat == DEAD) + to_chat(user, "[M] is dead! You can not help [M.p_them()].") + return + if(iscarbon(M)) + return heal_carbon(M, user, heal_brute, heal_burn) + to_chat(user, "You can't heal [M] with \the [src]!") + +/obj/item/stack/medical/ointment/suicide_act(mob/living/user) + user.visible_message("[user] is squeezing \the [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?") + return TOXLOSS /obj/item/stack/medical/mesh name = "regenerative mesh" @@ -237,21 +273,41 @@ self_delay = 30 other_delay = 10 amount = 15 + heal_burn = 10 max_amount = 15 repeating = TRUE - var/heal_burn = 10 + sanitization = 0.75 + flesh_regeneration = 3 var/is_open = TRUE ///This var determines if the sterile packaging of the mesh has been opened. grind_results = list(/datum/reagent/medicine/spaceacillin = 2) /obj/item/stack/medical/mesh/one amount = 1 +/obj/item/stack/medical/mesh/advanced + name = "advanced regenerative mesh" + desc = "An advanced mesh made with aloe extracts and sterilizing chemicals, used to treat burns." + gender = PLURAL + singular_name = "advanced regenerative mesh" + icon_state = "aloe_mesh" + heal_burn = 15 + grind_results = list(/datum/reagent/consumable/aloejuice = 1) + +/obj/item/stack/medical/mesh/advanced/one + amount = 1 + /obj/item/stack/medical/mesh/Initialize() . = ..() if(amount == max_amount) //only seal full mesh packs is_open = FALSE update_icon() +/obj/item/stack/medical/mesh/advanced/update_icon_state() + if(!is_open) + icon_state = "aloe_mesh_closed" + else + return ..() + /obj/item/stack/medical/mesh/update_icon_state() if(!is_open) icon_state = "regen_mesh_closed" @@ -264,8 +320,8 @@ to_chat(user, "[M] is dead! You can not help [M.p_them()].") return if(iscarbon(M)) - return heal_carbon(M, user, 0, heal_burn) - to_chat(user, "You can't heal [M] with the \the [src]!") + return heal_carbon(M, user, heal_brute, heal_burn) + to_chat(user, "You can't heal [M] with \the [src]!") /obj/item/stack/medical/mesh/try_heal(mob/living/M, mob/user, silent = FALSE) @@ -280,7 +336,7 @@ return . = ..() -/obj/item/stack/medical/mesh/attack_hand(mob/user) +/obj/item/stack/medical/mesh/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!is_open & user.get_inactive_held_item() == src) to_chat(user, "You need to open [src] first.") return @@ -294,3 +350,83 @@ playsound(src, 'sound/items/poster_ripped.ogg', 20, TRUE) return . = ..() + +/obj/item/stack/medical/bone_gel + name = "bone gel" + singular_name = "bone gel" + desc = "A potent medical gel that, when applied to a damaged bone in a proper surgical setting, triggers an intense melding reaction to repair the wound. Can be directly applied alongside surgical sticky tape to a broken bone in dire circumstances, though this is very harmful to the patient and not recommended." + + icon = 'icons/obj/surgery.dmi' + icon_state = "bone-gel" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + + amount = 4 + self_delay = 20 + grind_results = list(/datum/reagent/medicine/bicaridine = 10) + novariants = TRUE + +/obj/item/stack/medical/bone_gel/attack(mob/living/M, mob/user) + to_chat(user, "Bone gel can only be used on fractured limbs while aggressively holding someone!") + return + +/obj/item/stack/medical/bone_gel/suicide_act(mob/user) + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.visible_message("[C] is squirting all of \the [src] into [C.p_their()] mouth! That's not proper procedure! It looks like [C.p_theyre()] trying to commit suicide!") + if(do_after(C, 2 SECONDS)) + C.emote("scream") + for(var/i in C.bodyparts) + var/obj/item/bodypart/bone = i + var/datum/wound/brute/bone/severe/oof_ouch = new + oof_ouch.apply_wound(bone) + var/datum/wound/brute/bone/critical/oof_OUCH = new + oof_OUCH.apply_wound(bone) + + for(var/i in C.bodyparts) + var/obj/item/bodypart/bone = i + bone.receive_damage(brute=60) + use(1) + return (BRUTELOSS) + else + C.visible_message("[C] screws up like an idiot and still dies anyway!") + return (BRUTELOSS) + +/obj/item/stack/medical/bone_gel/cyborg + custom_materials = null + is_cyborg = 1 + cost = 250 + +/obj/item/stack/medical/aloe + name = "aloe cream" + desc = "A healing paste you can apply on wounds." + + icon_state = "aloe_paste" + self_delay = 20 + other_delay = 10 + novariants = TRUE + amount = 20 + max_amount = 20 + var/heal = 3 + grind_results = list(/datum/reagent/consumable/aloejuice = 1) + +/obj/item/stack/medical/aloe/heal(mob/living/M, mob/user) + . = ..() + if(M.stat == DEAD) + to_chat(user, "[M] is dead! You can not help [M.p_them()].") + return FALSE + if(iscarbon(M)) + return heal_carbon(M, user, heal, heal) + if(isanimal(M)) + var/mob/living/simple_animal/critter = M + if (!(critter.healable)) + to_chat(user, "You cannot use \the [src] on [M]!") + return FALSE + else if (critter.health == critter.maxHealth) + to_chat(user, "[M] is at full health.") + return FALSE + user.visible_message("[user] applies \the [src] on [M].", "You apply \the [src] on [M].") + M.heal_bodypart_damage(heal, heal) + return TRUE + + to_chat(user, "You can't heal [M] with the \the [src]!") diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 1306ad7610..0383c3f1ee 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -288,7 +288,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ merge_type = /obj/item/stack/sheet/mineral/wood novariants = TRUE material_type = /datum/material/wood - grind_results = list(/datum/reagent/carbon = 20) + grind_results = list(/datum/reagent/cellulose = 20) walltype = /turf/closed/wall/mineral/wood /obj/item/stack/sheet/mineral/wood/attackby(obj/item/W, mob/user, params) // NOTE: sheet_types.dm is where the WOOD stack lives. Maybe move this over there. @@ -350,7 +350,7 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/bamboo - grind_results = list(/datum/reagent/carbon = 5) + grind_results = list(/datum/reagent/cellulose = 10) material_type = /datum/material/bamboo /obj/item/stack/sheet/mineral/bamboo/get_main_recipes() diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 16b46567c7..5c88951654 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -25,9 +25,18 @@ var/list/mats_per_unit //list that tells you how much is in a single unit. ///Datum material type that this stack is made of var/material_type + max_integrity = 100 //NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind() var/obj/structure/table/tableVariant // we tables now (stores table variant to be built from this stack) + // The following are all for medical treatment, they're here instead of /stack/medical because sticky tape can be used as a makeshift bandage or splint + /// If set and this used as a splint for a broken bone wound, this is used as a multiplier for applicable slowdowns (lower = better) (also for speeding up burn recoveries) + var/splint_factor + /// How much blood flow this stack can absorb if used as a bandage on a cut wound, note that absorption is how much we lower the flow rate, not the raw amount of blood we suck up + var/absorption_capacity + /// How quickly we lower the blood flow on a cut wound we're bandaging. Expected lifetime of this bandage in ticks is thus absorption_capacity/absorption_rate, or until the cut heals, whichever comes first + var/absorption_rate + /obj/item/stack/on_grind() for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists grind_results[grind_results[i]] *= get_amount() //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size @@ -390,7 +399,7 @@ . = ..() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/stack/attack_hand(mob/user) +/obj/item/stack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.get_inactive_held_item() == src) if(zero_amount()) return diff --git a/code/game/objects/items/stacks/tape.dm b/code/game/objects/items/stacks/tape.dm index d33d106d11..bbfee8dece 100644 --- a/code/game/objects/items/stacks/tape.dm +++ b/code/game/objects/items/stacks/tape.dm @@ -7,10 +7,14 @@ icon = 'icons/obj/tapes.dmi' icon_state = "tape_w" var/prefix = "sticky" + w_class = WEIGHT_CLASS_TINY + full_w_class = WEIGHT_CLASS_TINY item_flags = NOBLUDGEON amount = 5 max_amount = 5 resistance_flags = FLAMMABLE + splint_factor = 0.8 + grind_results = list(/datum/reagent/cellulose = 5) var/list/conferred_embed = EMBED_HARMLESS var/overwrite_existing = FALSE @@ -53,6 +57,7 @@ icon_state = "tape_y" prefix = "super sticky" conferred_embed = EMBED_HARMLESS_SUPERIOR + splint_factor = 0.6 /obj/item/stack/sticky_tape/pointy name = "pointy tape" @@ -68,4 +73,14 @@ desc = "You didn't know tape could look so sinister. Welcome to Space Station 13." icon_state = "tape_spikes" prefix = "super pointy" - conferred_embed = EMBED_POINTY_SUPERIOR \ No newline at end of file + conferred_embed = EMBED_POINTY_SUPERIOR + +/obj/item/stack/sticky_tape/surgical + name = "surgical tape" + singular_name = "surgical tape" + desc = "Made for patching broken bones back together alongside bone gel, not for playing pranks." + //icon_state = "tape_spikes" + prefix = "surgical" + conferred_embed = list("embed_chance" = 30, "pain_mult" = 0, "jostle_pain_mult" = 0, "ignore_throwspeed_threshold" = TRUE) + splint_factor = 0.4 + custom_price = 500 diff --git a/code/game/objects/items/stacks/wrap.dm b/code/game/objects/items/stacks/wrap.dm index 10240e902b..6ae63e640f 100644 --- a/code/game/objects/items/stacks/wrap.dm +++ b/code/game/objects/items/stacks/wrap.dm @@ -35,6 +35,7 @@ amount = 25 max_amount = 25 resistance_flags = FLAMMABLE + grind_results = list(/datum/reagent/cellulose = 5) /obj/item/stack/packageWrap/suicide_act(mob/living/user) user.visible_message("[user] begins wrapping [user.p_them()]self in \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 3d5f0dc924..f15588a7f1 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -369,6 +369,7 @@ new /obj/item/circular_saw(src) new /obj/item/surgicaldrill(src) new /obj/item/cautery(src) + new /obj/item/bonesetter(src) new /obj/item/surgical_drapes(src) new /obj/item/clothing/mask/surgical(src) new /obj/item/reagent_containers/medspray/sterilizine(src) @@ -391,6 +392,7 @@ new /obj/item/circular_saw(src) new /obj/item/surgicaldrill(src) new /obj/item/cautery(src) + new /obj/item/bonesetter(src) new /obj/item/surgical_drapes(src) new /obj/item/clothing/mask/surgical(src) new /obj/item/reagent_containers/medspray/sterilizine(src) @@ -485,6 +487,7 @@ new /obj/item/circular_saw(src) new /obj/item/surgicaldrill(src) new /obj/item/cautery(src) + new /obj/item/bonesetter(src) new /obj/item/surgical_drapes(src) new /obj/item/clothing/suit/straight_jacket(src) new /obj/item/clothing/mask/muzzle(src) @@ -501,8 +504,8 @@ new /obj/item/scalpel/advanced(src) new /obj/item/retractor/advanced(src) new /obj/item/surgicaldrill/advanced(src) + new /obj/item/bonesetter(src) new /obj/item/surgical_drapes(src) - new /obj/item/storage/firstaid/tactical(src) new /obj/item/clothing/suit/straight_jacket(src) new /obj/item/clothing/mask/muzzle(src) new /obj/item/mmi/syndie(src) @@ -648,3 +651,9 @@ obj/item/storage/backpack/duffelbag/syndie/shredderbundle new /obj/item/gun/ballistic/automatic/flechette/shredder(src) new /obj/item/storage/belt/military(src) new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src) + +/obj/item/storage/backpack/snail + name = "snail shell" + desc = "Worn by snails as armor and storage compartment." + icon_state = "snailshell" + item_state = "snailshell" diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 4fa742df46..52e8e9193f 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -162,6 +162,7 @@ /obj/item/surgical_drapes, //for true paramedics /obj/item/scalpel, /obj/item/circular_saw, + /obj/item/bonesetter, /obj/item/surgicaldrill, /obj/item/retractor, /obj/item/cautery, @@ -181,7 +182,8 @@ /obj/item/implant, /obj/item/implanter, /obj/item/pinpointer/crew, - /obj/item/reagent_containers/chem_pack + /obj/item/reagent_containers/chem_pack, + /obj/item/stack/sticky_tape //surgical tape )) /obj/item/storage/belt/medical/surgery_belt_adv @@ -811,4 +813,3 @@ attack_verb = list("bashed", "slashes", "prods", "pokes") fitting_swords = list(/obj/item/melee/rapier) starting_sword = /obj/item/melee/rapier - diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index 927a29407c..28f77b7676 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -398,6 +398,20 @@ STR.max_items = 6 STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/nugget)) +/obj/item/storage/fancy/cracker_pack + name = "cracker pack" + desc = "A pack of delicious crackers. Keep away from parrots!" + icon = 'icons/obj/food/containers.dmi' + icon_state = "crackerbox" + icon_type = "cracker" + spawn_type = /obj/item/reagent_containers/food/snacks/cracker + +/obj/item/storage/fancy/cracker_pack/ComponentInitialize() + . = ..() + var/datum/component/storage/STR = GetComponent(/datum/component/storage) + STR.max_items = 6 + STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/cracker)) + /* * Ring Box */ diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index d7065df0f0..480e1966e9 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -41,9 +41,25 @@ new /obj/item/stack/medical/suture(src) new /obj/item/stack/medical/mesh(src) new /obj/item/stack/medical/mesh(src) - new /obj/item/reagent_containers/hypospray/medipen(src) + new /obj/item/reagent_containers/hypospray/medipen/ekit(src) new /obj/item/healthanalyzer(src) +/obj/item/storage/firstaid/emergency + icon_state = "medbriefcase" + name = "emergency first-aid kit" + desc = "A very simple first aid kit meant to secure and stabilize serious wounds for later treatment." + +/obj/item/storage/firstaid/emergency/PopulateContents() + if(empty) + return + var/static/items_inside = list( + /obj/item/healthanalyzer/wound = 1, + /obj/item/stack/medical/gauze = 1, + /obj/item/stack/medical/suture/emergency = 1, + /obj/item/stack/medical/ointment = 1, + /obj/item/reagent_containers/hypospray/medipen/ekit = 2) + generate_items_inside(items_inside,src) + /obj/item/storage/firstaid/ancient icon_state = "firstaid" desc = "A first aid kit with the ability to heal common types of injuries." @@ -229,6 +245,25 @@ STR.click_gather = TRUE STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice)) +/obj/item/storage/pill_bottle/AltClick(mob/living/carbon/user) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + if(!length(user.get_empty_held_indexes())) + to_chat(user, "Your hands are full!") + return + var/obj/item/reagent_containers/pill/P = locate() in contents + if(P) + SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, P, user) + if(!user.put_in_hands(P)) + P.forceMove(user.drop_location()) // make sure it's not stuck in the user if the put in hands somehow fails + to_chat(user, "[P] drops to the floor!") + else + to_chat(user, "You take \a [P] out of [src].") + else + to_chat(user, "There are no pills left in the bottle.") + return TRUE + + /obj/item/storage/pill_bottle/suicide_act(mob/user) user.visible_message("[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!") return (TOXLOSS) @@ -416,6 +451,7 @@ /obj/item/retractor, /obj/item/cautery, /obj/item/surgical_drapes, + /obj/item/bonesetter, /obj/item/autosurgeon, /obj/item/organ, /obj/item/implant, diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm index 0e9a9fda61..6061feb893 100644 --- a/code/game/objects/items/storage/secure.dm +++ b/code/game/objects/items/storage/secure.dm @@ -205,7 +205,7 @@ new /obj/item/paper(src) new /obj/item/pen(src) -/obj/item/storage/secure/safe/attack_hand(mob/user) +/obj/item/storage/secure/safe/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index fd50bd022f..5e3ff67f4c 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -20,6 +20,7 @@ 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 /obj/item/storage/toolbox/greyscale icon_state = "toolbox_default" diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index b601e4310e..42e25273a2 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -143,7 +143,6 @@ if(prob(50)) step(W, pick(GLOB.alldirs)) ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC) - H.bleed_rate = 5 H.gib_animation() sleep(3) H.adjustBruteLoss(1000) //to make the body super-bloody diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index b1c0d3dfbb..0a7eefb786 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -72,7 +72,7 @@ QDEL_NULL(noz) return ..() -/obj/item/watertank/attack_hand(mob/user) +/obj/item/watertank/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if (user.get_item_by_slot(user.getBackSlot()) == src) toggle_mister(user) else diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index bf1eca01f9..fe2e0df2eb 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -574,7 +574,7 @@ else . = ..() -/obj/item/toy/prize/attack_hand(mob/user) +/obj/item/toy/prize/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -813,7 +813,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE //ATTACK HAND NOT CALLING PARENT -/obj/item/toy/cards/deck/attack_hand(mob/user) +/obj/item/toy/cards/deck/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) draw_card(user) /obj/item/toy/cards/deck/proc/draw_card(mob/user) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 7524bb93e1..56737cd1a9 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -574,6 +574,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' force = 10 + wound_bonus = -10 throwforce = 12 attack_verb = list("beat", "smacked") custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 3.5) @@ -626,7 +627,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 homerun_ready = 0 return else if(!target.anchored) - target.throw_at(throw_target, rand(1,2), 7, user) + var/whack_speed = (prob(60) ? 1 : 4) + target.throw_at(throw_target, rand(1, 2), whack_speed, user) // sorry friends, 7 speed batting caused wounds to absolutely delete whoever you knocked your target into (and said target) /obj/item/melee/baseball_bat/ablative name = "metal baseball bat" @@ -706,6 +708,92 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 item_flags = DROPDEL | ABSTRACT attack_verb = list("bopped") +/obj/item/circlegame/Initialize() + . = ..() + var/mob/living/owner = loc + if(!istype(owner)) + return + RegisterSignal(owner, COMSIG_PARENT_EXAMINE, .proc/ownerExamined) + +/obj/item/circlegame/Destroy() + var/mob/owner = loc + if(istype(owner)) + UnregisterSignal(owner, COMSIG_PARENT_EXAMINE) + return ..() + +/obj/item/circlegame/dropped(mob/user) + UnregisterSignal(user, COMSIG_PARENT_EXAMINE) //loc will have changed by the time this is called, so Destroy() can't catch it + // this is a dropdel item. + return ..() + +/// Stage 1: The mistake is made +/obj/item/circlegame/proc/ownerExamined(mob/living/owner, mob/living/sucker) + if(!istype(sucker) || !in_range(owner, sucker)) + return + addtimer(CALLBACK(src, .proc/waitASecond, owner, sucker), 4) + +/// Stage 2: Fear sets in +/obj/item/circlegame/proc/waitASecond(mob/living/owner, mob/living/sucker) + if(QDELETED(sucker) || QDELETED(src) || QDELETED(owner)) + return + + if(owner == sucker) // big mood + to_chat(owner, "Wait a second... you just looked at your own [src.name]!") + addtimer(CALLBACK(src, .proc/selfGottem, owner), 10) + else + to_chat(sucker, "Wait a second... was that a-") + addtimer(CALLBACK(src, .proc/GOTTEM, owner, sucker), 6) + +/// Stage 3A: We face our own failures +/obj/item/circlegame/proc/selfGottem(mob/living/owner) + if(QDELETED(src) || QDELETED(owner)) + return + + playsound(get_turf(owner), 'sound/effects/hit_punch.ogg', 50, TRUE, -1) + owner.visible_message("[owner] shamefully bops [owner.p_them()]self with [owner.p_their()] [src.name].", "You shamefully bop yourself with your [src.name].", \ + "You hear a dull thud!") + log_combat(owner, owner, "bopped", src.name, "(self)") + owner.do_attack_animation(owner) + owner.apply_damage(100, STAMINA) + owner.Knockdown(10) + qdel(src) + +/// Stage 3B: We face our reckoning (unless we moved away or they're incapacitated) +/obj/item/circlegame/proc/GOTTEM(mob/living/owner, mob/living/sucker) + if(QDELETED(sucker)) + return + + if(QDELETED(src) || QDELETED(owner)) + to_chat(sucker, "Nevermind... must've been your imagination...") + return + + if(!in_range(owner, sucker) || !(owner.mobility_flags & MOBILITY_USE)) + to_chat(sucker, "Phew... you moved away before [owner] noticed you saw [owner.p_their()] [src.name]...") + return + + to_chat(owner, "[sucker] looks down at your [src.name] before trying to avert [sucker.p_their()] eyes, but it's too late!") + to_chat(sucker, "[owner] sees the fear in your eyes as you try to look away from [owner.p_their()] [src.name]!") + + playsound(get_turf(owner), 'sound/effects/hit_punch.ogg', 50, TRUE, -1) + owner.do_attack_animation(sucker) + + if(HAS_TRAIT(owner, TRAIT_HULK)) + owner.visible_message("[owner] bops [sucker] with [owner.p_their()] [src.name] much harder than intended, sending [sucker.p_them()] flying!", \ + "You bop [sucker] with your [src.name] much harder than intended, sending [sucker.p_them()] flying!", "You hear a sickening sound of flesh hitting flesh!", ignored_mobs=list(sucker)) + to_chat(sucker, "[owner] bops you incredibly hard with [owner.p_their()] [src.name], sending you flying!") + sucker.apply_damage(50, STAMINA) + sucker.Knockdown(50) + log_combat(owner, sucker, "bopped", src.name, "(setup- Hulk)") + var/atom/throw_target = get_edge_target_turf(sucker, owner.dir) + sucker.throw_at(throw_target, 6, 3, owner) + else + owner.visible_message("[owner] bops [sucker] with [owner.p_their()] [src.name]!", "You bop [sucker] with your [src.name]!", \ + "You hear a dull thud!", ignored_mobs=list(sucker)) + sucker.apply_damage(15, STAMINA) + log_combat(owner, sucker, "bopped", src.name, "(setup)") + to_chat(sucker, "[owner] bops you with [owner.p_their()] [src.name]!") + qdel(src) + /obj/item/slapper name = "slapper" desc = "This is how real men fight." diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index fb3b1535ed..79dd13b0ae 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -10,6 +10,11 @@ var/damtype = BRUTE var/force = 0 + /// How good a given object is at causing wounds on carbons. Higher values equal better shots at creating serious wounds. + var/wound_bonus = 0 + /// If this attacks a human with no wound armor on the affected body part, add this to the wound mod. Some attacks may be significantly worse at wounding if there's even a slight layer of armor to absorb some of it vs bare flesh + var/bare_wound_bonus = 0 + var/datum/armor/armor var/obj_integrity //defaults to max_integrity var/max_integrity = 500 diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index d30f617919..cce4955210 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -28,7 +28,7 @@ queue_smooth_neighbors(src) return ..() -/obj/structure/attack_hand(mob/user) +/obj/structure/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index a793459c5d..a6cd8df746 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -249,7 +249,7 @@ /obj/structure/alien/egg/attack_alien(mob/living/carbon/alien/user) return attack_hand(user) -/obj/structure/alien/egg/attack_hand(mob/living/user) +/obj/structure/alien/egg/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 821409c26b..7ea678cae4 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -52,7 +52,7 @@ /obj/structure/sign/barsign/attack_ai(mob/user) return attack_hand(user) -/obj/structure/sign/barsign/attack_hand(mob/user) +/obj/structure/sign/barsign/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index a4ee2f16e2..e45ddf650c 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -311,7 +311,7 @@ LINEN BINS /obj/structure/bedsheetbin/attack_paw(mob/user) return attack_hand(user) -/obj/structure/bedsheetbin/attack_hand(mob/user) +/obj/structure/bedsheetbin/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 5da04a6686..4b9251d8ec 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -458,7 +458,7 @@ return container_resist(user) -/obj/structure/closet/attack_hand(mob/user) +/obj/structure/closet/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/crates_lockers/closets/genpop.dm b/code/game/objects/structures/crates_lockers/closets/genpop.dm index 2b263bb1ed..04c2f37b0f 100644 --- a/code/game/objects/structures/crates_lockers/closets/genpop.dm +++ b/code/game/objects/structures/crates_lockers/closets/genpop.dm @@ -91,7 +91,7 @@ locked = TRUE return ..() -/obj/structure/closet/secure_closet/genpop/attack_hand(mob/user) +/obj/structure/closet/secure_closet/genpop/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.lying && get_dist(src, user) > 0) return @@ -114,4 +114,4 @@ return - ..() \ No newline at end of file + ..() diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 2c977a34d6..99bce305f8 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -41,7 +41,7 @@ if(manifest) . += "manifest" -/obj/structure/closet/crate/attack_hand(mob/user) +/obj/structure/closet/crate/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/crates_lockers/crates/large.dm b/code/game/objects/structures/crates_lockers/crates/large.dm index 880460a23c..d8c2f7f91c 100644 --- a/code/game/objects/structures/crates_lockers/crates/large.dm +++ b/code/game/objects/structures/crates_lockers/crates/large.dm @@ -8,7 +8,7 @@ delivery_icon = "deliverybox" integrity_failure = 0 //Makes the crate break when integrity reaches 0, instead of opening and becoming an invisible sprite. -/obj/structure/closet/crate/large/attack_hand(mob/user) +/obj/structure/closet/crate/large/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) if(manifest) tear_manifest(user) @@ -40,4 +40,4 @@ else to_chat(user, "You need a crowbar to pry this open!") return FALSE //Just stop. Do nothing. Don't turn into an invisible sprite. Don't open like a locker. - //The large crate has no non-attack interactions other than the crowbar, anyway. \ No newline at end of file + //The large crate has no non-attack interactions other than the crowbar, anyway. diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index c332a07edf..4db889b392 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -157,7 +157,7 @@ /obj/structure/displaycase/attack_paw(mob/user) return attack_hand(user) -/obj/structure/displaycase/attack_hand(mob/user) +/obj/structure/displaycase/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/divine.dm b/code/game/objects/structures/divine.dm index bca96e67d1..5afe97f669 100644 --- a/code/game/objects/structures/divine.dm +++ b/code/game/objects/structures/divine.dm @@ -7,7 +7,7 @@ density = FALSE can_buckle = 1 -/obj/structure/sacrificealtar/attack_hand(mob/living/user) +/obj/structure/sacrificealtar/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -30,7 +30,7 @@ var/time_between_uses = 1800 var/last_process = 0 -/obj/structure/healingfountain/attack_hand(mob/living/user) +/obj/structure/healingfountain/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -48,4 +48,4 @@ if(last_process + time_between_uses > world.time) icon_state = "fountain" else - icon_state = "fountain-red" \ No newline at end of file + icon_state = "fountain-red" diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 528153324d..9279bf1d73 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -19,7 +19,7 @@ new /obj/item/stack/sheet/mineral/wood(drop_location(), 10) qdel(src) -/obj/structure/dresser/attack_hand(mob/user) +/obj/structure/dresser/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(. || !ishuman(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return @@ -46,7 +46,7 @@ switch(choice) if("Underwear") var/new_undies = input(H, "Select your underwear", "Changing") as null|anything in GLOB.underwear_list - if(H.underwear) + if(new_undies) H.underwear = new_undies H.saved_underwear = new_undies var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[new_undies] diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 3bc84deb4d..a279070e69 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -69,7 +69,7 @@ return ..() -/obj/structure/extinguisher_cabinet/attack_hand(mob/user) +/obj/structure/extinguisher_cabinet/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index 679a755321..eaa6e574cd 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -41,7 +41,7 @@ new /obj/structure/falsewall/brass(loc) qdel(src) -/obj/structure/falsewall/attack_hand(mob/user) +/obj/structure/falsewall/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(opening) return . = ..() @@ -180,7 +180,7 @@ radiate() return ..() -/obj/structure/falsewall/uranium/attack_hand(mob/user) +/obj/structure/falsewall/uranium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) radiate() . = ..() diff --git a/code/game/objects/structures/femur_breaker.dm b/code/game/objects/structures/femur_breaker.dm index 7331285161..1fa21d119e 100644 --- a/code/game/objects/structures/femur_breaker.dm +++ b/code/game/objects/structures/femur_breaker.dm @@ -32,7 +32,7 @@ if (LAZYLEN(buckled_mobs)) . += "Someone appears to be strapped in. You can help them unbuckle, or activate the femur breaker." -/obj/structure/femur_breaker/attack_hand(mob/user) +/obj/structure/femur_breaker/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) // Currently being used diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm index 35891fa607..5803fb1306 100644 --- a/code/game/objects/structures/fence.dm +++ b/code/game/objects/structures/fence.dm @@ -120,7 +120,7 @@ open = TRUE density = TRUE -/obj/structure/fence/door/attack_hand(mob/user) +/obj/structure/fence/door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(can_open(user)) toggle(user) @@ -156,4 +156,4 @@ #undef NO_HOLE #undef MEDIUM_HOLE #undef LARGE_HOLE -#undef MAX_HOLE_SIZE \ No newline at end of file +#undef MAX_HOLE_SIZE diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index bcf1016c1e..de88372b1e 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -105,7 +105,7 @@ fireaxe = null qdel(src) -/obj/structure/fireaxecabinet/attack_hand(mob/user) +/obj/structure/fireaxecabinet/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index ce78b92f38..6d72bb58b2 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -65,7 +65,7 @@ var/gift_type = /obj/item/a_gift/anything var/list/ckeys_that_took = list() -/obj/structure/flora/tree/pine/xmas/presents/attack_hand(mob/living/user) +/obj/structure/flora/tree/pine/xmas/presents/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm index 736e58143e..1dcda6eb50 100644 --- a/code/game/objects/structures/fluff.dm +++ b/code/game/objects/structures/fluff.dm @@ -110,7 +110,7 @@ desc = "Space Jesus is my copilot." icon_state = "driverseat" -/obj/structure/fluff/bus/passable/seat/driver/attack_hand(mob/user) +/obj/structure/fluff/bus/passable/seat/driver/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) playsound(src, 'sound/items/carhorn.ogg', 50, 1) . = ..() diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 4455c8820d..03bcdde57c 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -186,7 +186,7 @@ else new_spawn.mind.assigned_role = "Free Golem" -/obj/effect/mob_spawn/human/golem/attack_hand(mob/user) +/obj/effect/mob_spawn/human/golem/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 20151a0bdb..efd1b486d0 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -99,7 +99,7 @@ ..(user, 1) return TRUE -/obj/structure/grille/attack_hand(mob/living/user) +/obj/structure/grille/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 0a5ba6a68c..acec52a583 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -51,7 +51,7 @@ if (LAZYLEN(buckled_mobs)) . += "Someone appears to be strapped in. You can help them out, or you can harm them by activating the guillotine." -/obj/structure/guillotine/attack_hand(mob/user) +/obj/structure/guillotine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) add_fingerprint(user) // Currently being used by something @@ -108,7 +108,7 @@ if (QDELETED(head)) return - playsound(src, 'sound/weapons/bladeslice.ogg', 100, 1) + playsound(src, 'sound/weapons/guillotine.ogg', 100, TRUE) if (blade_sharpness >= GUILLOTINE_DECAP_MIN_SHARP || head.brute_dam >= 100) head.dismember() log_combat(user, H, "beheaded", src) @@ -256,4 +256,4 @@ #undef GUILLOTINE_ACTIVATE_DELAY #undef GUILLOTINE_WRENCH_DELAY #undef GUILLOTINE_ACTION_INUSE -#undef GUILLOTINE_ACTION_WRENCH \ No newline at end of file +#undef GUILLOTINE_ACTION_WRENCH diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm index ede7e31e0d..1cab600fb1 100644 --- a/code/game/objects/structures/guncase.dm +++ b/code/game/objects/structures/guncase.dm @@ -53,7 +53,7 @@ else return ..() -/obj/structure/guncase/attack_hand(mob/user) +/obj/structure/guncase/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/headpike.dm b/code/game/objects/structures/headpike.dm index 65d930e08b..7a67387a8e 100644 --- a/code/game/objects/structures/headpike.dm +++ b/code/game/objects/structures/headpike.dm @@ -37,7 +37,7 @@ MA.pixel_y = 12 . += H -/obj/structure/headpike/attack_hand(mob/user) +/obj/structure/headpike/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -47,4 +47,4 @@ victim = null spear.forceMove(drop_location()) spear = null - qdel(src) \ No newline at end of file + qdel(src) diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index c49159a992..844c2ff8fd 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -25,7 +25,7 @@ projector = null return ..() -/obj/structure/holosign/attack_hand(mob/living/user) +/obj/structure/holosign/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -162,7 +162,7 @@ return TRUE //nice or benign diseases! return TRUE -/obj/structure/holosign/barrier/medical/attack_hand(mob/living/user) +/obj/structure/holosign/barrier/medical/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(CanPass(user) && user.a_intent == INTENT_HELP) force_allaccess = !force_allaccess to_chat(user, "You [force_allaccess ? "deactivate" : "activate"] the biometric scanners.") //warning spans because you can make the station sick! @@ -182,7 +182,7 @@ /obj/structure/holosign/barrier/cyborg/hacked/proc/cooldown() shockcd = FALSE -/obj/structure/holosign/barrier/cyborg/hacked/attack_hand(mob/living/user) +/obj/structure/holosign/barrier/cyborg/hacked/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index dc4a741b8b..72487ddc16 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -91,7 +91,7 @@ else return ..() -/obj/structure/janitorialcart/attack_hand(mob/user) +/obj/structure/janitorialcart/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 05a7e1c958..5706f79192 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -61,7 +61,7 @@ return TRUE //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/kitchenspike/attack_hand(mob/user) +/obj/structure/kitchenspike/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(VIABLE_MOB_CHECK(user.pulling) && user.a_intent == INTENT_GRAB && !has_buckled_mobs()) var/mob/living/L = user.pulling if(HAS_TRAIT(user, TRAIT_PACIFISM) && L.stat != DEAD) diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index f321498bfd..6037183cc9 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -122,7 +122,7 @@ return FALSE return TRUE -/obj/structure/ladder/attack_hand(mob/user) +/obj/structure/ladder/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/life_candle.dm b/code/game/objects/structures/life_candle.dm index a64dc6c6a9..5dc0bcdab5 100644 --- a/code/game/objects/structures/life_candle.dm +++ b/code/game/objects/structures/life_candle.dm @@ -24,7 +24,7 @@ var/respawn_time = 50 var/respawn_sound = 'sound/magic/staff_animation.ogg' -/obj/structure/life_candle/attack_hand(mob/user) +/obj/structure/life_candle/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -38,7 +38,7 @@ linked_minds |= user.mind update_icon() - float(linked_minds.len) + INVOKE_ASYNC(src, /atom/movable.proc/float, linked_minds.len) if(linked_minds.len) START_PROCESSING(SSobj, src) set_light(lit_luminosity) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index f52fa0576a..cca41b4e11 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -50,7 +50,7 @@ /obj/structure/mineral_door/attack_paw(mob/user) return attack_hand(user) -/obj/structure/mineral_door/attack_hand(mob/user) +/obj/structure/mineral_door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 65e1b7dd9a..b1829054ce 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -15,7 +15,7 @@ if(icon_state == "mirror_broke" && !broken) obj_break(null, mapload) -/obj/structure/mirror/attack_hand(mob/user) +/obj/structure/mirror/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -118,7 +118,7 @@ choosable_races += S.id ..() -/obj/structure/mirror/magic/attack_hand(mob/user) +/obj/structure/mirror/magic/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 19106f5fc4..9639ffae51 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -58,7 +58,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an /obj/structure/bodycontainer/attack_paw(mob/user) return attack_hand(user) -/obj/structure/bodycontainer/attack_hand(mob/user) +/obj/structure/bodycontainer/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -330,7 +330,7 @@ GLOBAL_LIST_EMPTY(crematoriums) /obj/structure/tray/attack_paw(mob/user) return attack_hand(user) -/obj/structure/tray/attack_hand(mob/user) +/obj/structure/tray/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm index 4a9a1bdce6..3a415b84a9 100644 --- a/code/game/objects/structures/spirit_board.dm +++ b/code/game/objects/structures/spirit_board.dm @@ -14,7 +14,7 @@ desc = "[initial(desc)] The planchette is sitting at \"[planchette]\"." return ..() -/obj/structure/spirit_board/attack_hand(mob/user) +/obj/structure/spirit_board/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -76,4 +76,4 @@ to_chat(M, "There aren't enough people to use the [src.name]!") return 0 - return 1 \ No newline at end of file + return 1 diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 466912f93e..1d7ba1d993 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -74,7 +74,7 @@ radiate() ..() -/obj/structure/statue/uranium/attack_hand(mob/user) +/obj/structure/statue/uranium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) radiate() . = ..() @@ -240,7 +240,7 @@ honk() return ..() -/obj/structure/statue/bananium/attack_hand(mob/user) +/obj/structure/statue/bananium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) honk() . = ..() diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 777be608b5..1b7eb25bb8 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -71,7 +71,10 @@ if(user.grab_state < GRAB_AGGRESSIVE) to_chat(user, "You need a better grip to do that!") return - tablepush(user, pushed_mob) + if(user.grab_state >= GRAB_NECK) + tablelimbsmash(user, pushed_mob) + else + tablepush(user, pushed_mob) if(user.a_intent == INTENT_HELP) pushed_mob.visible_message("[user] begins to place [pushed_mob] onto [src]...", \ "[user] begins to place [pushed_mob] onto [src]...") @@ -138,6 +141,22 @@ H.emote("nya") SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table) +/obj/structure/table/proc/tablelimbsmash(mob/living/user, mob/living/pushed_mob) + pushed_mob.Knockdown(30) + var/obj/item/bodypart/banged_limb = pushed_mob.get_bodypart(user.zone_selected) || pushed_mob.get_bodypart(BODY_ZONE_HEAD) + var/extra_wound = 0 + if(HAS_TRAIT(user, TRAIT_HULK)) + extra_wound = 20 + banged_limb.receive_damage(30, wound_bonus = extra_wound) + pushed_mob.apply_damage(60, STAMINA) + take_damage(50) + + playsound(pushed_mob, 'sound/effects/bang.ogg', 90, TRUE) + pushed_mob.visible_message("[user] smashes [pushed_mob]'s [banged_limb.name] against \the [src]!", + "[user] smashes your [banged_limb.name] against \the [src]") + log_combat(user, pushed_mob, "head slammed", null, "against [src]") + SEND_SIGNAL(pushed_mob, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table_limbsmash, banged_limb) + /obj/structure/table/shove_act(mob/living/target, mob/living/user) if(CHECK_MOBILITY(target, MOBILITY_STAND)) target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_TABLE) @@ -553,7 +572,7 @@ change_construction_value(-2) return ..() -/obj/structure/table/reinforced/brass/tablepush(mob/living/user, mob/living/pushed_mob) +/obj/structure/table/reinforced/brass/tablelimbsmash(mob/living/user, mob/living/pushed_mob) .= ..() playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) @@ -577,7 +596,7 @@ buildstack = /obj/item/stack/tile/bronze canSmoothWith = list(/obj/structure/table/reinforced/brass, /obj/structure/table/bronze) -/obj/structure/table/bronze/tablepush(mob/living/user, mob/living/pushed_mob) +/obj/structure/table/bronze/tablelimbsmash(mob/living/user, mob/living/pushed_mob) ..() playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 50, TRUE) @@ -606,7 +625,7 @@ computer.table = src break -/obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob) +/obj/structure/table/optable/tablelimbsmash(mob/living/user, mob/living/pushed_mob) pushed_mob.forceMove(loc) pushed_mob.set_resting(TRUE, TRUE) visible_message("[user] has laid [pushed_mob] on [src].") @@ -676,7 +695,7 @@ /obj/structure/rack/attack_paw(mob/living/user) attack_hand(user) -/obj/structure/rack/attack_hand(mob/living/user) +/obj/structure/rack/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index cf9cf2a830..e2298ac6c5 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -74,6 +74,9 @@ ui = new(user, src, ui_key, "TankDispenser", name, 275, 103, master_ui, state) ui.open() +/obj/structure/tank_dispenser/attack_robot(mob/user) + ui_interact(user) + /obj/structure/tank_dispenser/ui_data(mob/user) var/list/data = list() data["oxygen"] = oxygentanks diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index 9dcfec43bf..a08d5c95c1 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -48,7 +48,7 @@ handle_density() to_chat(user, "You slide the target into the stake.") -/obj/structure/target_stake/attack_hand(mob/user) +/obj/structure/target_stake/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index ba23878168..7f597857d9 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -58,7 +58,7 @@ qdel(R) -/obj/structure/transit_tube/station/attack_hand(mob/user) +/obj/structure/transit_tube/station/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index acb88fbb1d..3dacd49fc9 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -26,7 +26,7 @@ AM.forceMove(loc) return ..() -/obj/structure/toilet/attack_hand(mob/living/user) +/obj/structure/toilet/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -174,7 +174,7 @@ ..() hiddenitem = new /obj/item/reagent_containers/food/urinalcake -/obj/structure/urinal/attack_hand(mob/user) +/obj/structure/urinal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -492,7 +492,7 @@ var/buildstacktype = /obj/item/stack/sheet/metal var/buildstackamount = 1 -/obj/structure/sink/attack_hand(mob/living/user) +/obj/structure/sink/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -784,7 +784,7 @@ return TRUE -/obj/structure/curtain/attack_hand(mob/user) +/obj/structure/curtain/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 17031a51df..38655df39e 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -167,7 +167,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) return 1 . = ..() -/obj/structure/window/attack_hand(mob/user) +/obj/structure/window/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -836,7 +836,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) for (var/i in 1 to rand(1,4)) . += new /obj/item/paper/natural(location) -/obj/structure/window/paperframe/attack_hand(mob/user) +/obj/structure/window/paperframe/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm index f9376c0672..4f7aa9e492 100644 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -52,7 +52,7 @@ set_light(0) return ..() -/turf/open/floor/light/attack_hand(mob/user) +/turf/open/floor/light/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm index f0ac0053ce..9a227d2594 100644 --- a/code/game/turfs/simulated/floor/mineral_floor.dm +++ b/code/game/turfs/simulated/floor/mineral_floor.dm @@ -149,7 +149,7 @@ if(!.) honk() -/turf/open/floor/mineral/bananium/attack_hand(mob/user) +/turf/open/floor/mineral/bananium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) .=..() if(!.) honk() @@ -202,7 +202,7 @@ if(!.) radiate() -/turf/open/floor/mineral/uranium/attack_hand(mob/user) +/turf/open/floor/mineral/uranium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) .=..() if(!.) radiate() diff --git a/code/game/turfs/simulated/floor/reinf_floor.dm b/code/game/turfs/simulated/floor/reinf_floor.dm index 7816341a0a..b050d8fb89 100644 --- a/code/game/turfs/simulated/floor/reinf_floor.dm +++ b/code/game/turfs/simulated/floor/reinf_floor.dm @@ -89,7 +89,7 @@ /turf/open/floor/engine/attack_paw(mob/user) return attack_hand(user) -/turf/open/floor/engine/attack_hand(mob/user) +/turf/open/floor/engine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/turfs/simulated/wall/mineral_walls.dm b/code/game/turfs/simulated/wall/mineral_walls.dm index a5f0d5e824..c8afe628db 100644 --- a/code/game/turfs/simulated/wall/mineral_walls.dm +++ b/code/game/turfs/simulated/wall/mineral_walls.dm @@ -72,7 +72,7 @@ return return -/turf/closed/wall/mineral/uranium/attack_hand(mob/user) +/turf/closed/wall/mineral/uranium/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) radiate() . = ..() diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index b01a1df2c0..df63cf93e6 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -137,7 +137,7 @@ to_chat(user, text("You punch the wall.")) return TRUE -/turf/closed/wall/attack_hand(mob/user) +/turf/closed/wall/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index b131a1ed70..0e028ed4af 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -133,10 +133,13 @@ else to_chat(user, "The plating is going to need some support! Place metal rods first.") -/turf/open/space/Entered(atom/movable/A) - ..() - if ((!(A) || src != A.loc)) - return +/turf/open/space/Entered(atom/movable/A, atom/OldLoc) + . = ..() + + var/turf/old = get_turf(OldLoc) + if(!isspaceturf(old) && ismob(A)) + var/mob/M = A + M.update_gravity(M.mob_has_gravity()) if(destination_z && destination_x && destination_y && !(A.pulledby || !A.can_be_z_moved)) var/tx = destination_x @@ -170,6 +173,12 @@ stoplag()//Let a diagonal move finish, if necessary A.newtonian_move(A.inertia_dir) +/turf/open/space/Exited(atom/movable/AM, atom/OldLoc) + . = ..() + var/turf/old = get_turf(OldLoc) + if(!isspaceturf(old) && ismob(AM)) + var/mob/M = AM + M.update_gravity(M.mob_has_gravity()) /turf/open/space/MakeSlippery(wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent) return diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index b1a10c72ce..02c12a9744 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -122,7 +122,7 @@ requires_activation = FALSE ..() -/turf/attack_hand(mob/user) +/turf/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 042a6e0fe9..1e3d1e93e3 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -863,7 +863,7 @@ if(jobban_isbanned(M, ROLE_TRAITOR) || isbanned_dept) dat += "Traitor" else - dat += "Traitor" + dat += "Traitor" //Changeling if(jobban_isbanned(M, ROLE_CHANGELING) || isbanned_dept) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index 044016698c..b757028ea2 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -666,8 +666,8 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null obj_count_finished = select_refs var/n = 0 for(var/i in found) - if(++n == 20000) - text_list += "
TRUNCATED - 20000 OBJECT LIMIT HIT" + if(++n == 2500) + text_list += "
TRUNCATED - 2500 OBJECT LIMIT HIT" SDQL_print(i, text_list, print_nulls) select_refs[REF(i)] = TRUE SDQL2_TICK_CHECK diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 33992a74bc..c559135bd1 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1269,8 +1269,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(!check_rights(R_ADMIN) || !check_rights(R_FUN)) return - var/list/punishment_list = list( - ADMIN_PUNISHMENT_PIE, + var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_CUSTOM_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, @@ -1282,8 +1281,11 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD, ADMIN_PUNISHMENT_SHOES, - ADMIN_PUNISHMENT_PICKLE - ) + ADMIN_PUNISHMENT_PICKLE, + ADMIN_PUNISHMENT_FRY, + ADMIN_PUNISHMENT_CRACK, + ADMIN_PUNISHMENT_BLEED, + ADMIN_PUNISHMENT_SCARIFY) var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list @@ -1361,8 +1363,37 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(amount) A.reagents.add_reagent(chosen_id, amount) A.splat(target) + if(ADMIN_PUNISHMENT_CRACK) + 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/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)) + 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)) + 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)) + slice_part.force_wound_upwards(type_wound, smited=TRUE) + type_wound = pick(list(/datum/wound/brute/cut/critical, /datum/wound/brute/cut/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...") if(ADMIN_PUNISHMENT_PICKLE) target.turn_into_pickle() + if(ADMIN_PUNISHMENT_FRY) + target.fry() if(ADMIN_PUNISHMENT_SHOES) if(!iscarbon(target)) diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm index b8d5b1bf6d..9c9715ee43 100644 --- a/code/modules/antagonists/abductor/machinery/console.dm +++ b/code/modules/antagonists/abductor/machinery/console.dm @@ -24,7 +24,7 @@ var/obj/machinery/computer/camera_advanced/abductor/camera var/list/datum/icon_snapshot/disguises = list() -/obj/machinery/abductor/console/attack_hand(mob/user) +/obj/machinery/abductor/console/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/abductor/machinery/dispenser.dm b/code/modules/antagonists/abductor/machinery/dispenser.dm index 17fa311c8f..ef423b6379 100644 --- a/code/modules/antagonists/abductor/machinery/dispenser.dm +++ b/code/modules/antagonists/abductor/machinery/dispenser.dm @@ -22,7 +22,7 @@ gland_colors[i] = random_color() amounts[i] = rand(1,5) -/obj/machinery/abductor/gland_dispenser/attack_hand(mob/user) +/obj/machinery/abductor/gland_dispenser/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/abductor/machinery/experiment.dm b/code/modules/antagonists/abductor/machinery/experiment.dm index f92cb987d0..b94912b635 100644 --- a/code/modules/antagonists/abductor/machinery/experiment.dm +++ b/code/modules/antagonists/abductor/machinery/experiment.dm @@ -21,7 +21,7 @@ return close_machine(target) -/obj/machinery/abductor/experiment/attack_hand(mob/user) +/obj/machinery/abductor/experiment/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm b/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm index 97b974e28f..f97e271e72 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm @@ -36,6 +36,6 @@ M.adjust_fire_stacks(round(reac_volume/10)) M.IgniteMob() if(M) - M.apply_damage(0.8*reac_volume, BURN) + M.apply_damage(0.8*reac_volume, BURN, wound_bonus=CANT_WOUND) if(iscarbon(M)) M.emote("scream") diff --git a/code/modules/antagonists/blob/blob/blobstrains/cryogenic_poison.dm b/code/modules/antagonists/blob/blob/blobstrains/cryogenic_poison.dm index 9b8edcd0e5..f8ef269986 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/cryogenic_poison.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/cryogenic_poison.dm @@ -22,7 +22,7 @@ M.reagents.add_reagent("frostoil", 0.3*reac_volume) M.reagents.add_reagent("ice", 0.3*reac_volume) M.reagents.add_reagent("cryogenic_poison", 0.3*reac_volume) - M.apply_damage(0.2*reac_volume, BRUTE) + M.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND) /datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(0.3*REAGENTS_EFFECT_MULTIPLIER, 0) diff --git a/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm b/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm index 0e665603c9..45bf2b1e1d 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm @@ -30,4 +30,4 @@ if(prob(reac_volume*2)) M.emp_act(EMP_LIGHT) if(M) - M.apply_damage(reac_volume, BURN) + M.apply_damage(reac_volume, BURN, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm b/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm index f8fd2e2f0d..3d005ba913 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm @@ -33,8 +33,8 @@ if(ROLE_BLOB in L.faction) //no friendly fire continue var/aoe_volume = ..(L, TOUCH, initial_volume, 0, L.get_permeability_protection(), O) - L.apply_damage(0.4*aoe_volume, BRUTE) + L.apply_damage(0.4*aoe_volume, BRUTE, wound_bonus=CANT_WOUND) if(M) - M.apply_damage(0.6*reac_volume, BRUTE) + M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND) else - M.apply_damage(0.6*reac_volume, BRUTE) + M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blob/blobstrains/networked_fibers.dm b/code/modules/antagonists/blob/blob/blobstrains/networked_fibers.dm index fac3470c7a..8ccf2b9c99 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/networked_fibers.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/networked_fibers.dm @@ -33,6 +33,6 @@ /datum/reagent/blob/networked_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - M.apply_damage(0.6*reac_volume, BRUTE) + M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND) if(M) - M.apply_damage(0.6*reac_volume, BURN) + M.apply_damage(0.6*reac_volume, BURN, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm b/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm index 6a984e66a2..11477712e7 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm @@ -44,7 +44,7 @@ T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS) M.adjust_fire_stacks(-(reac_volume / 10)) M.ExtinguishMob() - M.apply_damage(0.4*reac_volume, BRUTE) + M.apply_damage(0.4*reac_volume, BRUTE, wound_bonus=CANT_WOUND) if(M) M.apply_damage(0.4*reac_volume, OXY) if(M) diff --git a/code/modules/antagonists/blob/blob/blobstrains/replicating_foam.dm b/code/modules/antagonists/blob/blob/blobstrains/replicating_foam.dm index 00743c671e..5565135c63 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/replicating_foam.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/replicating_foam.dm @@ -31,4 +31,4 @@ /datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - M.apply_damage(0.7*reac_volume, BRUTE) + M.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm b/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm index dbb3d6fb9b..9265158e1b 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm @@ -32,4 +32,4 @@ /datum/reagent/blob/shifting_fragments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - M.apply_damage(0.7*reac_volume, BRUTE) + M.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm b/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm index d58fb5b37d..daad0068e2 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm @@ -30,9 +30,9 @@ /datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() - M.apply_damage(0.2*reac_volume, BRUTE) + M.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND) if(M && reac_volume) for(var/obj/structure/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.6*reac_volume if(M) B.blob_attack_animation(M) //show them they're getting a bad time - M.apply_damage(0.3*reac_volume, BRUTE) + M.apply_damage(0.3*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm index e85d3af5a0..a555677719 100644 --- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm +++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm @@ -110,7 +110,7 @@ if (bloodsuckerdatum && bloodsuckerdatum.coffin == src) bloodsuckerdatum.coffin = null bloodsuckerdatum.lair = null - to_chat(resident, "You sense that the link with your coffin, your sacred place of rest, has been brokem! You will need to seek another.") + to_chat(resident, "You sense that the link with your coffin, your sacred place of rest, has been broken! You will need to seek another.") resident = null // Remove resident. Because this object isnt removed from the game immediately (GC?) we need to give them a way to see they don't have a home anymore. /obj/structure/closet/crate/coffin/can_open(mob/living/user) diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm index 090ef45d89..9301d0c239 100644 --- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm +++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm @@ -217,7 +217,7 @@ return FALSE return ..() -/obj/structure/bloodsucker/vassalrack/attack_hand(mob/user) +/obj/structure/bloodsucker/vassalrack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) //. = ..() // Taken from sacrificial altar in divine.dm //if(.) // return @@ -469,7 +469,7 @@ . += {"This is a magical candle which drains at the sanity of the fools who havent yet accepted your master, as long as it is active.\n You can turn it on and off by clicking on it while you are next to it"} */ -/obj/structure/bloodsucker/candelabrum/attack_hand(mob/user) +/obj/structure/bloodsucker/candelabrum/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/datum/antagonist/vassal/T = user.mind.has_antag_datum(ANTAG_DATUM_VASSAL) if(AmBloodsucker(user) || istype(T)) toggle() diff --git a/code/modules/antagonists/bloodsucker/powers/feed.dm b/code/modules/antagonists/bloodsucker/powers/feed.dm index a113f9c083..caca020b32 100644 --- a/code/modules/antagonists/bloodsucker/powers/feed.dm +++ b/code/modules/antagonists/bloodsucker/powers/feed.dm @@ -226,7 +226,9 @@ playsound(get_turf(target), 'sound/effects/splat.ogg', 40, 1) if(ishuman(target)) var/mob/living/carbon/human/H = target - H.bleed_rate += 5 + var/obj/item/bodypart/head_part = H.get_bodypart(BODY_ZONE_HEAD) + if(head_part) + head_part.generic_bleedstacks += 5 target.add_splatter_floor(get_turf(target)) user.add_mob_blood(target) // Put target's blood on us. The donor goes in the ( ) target.add_mob_blood(target) diff --git a/code/modules/antagonists/bloodsucker/powers/recuperate.dm b/code/modules/antagonists/bloodsucker/powers/recuperate.dm index 6b8795ea02..90a2e3ff38 100644 --- a/code/modules/antagonists/bloodsucker/powers/recuperate.dm +++ b/code/modules/antagonists/bloodsucker/powers/recuperate.dm @@ -27,8 +27,9 @@ C.blood_volume -= 0.2 C.adjustStaminaLoss(-15) // Stop Bleeding - if(istype(H) && H.bleed_rate > 0 && rand(20) == 0) - H.bleed_rate -- + if(istype(H) && H.is_bleeding() && rand(20) == 0) + for(var/obj/item/bodypart/part in H.bodyparts) + part.generic_bleedstacks -- C.Jitter(5) sleep(10) // DONE! diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 3267f2bdc1..d06ebe9d9d 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -20,6 +20,8 @@ var/datum/changelingprofile/first_prof = null var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation. var/absorbedcount = 0 + /// did we get succed by another changeling + var/hostile_absorbed = FALSE var/trueabsorbs = 0//dna gained using absorb, not dna sting var/chem_charges = 20 var/chem_storage = 75 diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index 3e2ff6f3dd..208fefee70 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -92,7 +92,7 @@ var/datum/antagonist/changeling/target_ling = target.mind.has_antag_datum(/datum/antagonist/changeling) - if(target_ling)//If the target was a changeling, suck out their extra juice and objective points! + if(target_ling && !target_ling.hostile_absorbed)//If the target was a changeling, suck out their extra juice and objective points! to_chat(user, "[target] was one of us. We have absorbed their power.") target_ling.remove_changeling_powers() changeling.geneticpoints += round(target_ling.geneticpoints/2) @@ -102,6 +102,7 @@ changeling.chem_storage += round(target_ling.chem_storage/2) changeling.chem_charges += min(target_ling.chem_charges, changeling.chem_storage) target_ling.chem_charges = 0 + target_ling.hostile_absorbed = TRUE target_ling.chem_storage = 0 changeling.absorbedcount += (target_ling.absorbedcount) target_ling.stored_profiles.len = 1 diff --git a/code/modules/antagonists/changeling/powers/fleshmend.dm b/code/modules/antagonists/changeling/powers/fleshmend.dm index afef2a10c7..0299abb09a 100644 --- a/code/modules/antagonists/changeling/powers/fleshmend.dm +++ b/code/modules/antagonists/changeling/powers/fleshmend.dm @@ -1,6 +1,6 @@ /obj/effect/proc_holder/changeling/fleshmend name = "Fleshmend" - desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath. Functions while unconscious. This ability is loud, and might cause our blood to react violently to heat." + desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath, as well as hiding all of our scars. Costs 20 chemicals." helptext = "If we are on fire, the healing effect will not function. Does not regrow limbs or restore lost blood." chemical_cost = 20 loudness = 2 diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index e4417a6d64..7d50374e96 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -165,6 +165,8 @@ hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = IS_SHARP + wound_bonus = -60 + bare_wound_bonus = 20 var/can_drop = FALSE var/fake = FALSE total_mass = TOTAL_MASS_HAND_REPLACEMENT diff --git a/code/modules/antagonists/changeling/powers/regenerate.dm b/code/modules/antagonists/changeling/powers/regenerate.dm index 1b27fa9694..bcebd8c62e 100644 --- a/code/modules/antagonists/changeling/powers/regenerate.dm +++ b/code/modules/antagonists/changeling/powers/regenerate.dm @@ -29,6 +29,9 @@ C.emote("scream") C.regenerate_limbs(1) C.regenerate_organs() + for(var/i in C.all_wounds) + var/datum/wound/W = i + W.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/changeling/powers/revive.dm b/code/modules/antagonists/changeling/powers/revive.dm index 6c2220648d..f193fb6736 100644 --- a/code/modules/antagonists/changeling/powers/revive.dm +++ b/code/modules/antagonists/changeling/powers/revive.dm @@ -36,9 +36,10 @@ . = ..() if(!.) return - - if(HAS_TRAIT(user, CHANGELING_DRAIN) || ((user.stat != DEAD) && !(HAS_TRAIT(user, TRAIT_DEATHCOMA)))) - var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) + var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) + if(!changeling) + return FALSE + if(changeling.hostile_absorbed || ((user.stat != DEAD) && !(HAS_TRAIT(user, TRAIT_DEATHCOMA)))) changeling.purchasedpowers -= src return FALSE diff --git a/code/modules/antagonists/changeling/powers/transform.dm b/code/modules/antagonists/changeling/powers/transform.dm index 795ba772d6..c0979b6936 100644 --- a/code/modules/antagonists/changeling/powers/transform.dm +++ b/code/modules/antagonists/changeling/powers/transform.dm @@ -18,7 +18,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/glasses/changeling/attack_hand(mob/user) +/obj/item/clothing/glasses/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -34,7 +34,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/under/changeling/attack_hand(mob/user) +/obj/item/clothing/under/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -51,7 +51,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/suit/changeling/attack_hand(mob/user) +/obj/item/clothing/suit/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -66,7 +66,7 @@ ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/head/changeling/attack_hand(mob/user) +/obj/item/clothing/head/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -82,7 +82,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/shoes/changeling/attack_hand(mob/user) +/obj/item/clothing/shoes/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -98,7 +98,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/gloves/changeling/attack_hand(mob/user) +/obj/item/clothing/gloves/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -114,7 +114,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/mask/changeling/attack_hand(mob/user) +/obj/item/clothing/mask/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) @@ -132,7 +132,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/changeling/attack_hand(mob/user) +/obj/item/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling)) to_chat(user, "You reabsorb [src] into your body.") qdel(src) diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index 036ea37ada..90c4bdf8de 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -28,7 +28,7 @@ return //you can't tk stomp sigils, but you can hit them with something //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/clockwork/sigil/attack_hand(mob/user) +/obj/effect/clockwork/sigil/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user) && !user.stat) if(is_servant_of_ratvar(user) && user.a_intent != INTENT_HARM) return ..() diff --git a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm index 36aaa27716..9106015c0a 100644 --- a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm +++ b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm @@ -64,7 +64,7 @@ ..() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user) +/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!uses) return FALSE if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm index fd519969db..d0d3bafe06 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm @@ -58,7 +58,7 @@ return ..() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clockwork/slab/debug/attack_hand(mob/living/user) +/obj/item/clockwork/slab/debug/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!is_servant_of_ratvar(user)) add_servant_of_ratvar(user) return ..() diff --git a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm index 43c05b8556..7578d41b15 100644 --- a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm +++ b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm @@ -32,7 +32,7 @@ clockwork_desc = initial(clockwork_desc) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clockwork/construct_chassis/attack_hand(mob/living/user) +/obj/item/clockwork/construct_chassis/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(w_class >= WEIGHT_CLASS_HUGE) to_chat(user, "[src] is too cumbersome to carry! Drag it around instead!") return diff --git a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm index 058bd9d24e..8c529d43a6 100644 --- a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm +++ b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm @@ -41,7 +41,7 @@ affected += try_use_power(MIN_CLOCKCULT_POWER*4) return affected -/obj/structure/destructible/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user) +/obj/structure/destructible/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm index c01c7f0f57..2c84a5b332 100644 --- a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm +++ b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm @@ -11,7 +11,7 @@ var/selection_timer //Timer ID; this is canceled if the vote is canceled var/kingmaking -/obj/structure/destructible/clockwork/eminence_spire/attack_hand(mob/living/user) +/obj/structure/destructible/clockwork/eminence_spire/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm index 7d8b206f41..385b9a5431 100644 --- a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm +++ b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm @@ -58,7 +58,7 @@ . += "There are [time_remaining] second[time_remaining != 1 ? "s" : ""] remaining to vote." . += "There are [voters.len]/[votes_needed] votes to activate the beacon!" -/obj/structure/destructible/clockwork/heralds_beacon/attack_hand(mob/living/user) +/obj/structure/destructible/clockwork/heralds_beacon/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/clockcult/clock_structures/mania_motor.dm b/code/modules/antagonists/clockcult/clock_structures/mania_motor.dm index 5fbaf9fd57..24d0651444 100644 --- a/code/modules/antagonists/clockcult/clock_structures/mania_motor.dm +++ b/code/modules/antagonists/clockcult/clock_structures/mania_motor.dm @@ -30,7 +30,7 @@ toggle() return TRUE -/obj/structure/destructible/clockwork/powered/mania_motor/attack_hand(mob/living/user) +/obj/structure/destructible/clockwork/powered/mania_motor/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/lever.dm b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/lever.dm index 12e4b62a65..d4a02cc3e1 100644 --- a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/lever.dm +++ b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/lever.dm @@ -6,7 +6,7 @@ max_integrity = 75 icon_state = "lever" -/obj/structure/destructible/clockwork/trap/trigger/lever/attack_hand(mob/living/user) +/obj/structure/destructible/clockwork/trap/trigger/lever/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/repeater.dm b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/repeater.dm index f5ed91ac15..e7d4e18c43 100644 --- a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/repeater.dm +++ b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/repeater.dm @@ -6,7 +6,7 @@ max_integrity = 15 //Fragile! icon_state = "repeater" -/obj/structure/destructible/clockwork/trap/trigger/repeater/attack_hand(mob/living/user) +/obj/structure/destructible/clockwork/trap/trigger/repeater/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 5b2dd7d007..4e9d40d91c 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -34,6 +34,8 @@ w_class = WEIGHT_CLASS_SMALL force = 15 throwforce = 25 + wound_bonus = -30 + bare_wound_bonus = 30 armour_penetration = 35 actions_types = list(/datum/action/item_action/cult_dagger) @@ -53,8 +55,10 @@ flags_1 = CONDUCT_1 sharpness = IS_SHARP w_class = WEIGHT_CLASS_BULKY - force = 30 + force = 30 // whoever balanced this got beat in the head by a bible too many times good lord throwforce = 10 + wound_bonus = -80 + bare_wound_bonus = 30 hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended") diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index b0538d6521..9b77e70a73 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -67,7 +67,7 @@ Runes can either be invoked by one's self or with many different cultists. Each to_chat(user, "You disrupt the magic of [src] with [I].") qdel(src) -/obj/effect/rune/attack_hand(mob/living/user) +/obj/effect/rune/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index d0ef5a83ce..21ccd425a3 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -112,7 +112,7 @@ if(stasis) return if(revealed && essence <= 0) - death() + INVOKE_ASYNC(src, .proc/death) if(unreveal_time && world.time >= unreveal_time) unreveal_time = 0 revealed = FALSE diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm index 6b063559dc..35a674fb0e 100644 --- a/code/modules/antagonists/slaughter/slaughter.dm +++ b/code/modules/antagonists/slaughter/slaughter.dm @@ -34,8 +34,11 @@ healable = 0 environment_smash = ENVIRONMENT_SMASH_STRUCTURES obj_damage = 50 - melee_damage_lower = 30 - melee_damage_upper = 30 + melee_damage_lower = 22.5 // reduced from 30 to 22.5 with wounds since they get big buffs to slicing wounds + melee_damage_upper = 22.5 + wound_bonus = -10 + bare_wound_bonus = 0 + sharpness = TRUE see_in_dark = 8 blood_volume = 0 //No bleeding on getting shot, for skeddadles lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE @@ -43,13 +46,25 @@ var/playstyle_string = "You are a slaughter demon, a terrible creature from another realm. You have a single desire: To kill. \ You may use the \"Blood Crawl\" ability near blood pools to travel through them, appearing and disappearing from the station at will. \ Pulling a dead or unconscious mob while you enter a pool will pull them in with you, allowing you to feast and regain your health. \ - You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. " + You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. \ + You gain strength the more attacks you land on live humanoids, though this resets when you return to the blood zone. You can also \ + launch a devastating slam attack with ctrl+shift+click, capable of smashing bones in one strike." loot = list(/obj/effect/decal/cleanable/blood, \ /obj/effect/decal/cleanable/blood/innards, \ /obj/item/organ/heart/demon) del_on_death = 1 deathmessage = "screams in anger as it collapses into a puddle of viscera!" + // How long it takes for the alt-click slam attack to come off cooldown + var/slam_cooldown_time = 45 SECONDS + // The actual instance var for the cooldown + var/slam_cooldown = 0 + // How many times we have hit humanoid targets since we last bloodcrawled, scaling wounding power + var/current_hitstreak = 0 + // How much both our wound_bonus and bare_wound_bonus go up per hitstreak hit + var/wound_bonus_per_hit = 5 + // How much our wound_bonus hitstreak bonus caps at (peak demonry) + var/wound_bonus_hitstreak_max = 12 /mob/living/simple_animal/slaughter/Initialize() ..() @@ -58,6 +73,33 @@ if(istype(loc, /obj/effect/dummy/phased_mob/slaughter)) bloodspell.phased = TRUE +/mob/living/simple_animal/slaughter/CtrlShiftClickOn(atom/A) + if(!isliving(A)) + return ..() + if(slam_cooldown + slam_cooldown_time > world.time) + to_chat(src, "Your slam ability is still on cooldown!") + return + + face_atom(A) + var/mob/living/victim = A + victim.take_bodypart_damage(brute=20, wound_bonus=wound_bonus) // don't worry, there's more punishment when they hit something + visible_message("[src] slams into [victim] with monstrous strength!", "You slam into [victim] with monstrous strength!", ignored_mobs=victim) + to_chat(victim, "[src] slams into you with monstrous strength, sending you flying like a ragdoll!") + var/turf/yeet_target = get_edge_target_turf(victim, dir) + victim.throw_at(yeet_target, 10, 5, src) + slam_cooldown = world.time + log_combat(src, victim, "slaughter slammed") + +/mob/living/simple_animal/slaughter/UnarmedAttack(atom/A, proximity) + if(iscarbon(A)) + var/mob/living/carbon/target = A + if(target.stat != DEAD && target.mind && current_hitstreak < wound_bonus_hitstreak_max) + current_hitstreak++ + wound_bonus += wound_bonus_per_hit + bare_wound_bonus += wound_bonus_per_hit + + return ..() + /obj/effect/decal/cleanable/blood/innards icon = 'icons/obj/surgery.dmi' name = "pile of viscera" diff --git a/code/modules/antagonists/slaughter/slaughter_antag.dm b/code/modules/antagonists/slaughter/slaughter_antag.dm index 87db9772b7..d6d504ef8e 100644 --- a/code/modules/antagonists/slaughter/slaughter_antag.dm +++ b/code/modules/antagonists/slaughter/slaughter_antag.dm @@ -15,6 +15,7 @@ /datum/antagonist/slaughter/greet() . = ..() owner.announce_objectives() + to_chat(owner, "You have a powerful alt-attack that slams people backwards that you can activate by shift+ctrl+clicking your target!") /datum/antagonist/slaughter/proc/forge_objectives() if(summoner) diff --git a/code/modules/antagonists/survivalist/survivalist.dm b/code/modules/antagonists/survivalist/survivalist.dm index 04ad53f65b..296369fe3b 100644 --- a/code/modules/antagonists/survivalist/survivalist.dm +++ b/code/modules/antagonists/survivalist/survivalist.dm @@ -23,6 +23,18 @@ /datum/antagonist/survivalist/guns greet_message = "Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, and don't let anyone take them!" +/datum/antagonist/survivalist/guns/forge_objectives() + var/datum/objective/steal_five_of_type/summon_guns/guns = new + guns.owner = owner + objectives += guns + ..() + /datum/antagonist/survivalist/magic name = "Amateur Magician" greet_message = "This magic stuff is... so powerful. You want more. More! They want your power. They can't have it! Don't let them have it!" + +/datum/antagonist/survivalist/magic/forge_objectives() + var/datum/objective/steal_five_of_type/summon_magic/magic = new + magic.owner = owner + objectives += magic + ..() diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index e559313aff..9a8b9c8d59 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -36,7 +36,7 @@ if(A) notify_ghosts("A swarmer shell has been created in [A.name].", 'sound/effects/bin_close.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE) -/obj/effect/mob_spawn/swarmer/attack_hand(mob/living/user) +/obj/effect/mob_spawn/swarmer/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -486,7 +486,7 @@ var/obj/O = target if(O.resistance_flags & INDESTRUCTIBLE) return FALSE - for(var/mob/living/L in GetAllContents()) + for(var/mob/living/L in target.GetAllContents()) if(!ispAI(L) && !isbrain(L)) to_chat(src, "An organism has been detected inside this object. Aborting.") return FALSE diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index ab043ef1c9..4c29c53a2e 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -503,6 +503,7 @@ name = "Summon Guns" desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long!" dynamic_requirement = 60 + limit = 1 /datum/spellbook_entry/summon/guns/IsAvailible() if(!SSticker.mode) // In case spellbook is placed on map @@ -521,6 +522,7 @@ name = "Summon Magic" desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time." dynamic_requirement = 60 + limit = 1 /datum/spellbook_entry/summon/magic/IsAvailible() if(!SSticker.mode) // In case spellbook is placed on map diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 7af823e8a9..e86b249be6 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -43,6 +43,12 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list()) var/list/dummy = get_gases() for(var/gas in dummy) dummy[gas] = get_moles(gas) + dummy["TEMP"] = return_temperature() + dummy["PRESSURE"] = return_pressure() + dummy["HEAT CAPACITY"] = heat_capacity() + dummy["TOTAL MOLES"] = total_moles() + dummy["VOLUME"] = return_volume() + dummy["THERMAL ENERGY"] = thermal_energy() return debug_variable("gases (READ ONLY)", dummy, 0, src) /datum/gas_mixture/vv_get_dropdown() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index d6cae58079..ae80825694 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -33,6 +33,8 @@ var/escape_in_progress = FALSE var/message_cooldown var/breakout_time = 300 + ///Cryo will continue to treat people with 0 damage but existing wounds, but will sound off when damage healing is done in case doctors want to directly treat the wounds instead + var/treating_wounds = FALSE fair_market_price = 10 payment_department = ACCOUNT_MED @@ -174,15 +176,27 @@ return if(mob_occupant.health >= mob_occupant.getMaxHealth()) // Don't bother with fully healed people. - on = FALSE - update_icon() - playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. - var/msg = "Patient fully restored." - if(autoeject) // Eject if configured. - msg += " Auto ejecting patient now." - open_machine() - radio.talk_into(src, msg, radio_channel) - return + if(iscarbon(mob_occupant)) + var/mob/living/carbon/C = mob_occupant + if(C.all_wounds) + if(!treating_wounds) // if we have wounds and haven't already alerted the doctors we're only dealing with the wounds, let them know + treating_wounds = TRUE + playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. + var/msg = "Patient vitals fully recovered, continuing automated wound treatment." + radio.talk_into(src, msg, radio_channel) + else // otherwise if we were only treating wounds and now we don't have any, turn off treating_wounds so we can boot 'em out + treating_wounds = FALSE + + if(!treating_wounds) + on = FALSE + update_icon() + playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. + var/msg = "Patient fully restored." + if(autoeject) // Eject if configured. + msg += " Auto ejecting patient now." + open_machine() + radio.talk_into(src, msg, radio_channel) + return var/datum/gas_mixture/air1 = airs[1] diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index fcdc564380..03c0f5178a 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -54,7 +54,7 @@ STOP_PROCESSING(SSobj, src) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/ctf/attack_hand(mob/living/user) +/obj/item/ctf/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(!is_ctf_target(user) && !anyonecanpickup) to_chat(user, "Non players shouldn't be moving the flag!") return @@ -679,7 +679,7 @@ /obj/machinery/control_point/attackby(mob/user, params) capture(user) -/obj/machinery/control_point/attack_hand(mob/user) +/obj/machinery/control_point/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index e91dfee034..4b2f1e9962 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -595,7 +595,7 @@ job_description = "Space Bar Patron" //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/mob_spawn/human/alive/space_bar_patron/attack_hand(mob/user) +/obj/effect/mob_spawn/human/alive/space_bar_patron/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) var/despawn = alert("Return to cryosleep? (Warning, Your mob will be deleted!)",,"Yes","No") if(despawn == "No" || !loc || !Adjacent(user)) return diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 6ddda43bc8..157fdb7bc7 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -188,7 +188,8 @@ GLOBAL_LIST_EMPTY(gateway_destinations) target = null dest.deactivate(src) QDEL_NULL(portal) - use_power = IDLE_POWER_USE + if(use_power == ACTIVE_POWER_USE) + use_power = IDLE_POWER_USE update_icon() /obj/machinery/gateway/process() @@ -216,7 +217,8 @@ GLOBAL_LIST_EMPTY(gateway_destinations) target = D target.activate(destination) generate_bumper() - use_power = ACTIVE_POWER_USE + if(use_power == IDLE_POWER_USE) + use_power = ACTIVE_POWER_USE update_icon() /obj/machinery/gateway/proc/Transfer(atom/movable/AM) diff --git a/code/modules/cargo/exports/organs_robotics.dm b/code/modules/cargo/exports/organs_robotics.dm index a6c5ee93ca..7f54e675ca 100644 --- a/code/modules/cargo/exports/organs_robotics.dm +++ b/code/modules/cargo/exports/organs_robotics.dm @@ -144,7 +144,7 @@ /datum/export/robotics/surgery_gear_basic cost = 10 unit_name = "surgery tool" - export_types = list(/obj/item/retractor, /obj/item/hemostat, /obj/item/cautery, /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/circular_saw, /obj/item/surgical_drapes) + export_types = list(/obj/item/retractor, /obj/item/hemostat, /obj/item/cautery, /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/circular_saw, /obj/item/bonesetter, /obj/item/surgical_drapes) /datum/export/robotics/mech_weapon_laser cost = 300 //Sadly just metal and glass diff --git a/code/modules/cargo/packs/goodies.dm b/code/modules/cargo/packs/goodies.dm index ac8b1e9032..2ff02d0473 100644 --- a/code/modules/cargo/packs/goodies.dm +++ b/code/modules/cargo/packs/goodies.dm @@ -75,3 +75,9 @@ desc = "The simple beach ball is one of Nanotrasen's most popular products. 'Why do we make beach balls? Because we can! (TM)' - Nanotrasen" cost = 200 contains = list(/obj/item/toy/beach_ball) + +/datum/supply_pack/goody/hell_single + name = "Hellgun Single-Pack" + 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) diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm index 2bb629308c..5eacc2f583 100644 --- a/code/modules/cargo/packs/medical.dm +++ b/code/modules/cargo/packs/medical.dm @@ -114,7 +114,9 @@ /obj/item/storage/box/medsprays, /obj/item/storage/box/syringes, /obj/item/storage/box/bodybags, - /obj/item/storage/pill_bottle/stimulant) + /obj/item/storage/pill_bottle/stimulant, + /obj/item/stack/medical/bone_gel, + /obj/item/stack/medical/bone_gel) crate_name = "medical supplies crate" /datum/supply_pack/medical/adv_surgery_tools diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 8b4c28a1f4..75e914ea68 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -83,24 +83,24 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/gender = MALE //gender of character (well duh) var/age = 30 //age of character var/underwear = "Nude" //underwear type - var/undie_color = "FFF" + var/undie_color = "FFFFFF" var/undershirt = "Nude" //undershirt type - var/shirt_color = "FFF" + var/shirt_color = "FFFFFF" var/socks = "Nude" //socks type - var/socks_color = "FFF" + var/socks_color = "FFFFFF" var/backbag = DBACKPACK //backpack type var/jumpsuit_style = PREF_SUIT //suit/skirt var/hair_style = "Bald" //Hair type - var/hair_color = "000" //Hair color + var/hair_color = "000000" //Hair color var/facial_hair_style = "Shaved" //Face hair type - var/facial_hair_color = "000" //Facial hair color + var/facial_hair_color = "000000" //Facial hair color var/skin_tone = "caucasian1" //Skin color var/use_custom_skin_tone = FALSE - var/eye_color = "000" //Eye color + var/eye_color = "000000" //Eye color var/datum/species/pref_species = new /datum/species/human() //Mutant race - var/list/features = list("mcolor" = "FFF", - "mcolor2" = "FFF", - "mcolor3" = "FFF", + var/list/features = list("mcolor" = "FFFFFF", + "mcolor2" = "FFFFFF", + "mcolor3" = "FFFFFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", @@ -131,23 +131,23 @@ GLOBAL_LIST_EMPTY(preferences_datums) "cock_shape" = DEF_COCK_SHAPE, "cock_length" = COCK_SIZE_DEF, "cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF, - "cock_color" = "fff", + "cock_color" = "ffffff", "cock_taur" = FALSE, "has_balls" = FALSE, - "balls_color" = "fff", + "balls_color" = "ffffff", "balls_shape" = DEF_BALLS_SHAPE, "balls_size" = BALLS_SIZE_DEF, "balls_cum_rate" = CUM_RATE, "balls_cum_mult" = CUM_RATE_MULT, "balls_efficiency" = CUM_EFFICIENCY, "has_breasts" = FALSE, - "breasts_color" = "fff", + "breasts_color" = "ffffff", "breasts_size" = BREASTS_SIZE_DEF, "breasts_shape" = DEF_BREASTS_SHAPE, "breasts_producing" = FALSE, "has_vag" = FALSE, "vag_shape" = DEF_VAGINA_SHAPE, - "vag_color" = "fff", + "vag_color" = "ffffff", "has_womb" = FALSE, "balls_visibility" = GEN_VISIBLE_NO_UNDIES, "breasts_visibility"= GEN_VISIBLE_NO_UNDIES, @@ -239,6 +239,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/autostand = TRUE var/auto_ooc = FALSE + /// If we have persistent scars enabled + var/persistent_scars = TRUE + /// We have 5 slots for persistent scars, if enabled we pick a random one to load (empty by default) and scars at the end of the shift if we survived as our original person + var/list/scars_list = list("1" = "", "2" = "", "3" = "", "4" = "", "5" = "") + /// Which of the 5 persistent scar slots we randomly roll to load for this round, if enabled. Actually rolled in [/datum/preferences/proc/load_character(slot)] + var/scars_index = 1 + /datum/preferences/New(client/C) parent = C @@ -825,6 +832,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Socks Color:     Change
" dat += "Backpack:[backbag]" dat += "Jumpsuit:
[jumpsuit_style]
" + if(CAN_SCAR in pref_species.species_traits) + dat += "
Temporal Scarring:
[(persistent_scars) ? "Enabled" : "Disabled"]" + dat += "Clear scar slots" dat += "Uplink Location:[uplink_spawn_loc]" dat += "" @@ -1697,7 +1707,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("hair") var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null if(new_hair) - hair_color = sanitize_hexcolor(new_hair) + hair_color = sanitize_hexcolor(new_hair, 6) if("hair_style") var/new_hair_style @@ -1714,7 +1724,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("facial") var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference","#"+facial_hair_color) as color|null if(new_facial) - facial_hair_color = sanitize_hexcolor(new_facial) + facial_hair_color = sanitize_hexcolor(new_facial, 6) if("facial_hair_style") var/new_facial_hair_style @@ -1739,7 +1749,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("undie_color") var/n_undie_color = input(user, "Choose your underwear's color.", "Character Preference", "#[undie_color]") as color|null if(n_undie_color) - undie_color = sanitize_hexcolor(n_undie_color) + undie_color = sanitize_hexcolor(n_undie_color, 6) if("undershirt") var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_list @@ -1749,7 +1759,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("shirt_color") var/n_shirt_color = input(user, "Choose your undershirt's color.", "Character Preference", "#[shirt_color]") as color|null if(n_shirt_color) - shirt_color = sanitize_hexcolor(n_shirt_color) + shirt_color = sanitize_hexcolor(n_shirt_color, 6) if("socks") var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list @@ -1759,12 +1769,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("socks_color") var/n_socks_color = input(user, "Choose your socks' color.", "Character Preference", "#[socks_color]") as color|null if(n_socks_color) - socks_color = sanitize_hexcolor(n_socks_color) + socks_color = sanitize_hexcolor(n_socks_color, 6) if("eyes") var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+eye_color) as color|null if(new_eyes) - eye_color = sanitize_hexcolor(new_eyes) + eye_color = sanitize_hexcolor(new_eyes, 6) if("species") var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_race_names @@ -1788,11 +1798,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) //Now that we changed our species, we must verify that the mutant colour is still allowed. var/temp_hsv = RGBtoHSV(features["mcolor"]) - if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) + if(features["mcolor"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) features["mcolor"] = pref_species.default_color - if(features["mcolor2"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) + if(features["mcolor2"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) features["mcolor2"] = pref_species.default_color - if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) + if(features["mcolor3"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) features["mcolor3"] = pref_species.default_color if("custom_species") @@ -1809,7 +1819,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_mutantcolor == "#000000") features["mcolor"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin - features["mcolor"] = sanitize_hexcolor(new_mutantcolor) + features["mcolor"] = sanitize_hexcolor(new_mutantcolor, 6) else to_chat(user, "Invalid color. Your color is not bright enough.") @@ -1820,7 +1830,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_mutantcolor == "#000000") features["mcolor2"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin - features["mcolor2"] = sanitize_hexcolor(new_mutantcolor) + features["mcolor2"] = sanitize_hexcolor(new_mutantcolor, 6) else to_chat(user, "Invalid color. Your color is not bright enough.") @@ -1831,7 +1841,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_mutantcolor == "#000000") features["mcolor3"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin - features["mcolor3"] = sanitize_hexcolor(new_mutantcolor) + features["mcolor3"] = sanitize_hexcolor(new_mutantcolor, 6) else to_chat(user, "Invalid color. Your color is not bright enough.") @@ -1959,7 +1969,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if (new_horn_color == "#000000") features["horns_color"] = "85615A" else - features["horns_color"] = sanitize_hexcolor(new_horn_color) + features["horns_color"] = sanitize_hexcolor(new_horn_color, 6) if("wings") var/new_wings @@ -1973,7 +1983,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if (new_wing_color == "#000000") features["wings_color"] = "#FFFFFF" else - features["wings_color"] = sanitize_hexcolor(new_wing_color) + features["wings_color"] = sanitize_hexcolor(new_wing_color, 6) if("frills") var/new_frills @@ -2147,7 +2157,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_cockcolor == "#000000") features["cock_color"] = pref_species.default_color else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) - features["cock_color"] = sanitize_hexcolor(new_cockcolor) + features["cock_color"] = sanitize_hexcolor(new_cockcolor, 6) else to_chat(user,"Invalid color. Your color is not bright enough.") @@ -2187,7 +2197,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_ballscolor == "#000000") features["balls_color"] = pref_species.default_color else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) - features["balls_color"] = sanitize_hexcolor(new_ballscolor) + features["balls_color"] = sanitize_hexcolor(new_ballscolor, 6) else to_chat(user,"Invalid color. Your color is not bright enough.") @@ -2214,7 +2224,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_breasts_color == "#000000") features["breasts_color"] = pref_species.default_color else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) - features["breasts_color"] = sanitize_hexcolor(new_breasts_color) + features["breasts_color"] = sanitize_hexcolor(new_breasts_color, 6) else to_chat(user,"Invalid color. Your color is not bright enough.") @@ -2236,7 +2246,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_vagcolor == "#000000") features["vag_color"] = pref_species.default_color else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) - features["vag_color"] = sanitize_hexcolor(new_vagcolor) + features["vag_color"] = sanitize_hexcolor(new_vagcolor, 6) else to_chat(user,"Invalid color. Your color is not bright enough.") @@ -2545,6 +2555,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("hear_midis") toggles ^= SOUND_MIDI + if("persistent_scars") + persistent_scars = !persistent_scars + + if("clear_scars") + to_chat(user, "All scar slots cleared. Please save character to confirm.") + scars_list["1"] = "" + scars_list["2"] = "" + scars_list["3"] = "" + scars_list["4"] = "" + scars_list["5"] = "" + if("lobby_music") toggles ^= SOUND_LOBBY if((toggles & SOUND_LOBBY) && user.client && isnewplayer(user)) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 440ee1fbc1..59d99674eb 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -224,6 +224,8 @@ 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 S["ooccolor"] >> ooccolor @@ -440,6 +442,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(needs_update == -2) //fatal, can't load any data return 0 + . = TRUE + //Species var/species_id S["species"] >> species_id @@ -453,6 +457,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(newtype) pref_species = new newtype + + scars_index = rand(1,5) + //Character S["real_name"] >> real_name S["nameless"] >> nameless @@ -497,6 +504,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["feature_insect_markings"] >> features["insect_markings"] S["feature_horns_color"] >> features["horns_color"] S["feature_wings_color"] >> features["wings_color"] + S["persistent_scars"] >> persistent_scars + S["scars1"] >> scars_list["1"] + S["scars2"] >> scars_list["2"] + S["scars3"] >> scars_list["3"] + S["scars4"] >> scars_list["4"] + S["scars5"] >> scars_list["5"] //Custom names @@ -623,14 +636,14 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_list) underwear = sanitize_inlist(underwear, GLOB.underwear_list) undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list) - undie_color = sanitize_hexcolor(undie_color, 3, FALSE, initial(undie_color)) - shirt_color = sanitize_hexcolor(shirt_color, 3, FALSE, initial(shirt_color)) + undie_color = sanitize_hexcolor(undie_color, 6, FALSE, initial(undie_color)) + shirt_color = sanitize_hexcolor(shirt_color, 6, FALSE, initial(shirt_color)) socks = sanitize_inlist(socks, GLOB.socks_list) - socks_color = sanitize_hexcolor(socks_color, 3, FALSE, initial(socks_color)) + socks_color = sanitize_hexcolor(socks_color, 6, FALSE, initial(socks_color)) age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) - hair_color = sanitize_hexcolor(hair_color, 3, 0) - facial_hair_color = sanitize_hexcolor(facial_hair_color, 3, 0) - eye_color = sanitize_hexcolor(eye_color, 3, 0) + hair_color = sanitize_hexcolor(hair_color, 6, FALSE) + facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE) + eye_color = sanitize_hexcolor(eye_color, 6, FALSE) var/static/allow_custom_skintones if(isnull(allow_custom_skintones)) @@ -641,12 +654,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car else skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones - GLOB.nonstandard_skin_tones, initial(skin_tone)) - features["horns_color"] = sanitize_hexcolor(features["horns_color"], 3, FALSE, "85615a") - features["wings_color"] = sanitize_hexcolor(features["wings_color"], 3, FALSE, "FFFFFF") + features["horns_color"] = sanitize_hexcolor(features["horns_color"], 6, FALSE, "85615a") + features["wings_color"] = sanitize_hexcolor(features["wings_color"], 6, FALSE, "FFFFFF") backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag)) jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style)) uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc)) - features["mcolor"] = sanitize_hexcolor(features["mcolor"], 3, 0) + features["mcolor"] = sanitize_hexcolor(features["mcolor"], 6, FALSE) features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard) features["tail_human"] = sanitize_inlist(features["tail_human"], GLOB.tails_list_human) features["snout"] = sanitize_inlist(features["snout"], GLOB.snouts_list) @@ -690,10 +703,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car features["cock_shape"] = sanitize_inlist(features["cock_shape"], GLOB.cock_shapes_list, DEF_COCK_SHAPE) features["balls_shape"] = sanitize_inlist(features["balls_shape"], GLOB.balls_shapes_list, DEF_BALLS_SHAPE) features["vag_shape"] = sanitize_inlist(features["vag_shape"], GLOB.vagina_shapes_list, DEF_VAGINA_SHAPE) - features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 3, FALSE, "FFF") - features["cock_color"] = sanitize_hexcolor(features["cock_color"], 3, FALSE, "FFF") - features["balls_color"] = sanitize_hexcolor(features["balls_color"], 3, FALSE, "FFF") - features["vag_color"] = sanitize_hexcolor(features["vag_color"], 3, FALSE, "FFF") + features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 6, FALSE, "FFFFFF") + features["cock_color"] = sanitize_hexcolor(features["cock_color"], 6, FALSE, "FFFFFF") + features["balls_color"] = sanitize_hexcolor(features["balls_color"], 6, FALSE, "FFFFFF") + features["vag_color"] = sanitize_hexcolor(features["vag_color"], 6, FALSE, "FFFFFF") features["breasts_visibility"] = sanitize_inlist(features["breasts_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) features["cock_visibility"] = sanitize_inlist(features["cock_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) features["balls_visibility"] = sanitize_inlist(features["balls_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) @@ -709,6 +722,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN) features["ooc_notes"] = copytext(features["ooc_notes"], 1, MAX_FLAVOR_LEN) + persistent_scars = sanitize_integer(persistent_scars) + scars_list["1"] = sanitize_text(scars_list["1"]) + scars_list["2"] = sanitize_text(scars_list["2"]) + scars_list["3"] = sanitize_text(scars_list["3"]) + scars_list["4"] = sanitize_text(scars_list["4"]) + scars_list["5"] = sanitize_text(scars_list["5"]) + joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole)) //Validate job prefs for(var/j in job_preferences) @@ -840,6 +860,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["vore_taste"] , vore_taste) WRITE_FILE(S["belly_prefs"] , belly_prefs) + WRITE_FILE(S["persistent_scars"] , persistent_scars) + WRITE_FILE(S["scars1"] , scars_list["1"]) + WRITE_FILE(S["scars2"] , scars_list["2"]) + WRITE_FILE(S["scars3"] , scars_list["3"]) + WRITE_FILE(S["scars4"] , scars_list["4"]) + WRITE_FILE(S["scars5"] , scars_list["5"]) + //gear loadout if(chosen_gear.len) var/text_to_save = chosen_gear.Join("|") diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index a28061db10..d2553c4d7c 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -4,7 +4,7 @@ max_integrity = 200 integrity_failure = 0.4 block_priority = BLOCK_PRIORITY_CLOTHING - var/damaged_clothes = 0 //similar to machine's BROKEN stat and structure's broken var + var/damaged_clothes = CLOTHING_PRISTINE //similar to machine's BROKEN stat and structure's broken var var/flash_protect = 0 //What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS var/tint = 0 //Sets the item's level of visual impairment tint, normally set to the same as flash_protect var/up = 0 //but separated to allow items to protect but not impair vision, like space helmets @@ -28,6 +28,9 @@ var/clothing_flags = NONE + // What items can be consumed to repair this clothing (must by an /obj/item/stack) + var/repairable_by = /obj/item/stack/sheet/cloth + //Var modification - PLEASE be careful with this I know who you are and where you live var/list/user_vars_to_edit //VARNAME = VARVALUE eg: "name" = "butts" var/list/user_vars_remembered //Auto built by the above + dropped() + equipped() @@ -45,7 +48,16 @@ var/list/species_restricted = null //Basically syntax is species_restricted = list("Species Name","Species Name") //Add a "exclude" string to do the opposite, making it only only species listed that can't wear it. - //You append this to clothing objects. + //You append this to clothing objects + + + + // How much clothing damage has been dealt to each of the limbs of the clothing, assuming it covers more than one limb + var/list/damage_by_parts + // How much integrity is in a specific limb before that limb is disabled (for use in [/obj/item/clothing/proc/take_damage_zone], and only if we cover multiple zones.) Set to 0 to disable shredding. + var/limb_integrity = 0 + // How many zones (body parts, not precise) we have disabled so far, for naming purposes + var/zones_disabled /obj/item/clothing/Initialize() . = ..() @@ -83,15 +95,105 @@ return ..() /obj/item/clothing/attackby(obj/item/W, mob/user, params) - if(damaged_clothes && istype(W, /obj/item/stack/sheet/cloth)) - var/obj/item/stack/sheet/cloth/C = W - C.use(1) - update_clothes_damaged_state(FALSE) - obj_integrity = max_integrity - to_chat(user, "You fix the damage on [src] with [C].") + if(damaged_clothes && istype(W, repairable_by)) + var/obj/item/stack/S = W + switch(damaged_clothes) + if(CLOTHING_DAMAGED) + S.use(1) + repair(user, params) + if(CLOTHING_SHREDDED) + if(S.amount < 3) + to_chat(user, "You require 3 [S.name] to repair [src].") + return + to_chat(user, "You begin fixing the damage to [src] with [S]...") + if(do_after(user, 6 SECONDS, TRUE, src)) + if(S.use(3)) + repair(user, params) return 1 return ..() +// Set the clothing's integrity back to 100%, remove all damage to bodyparts, and generally fix it up +/obj/item/clothing/proc/repair(mob/user, params) + damaged_clothes = CLOTHING_PRISTINE + update_clothes_damaged_state() + obj_integrity = max_integrity + name = initial(name) // remove "tattered" or "shredded" if there's a prefix + body_parts_covered = initial(body_parts_covered) + slot_flags = initial(slot_flags) + damage_by_parts = null + if(user) + UnregisterSignal(user, COMSIG_MOVABLE_MOVED) + to_chat(user, "You fix the damage on [src].") + +/** + * take_damage_zone() is used for dealing damage to specific bodyparts on a worn piece of clothing, meant to be called from [/obj/item/bodypart/proc/check_woundings_mods()] + * + * This proc only matters when a bodypart that this clothing is covering is harmed by a direct attack (being on fire or in space need not apply), and only if this clothing covers + * more than one bodypart to begin with. No point in tracking damage by zone for a hat, and I'm not cruel enough to let you fully break them in a few shots. + * Also if limb_integrity is 0, then this clothing doesn't have bodypart damage enabled so skip it. + * + * Arguments: + * * def_zone: The bodypart zone in question + * * damage_amount: Incoming damage + * * damage_type: BRUTE or BURN + * * armour_penetration: If the attack had armour_penetration + */ +/obj/item/clothing/proc/take_damage_zone(def_zone, damage_amount, damage_type, armour_penetration) + if(!def_zone || !limb_integrity || (initial(body_parts_covered) in GLOB.bitflags)) // the second check sees if we only cover one bodypart anyway and don't need to bother with this + return + var/list/covered_limbs = body_parts_covered2organ_names(body_parts_covered) // what do we actually cover? + if(!(def_zone in covered_limbs)) + return + + var/damage_dealt = take_damage(damage_amount * 0.1, damage_type, armour_penetration, FALSE) * 10 // only deal 10% of the damage to the general integrity damage, then multiply it by 10 so we know how much to deal to limb + LAZYINITLIST(damage_by_parts) + damage_by_parts[def_zone] += damage_dealt + if(damage_by_parts[def_zone] > limb_integrity) + disable_zone(def_zone, damage_type) + +/** + * disable_zone() is used to disable a given bodypart's protection on our clothing item, mainly from [/obj/item/clothing/proc/take_damage_zone()] + * + * This proc disables all protection on the specified bodypart for this piece of clothing: it'll be as if it doesn't cover it at all anymore (because it won't!) + * If every possible bodypart has been disabled on the clothing, we put it out of commission entirely and mark it as shredded, whereby it will have to be repaired in + * order to equip it again. Also note we only consider it damaged if there's more than one bodypart disabled. + * + * Arguments: + * * def_zone: The bodypart zone we're disabling + * * damage_type: Only really relevant for the verb for describing the breaking, and maybe obj_destruction() + */ +/obj/item/clothing/proc/disable_zone(def_zone, damage_type) + var/list/covered_limbs = body_parts_covered2organ_names(body_parts_covered) + if(!(def_zone in covered_limbs)) + return + + var/zone_name = parse_zone(def_zone) + var/break_verb = ((damage_type == BRUTE) ? "torn" : "burned") + + if(iscarbon(loc)) + var/mob/living/carbon/C = loc + C.visible_message("The [zone_name] on [C]'s [src.name] is [break_verb] away!", "The [zone_name] on your [src.name] is [break_verb] away!", vision_distance = COMBAT_MESSAGE_RANGE) + RegisterSignal(C, COMSIG_MOVABLE_MOVED, .proc/bristle) + + zones_disabled++ + for(var/i in zone2body_parts_covered(def_zone)) + body_parts_covered &= ~i + + if(body_parts_covered == NONE) // if there are no more parts to break then the whole thing is kaput + obj_destruction((damage_type == BRUTE ? "melee" : "laser")) // melee/laser is good enough since this only procs from direct attacks anyway and not from fire/bombs + return + + damaged_clothes = CLOTHING_DAMAGED + switch(zones_disabled) + if(1) + name = "damaged [initial(name)]" + if(2) + name = "mangy [initial(name)]" + if(3 to INFINITY) // take better care of your shit, dude + name = "tattered [initial(name)]" + + update_clothes_damaged_state() + /obj/item/clothing/Destroy() user_vars_remembered = null //Oh god somebody put REFERENCES in here? not to worry, we'll clean it up return ..() @@ -100,6 +202,7 @@ ..() if(!istype(user)) return + UnregisterSignal(user, COMSIG_MOVABLE_MOVED) if(LAZYLEN(user_vars_remembered)) for(var/variable in user_vars_remembered) if(variable in user.vars) @@ -112,7 +215,9 @@ if (!istype(user)) return if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item? - if (LAZYLEN(user_vars_to_edit)) + if(iscarbon(user) && LAZYLEN(zones_disabled)) + RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/bristle) + if(LAZYLEN(user_vars_to_edit)) for(var/variable in user_vars_to_edit) if(variable in user.vars) LAZYSET(user_vars_remembered, variable, user.vars[variable]) @@ -120,8 +225,19 @@ /obj/item/clothing/examine(mob/user) . = ..() - if(damaged_clothes) - . += "It looks damaged!" + if(damaged_clothes == CLOTHING_SHREDDED) + . += "It is completely shredded and requires mending before it can be worn again!" + return + for(var/zone in damage_by_parts) + var/pct_damage_part = damage_by_parts[zone] / limb_integrity * 100 + var/zone_name = parse_zone(zone) + switch(pct_damage_part) + if(100 to INFINITY) + . += "The [zone_name] is useless and requires mending!" + if(60 to 99) + . += "The [zone_name] is heavily shredded!" + if(30 to 59) + . += "The [zone_name] is partially shredded." var/datum/component/storage/pockets = GetComponent(/datum/component/storage) if(pockets) var/list/how_cool_are_your_threads = list("") @@ -139,8 +255,8 @@ . += how_cool_are_your_threads.Join() /obj/item/clothing/obj_break(damage_flag) - if(!damaged_clothes) - update_clothes_damaged_state(TRUE) + damaged_clothes = CLOTHING_DAMAGED + update_clothes_damaged_state() if(ismob(loc)) //It's not important enough to warrant a message if nobody's wearing it var/mob/M = loc to_chat(M, "Your [name] starts to fall apart!") @@ -222,16 +338,25 @@ BLIND // can't see anything /obj/item/clothing/obj_destruction(damage_flag) - if(damage_flag == "bomb" || damage_flag == "melee") + if(damage_flag == "bomb") var/turf/T = get_turf(src) spawn(1) //so the shred survives potential turf change from the explosion. var/obj/effect/decal/cleanable/shreds/Shreds = new(T) Shreds.desc = "The sad remains of what used to be [name]." deconstruct(FALSE) + else if(!(damage_flag in list("acid", "fire"))) + damaged_clothes = CLOTHING_SHREDDED + body_parts_covered = NONE + name = "shredded [initial(name)]" + slot_flags = NONE + update_clothes_damaged_state() + if(ismob(loc)) + var/mob/M = loc + M.visible_message("[M]'s [src.name] falls off, completely shredded!", "Your [src.name] falls off, completely shredded!", vision_distance = COMBAT_MESSAGE_RANGE) + M.dropItemToGround(src) else ..() - //Species-restricted clothing check. - Thanks Oraclestation, BS13, /vg/station etc. /obj/item/clothing/mob_can_equip(mob/M, slot, disable_warning = TRUE) @@ -265,3 +390,12 @@ BLIND // can't see anything return FALSE return TRUE + + + +/// If we're a clothing with at least 1 shredded/disabled zone, give the wearer a periodic heads up letting them know their clothes are damaged +/obj/item/clothing/proc/bristle(mob/living/L) + if(!istype(L)) + return + if(prob(0.2)) + to_chat(L, "The damaged threads on your [src.name] chafe!") diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm index ddf5e4b584..a206b9adc7 100644 --- a/code/modules/clothing/gloves/_gloves.dm +++ b/code/modules/clothing/gloves/_gloves.dm @@ -34,7 +34,7 @@ if(blood_DNA) . += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color()) -/obj/item/clothing/gloves/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/gloves/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index a8017631bd..b06636ea2e 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -196,3 +196,15 @@ transfer_prints = FALSE strip_mod = 5 strip_silence = TRUE + +/obj/item/clothing/gloves/evening + name = "evening gloves" + desc = "Thin, pretty gloves intended for use in regal feminine attire, but knowing Space China these are just for some maid fetish." + icon_state = "evening" + item_state = "evening" + strip_delay = 40 + equip_delay_other = 20 + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + strip_mod = 0.9 + custom_price = PRICE_ALMOST_CHEAP diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm index 475e7a4e51..dc07d5e050 100644 --- a/code/modules/clothing/head/_head.dm +++ b/code/modules/clothing/head/_head.dm @@ -8,6 +8,7 @@ var/blockTracking = 0 //For AI tracking var/can_toggle = null dynamic_hair_suffix = "+generic" + var/datum/beepsky_fashion/beepsky_fashion //the associated datum for applying this to a secbot /obj/item/clothing/head/Initialize() . = ..() @@ -56,7 +57,7 @@ if(blood_DNA) . += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color()) -/obj/item/clothing/head/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/head/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm index 314142d0cc..20cb7cc824 100644 --- a/code/modules/clothing/head/collectable.dm +++ b/code/modules/clothing/head/collectable.dm @@ -27,7 +27,9 @@ icon_state = "chef" item_state = "chef" dynamic_hair_suffix = "" + dog_fashion = /datum/dog_fashion/head/chef + beepsky_fashion = /datum/beepsky_fashion/chef /obj/item/clothing/head/collectable/paper name = "collectable paper hat" @@ -42,6 +44,8 @@ icon_state = "tophat" item_state = "that" + beepsky_fashion = /datum/beepsky_fashion/tophat + /obj/item/clothing/head/collectable/captain name = "collectable captain's hat" desc = "A collectable hat that'll make you look just like a real comdom!" @@ -49,6 +53,7 @@ item_state = "caphat" dog_fashion = /datum/dog_fashion/head/captain + beepsky_fashion = /datum/beepsky_fashion/captain /obj/item/clothing/head/collectable/police name = "collectable police officer's hat" @@ -91,6 +96,7 @@ item_state = "pirate" dog_fashion = /datum/dog_fashion/head/pirate + beepsky_fashion = /datum/beepsky_fashion/pirate /obj/item/clothing/head/collectable/kitty name = "collectable kitty ears" @@ -100,6 +106,7 @@ dynamic_hair_suffix = "" dog_fashion = /datum/dog_fashion/head/kitty + beepsky_fashion = /datum/beepsky_fashion/cat /obj/item/clothing/head/collectable/rabbitears name = "collectable rabbit ears" @@ -116,6 +123,7 @@ icon_state = "wizard" dog_fashion = /datum/dog_fashion/head/blue_wizard + beepsky_fashion = /datum/beepsky_fashion/wizard /obj/item/clothing/head/collectable/hardhat name = "collectable hard hat" diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 80d0b7c8a8..12a4a43ca7 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -15,6 +15,7 @@ dynamic_hair_suffix = "+generic" dog_fashion = /datum/dog_fashion/head + beepsky_fashion = /datum/beepsky_fashion/engineer /obj/item/clothing/head/hardhat/ComponentInitialize() diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 638a0c2f23..5af694ea1b 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -13,7 +13,9 @@ strip_delay = 10 equip_delay_other = 10 dynamic_hair_suffix = "" + dog_fashion = /datum/dog_fashion/head/chef + beepsky_fashion = /datum/beepsky_fashion/chef /obj/item/clothing/head/chefhat/suicide_act(mob/user) user.visible_message("[user] is donning [src]! It looks like [user.p_theyre()] trying to become a chef.") @@ -33,7 +35,9 @@ flags_inv = 0 armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) strip_delay = 60 + dog_fashion = /datum/dog_fashion/head/captain + beepsky_fashion = /datum/beepsky_fashion/captain //Captain: This is no longer space-worthy /obj/item/clothing/head/caphat/parade diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 73675257e4..72d0f68c18 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -20,9 +20,11 @@ desc = "It's an amish looking hat." icon_state = "tophat" item_state = "that" - dog_fashion = /datum/dog_fashion/head throwforce = 1 + dog_fashion = /datum/dog_fashion/head + beepsky_fashion = /datum/beepsky_fashion/tophat + /obj/item/clothing/head/canada name = "striped red tophat" desc = "It smells like fresh donut holes. / Il sent comme des trous de beignets frais." @@ -126,7 +128,9 @@ desc = "Yarr." icon_state = "pirate" item_state = "pirate" + dog_fashion = /datum/dog_fashion/head/pirate + beepsky_fashion = /datum/beepsky_fashion/pirate /obj/item/clothing/head/pirate/captain name = "pirate captain hat" @@ -189,6 +193,8 @@ desc = "A really cool hat if you're a mobster. A really lame hat if you're not." pocket_storage_component_path = /datum/component/storage/concrete/pockets/small + beepsky_fashion = /datum/beepsky_fashion/fedora + /obj/item/clothing/head/fedora/suicide_act(mob/user) if(user.gender == FEMALE) return 0 @@ -205,7 +211,9 @@ item_state = "sombrero" desc = "You can practically taste the fiesta." flags_inv = HIDEHAIR + dog_fashion = /datum/dog_fashion/head/sombrero + beepsky_fashion = /datum/beepsky_fashion/sombrero /obj/item/clothing/head/sombrero/green name = "green sombrero" @@ -213,6 +221,7 @@ item_state = "greensombrero" desc = "As elegant as a dancing cactus." flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS + dog_fashion = null /obj/item/clothing/head/sombrero/shamebrero @@ -220,6 +229,7 @@ icon_state = "shamebrero" item_state = "shamebrero" desc = "Once it's on, it never comes off." + dog_fashion = null /obj/item/clothing/head/sombrero/shamebrero/Initialize() @@ -248,7 +258,9 @@ item_state = "that" cold_protection = HEAD min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT + dog_fashion = /datum/dog_fashion/head/santa + beepsky_fashion = /datum/beepsky_fashion/santa /obj/item/clothing/head/jester name = "jester hat" @@ -286,6 +298,8 @@ resistance_flags = FIRE_PROOF dynamic_hair_suffix = "" + beepsky_fashion = /datum/beepsky_fashion/king + /obj/item/clothing/head/crown/fancy name = "magnificent crown" desc = "A crown worn by only the highest emperors of the land space." @@ -391,7 +405,9 @@ name = "cowboy hat" desc = "A standard brown cowboy hat, yeehaw." icon_state = "cowboyhat" - item_state= "cowboyhat" + item_state = "cowboyhat" + + beepsky_fashion = /datum/beepsky_fashion/cowboy /obj/item/clothing/head/cowboyhat/black name = "black cowboy hat" @@ -446,3 +462,10 @@ /obj/item/clothing/head/kepi/old icon_state = "kepi_old" desc = "A flat, white circular cap with a visor, that demands some honor from it's wearer." + +/obj/item/clothing/head/maid + name = "maid headband" + desc = "Maid in China." + icon_state = "maid" + item_state = "maid" + dynamic_hair_suffix = "" diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 723fb93b78..1d9c3dd325 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -50,6 +50,8 @@ flags_cover = HEADCOVERSEYES heat = 1000 + beepsky_fashion = /datum/beepsky_fashion/cake + /obj/item/clothing/head/hardhat/cakehat/process() var/turf/location = src.loc if(ishuman(location)) @@ -131,6 +133,7 @@ dynamic_hair_suffix = "" dog_fashion = /datum/dog_fashion/head/kitty + beepsky_fashion = /datum/beepsky_fashion/cat /obj/item/clothing/head/kitty/equipped(mob/living/carbon/human/user, slot) if(ishuman(user) && slot == SLOT_HEAD) @@ -287,7 +290,7 @@ if(!target.IsUnconscious()) to_chat(target, "Your zealous conspirationism rapidly dissipates as the donned hat warps up into a ruined mess. All those theories starting to sound like nothing but a ridicolous fanfare.") -/obj/item/clothing/head/foilhat/attack_hand(mob/user) +/obj/item/clothing/head/foilhat/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!warped && iscarbon(user)) var/mob/living/carbon/C = user if(src == C.head) diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm index 7df38661e5..94f7ee179a 100644 --- a/code/modules/clothing/masks/_masks.dm +++ b/code/modules/clothing/masks/_masks.dm @@ -8,6 +8,7 @@ var/modifies_speech = FALSE var/mask_adjusted = 0 var/adjusted_flags = null + var/datum/beepsky_fashion/beepsky_fashion //the associated datum for applying this to a secbot /obj/item/clothing/mask/attack_self(mob/user) if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE)) @@ -37,7 +38,7 @@ if(blood_DNA) . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color()) -/obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/mask/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 6a836cad7b..c3934aa78c 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -219,7 +219,7 @@ lock = TRUE return -/obj/item/clothing/neck/petcollar/locked/attack_hand(mob/user) +/obj/item/clothing/neck/petcollar/locked/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user && user.get_item_by_slot(SLOT_NECK) && lock != FALSE) to_chat(user, "The collar is locked! You'll need unlock the collar before you can take it off!") return diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 8de65b3a06..c12702424b 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -108,7 +108,7 @@ restore_offsets(user) . = ..() -/obj/item/clothing/shoes/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/shoes/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 695d25dbf4..f563c1029d 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -94,7 +94,7 @@ icon_state = "hardsuit-engineering" item_state = "eng_hardsuit" 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) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser) siemens_coefficient = 0 var/obj/item/clothing/head/helmet/space/hardsuit/helmet @@ -167,7 +167,7 @@ desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." icon_state = "hardsuit0-engineering" item_state = "eng_helm" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75, "wound" = 10) hardsuit_type = "engineering" resistance_flags = FIRE_PROOF @@ -176,7 +176,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding." icon_state = "hardsuit-engineering" item_state = "eng_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75, "wound" = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine resistance_flags = FIRE_PROOF mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC @@ -188,7 +188,7 @@ icon_state = "hardsuit0-atmospherics" item_state = "atmo_helm" hardsuit_type = "atmospherics" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75, "wound" = 10) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -197,7 +197,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding." icon_state = "hardsuit-atmospherics" item_state = "atmo_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75, "wound" = 10) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/atmos @@ -209,7 +209,7 @@ icon_state = "hardsuit0-white" item_state = "ce_helm" hardsuit_type = "white" - armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90) + armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90, "wound" = 10) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -218,7 +218,7 @@ name = "advanced hardsuit" desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish." item_state = "ce_hardsuit" - armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 95, "fire" = 100, "acid" = 90) + armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 95, "fire" = 100, "acid" = 90, "wound" = 10) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/elite @@ -234,7 +234,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF heat_protection = HEAD - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75, "wound" = 15) 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) @@ -249,7 +249,7 @@ item_state = "mining_hardsuit" max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75, "wound" = 15) 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/mining heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -267,7 +267,7 @@ icon_state = "hardsuit1-syndi" item_state = "syndie_helm" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90) + armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90, "wound" = 25) on = FALSE var/obj/item/clothing/suit/space/hardsuit/syndi/linkedsuit = null actions_types = list(/datum/action/item_action/toggle_helmet_mode) @@ -345,7 +345,7 @@ item_state = "syndie_hardsuit" hardsuit_type = "syndi" w_class = WEIGHT_CLASS_NORMAL - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90) + armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90, "wound" = 25) 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) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi jetpack = /obj/item/tank/jetpack/suit @@ -358,7 +358,7 @@ alt_desc = "An elite version of the syndicate helmet, with improved armour and fireproofing. It is in combat mode. Property of Gorlex Marauders." icon_state = "hardsuit0-syndielite" hardsuit_type = "syndielite" - armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100) + armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100, "wound" = 25) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -376,7 +376,7 @@ icon_state = "hardsuit0-syndielite" hardsuit_type = "syndielite" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite - armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100) + armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100, "wound" = 25) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -416,7 +416,7 @@ item_state = "wiz_helm" hardsuit_type = "wiz" resistance_flags = FIRE_PROOF | ACID_PROOF //No longer shall our kind be foiled by lone chemists with spray bottles! - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -431,7 +431,7 @@ item_state = "wiz_hardsuit" w_class = WEIGHT_CLASS_NORMAL resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) allowed = list(/obj/item/teleportation_scroll, /obj/item/tank/internals) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -451,7 +451,7 @@ item_state = "medical_helm" hardsuit_type = "medical" flash_protect = 0 - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75, "wound" = 10) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS @@ -474,7 +474,7 @@ item_state = "medical_hardsuit" slowdown = 0.8 allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/firstaid, /obj/item/healthanalyzer, /obj/item/stack/medical) - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75, "wound" = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/medical mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC @@ -486,7 +486,7 @@ hardsuit_type = "rd" resistance_flags = ACID_PROOF | FIRE_PROOF max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80, "wound" = 15) var/obj/machinery/doppler_array/integrated/bomb_radar clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_research_scanner) @@ -516,7 +516,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT //Same as an emergency firesuit. Not ideal for extended exposure. allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/gun/energy/wormhole_projector, /obj/item/hand_tele, /obj/item/aicard) - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80, "wound" = 15) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/rd //Security hardsuit @@ -526,14 +526,14 @@ icon_state = "hardsuit0-sec" item_state = "sec_helm" hardsuit_type = "sec" - armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75) + armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75, "wound" = 20) /obj/item/clothing/suit/space/hardsuit/security icon_state = "hardsuit-sec" name = "security hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." item_state = "sec_hardsuit" - armor = list("melee" = 35, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75) + armor = list("melee" = 35, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75, "wound" = 20) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC @@ -547,13 +547,13 @@ desc = "A special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor." icon_state = "hardsuit0-hos" hardsuit_type = "hos" - armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95) + armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95, "wound" = 25) /obj/item/clothing/suit/space/hardsuit/security/hos icon_state = "hardsuit-hos" name = "head of security's hardsuit" desc = "A special bulky suit that protects against hazardous, low pressure environments. Has an additional layer of armor." - armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95) + armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95, "wound" = 25) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos jetpack = /obj/item/tank/jetpack/suit @@ -563,7 +563,7 @@ icon_state = "capspace" item_state = "capspacehelmet" desc = "A tactical SWAT helmet MK.II boasting better protection and a horrible fashion sense." - armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR //we want to see the mask heat_protection = HEAD @@ -578,7 +578,7 @@ desc = "A MK.II SWAT suit with streamlined joints and armor made out of superior materials, insulated against intense heat. The most advanced tactical armor available Usually reserved for heavy hitter corporate security, this one has a regal finish in Nanotrasen company colors. Better not let the assistants get a hold of it." icon_state = "caparmor" item_state = "capspacesuit" - armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) resistance_flags = FIRE_PROOF | ACID_PROOF heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT //this needed to be added a long fucking time ago @@ -594,7 +594,7 @@ desc = "A special helmet designed for work in a hazardous, low-humor environment. Has radiation shielding." icon_state = "hardsuit0-clown" item_state = "hardsuit0-clown" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 30) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 30, "wound" = 10) hardsuit_type = "clown" /obj/item/clothing/suit/space/hardsuit/clown @@ -602,7 +602,7 @@ desc = "A special suit that protects against hazardous, low humor environments. Has radiation shielding. Only a true clown can wear it." icon_state = "hardsuit-clown" item_state = "clown_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 30) + armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 30, "wound" = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/clown mutantrace_variation = STYLE_DIGITIGRADE @@ -620,7 +620,7 @@ desc = "Early prototype RIG hardsuit helmet, designed to quickly shift over a user's head. Design constraints of the helmet mean it has no inbuilt cameras, thus it restricts the users visability." icon_state = "hardsuit0-ancient" item_state = "anc_helm" - armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75, "wound" = 10) hardsuit_type = "ancient" resistance_flags = FIRE_PROOF @@ -629,7 +629,7 @@ desc = "Prototype powered RIG hardsuit. Provides excellent protection from the elements of space while being comfortable to move around in, thanks to the powered locomotives. Remains very bulky however." icon_state = "hardsuit-ancient" item_state = "anc_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75) + armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75, "wound" = 10) slowdown = 3 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient resistance_flags = FIRE_PROOF @@ -642,7 +642,7 @@ desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storage bags on to the suit." icon_state = "hardsuit-ancient" item_state = "anc_hardsuit" - armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 10) slowdown = 6 //Slow allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason @@ -655,7 +655,7 @@ desc = "The M.A.S.O.N RIG helmet is complimentary to the rest of the armor. It features a very large, high powered flood lamp and robust flash protection." icon_state = "hardsuit0-ancient" item_state = "anc_helm" - armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 10) hardsuit_type = "ancient" brightness_on = 16 flash_protect = 5 //We will not be flash by bombs @@ -746,7 +746,7 @@ icon_state = "hardsuit-hos" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos allowed = null - armor = list("melee" = 30, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 30, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) resistance_flags = FIRE_PROOF | ACID_PROOF var/max_charges = 3 //How many charges total the shielding has var/current_charges //if null, will default to max_chargs @@ -826,7 +826,7 @@ icon_state = "hardsuit1-syndi" item_state = "syndie_hardsuit" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) 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) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi slowdown = 0 @@ -842,7 +842,7 @@ icon_state = "hardsuit1-syndi" item_state = "syndie_helm" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) ///SWAT version /obj/item/clothing/suit/space/hardsuit/shielded/swat @@ -853,7 +853,7 @@ hardsuit_type = "syndi" max_charges = 4 recharge_delay = 15 - 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 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/swat @@ -865,7 +865,7 @@ icon_state = "deathsquad" item_state = "deathsquad" hardsuit_type = "syndi" - 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 actions_types = list() diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 7df91352ca..ee70f54ed0 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -22,7 +22,7 @@ Contains: desc = "An advanced tactical space helmet." icon_state = "deathsquad" item_state = "deathsquad" - 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 @@ -37,7 +37,7 @@ Contains: icon_state = "deathsquad" 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" = 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 diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 8de49c63de..0d16f9bdfa 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -10,6 +10,7 @@ var/blood_overlay_type = "suit" var/togglename = null var/suittoggled = FALSE + limb_integrity = 0 // disabled for most exo-suits mutantrace_variation = STYLE_DIGITIGRADE /obj/item/clothing/suit/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) @@ -28,7 +29,7 @@ if(A.above_suit) . += U.accessory_overlay -/obj/item/clothing/suit/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/suit/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 0ef1a83bf5..b61743729f 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -8,7 +8,8 @@ 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) + armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 15) + /obj/item/clothing/suit/armor/Initialize() . = ..() @@ -57,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) + armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90, "wound" = 20) cold_protection = CHEST|GROIN|LEGS|ARMS heat_protection = CHEST|GROIN|LEGS|ARMS strip_delay = 80 @@ -123,7 +124,7 @@ icon_state = "capcarapace" item_state = "armor" body_parts_covered = CHEST|GROIN - armor = list("melee" = 50, "bullet" = 40, "laser" = 50, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90) + armor = list("melee" = 50, "bullet" = 40, "laser" = 50, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90, "wound" = 10) dog_fashion = null resistance_flags = FIRE_PROOF @@ -147,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) + armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80, "wound" = 30) blocks_shove_knockdown = TRUE strip_delay = 80 equip_delay_other = 60 @@ -158,7 +159,7 @@ icon_state = "bonearmor" item_state = "bonearmor" blood_overlay_type = "armor" - armor = list("melee" = 35, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list("melee" = 35, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS /obj/item/clothing/suit/armor/bulletproof @@ -167,7 +168,7 @@ icon_state = "bulletproof" item_state = "armor" blood_overlay_type = "armor" - armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 20) strip_delay = 70 equip_delay_other = 50 mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -285,7 +286,7 @@ desc = "A classic suit of armour, able to be made from many different materials." icon_state = "knight_greyscale" item_state = "knight_greyscale" - armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40) + armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40, "wound" = 15) material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS //Can change color and add prefix /obj/item/clothing/suit/armor/vest/durathread @@ -304,7 +305,7 @@ desc = "A bulletproof vest with forest camo. Good thing there's plenty of forests to hide in around here, right?" icon_state = "rus_armor" item_state = "rus_armor" - armor = list("melee" = 25, "bullet" = 30, "laser" = 0, "energy" = 15, "bomb" = 10, "bio" = 0, "rad" = 20, "fire" = 20, "acid" = 50) + armor = list("melee" = 25, "bullet" = 30, "laser" = 0, "energy" = 15, "bomb" = 10, "bio" = 0, "rad" = 20, "fire" = 20, "acid" = 50, "wound" = 10) /obj/item/clothing/suit/armor/vest/russian_coat name = "russian battle coat" @@ -315,4 +316,4 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50) + armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50, "wound" = 10) diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index 047dc7b7a3..977e916f87 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -4,11 +4,12 @@ icon_state = "wizard" gas_transfer_coefficient = 0.01 // IT'S MAGICAL OKAY JEEZ +1 TO NOT DIE permeability_coefficient = 0.01 - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) + armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 20) strip_delay = 50 equip_delay_other = 50 resistance_flags = FIRE_PROOF | ACID_PROOF dog_fashion = /datum/dog_fashion/head/blue_wizard + beepsky_fashion = /datum/beepsky_fashion/wizard var/magic_flags = SPELL_WIZARD_HAT /obj/item/clothing/head/wizard/ComponentInitialize() @@ -73,7 +74,7 @@ gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 body_parts_covered = CHEST|GROIN|ARMS|LEGS - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) + armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 20) allowed = list(/obj/item/teleportation_scroll) flags_inv = HIDEJUMPSUIT strip_delay = 50 diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index e0ecf24204..23cb2b1c15 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -5,8 +5,9 @@ permeability_coefficient = 0.9 block_priority = BLOCK_PRIORITY_UNIFORM slot_flags = ITEM_SLOT_ICLOTHING - 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) mutantrace_variation = STYLE_DIGITIGRADE|USE_TAUR_CLIP_MASK + limb_integrity = 30 var/fitted = FEMALE_UNIFORM_FULL // For use in alternate clothing styles for women var/has_sensor = HAS_SENSORS // For the crew computer var/random_sensor = TRUE @@ -39,7 +40,7 @@ if(!attach_accessory(I, user)) return ..() -/obj/item/clothing/under/update_clothes_damaged_state(damaging = TRUE) +/obj/item/clothing/under/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc diff --git a/code/modules/clothing/under/jobs/cargo.dm b/code/modules/clothing/under/jobs/cargo.dm index aa4db2fd30..8fbc343598 100644 --- a/code/modules/clothing/under/jobs/cargo.dm +++ b/code/modules/clothing/under/jobs/cargo.dm @@ -34,8 +34,9 @@ mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/under/rank/cargo/miner - desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty." name = "shaft miner's jumpsuit" + desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty." + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 0, "wound" = 10) icon_state = "miner" item_state = "miner" diff --git a/code/modules/clothing/under/jobs/command.dm b/code/modules/clothing/under/jobs/command.dm index 1bc0f64373..8272c36cf3 100644 --- a/code/modules/clothing/under/jobs/command.dm +++ b/code/modules/clothing/under/jobs/command.dm @@ -19,6 +19,7 @@ /obj/item/clothing/under/rank/captain/suit name = "captain's suit" desc = "A green suit and yellow necktie. Exemplifies authority." + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 15) icon_state = "green_suit" item_state = "dg_suit" can_adjust = FALSE diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index 26fff7c8ed..7747d2e181 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -19,7 +19,7 @@ desc = "A tactical security jumpsuit for officers complete with Nanotrasen belt buckle." icon_state = "rsecurity" item_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) /obj/item/clothing/under/rank/security/officer/grey name = "grey security jumpsuit" @@ -67,7 +67,7 @@ desc = "A formal security suit for officers complete with Nanotrasen belt buckle." icon_state = "rwarden" item_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) /obj/item/clothing/under/rank/security/warden/grey name = "grey security suit" @@ -101,7 +101,7 @@ desc = "Someone who wears this means business." icon_state = "detective" item_state = "det" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) /obj/item/clothing/under/rank/security/detective/skirt name = "detective's suitskirt" @@ -138,7 +138,7 @@ desc = "A security jumpsuit decorated for those few with the dedication to achieve the position of Head of Security." icon_state = "rhos" item_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) strip_delay = 60 /obj/item/clothing/under/rank/security/head_of_security/skirt diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index 0ace65ffd3..cf2ac93360 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -143,7 +143,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 if(L && (L.density || prob(10))) L.ex_act(EXPLODE_HEAVY) -obj/effect/immovablerod/attack_hand(mob/living/user) +obj/effect/immovablerod/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(ishuman(user)) var/mob/living/carbon/human/U = user if(U.job in list("Research Director")) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index a17df4db9a..ad786561f4 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -346,7 +346,7 @@ SM.on_cross(src, AM) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/spacevine/attack_hand(mob/user) +/obj/structure/spacevine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) for(var/datum/spacevine_mutation/SM in mutations) SM.on_hit(src, user) user_unbuckle_mob(user, user) diff --git a/code/modules/events/stray_cargo.dm b/code/modules/events/stray_cargo.dm index 02d02a8510..031642c875 100644 --- a/code/modules/events/stray_cargo.dm +++ b/code/modules/events/stray_cargo.dm @@ -2,7 +2,7 @@ /datum/round_event_control/stray_cargo name = "Stray Cargo Pod" typepath = /datum/round_event/stray_cargo - weight = 20 + weight = 5 max_occurrences = 4 earliest_start = 10 MINUTES diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 900fc99171..adb8e47c94 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -13,15 +13,31 @@ The nutriment reagent and bitesize variable replace the old heal_amt and amount bitesize of 2, then it'll take 3 bites to eat. Unlike the old system, the contained reagents are evenly spread among all the bites. No more contained reagents = no more bites. -Here is an example of the new formatting for anyone who wants to add more food items. +Food formatting and crafting examples. ``` -/obj/item/reagent_containers/food/snacks/xenoburger //Identification path for the object. - name = "Xenoburger" //Name that displays in the UI. - desc = "Smells caustic. Tastes like heresy." //Duh - icon_state = "xburger" //Refers to an icon in food.dmi - list_reagents = list(/datum/reagent/xenomicrobes = 10, - /datum/reagent/consumable/nutriment = 2) //What's inside the snack. - bitesize = 3 //This is the amount each bite consumes. +/obj/item/reagent_containers/food/snacks/saltedcornchips //Identification path for the object. + name = "salted corn chips" //Name that displays when hovered over. + desc = "Manufactured in a far away factory." //Description on examine. + icon_state = "saltychip" //Refers to an icon, usually in food.dmi + bitesize = 3 //How many reagents are consumed in each bite. + list_reagents = list(/datum/reagent/consumable/nutriment = 6, //What's inside the snack, but only if spawned. For example, from a chemical reaction, vendor, or slime core spawn. + /datum/reagent/consumable/nutriment/vitamin = 2) + bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, //What's -added- to the food, in addition to the reagents contained inside the foods used to craft it. Basically, a reward for cooking. + /datum/reagent/consumable/nutriment/vitamin = 1) ^^For example. Egg+Egg = 2Egg + Bonus Reagents. + filling_color = "#F4A460" //What color it will use if put in a custom food. + tastes = list("salt" = 1, "oil" = 1) //Descriptive flavoring displayed when eaten. IE: "You taste a bit of salt and a bit of oil." + foodtype = GRAIN | JUNKFOOD //Tag for racial or custom food preferences. IE: Most Lizards cannot have GRAIN. + +Crafting Recipe (See files in code/modules/food_and_drinks/recipes/tablecraft/) + +/datum/crafting_recipe/food/nachos + name ="Salted Corn Chips" //Name that displays in the Crafting UI + reqs = list( //The list of ingredients to make the food. + /obj/item/reagent_containers/food/snacks/tortilla = 1, + /datum/reagent/consumable/sodiumchloride = 1 //As a note, reagents and non-food items don't get added to the food. If you + ) ^^want the reagents, make sure the food item has it listed under bonus_reagents. + result = /obj/item/reagent_containers/food/snacks/saltedcornchips //Resulting object. + subcategory = CAT_MISCFOOD //Subcategory the food falls under in the Food Tab of the crafting menu. ``` All foods are distributed among various categories. Use common sense. @@ -390,3 +406,13 @@ All foods are distributed among various categories. Use common sense. TB.MouseDrop(over) else return ..() + +// //////////////////////////////////////////////Frying//////////////////////////////////////// +/atom/proc/fry(cook_time = 30) //you can truly fry anything + //don't fry reagent containers that aren't food items, indestructable items, or items that are already fried + if(isitem(src)) + var/obj/item/fried_item = src + if(fried_item.resistance_flags & INDESTRUCTIBLE) + return + if(!GetComponent(/datum/component/fried) && (!reagents || isfood(src) || ismob(src))) + AddComponent(/datum/component/fried, frying_power = cook_time) diff --git a/code/modules/food_and_drinks/food/snacks_bread.dm b/code/modules/food_and_drinks/food/snacks_bread.dm index f3d84f7169..0d7c715654 100644 --- a/code/modules/food_and_drinks/food/snacks_bread.dm +++ b/code/modules/food_and_drinks/food/snacks_bread.dm @@ -191,93 +191,6 @@ tastes = list("bread" = 1, "garlic" = 1, "butter" = 1) foodtype = GRAIN -/obj/item/reagent_containers/food/snacks/deepfryholder - name = "Deep Fried Foods Holder Obj" - desc = "If you can see this description the code for the deep fryer fucked up." - icon = 'icons/obj/food/food.dmi' - icon_state = "" - bitesize = 2 - var/fried_garbage = FALSE //did you really fry a fire extinguisher? - -GLOBAL_VAR_INIT(frying_hardmode, TRUE) -GLOBAL_VAR_INIT(frying_bad_chem_add_volume, TRUE) -GLOBAL_LIST_INIT(frying_bad_chems, list( -/datum/reagent/toxin/bad_food = 3, -/datum/reagent/drug/aranesp = 2, -/datum/reagent/toxin = 2, -/datum/reagent/lithium = 2, -/datum/reagent/mercury = 2, -)) - -/obj/item/reagent_containers/food/snacks/deepfryholder/Initialize(mapload, obj/item/fried) - . = ..() - name = fried.name //We'll determine the other stuff when it's actually removed - appearance = fried.appearance - layer = initial(layer) - plane = initial(plane) - lefthand_file = fried.lefthand_file - righthand_file = fried.righthand_file - item_state = fried.item_state - desc = fried.desc - w_class = fried.w_class - slowdown = fried.slowdown - equip_delay_self = fried.equip_delay_self - equip_delay_other = fried.equip_delay_other - strip_delay = fried.strip_delay - species_exception = fried.species_exception - item_flags = fried.item_flags - obj_flags = fried.obj_flags - - if(isfood(fried)) - fried.reagents.trans_to(src, fried.reagents.total_volume) - qdel(fried) - else - fried.forceMove(src) - trash = fried - fried_garbage = TRUE - -/obj/item/reagent_containers/food/snacks/deepfryholder/Destroy() - if(trash) - QDEL_NULL(trash) - . = ..() - -/obj/item/reagent_containers/food/snacks/deepfryholder/On_Consume(mob/living/eater) - if(fried_garbage && GLOB.frying_hardmode && GLOB.frying_bad_chems.len) - var/R = rand(1, GLOB.frying_bad_chems.len) - var/bad_chem = GLOB.frying_bad_chems[R] - var/bad_chem_amount = GLOB.frying_bad_chems[bad_chem] - eater.reagents.add_reagent(bad_chem, bad_chem_amount) - //All fried inedible items also get condensed cooking oil added, which induces minor vomiting and heart damage - eater.reagents.add_reagent(/datum/reagent/toxin/condensed_cooking_oil, 2) - if(trash) - QDEL_NULL(trash) - ..() - -/obj/item/reagent_containers/food/snacks/deepfryholder/proc/fry(cook_time = 30) - switch(cook_time) - if(0 to 15) - add_atom_colour(rgb(166,103,54), FIXED_COLOUR_PRIORITY) - name = "lightly-fried [name]" - desc = "[desc] It's been lightly fried in a deep fryer." - adjust_food_quality(food_quality - 5) - if(16 to 49) - add_atom_colour(rgb(103,63,24), FIXED_COLOUR_PRIORITY) - name = "fried [name]" - desc = "[desc] It's been fried, increasing its tastiness value by [rand(1, 75)]%." - adjust_food_quality(food_quality - 10) - if(50 to 59) - add_atom_colour(rgb(63,23,4), FIXED_COLOUR_PRIORITY) - name = "deep-fried [name]" - desc = "[desc] Deep-fried to perfection." - adjust_food_quality(food_quality) //we shouldn't punish perfection in the fried arts - if(60 to INFINITY) - add_atom_colour(rgb(33,19,9), FIXED_COLOUR_PRIORITY) - name = "the physical manifestation of the very concept of fried foods" - desc = "A heavily-fried...something. Who can tell anymore?" - adjust_food_quality(0) //good job, you're truly the best cook. - filling_color = color - foodtype |= FRIED - /obj/item/reagent_containers/food/snacks/butteredtoast name = "buttered toast" desc = "Butter lightly spread over a piece of toast." diff --git a/code/modules/food_and_drinks/food/snacks_meat.dm b/code/modules/food_and_drinks/food/snacks_meat.dm index e25f99c69e..2a4139dbb9 100644 --- a/code/modules/food_and_drinks/food/snacks_meat.dm +++ b/code/modules/food_and_drinks/food/snacks_meat.dm @@ -174,6 +174,27 @@ tastes = list("meat" = 1, "smoke" = 1) foodtype = MEAT +/obj/item/reagent_containers/food/snacks/meatloaf + name = "meatloaf" + desc = "Meat! In a loaf!" + icon_state = "meatloaf" + filling_color = "#8f0f0f" + list_reagents = list(/datum/reagent/consumable/nutriment = 10) + bonus_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/consumable/ketchup = 5) + tastes = list("meat" = 1, "ketchup" = 1) + slices_num = 5 + slice_path = /obj/item/reagent_containers/food/snacks/meatloaf_slice + foodtype = MEAT + +/obj/item/reagent_containers/food/snacks/meatloaf_slice + name = "meatloaf slice" + filling_color = "#8f0f0f" + desc = "Meat! In chunky slices!" + icon_state = "meatloaf_slice" + list_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/ketchup = 1) + tastes = list("meat" = 1, "ketchup" = 1) + foodtype = MEAT + /obj/item/reagent_containers/food/snacks/kebab trash = /obj/item/stack/rods icon_state = "kebab" @@ -302,6 +323,16 @@ desc = "A 'chicken' nugget vaguely shaped like a [shape]." icon_state = "nugget_[shape]" +/obj/item/reagent_containers/food/snacks/sweet_and_sour + name = "sweet and sour chicken" + desc = "More sweet than sour, but delicious nonetheless." + icon_state = "sweet_and_sour" + filling_color = "#B22222" + bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/soysauce = 2) + list_reagents = list(/datum/reagent/consumable/nutriment = 9, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/consumable/soysauce = 2) + tastes = list("\"chicken\"" = 1) + foodtype = MEAT | PINEAPPLE + /obj/item/reagent_containers/food/snacks/pigblanket name = "pig in a blanket" desc = "A tiny sausage wrapped in a flakey, buttery roll. Free this pig from its blanket prison by eating it." diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index 7b0ffe2a19..e0697cecea 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -557,6 +557,26 @@ tastes = list("butter" = 1) foodtype = JUNKFOOD +/obj/item/reagent_containers/food/snacks/mashedpotato + name = "mashed potatoes" + desc = "A diced and smashed potato, served with sour cream." + icon_state = "mashedpotato" + list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/consumable/sodiumchloride = 1) + bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1) + filling_color = "#FFD700" + tastes = list("butter" = 1, "sour cream" = 1) + foodtype = GRAIN + +/obj/item/reagent_containers/food/snacks/butteredpotato + name = "buttered potatoes" + desc = "Mashed potatoes served with an ample serving of butter, and sour cream." + icon_state = "buttermash" + list_reagents = list(/datum/reagent/consumable/nutriment = 7, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/consumable/sodiumchloride = 2) + bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 1) + filling_color = "#FFD700" + tastes = list("potatoes" = 1, "sour cream" = 1, "butter" = 1) + foodtype = GRAIN | DAIRY + /obj/item/reagent_containers/food/snacks/onionrings name = "onion rings" desc = "Onion slices coated in batter." diff --git a/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm b/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm index d812655b91..a606b9fe5a 100644 --- a/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm +++ b/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm @@ -153,3 +153,13 @@ bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3) tastes = list("tuna" = 4, "mayonnaise" = 2, "bread" = 2) foodtype = GRAIN | MEAT + +/obj/item/reagent_containers/food/snacks/meatballsub + name = "meatball sub" + desc = "At some point, you need to be the cheif sub." + icon = 'icons/obj/food/food.dmi' + icon_state = "meatballsub" + list_reagents = list(/datum/reagent/consumable/nutriment = 12, /datum/reagent/consumable/nutriment/vitamin = 4) + bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3) + tastes = list("meat" = 2, "toasted bread" = 1) + foodtype = GRAIN | MEAT diff --git a/code/modules/food_and_drinks/food/snacks_soup.dm b/code/modules/food_and_drinks/food/snacks_soup.dm index a6a251a84c..ffafcc6b1e 100644 --- a/code/modules/food_and_drinks/food/snacks_soup.dm +++ b/code/modules/food_and_drinks/food/snacks_soup.dm @@ -125,6 +125,15 @@ tastes = list("tomato" = 1, "mint" = 1) foodtype = VEGETABLES +/obj/item/reagent_containers/food/snacks/soup/bearchili + name = "bear chili" + desc = "Sensationally seasoned bear meat diced up with some peppers." + icon_state = "bearchili" + bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/consumable/capsaicin = 1) + list_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/medicine/morphine = 5, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/consumable/capsaicin = 5) + tastes = list("the outdoors" = 1, "hot peppers" = 1) + foodtype = VEGETABLES | MEAT + /obj/item/reagent_containers/food/snacks/soup/monkeysdelight name = "monkey's delight" desc = "A delicious soup with dumplings and hunks of monkey meat simmered to perfection, in a broth that tastes faintly of bananas." @@ -253,6 +262,16 @@ filling_color = "#CC2B52" foodtype = VEGETABLES | TOXIC +/obj/item/reagent_containers/food/snacks/soup/spiral_soup + name = "spiral soup" + desc = "The swirling of this soup is both frightening, and enticing." + icon_state = "spiral_soup" + list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/liquidelectricity = 5, /datum/reagent/cryptobiolin = 10, /datum/reagent/toxin/rotatium = 10) + bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/cryptobiolin = 15, /datum/reagent/toxin/rotatium = 15, /datum/reagent/consumable/liquidelectricity = 2) + tastes = list("the floor" = 1, "the ceiling" = 1, "regret" = 2) + filling_color = "#4476e2" + foodtype = GROSS | TOXIC | VEGETABLES + /obj/item/reagent_containers/food/snacks/soup/bungocurry name = "bungo curry" desc = "A spicy vegetable curry made with the humble bungo fruit, Exotic!" diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 0a3d172bb0..f3c63c1ba2 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -29,7 +29,7 @@ God bless America. use_power = IDLE_POWER_USE idle_power_usage = 5 layer = BELOW_OBJ_LAYER - var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW? + var/obj/item/frying //What's being fried RIGHT NOW? var/cook_time = 0 var/oil_use = 0.05 //How much cooking oil is used per tick var/fry_speed = 1 //How quickly we fry food @@ -91,25 +91,21 @@ God bless America. if(I.resistance_flags & INDESTRUCTIBLE) to_chat(user, "You don't feel it would be wise to fry [I]...") return - if(istype(I, /obj/item/reagent_containers/food/snacks/deepfryholder)) + if(I.GetComponent(/datum/component/fried)) to_chat(user, "Your cooking skills are not up to the legendary Doublefry technique.") return if(default_unfasten_wrench(user, I)) return else if(default_deconstruction_screwdriver(user, "fryer_off", "fryer_off" ,I)) //where's the open maint panel icon?! return + else if(I.reagents && !isfood(I)) + return else if(is_type_in_typecache(I, deepfry_blacklisted_items) || HAS_TRAIT(I, TRAIT_NODROP) || (I.item_flags & (ABSTRACT | DROPDEL))) return ..() else if(!frying && user.transferItemToLoc(I, src)) + frying = I to_chat(user, "You put [I] into [src].") - frying = new/obj/item/reagent_containers/food/snacks/deepfryholder(src, I) - //setup food quality for item depending on if it's edible or not - if(isfood(I)) - var/obj/item/reagent_containers/food/original_food = I - frying.adjust_food_quality(original_food.food_quality) //food quality remains unchanged until degree of frying is calculated - else - frying.adjust_food_quality(10) //inedible fried item has low quality icon_state = "fryer_on" fry_loop.start() @@ -134,7 +130,7 @@ God bless America. /obj/machinery/deepfryer/attack_ai(mob/user) return -/obj/machinery/deepfryer/attack_hand(mob/user) +/obj/machinery/deepfryer/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(frying) if(frying.loc == src) to_chat(user, "You eject [frying] from [src].") diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index dcea93f06f..53da7326a2 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -63,7 +63,7 @@ /obj/machinery/gibber/relaymove(mob/living/user) go_out() -/obj/machinery/gibber/attack_hand(mob/user) +/obj/machinery/gibber/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/food_and_drinks/kitchen_machinery/grill.dm b/code/modules/food_and_drinks/kitchen_machinery/grill.dm index 547ed244c0..a5a90b33e4 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/grill.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/grill.dm @@ -107,7 +107,7 @@ /obj/machinery/grill/attack_ai(mob/user) return -/obj/machinery/grill/attack_hand(mob/user) +/obj/machinery/grill/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(grilled_item) to_chat(user, "You take out [grilled_item] from [src].") grilled_item.forceMove(drop_location()) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index 19ded25b08..006c3fb6ad 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -107,7 +107,7 @@ update_icon() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/pizzabox/attack_hand(mob/user) +/obj/item/pizzabox/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.get_inactive_held_item() != src) return ..() if(open) diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm index 60b363c168..17ea36a160 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm @@ -84,6 +84,17 @@ result = /obj/item/reagent_containers/food/snacks/nugget subcategory = CAT_MEAT +/datum/crafting_recipe/food/sweet_and_sour + name = "Sweet and sour \"chicken\"" + reqs = list( + /obj/item/reagent_containers/food/snacks/nugget = 2, + /obj/item/reagent_containers/food/snacks/pineappleslice = 1, + /datum/reagent/consumable/soysauce = 2, + /datum/reagent/consumable/sodiumchloride = 1 + ) + result = /obj/item/reagent_containers/food/snacks/sweet_and_sour + subcategory = CAT_MEAT + /datum/crafting_recipe/food/corndog name = "Corndog meal" reqs = list( @@ -135,6 +146,16 @@ result = /obj/item/reagent_containers/food/snacks/sausage subcategory = CAT_MEAT +/datum/crafting_recipe/food/meatloaf + name = "Meatloaf" + reqs = list( + /obj/item/reagent_containers/food/snacks/meat/cutlet = 4, + /datum/reagent/consumable/eggyolk = 10, + /datum/reagent/consumable/ketchup = 5 + ) + result = /obj/item/reagent_containers/food/snacks/meatloaf + subcategory = CAT_MEAT + /datum/crafting_recipe/food/pigblanket name = "Pig in a Blanket" reqs = list( diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm index bbaa49a1eb..affb76cca7 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm @@ -113,6 +113,25 @@ result = /obj/item/reagent_containers/food/snacks/loadedbakedpotato subcategory = CAT_MISCFOOD +/datum/crafting_recipe/food/mashedpotato + name = "Mashed potato" + reqs = list( + /obj/item/reagent_containers/food/snacks/grown/potato = 1, + /datum/reagent/consumable/cream = 5, + /datum/reagent/consumable/sodiumchloride = 1 + ) + result = /obj/item/reagent_containers/food/snacks/mashedpotato + subcategory = CAT_MISCFOOD + +/datum/crafting_recipe/food/butteredpotato + name = "Buttered mash" + reqs = list( + /obj/item/reagent_containers/food/snacks/mashedpotato = 1, + /obj/item/reagent_containers/food/snacks/butter = 1 + ) + result = /obj/item/reagent_containers/food/snacks/butteredpotato + subcategory = CAT_MISCFOOD + /datum/crafting_recipe/food/melonfruitbowl name ="Melon fruit bowl" reqs = list( diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm index 60bcd65a80..81c5b4dd92 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm @@ -115,6 +115,15 @@ result = /obj/item/reagent_containers/food/snacks/tuna_sandwich subcategory = CAT_SANDWICH +/datum/crafting_recipe/food/meatballsub + name = "Meatball sub" + reqs = list( + /obj/item/reagent_containers/food/snacks/meatball = 3, + /obj/item/reagent_containers/food/snacks/bun = 1 + ) + result = /obj/item/reagent_containers/food/snacks/meatballsub + subcategory = CAT_SANDWICH + /datum/crafting_recipe/food/hotdog name = "Hot dog" reqs = list( diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm index 8f4b4c2726..6372137edc 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm @@ -13,6 +13,17 @@ result = /obj/item/reagent_containers/food/snacks/soup/amanitajelly subcategory = CAT_SOUP +/datum/crafting_recipe/food/bearchili + name = "Bear chili" + reqs = list( + /datum/reagent/water = 10, + /obj/item/reagent_containers/glass/bowl = 1, + /obj/item/reagent_containers/food/snacks/meat/steak/bear = 1, + /obj/item/reagent_containers/food/snacks/grown/chili = 1, + ) + result = /obj/item/reagent_containers/food/snacks/soup/bearchili + subcategory = CAT_SOUP + /datum/crafting_recipe/food/beetsoup name = "Beet soup" reqs = list( @@ -204,6 +215,18 @@ result = /obj/item/reagent_containers/food/snacks/soup/spacylibertyduff subcategory = CAT_SOUP +/datum/crafting_recipe/food/spiralsoup + name = "Spiral soup" + reqs = list( + /obj/item/reagent_containers/glass/bowl = 1, + /obj/item/reagent_containers/food/snacks/grown/mushroom/jupitercup = 2, + /datum/reagent/cryptobiolin = 15, + /datum/reagent/toxin/rotatium = 15, + /datum/reagent/consumable/milk = 10 + ) + result = /obj/item/reagent_containers/food/snacks/soup/spacylibertyduff + subcategory = CAT_SOUP + /datum/crafting_recipe/food/sweetpotatosoup name = "Sweet potato soup" reqs = list( diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 3455a97ba2..93c733391e 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -313,6 +313,8 @@ 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%;} .boldnotice {color: #000099; font-weight: bold;} .adminnotice {color: #0000ff;} .adminhelp {color: #ff0000; font-weight: bold;} diff --git a/code/modules/holiday/halloween/bartholomew.dm b/code/modules/holiday/halloween/bartholomew.dm index 82ac374525..eb90a0c82d 100644 --- a/code/modules/holiday/halloween/bartholomew.dm +++ b/code/modules/holiday/halloween/bartholomew.dm @@ -31,7 +31,7 @@ return say("It doesn't seem like that's magical enough!") -/obj/item/barthpot/attack_hand(mob/user) +/obj/item/barthpot/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!active) say("Meow!") return diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm index 957d9df376..01e71d1129 100644 --- a/code/modules/holiday/halloween/jacqueen.dm +++ b/code/modules/holiday/halloween/jacqueen.dm @@ -406,14 +406,14 @@ . = ..() ADD_TRAIT(src, TRAIT_NODROP, GLUED_ITEM_TRAIT) -/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user) +/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) to_chat(user, "Boooooo~!") return else ..() -/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user) +/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) to_chat(user, "Boooooo~!") return diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 0c5b5a4031..b6c89bcf0e 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -105,7 +105,7 @@ if(user.transferItemToLoc(W, drop_location())) visible_message(" [user] dunks [W] into \the [src]!") -/obj/structure/holohoop/attack_hand(mob/user) +/obj/structure/holohoop/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/holodeck/turfs.dm b/code/modules/holodeck/turfs.dm index 7b5b0586d1..f686bee63a 100644 --- a/code/modules/holodeck/turfs.dm +++ b/code/modules/holodeck/turfs.dm @@ -134,7 +134,7 @@ tiled_dirt = FALSE baseturfs = /turf/open/floor/holofloor/snow -/turf/open/floor/holofloor/snow/attack_hand(mob/living/user) +/turf/open/floor/holofloor/snow/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm index 11bb44ce97..70e204a14f 100644 --- a/code/modules/hydroponics/fermenting_barrel.dm +++ b/code/modules/hydroponics/fermenting_barrel.dm @@ -56,7 +56,7 @@ else return ..() -/obj/structure/fermenting_barrel/attack_hand(mob/user) +/obj/structure/fermenting_barrel/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) open = !open if(open) DISABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE) diff --git a/code/modules/hydroponics/grown/chili.dm b/code/modules/hydroponics/grown/chili.dm index 0522b5fd45..42674029fb 100644 --- a/code/modules/hydroponics/grown/chili.dm +++ b/code/modules/hydroponics/grown/chili.dm @@ -80,7 +80,7 @@ foodtype = FRUIT wine_power = 50 -/obj/item/reagent_containers/food/snacks/grown/ghost_chili/attack_hand(mob/user) +/obj/item/reagent_containers/food/snacks/grown/ghost_chili/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index f4748ccde8..6ac7bbcfcb 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -107,8 +107,8 @@ icon_state = "orang" filling_color = "#FFA500" juice_results = list(/datum/reagent/consumable/orangejuice = 0) - distill_reagent = /datum/reagent/consumable/ethanol/triple_sec - tastes = list("polygons" = 1, "oranges" = 1) + distill_reagent = /datum/reagent/toxin/mindbreaker + tastes = list("polygons" = 1, "bluespace" = 1, "the true nature of reality" = 1) /obj/item/reagent_containers/food/snacks/grown/citrus/orange_3d/pickup(mob/user) . = ..() diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm index 6c852c426d..ad09751e44 100644 --- a/code/modules/hydroponics/grown/corn.dm +++ b/code/modules/hydroponics/grown/corn.dm @@ -38,6 +38,7 @@ throwforce = 0 throw_speed = 3 throw_range = 7 + grind_results = list(/datum/reagent/cellulose = 10) /obj/item/grown/corncob/attackby(obj/item/grown/W, mob/user, params) if(W.get_sharpness()) diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm index 01044cda25..fe60e9f397 100644 --- a/code/modules/hydroponics/grown/misc.dm +++ b/code/modules/hydroponics/grown/misc.dm @@ -504,3 +504,34 @@ prime() if(!QDELETED(src)) qdel(src) + +/obj/item/seeds/aloe + name = "pack of aloe seeds" + desc = "These seeds grow into aloe." + icon_state = "seed-aloe" + species = "aloe" + plantname = "Aloe" + product = /obj/item/reagent_containers/food/snacks/grown/aloe + lifespan = 60 + endurance = 25 + maturation = 4 + production = 4 + yield = 6 + growthstages = 5 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + reagents_add = list(/datum/reagent/consumable/nutriment/vitamin = 0.05, /datum/reagent/consumable/nutriment = 0.05) + +/obj/item/reagent_containers/food/snacks/grown/aloe + seed = /obj/item/seeds/aloe + name = "aloe" + desc = "Cut leaves from the aloe plant." + icon_state = "aloe" + filling_color = "#90EE90" + bitesize_mod = 5 + foodtype = VEGETABLES + juice_results = list(/datum/reagent/consumable/aloejuice = 0) + distill_reagent = /datum/reagent/consumable/ethanol/tequila + +/obj/item/reagent_containers/food/snacks/grown/aloe/microwave_act(obj/machinery/microwave/M) + new /obj/item/stack/medical/aloe(drop_location(), 2) + qdel(src) \ No newline at end of file diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index 0979ea483f..cee7748c59 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -90,6 +90,7 @@ icon_state = "deathnettle" force = 30 throwforce = 15 + wound_bonus = CANT_WOUND /obj/item/reagent_containers/food/snacks/grown/nettle/death/add_juice() ..() diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 28ae5f4b69..164c27d105 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -16,6 +16,7 @@ icon_dead = "towercap-dead" genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) mutatelist = list(/obj/item/seeds/tower/steel) + reagents_add = list(/datum/reagent/cellulose = 0.05) /obj/item/seeds/tower/steel name = "pack of steel-cap mycelium" @@ -25,6 +26,7 @@ plantname = "Steel Caps" product = /obj/item/grown/log/steel mutatelist = list() + reagents_add = list(/datum/reagent/cellulose = 0.05, /datum/reagent/iron = 0.05) rarity = 20 /obj/item/grown/log @@ -205,7 +207,7 @@ return ..() -/obj/structure/bonfire/attack_hand(mob/user) +/obj/structure/bonfire/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index b7665d7b5d..b673937c9c 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -888,7 +888,7 @@ return ..() -/obj/machinery/hydroponics/attack_hand(mob/user) +/obj/machinery/hydroponics/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index a666a36099..887ea0417c 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -157,12 +157,12 @@ /datum/plant_gene/reagent/polypyr name = "Polypyrylium Oligomers" - reagent_id = "polypyr" + reagent_id = /datum/reagent/medicine/polypyr rate = 0.15 /datum/plant_gene/reagent/liquidelectricity name = "Liquid Electricity" - reagent_id = "liquidelectricity" + reagent_id = /datum/reagent/consumable/liquidelectricity rate = 0.1 // Various traits affecting the product. Each must be somehow useful. diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 384991e976..c3e0a7abcc 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -611,7 +611,7 @@ return ..() -/obj/item/electronic_assembly/attack_hand(mob/user) +/obj/item/electronic_assembly/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(anchored) attack_self(user) return diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index c700d668c5..bd36218211 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -203,21 +203,24 @@ var/pda_slot = SLOT_BELT /datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) - switch(preference_source?.prefs.backbag) - if(GBACKPACK) - back = /obj/item/storage/backpack //Grey backpack - if(GSATCHEL) - back = /obj/item/storage/backpack/satchel //Grey satchel - if(GDUFFELBAG) - back = /obj/item/storage/backpack/duffelbag //Grey Duffel bag - if(LSATCHEL) - back = /obj/item/storage/backpack/satchel/leather //Leather Satchel - if(DSATCHEL) - back = satchel //Department satchel - if(DDUFFELBAG) - back = duffelbag //Department duffel bag - else - back = backpack //Department backpack + var/preference_backpack = preference_source?.prefs.backbag + + if(preference_backpack) + switch(preference_backpack) + if(DBACKPACK) + back = backpack //Department backpack + if(DSATCHEL) + back = satchel //Department satchel + if(DDUFFELBAG) + back = duffelbag //Department duffel bag + else + var/find_preference_backpack = GLOB.backbaglist[preference_backpack] //attempt to find non-department backpack + if(find_preference_backpack) + back = find_preference_backpack + else //tried loading in a backpack that we don't allow as a loadout one + back = backpack + else //somehow doesn't have a preference set, should never reach this point but just-in-case + back = backpack //converts the uniform string into the path we'll wear, whether it's the skirt or regular variant var/holder diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm index adee2856fa..9cbc15ca28 100644 --- a/code/modules/jobs/job_types/chief_medical_officer.dm +++ b/code/modules/jobs/job_types/chief_medical_officer.dm @@ -45,7 +45,7 @@ shoes = /obj/item/clothing/shoes/sneakers/brown suit = /obj/item/clothing/suit/toggle/labcoat/cmo l_hand = /obj/item/storage/firstaid/regular - suit_store = /obj/item/flashlight/pen + suit_store = /obj/item/flashlight/pen/paramedic backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1) backpack = /obj/item/storage/backpack/medic diff --git a/code/modules/jobs/job_types/paramedic.dm b/code/modules/jobs/job_types/paramedic.dm index 9bdfdfe279..c8188cae8a 100644 --- a/code/modules/jobs/job_types/paramedic.dm +++ b/code/modules/jobs/job_types/paramedic.dm @@ -36,7 +36,7 @@ suit = /obj/item/clothing/suit/toggle/labcoat/paramedic belt = /obj/item/storage/belt/medical l_hand = /obj/item/storage/firstaid/regular - suit_store = /obj/item/flashlight/pen + suit_store = /obj/item/flashlight/pen/paramedic id = /obj/item/card/id r_pocket = /obj/item/pinpointer/crew l_pocket = /obj/item/pda/medical diff --git a/code/modules/keybindings/keybind/combat.dm b/code/modules/keybindings/keybind/combat.dm index 8a0e713d8f..c4b44b5283 100644 --- a/code/modules/keybindings/keybind/combat.dm +++ b/code/modules/keybindings/keybind/combat.dm @@ -26,6 +26,7 @@ L.keybind_stop_active_blocking() /datum/keybinding/living/active_block_toggle + hotkey_keys = list("Unbound") name = "active_block_toggle" full_name = "Block (Toggle)" category = CATEGORY_COMBAT diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 89fa3ac6cf..e5d9672d4a 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -112,7 +112,7 @@ else return ..() -/obj/structure/bookcase/attack_hand(mob/living/user) +/obj/structure/bookcase/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(. || !istype(user)) return diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 144037b3a7..f65ea27216 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -523,7 +523,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums else return ..() -/obj/machinery/libraryscanner/attack_hand(mob/user) +/obj/machinery/libraryscanner/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 94f5be65bf..d2da0f779e 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -150,7 +150,7 @@ new /obj/item/clothing/head/bearpelt(src) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/closet/crate/secure/loot/attack_hand(mob/user) +/obj/structure/closet/crate/secure/loot/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(locked) to_chat(user, "The crate is locked with a Deca-code lock.") var/input = input(usr, "Enter [codelen] digits. All digits must be unique.", "Deca-Code Lock", "") as text diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index 8320a2a534..bf7a966f7d 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -275,7 +275,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also var/anti_spam_cd = 0 //The linking process might be a bit intensive, so this here to prevent over use. var/console_range = 15 //Wifi range of the beacon to find the aux base console -/obj/structure/mining_shuttle_beacon/attack_hand(mob/user) +/obj/structure/mining_shuttle_beacon/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 39f8e296af..cda38033c2 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -5,10 +5,8 @@ icon_state = "explorer" item_state = "explorer" body_parts_covered = CHEST|GROIN|LEGS|ARMS - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT cold_protection = CHEST|GROIN|LEGS|ARMS - max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - heat_protection = CHEST|GROIN|LEGS|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT hoodtype = /obj/item/clothing/head/hooded/explorer armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) flags_inv = HIDEJUMPSUIT|HIDETAUR @@ -24,9 +22,7 @@ flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT cold_protection = HEAD - max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT - heat_protection = HEAD - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) + armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50, "wound" = 10) resistance_flags = FIRE_PROOF /obj/item/clothing/suit/hooded/explorer/standard @@ -50,7 +46,7 @@ visor_flags_inv = HIDEFACIALHAIR visor_flags_cover = MASKCOVERSMOUTH actions_types = list(/datum/action/item_action/adjust) - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40, "wound" = 5) resistance_flags = FIRE_PROOF /obj/item/clothing/mask/gas/explorer/attack_self(mob/user) diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm index 0a928e83c7..ae2889e8a2 100644 --- a/code/modules/mining/equipment/marker_beacons.dm +++ b/code/modules/mining/equipment/marker_beacons.dm @@ -103,7 +103,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( icon_state = "[initial(icon_state)][lowertext(picked_color)]-on" set_light(light_range, light_power, GLOB.marker_beacon_colors[picked_color]) -/obj/structure/marker_beacon/attack_hand(mob/living/user) +/obj/structure/marker_beacon/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index ab0356aa66..2ca5f88ac8 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -167,7 +167,7 @@ qdel(src) return TRUE -/obj/item/gps/computer/attack_hand(mob/user) +/obj/item/gps/computer/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -204,7 +204,7 @@ var/obj/item/reagent_containers/food/snacks/donkpocket/warm/W = new(src) load(W) if(prob(50)) - var/obj/item/storage/pill_bottle/dice/D = new(src) + var/obj/item/storage/box/dice/D = new(src) load(D) else var/obj/item/instrument/guitar/G = new(src) @@ -318,4 +318,4 @@ icon = initial(I.icon) desc = initial(I.desc) icon_state = initial(I.icon_state) - item_state = initial(I.item_state) \ No newline at end of file + item_state = initial(I.item_state) diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index a3e71aa9de..c0d63fab9c 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -141,7 +141,7 @@ GLOBAL_LIST(labor_sheet_values) icon_state = "console" density = FALSE -/obj/machinery/mineral/labor_points_checker/attack_hand(mob/user) +/obj/machinery/mineral/labor_points_checker/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index 38830fd824..e39b833793 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -62,7 +62,7 @@ else return ..() -/obj/structure/flora/ash/attack_hand(mob/user) +/obj/structure/flora/ash/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index e611ccf232..bfdb731869 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -79,9 +79,9 @@ new /obj/item/clothing/neck/necklace/memento_mori(src) if(29) if(prob(50)) - new /obj/item/malf_upgrade + new /obj/item/malf_upgrade(src) else - new /obj/item/disk/tech_disk/illegal + new /obj/item/disk/tech_disk/illegal(src) //KA modkit design discs /obj/item/disk/design_disk/modkit_disc @@ -1104,7 +1104,7 @@ var/blast_range = 13 //how long the cardinal blast's walls are var/obj/effect/hierophant/beacon //the associated beacon we teleport to var/teleporting = FALSE //if we ARE teleporting - var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets + var/friendly_fire_check = TRUE //if the blasts we make will consider our faction against the faction of hit targets /obj/item/hierophant_club/ComponentInitialize() . = ..() diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm index 1c535fd9ab..d454c3d118 100644 --- a/code/modules/mining/lavaland/ruins/gym.dm +++ b/code/modules/mining/lavaland/ruins/gym.dm @@ -29,7 +29,7 @@ /obj/structure/weightmachine/proc/AnimateMachine(mob/living/user) return -/obj/structure/weightmachine/attack_hand(mob/living/user) +/obj/structure/weightmachine/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -92,4 +92,4 @@ sleep(3) animate(user, pixel_y = 2, time = 3) sleep(3) - cut_overlay(swole_overlay) \ No newline at end of file + cut_overlay(swole_overlay) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index f10229f4bf..6567793b80 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -80,7 +80,7 @@ var/static/list/dumb_rev_heads = list() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/machinery/computer/shuttle/mining/attack_hand(mob/user) +/obj/machinery/computer/shuttle/mining/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(is_station_level(user.z) && user.mind && is_head_revolutionary(user) && !(user.mind in dumb_rev_heads)) to_chat(user, "You get a feeling that leaving the station might be a REALLY dumb idea...") dumb_rev_heads += user.mind diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index e689a37b25..f9d18fecc2 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -38,7 +38,7 @@ ui_interact(user) . = ..() -/obj/structure/ore_box/attack_hand(mob/user) +/obj/structure/ore_box/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index d3892cc282..49a3bffd42 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -558,12 +558,25 @@ 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]"] + var/valid_scars = "" + for(var/scar_line in splittext(scar_string, ";")) + if(H.load_scar(scar_line)) + valid_scars += "[scar_line];" + + 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) if(transfer_after) mind.late_joiner = TRUE mind.active = 0 //we wish to transfer the key manually mind.transfer_to(H) //won't transfer key since the mind is not active + mind.original_character = H H.name = real_name diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 8ca4e6a0e4..478599e2c0 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -5,16 +5,26 @@ #define EXOTIC_BLEED_MULTIPLIER 4 //Multiplies the actually bled amount by this number for the purposes of turf reaction calculations. -/mob/living/carbon/human/proc/suppress_bloodloss(amount) - if(bleedsuppress) +/mob/living/carbon/monkey/handle_blood() + if(bodytemperature <= TCRYO || (HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood. return - else - bleedsuppress = TRUE - addtimer(CALLBACK(src, .proc/resume_bleeding), amount) + + var/temp_bleed = 0 + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + temp_bleed += BP.get_bleed_rate() + BP.generic_bleedstacks = max(0, BP.generic_bleedstacks - 1) + bleed(temp_bleed) + + //Blood regeneration if there is some space + if(blood_volume < BLOOD_VOLUME_NORMAL) + blood_volume += 0.1 // regenerate blood VERY slowly + if(blood_volume < BLOOD_VOLUME_OKAY) + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) /mob/living/carbon/human/proc/resume_bleeding() bleedsuppress = 0 - if(stat != DEAD && bleed_rate) + if(stat != DEAD && is_bleeding()) to_chat(src, "The blood soaks through your bandage.") @@ -29,20 +39,13 @@ // Takes care blood loss and regeneration /mob/living/carbon/human/handle_blood() - if(NOBLOOD in dna.species.species_traits) - bleed_rate = 0 + if(NOBLOOD in dna.species.species_traits || bleedsuppress || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) return - if(bleed_rate < 0) - bleed_rate = 0 - - if(HAS_TRAIT(src, TRAIT_NOMARROW)) //Bloodsuckers don't need to be here. - return - - if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood. + if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood. //Blood regeneration if there is some space - if(blood_volume < (BLOOD_VOLUME_NORMAL * blood_ratio) && !HAS_TRAIT(src, TRAIT_NOHUNGER)) + if(blood_volume < BLOOD_VOLUME_NORMAL && !HAS_TRAIT(src, TRAIT_NOHUNGER)) var/nutrition_ratio = 0 switch(nutrition) if(0 to NUTRITION_LEVEL_STARVING) @@ -55,22 +58,27 @@ nutrition_ratio = 0.8 else nutrition_ratio = 1 - if(HAS_TRAIT(src, TRAIT_HIGH_BLOOD)) - nutrition_ratio *= 1.2 if(satiety > 80) nutrition_ratio *= 1.25 adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR) - blood_volume = min((BLOOD_VOLUME_NORMAL * blood_ratio), blood_volume + 0.5 * nutrition_ratio) + blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio) //Effects of bloodloss var/word = pick("dizzy","woozy","faint") - switch(blood_volume * INVERSE(blood_ratio)) + 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.") if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) if(prob(5)) to_chat(src, "You feel [word].") - adjustOxyLoss(round(((BLOOD_VOLUME_NORMAL * blood_ratio) - blood_volume) * 0.01, 1)) + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - adjustOxyLoss(round(((BLOOD_VOLUME_NORMAL * blood_ratio) - blood_volume) * 0.02, 1)) + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) if(prob(5)) blur_eyes(6) to_chat(src, "You feel very [word].") @@ -87,24 +95,11 @@ //Bleeding out for(var/X in bodyparts) var/obj/item/bodypart/BP = X - var/brutedamage = BP.brute_dam + temp_bleed += BP.get_bleed_rate() + BP.generic_bleedstacks = max(0, BP.generic_bleedstacks - 1) - if(BP.status == BODYPART_ROBOTIC) //for the moment, synth limbs won't bleed, but soon, my pretty. - continue - - //We want an accurate reading of .len - listclearnulls(BP.embedded_objects) - for(var/obj/item/embeddies in BP.embedded_objects) - if(!embeddies.isEmbedHarmless()) - temp_bleed += 0.5 - - if(brutedamage >= 20) - temp_bleed += (brutedamage * 0.013) - - bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases - - if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH))) - bleed(bleed_rate) + if(temp_bleed) + bleed(temp_bleed) //Makes a blood drop, leaking amt units of blood from the mob /mob/living/carbon/proc/bleed(amt) @@ -128,9 +123,11 @@ /mob/living/proc/restore_blood() blood_volume = initial(blood_volume) -/mob/living/carbon/human/restore_blood() +/mob/living/carbon/restore_blood() blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio) - bleed_rate = 0 + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + BP.generic_bleedstacks = 0 /**************************************************** BLOOD TRANSFERS diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 4fda02317e..b6f8dd349b 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -331,6 +331,8 @@ max_traumas = TRAUMA_LIMIT_BASIC if(TRAUMA_RESILIENCE_SURGERY) max_traumas = TRAUMA_LIMIT_SURGERY + if(TRAUMA_RESILIENCE_WOUND) + max_traumas = TRAUMA_LIMIT_WOUND if(TRAUMA_RESILIENCE_LOBOTOMY) max_traumas = TRAUMA_LIMIT_LOBOTOMY if(TRAUMA_RESILIENCE_MAGIC) @@ -389,7 +391,7 @@ return var/trauma_type = pick(possible_traumas) - gain_trauma(trauma_type, resilience) + return gain_trauma(trauma_type, resilience) //Cure a random trauma of a certain resilience level /obj/item/organ/brain/proc/cure_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience = TRAUMA_RESILIENCE_BASIC) diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index e35c905539..c5a69553aa 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -59,7 +59,7 @@ return attack_hand(user) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/clothing/mask/facehugger/attack_hand(mob/user) +/obj/item/clothing/mask/facehugger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if((stat == CONSCIOUS && !sterile) && !isalien(user)) if(Leap(user)) return diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 8472c8bdae..4b7e27656b 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -88,11 +88,32 @@ for(var/datum/surgery/S in surgeries) if(S.next_step(user,user.a_intent)) return 1 + + 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)) + if(W.try_treating(I, user)) + return 1 + return ..() /mob/living/carbon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() var/hurt = TRUE + var/extra_speed = 0 + if(throwingdatum.thrower != src) + extra_speed = min(max(0, throwingdatum.speed - initial(throw_speed)), 3) if(GetComponent(/datum/component/tackler)) return if(throwingdatum?.thrower && iscyborg(throwingdatum.thrower)) @@ -102,18 +123,18 @@ if(hit_atom.density && isturf(hit_atom)) if(hurt) DefaultCombatKnockdown(20) - take_bodypart_damage(10) + take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5) if(iscarbon(hit_atom) && hit_atom != src) var/mob/living/carbon/victim = hit_atom if(victim.movement_type & FLYING) return if(hurt) - victim.take_bodypart_damage(10) - take_bodypart_damage(10) + victim.take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5) + take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5) victim.DefaultCombatKnockdown(20) DefaultCombatKnockdown(20) - visible_message("[src] crashes into [victim], knocking them both over!",\ - "You violently crash into [victim]!") + visible_message("[src] crashes into [victim] [extra_speed ? "really hard" : ""], knocking them both over!",\ + "You violently crash into [victim] [extra_speed ? "extra hard" : ""]!") playsound(src,'sound/weapons/punch1.ogg',50,1) @@ -153,6 +174,7 @@ if(IS_STAMCRIT(src)) to_chat(src, "You're too exhausted.") return + var/random_turn = a_intent == INTENT_HARM //END OF CIT CHANGES @@ -196,12 +218,18 @@ adjustStaminaLossBuffered(I.getweight(src, STAM_COST_THROW_MULT, SKILL_THROW_STAM_COST)) if(thrown_thing) - visible_message("[src] has thrown [thrown_thing].") - log_message("has thrown [thrown_thing]", LOG_ATTACK) + var/power_throw = 0 + if(HAS_TRAIT(src, TRAIT_HULK)) + power_throw++ + if(pulling && grab_state >= GRAB_NECK) + power_throw++ + visible_message("[src] throws [thrown_thing][power_throw ? " really hard!" : "."]", \ + "You throw [thrown_thing][power_throw ? " really hard!" : "."]") + log_message("has thrown [thrown_thing] [power_throw ? "really hard" : ""]", LOG_ATTACK) do_attack_animation(target, no_effect = 1) playsound(loc, 'sound/weapons/punchmiss.ogg', 50, 1, -1) newtonian_move(get_dir(target, src)) - thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force, random_turn) + thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed + power_throw, src, null, null, null, move_force, random_turn) /mob/living/carbon/restrained(ignore_grab) . = (handcuffed || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE)) @@ -892,6 +920,9 @@ var/datum/disease/D = thing if(D.severity != DISEASE_SEVERITY_POSITIVE) D.cure(FALSE) + for(var/thing in all_wounds) + var/datum/wound/W = thing + W.remove_wound() if(admin_revive) regenerate_limbs() regenerate_organs() @@ -982,6 +1013,10 @@ if(SANITY_NEUTRAL to SANITY_GREAT) . *= 0.90 + for(var/i in status_effects) + var/datum/status_effect/S = i + . *= S.interact_speed_modifier() + /mob/living/carbon/proc/create_internal_organs() for(var/X in internal_organs) @@ -1170,3 +1205,47 @@ if(wear_mask) if(wear_mask.flags_inv & HIDEEYES) LAZYOR(., SLOT_GLASSES) + +// if any of our bodyparts are bleeding +/mob/living/carbon/proc/is_bleeding() + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + if(BP.get_bleed_rate()) + return TRUE + +// get our total bleedrate +/mob/living/carbon/proc/get_total_bleed_rate() + var/total_bleed_rate = 0 + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + total_bleed_rate += BP.get_bleed_rate() + + return total_bleed_rate + +/** + * 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. + * + * 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 + */ +/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/wound_type + if(forced_type) + if(islist(forced_type)) + wound_type = pick(forced_type) + else + wound_type = forced_type + else + wound_type = pick(WOUND_LIST_BONE + WOUND_LIST_CUT + WOUND_LIST_BURN) + + var/datum/wound/W = new wound_type + S.generate(BP, W) + S.fake = TRUE + QDEL_NULL(W) diff --git a/code/modules/mob/living/carbon/carbon_active_parry.dm b/code/modules/mob/living/carbon/carbon_active_parry.dm new file mode 100644 index 0000000000..2683b6db6b --- /dev/null +++ b/code/modules/mob/living/carbon/carbon_active_parry.dm @@ -0,0 +1,2 @@ +/mob/living/carbon/check_unarmed_parry_activation_special() + return ..() && length(get_empty_held_indexes()) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index bfa9c40a7c..196cec849d 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -79,7 +79,7 @@ send_item_attack_message(I, user, affecting.name, totitemdamage) I.do_stagger_action(src, user, totitemdamage) if(I.force) - apply_damage(totitemdamage, I.damtype, affecting) //CIT CHANGE - replaces I.force with totitemdamage + 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 if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC) var/basebloodychance = affecting.brute_dam + totitemdamage if(prob(basebloodychance)) @@ -112,7 +112,7 @@ return //so we don't call the carbon's attack_hand(). //ATTACK HAND IGNORING PARENT RETURN VALUE -/mob/living/carbon/attack_hand(mob/living/carbon/human/user) +/mob/living/carbon/attack_hand(mob/living/carbon/human/user, act_intent, unarmed_attack_flags) . = ..() if(.) //was the attack blocked? return @@ -127,11 +127,14 @@ ContactContractDisease(D) if(lying && surgeries.len) - if(user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM) + if(act_intent == INTENT_HELP || act_intent == INTENT_DISARM) for(var/datum/surgery/S in surgeries) - if(S.next_step(user, user.a_intent)) + if(S.next_step(user, act_intent)) return TRUE + for(var/datum/wound/W in all_wounds) + if(W.try_handling(user)) + return 1 /mob/living/carbon/attack_paw(mob/living/carbon/monkey/M) @@ -467,3 +470,8 @@ if (BP.status < 2) amount += BP.burn_dam return amount + +/mob/living/carbon/proc/get_interaction_efficiency(zone) + var/obj/item/bodypart/limb = get_bodypart(zone) + if(!limb) + return diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index a0f6a9bfcc..2ce59fb790 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -65,6 +65,11 @@ var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects var/tackling = FALSE //Whether or not we are tackling, this will prevent the knock into effects for carbons + /// All of the wounds a carbon has afflicted throughout their limbs + var/list/all_wounds + /// All of the scars a carbon has afflicted throughout their limbs + var/list/all_scars + /// Protection (insulation) from the heat, Value 0-1 corresponding to the percentage of protection var/heat_protection = 0 // No heat protection /// Protection (insulation) from the cold, Value 0-1 corresponding to the percentage of protection @@ -72,3 +77,4 @@ /// Timer id of any transformation var/transformation_timer + diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index becff250b9..ddf1019f2a 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) +/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) SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone) var/hit_percent = (100-blocked)/100 if(!forced && hit_percent <= 0) @@ -21,13 +21,13 @@ switch(damagetype) if(BRUTE) if(BP) - if(damage > 0 ? BP.receive_damage(damage_amount) : BP.heal_damage(abs(damage_amount), 0)) + if(BP.receive_damage(damage_amount, 0, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) update_damage_overlays() else //no bodypart, we deal damage with a more general method. adjustBruteLoss(damage_amount, forced = forced) if(BURN) if(BP) - if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount))) + if(BP.receive_damage(0, damage_amount, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) update_damage_overlays() else adjustFireLoss(damage_amount, forced = forced) @@ -202,12 +202,12 @@ //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) +/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) var/list/obj/item/bodypart/parts = get_damageable_bodyparts() if(!parts.len) return var/obj/item/bodypart/picked = pick(parts) - if(picked.receive_damage(brute, burn, stamina)) + if(picked.receive_damage(brute, burn, stamina,check_armor ? run_armor_check(picked, (brute ? "melee" : burn ? "fire" : stamina ? "bullet" : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) update_damage_overlays() //Heal MANY bodyparts, in random order @@ -235,12 +235,12 @@ update_damage_overlays() update_stamina() //CIT CHANGE - makes sure update_stamina() always gets called after a health update -// damage MANY bodyparts, in random order -/mob/living/carbon/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE) +/// damage MANY bodyparts, in random order +/mob/living/carbon/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status) if(status_flags & GODMODE) return //godmode - var/list/obj/item/bodypart/parts = get_damageable_bodyparts() + var/list/obj/item/bodypart/parts = get_damageable_bodyparts(required_status) var/update = 0 while(parts.len && (brute > 0 || burn > 0 || stamina > 0)) var/obj/item/bodypart/picked = pick(parts) @@ -253,7 +253,7 @@ var/stamina_was = picked.stamina_dam - update |= picked.receive_damage(brute_per_part, burn_per_part, stamina_per_part, FALSE) + update |= picked.receive_damage(brute_per_part, burn_per_part, stamina_per_part, FALSE, required_status, wound_bonus = CANT_WOUND) // disabling wounds from these for now cuz your entire body snapping cause your heart stopped would suck brute = round(brute - (picked.brute_dam - brute_was), DAMAGE_PRECISION) burn = round(burn - (picked.burn_dam - burn_was), DAMAGE_PRECISION) @@ -265,3 +265,12 @@ if(update) update_damage_overlays() update_stamina() + +///Returns a list of bodyparts with wounds (in case someone has a wound on an otherwise fully healed limb) +/mob/living/carbon/proc/get_wounded_bodyparts(brute = FALSE, burn = FALSE, stamina = FALSE, status) + var/list/obj/item/bodypart/parts = list() + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + if(LAZYLEN(BP.wounds)) + parts += BP + return parts diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index b07aab30d1..be046a3713 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -44,6 +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) + msg += "[W.get_examine_description(user)]\n" for(var/X in disabled) var/obj/item/bodypart/BP = X @@ -99,6 +101,22 @@ if(pulledby && pulledby.grab_state) msg += "[t_He] [t_is] restrained by [pulledby]'s grip.\n" + var/scar_severity = 0 + for(var/i in all_scars) + var/datum/scar/S = i + if(S.is_visible(user)) + scar_severity += S.severity + + switch(scar_severity) + if(1 to 2) + 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) + msg += "[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...\n" + if(7 to INFINITY) + msg += "[t_He] [t_is] just absolutely fucked up, you can look again to take a closer look...\n" + if(msg.len) . += "[msg.Join("")]" @@ -135,3 +153,25 @@ . += "[t_He] look[p_s()] ecstatic." SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) . += "*---------*" + +/mob/living/carbon/examine_more(mob/user) + if(!all_scars) + return ..() + + var/list/visible_scars + for(var/i in all_scars) + var/datum/scar/S = i + if(S.is_visible(user)) + LAZYADD(visible_scars, S) + + if(!visible_scars) + return ..() + + var/msg = list("You examine [src] closer, and note the following...") + for(var/i in visible_scars) + var/datum/scar/S = i + var/scar_text = S.get_examine_description(user) + if(scar_text) + msg += "[scar_text]" + + return msg diff --git a/code/modules/mob/living/carbon/human/damage_procs.dm b/code/modules/mob/living/carbon/human/damage_procs.dm index 651fec8415..5cd00b7e6a 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) + return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage, wound_bonus, bare_wound_bonus, sharpness) -/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage) - // depending on the species, it will run the corresponding apply_damage code there - return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index d32184edb5..77137c7239 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -163,16 +163,18 @@ 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/X in disabled) var/obj/item/bodypart/BP = X var/damage_text - if(!(BP.get_damage(include_stamina = FALSE) >= BP.max_damage)) //Stamina is disabling the limb - damage_text = "limp and lifeless" - else - damage_text = (BP.brute_dam >= BP.burn_dam) ? BP.heavy_brute_msg : BP.heavy_burn_msg - msg += "[capitalize(t_his)] [BP.name] is [damage_text]!\n" - + if(BP.is_disabled() != BODYPART_DISABLED_WOUND) // skip if it's disabled by a wound (cuz we'll be able to see the bone sticking out!) + if(!(BP.get_damage(include_stamina = FALSE) >= BP.max_damage)) //we don't care if it's stamcritted + damage_text = "limp and lifeless" + else + damage_text = (BP.brute_dam >= BP.burn_dam) ? BP.heavy_brute_msg : BP.heavy_burn_msg + msg += "[capitalize(t_his)] [BP.name] is [damage_text]!\n" //stores missing limbs var/l_limbs_missing = 0 var/r_limbs_missing = 0 @@ -246,16 +248,40 @@ if(DISGUST_LEVEL_DISGUSTED to INFINITY) msg += "[t_He] look[p_s()] extremely disgusted.\n" - if(ShowAsPaleExamine()) - msg += "[t_He] [t_has] pale skin.\n" + var/apparent_blood_volume = blood_volume + if(skin_tone == "albino") + apparent_blood_volume -= 150 // enough to knock you down one tier + switch(apparent_blood_volume) + if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) + msg += "[t_He] [t_has] pale skin.\n" + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) + msg += "[t_He] look[p_s()] like pale death.\n" + if(-INFINITY to BLOOD_VOLUME_BAD) + msg += "[t_He] resemble[p_s()] a crushed, empty juice pouch.\n" if(bleedsuppress) - msg += "[t_He] [t_is] bandaged with something.\n" - else if(bleed_rate) - if(bleed_rate >= 8) //8 is the rate at which heparin causes you to bleed - msg += "[t_He] [t_is] bleeding uncontrollably!\n" - else - msg += "[t_He] [t_is] bleeding!\n" + msg += "[t_He] [t_is] embued with a power that defies bleeding.\n" // only statues and highlander sword can cause this so whatever + else if(is_bleeding()) + var/list/obj/item/bodypart/bleeding_limbs = list() + + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + if(BP.get_bleed_rate()) + bleeding_limbs += BP + + var/num_bleeds = LAZYLEN(bleeding_limbs) + var/bleed_text = "[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]" : ""]" + if(3 to INFINITY) + for(var/i in 1 to (num_bleeds - 1)) + var/obj/item/bodypart/BP = bleeding_limbs[i] + bleed_text += " [BP.name]," + bleed_text += " and [bleeding_limbs[num_bleeds].name]" + + bleed_text += "!\n" + msg += bleed_text if(reagents.has_reagent(/datum/reagent/teslium)) msg += "[t_He] [t_is] emitting a gentle blue glow!\n" @@ -331,6 +357,21 @@ if(digitalcamo) msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n" + var/scar_severity = 0 + for(var/i in all_scars) + var/datum/scar/S = i + if(S.is_visible(user)) + scar_severity += S.severity + + switch(scar_severity) + if(1 to 2) + 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) + msg += "[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...\n" + if(7 to INFINITY) + msg += "[t_He] [t_is] just absolutely fucked up, you can look again to take a closer look...\n" if (length(msg)) . += "[msg.Join("")]" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 85eca1500e..f42c1bcd64 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1067,10 +1067,21 @@ remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown) remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying) + /mob/living/carbon/human/do_after_coefficent() . = ..() . *= physiology.do_after_speed +/mob/living/carbon/human/is_bleeding() + if(NOBLOOD in dna.species.species_traits || bleedsuppress) + return FALSE + return ..() + +/mob/living/carbon/human/get_total_bleed_rate() + if(NOBLOOD in dna.species.species_traits) + return FALSE + return ..() + /mob/living/carbon/human/species var/race = null diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 63296021ff..6737176d09 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -34,6 +34,19 @@ protection += physiology.armor.getRating(d_type) return protection +///Get all the clothing on a specific body part +/mob/living/carbon/human/proc/clothingonpart(obj/item/bodypart/def_zone) + var/list/covering_part = list() + var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor) + for(var/bp in body_parts) + if(!bp) + continue + if(bp && istype(bp , /obj/item/clothing)) + var/obj/item/clothing/C = bp + if(C.body_parts_covered & def_zone.body_part) + covering_part += C + return covering_part + /mob/living/carbon/human/on_hit(obj/item/projectile/P) if(dna && dna.species) dna.species.on_hit(P, src) @@ -106,16 +119,16 @@ visible_message("[user] [hulk_verb_continous] [src]!", \ "[user] [hulk_verb_continous] you!", null, COMBAT_MESSAGE_RANGE, null, user, "You [hulk_verb_simple] [src]!") - adjustBruteLoss(15) + apply_damage(15, BRUTE, wound_bonus=10) return 1 -/mob/living/carbon/human/attack_hand(mob/user) +/mob/living/carbon/human/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) //To allow surgery to return properly. return if(ishuman(user)) var/mob/living/carbon/human/H = user - dna.species.spec_attack_hand(H, src) + dna.species.spec_attack_hand(H, src, null, act_intent, unarmed_attack_flags) /mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M) var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) @@ -217,16 +230,17 @@ if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration) - apply_damage(damage, M.melee_damage_type, affecting, armor) - + apply_damage(damage, M.melee_damage_type, affecting, armor, wound_bonus = M.wound_bonus, bare_wound_bonus = M.bare_wound_bonus, sharpness = M.sharpness) /mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M) . = ..() if(!.) //unsuccessful slime attack return var/damage = rand(5, 25) + var/wound_mod = -45 // 25^1.4=90, 90-45=45 if(M.is_adult) damage = rand(10, 35) + wound_mod = -90 // 35^1.4=145, 145-90=55 var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) if(!dam_zone) //Dismemberment successful @@ -236,7 +250,7 @@ if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) var/armor_block = run_armor_check(affecting, "melee") - apply_damage(damage, BRUTE, affecting, armor_block) + apply_damage(damage, BRUTE, affecting, armor_block, wound_bonus=wound_mod) /mob/living/carbon/human/mech_melee_attack(obj/mecha/M) if(M.occupant.a_intent == INTENT_HARM) @@ -614,6 +628,20 @@ no_damage = TRUE to_send += "\t Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" + for(var/thing in LB.wounds) + var/datum/wound/W = thing + var/msg + switch(W.severity) + if(WOUND_SEVERITY_TRIVIAL) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]." + if(WOUND_SEVERITY_MODERATE) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + if(WOUND_SEVERITY_SEVERE) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + if(WOUND_SEVERITY_CRITICAL) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!" + to_chat(src, msg) + for(var/obj/item/I in LB.embedded_objects) if(I.isEmbedHarmless()) to_chat(src, "\t There is \a [I] stuck to your [LB.name]!") @@ -623,8 +651,25 @@ for(var/t in missing) to_send += "Your [parse_zone(t)] is missing!\n" - if(bleed_rate) - to_send += "You are bleeding!\n" + if(is_bleeding()) + var/list/obj/item/bodypart/bleeding_limbs = list() + for(var/i in bodyparts) + var/obj/item/bodypart/BP = i + if(BP.get_bleed_rate()) + bleeding_limbs += BP + + var/num_bleeds = LAZYLEN(bleeding_limbs) + var/bleed_text = "You are bleeding from your" + switch(num_bleeds) + if(1 to 2) + bleed_text += " [bleeding_limbs[1].name][num_bleeds == 2 ? " and [bleeding_limbs[2].name]" : ""]" + if(3 to INFINITY) + for(var/i in 1 to (num_bleeds - 1)) + var/obj/item/bodypart/BP = bleeding_limbs[i] + bleed_text += " [BP.name]," + bleed_text += " and [bleeding_limbs[num_bleeds].name]" + bleed_text += "!" + to_chat(src, bleed_text) if(getStaminaLoss()) if(getStaminaLoss() > 30) to_send += "You're completely exhausted.\n" @@ -717,6 +762,89 @@ ..() +/mob/living/carbon/human/check_self_for_injuries() + if(stat == DEAD || stat == UNCONSCIOUS) + return + + visible_message("[src] examines [p_them()]self.", \ + "You check yourself for injuries.") + + var/list/missing = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + + for(var/X in bodyparts) + var/obj/item/bodypart/LB = X + missing -= LB.body_zone + if(LB.is_pseudopart) //don't show injury text for fake bodyparts; ie chainsaw arms or synthetic armblades + continue + var/self_aware = FALSE + if(HAS_TRAIT(src, TRAIT_SELF_AWARE)) + self_aware = TRUE + var/limb_max_damage = LB.max_damage + var/status = "" + var/brutedamage = LB.brute_dam + var/burndamage = LB.burn_dam + if(hallucination) + if(prob(30)) + brutedamage += rand(30,40) + if(prob(30)) + burndamage += rand(30,40) + + if(HAS_TRAIT(src, TRAIT_SELF_AWARE)) + status = "[brutedamage] brute damage and [burndamage] burn damage" + if(!brutedamage && !burndamage) + status = "no damage" + + else + if(brutedamage > 0) + status = LB.light_brute_msg + if(brutedamage > (limb_max_damage*0.4)) + status = LB.medium_brute_msg + if(brutedamage > (limb_max_damage*0.8)) + status = LB.heavy_brute_msg + if(brutedamage > 0 && burndamage > 0) + status += " and " + + if(burndamage > (limb_max_damage*0.8)) + status += LB.heavy_burn_msg + else if(burndamage > (limb_max_damage*0.2)) + status += LB.medium_burn_msg + else if(burndamage > 0) + status += LB.light_burn_msg + + if(status == "") + status = "OK" + var/no_damage + if(status == "OK" || status == "no damage") + no_damage = TRUE + var/isdisabled = " " + if(LB.is_disabled()) + isdisabled = " is disabled " + if(no_damage) + isdisabled += " but otherwise " + else + isdisabled += " and " + to_chat(src, "\t Your [LB.name][isdisabled][self_aware ? " has " : " is "][status].") + + for(var/thing in LB.wounds) + var/datum/wound/W = thing + var/msg + switch(W.severity) + if(WOUND_SEVERITY_TRIVIAL) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]." + if(WOUND_SEVERITY_MODERATE) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + if(WOUND_SEVERITY_SEVERE) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + if(WOUND_SEVERITY_CRITICAL) + msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!" + to_chat(src, msg) + + for(var/obj/item/I in LB.embedded_objects) + if(I.isEmbedHarmless()) + to_chat(src, "\t There is \a [I] stuck to your [LB.name]!") + else + to_chat(src, "\t There is \a [I] embedded in your [LB.name]!") + /mob/living/carbon/human/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone) if(damage_type != BRUTE && damage_type != BURN) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index e7be540eb9..aea4ee2ead 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -7,12 +7,14 @@ buckle_lying = FALSE mob_biotypes = MOB_ORGANIC|MOB_HUMANOID /// Enable stamina combat - combat_flags = COMBAT_FLAGS_DEFAULT + combat_flags = COMBAT_FLAGS_DEFAULT | COMBAT_FLAG_UNARMED_PARRY status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER has_field_of_vision = FALSE //Handled by species. blocks_emissive = EMISSIVE_BLOCK_UNIQUE + block_parry_data = /datum/block_parry_data/unarmed/human + //Hair colour and style var/hair_color = "000" var/hair_style = "Bald" @@ -49,7 +51,6 @@ var/special_voice = "" // For changing our voice. Used by a symptom. - var/bleed_rate = 0 //how much are we bleeding var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding var/blood_state = BLOOD_STATE_NOT_BLOODY @@ -71,3 +72,45 @@ var/lastpuke = 0 var/account_id var/last_fire_update + +/// Unarmed parry data for human +/datum/block_parry_data/unarmed/human + parry_respect_clickdelay = TRUE + parry_stamina_cost = 4 + parry_attack_types = ATTACK_TYPE_UNARMED + parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING + + parry_time_windup = 0 + parry_time_spindown = 1 + parry_time_active = 5 + + parry_time_perfect = 1 + parry_time_perfect_leeway = 1 + parry_imperfect_falloff_percent = 20 + parry_efficiency_perfect = 100 + + parry_efficiency_considered_successful = 0.01 + parry_efficiency_to_counterattack = 0.01 + parry_max_attacks = 3 + parry_cooldown = 30 + parry_failed_stagger_duration = 0 + parry_failed_clickcd_duration = 0.4 + + parry_data = list( // yeah it's snowflake + "HUMAN_PARRY_STAGGER" = 3 SECONDS, + "HUMAN_PARRY_PUNCH" = TRUE, + "HUMAN_PARRY_MININUM_EFFICIENCY" = 0.9 + ) + +/mob/living/carbon/human/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, parry_efficiency, parry_time) + var/datum/block_parry_data/D = return_block_parry_datum(block_parry_data) + if(!owner.Adjacent(attacker)) + return ..() + if(parry_efficiency < D.parry_data["HUMAN_PARRY_MINIMUM_EFFICIENCY"]) + return ..() + visible_message("[src] strikes back perfectly at [attacker], staggering them!") + if(D.parry_data["HUMAN_PARRY_PUNCH"]) + UnarmedAttack(attacker, TRUE, INTENT_HARM, UNARMED_ATTACK_PARRY) + var/mob/living/L = attacker + if(istype(L)) + L.Stagger(D.parry_data["HUMAN_PARRY_STAGGER"]) diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 7c256f5367..8672c0e83d 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -151,3 +151,22 @@ if(blood_dna.len) last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works last_blood_DNA = blood_dna[blood_dna.len]*/ + +/// 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) + return + var/scars = "" + for(var/i in all_scars) + var/datum/scar/S = i + scars += "[S.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) + 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])) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 22431f9978..bcb658eab8 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -59,7 +59,7 @@ . = ..() for(var/datum/mutation/human/HM in dna.mutations) HM.on_move(NewLoc) - if(. && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) && !(movement_type & FLYING) && CHECK_ALL_MOBILITY(src, MOBILITY_MOVE|MOBILITY_STAND) && m_intent == MOVE_INTENT_RUN && has_gravity(loc) && !pulledby) + if(. && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) && !(movement_type & FLYING) && CHECK_ALL_MOBILITY(src, MOBILITY_MOVE|MOBILITY_STAND) && m_intent == MOVE_INTENT_RUN && has_gravity(loc) && (!pulledby || (pulledby.pulledby == src))) if(!HAS_TRAIT(src, TRAIT_FREESPRINT)) doSprintLossTiles(1) if((oldpseudoheight - pseudo_z_axis) >= 8) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index fa258eb814..ba6fde421d 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -7,7 +7,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/id // if the game needs to manually check your race to do something not included in a proc here, it will use this var/limbs_id //this is used if you want to use a different species limb sprites. Mainly used for angels as they look like humans. var/name // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever - var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race + var/default_color = "#FFFFFF" // if alien colors are disabled, this is the color that will be used by that race var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows var/has_field_of_vision = TRUE @@ -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() + var/list/species_traits = list(CAN_SCAR) //by default they can scar unless set to something else // generic traits tied to having the species var/list/inherent_traits = list() var/inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID @@ -854,10 +854,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/g = (H.dna.features["body_model"] == FEMALE) ? "f" : "m" var/list/colorlist = list() var/husk = HAS_TRAIT(H, TRAIT_HUSK) - colorlist += husk ? ReadRGB("#a3a3a3") :ReadRGB("[H.dna.features["mcolor"]]0") - colorlist += husk ? ReadRGB("#a3a3a3") :ReadRGB("[H.dna.features["mcolor2"]]0") - colorlist += husk ? ReadRGB("#a3a3a3") : ReadRGB("[H.dna.features["mcolor3"]]0") - colorlist += list(0,0,0, hair_alpha) + colorlist += husk ? ReadRGB("#a3a3a3") : ReadRGB("[H.dna.features["mcolor"]]00") + colorlist += husk ? ReadRGB("#a3a3a3") : ReadRGB("[H.dna.features["mcolor2"]]00") + colorlist += husk ? ReadRGB("#a3a3a3") : ReadRGB("[H.dna.features["mcolor3"]]00") + colorlist += husk ? list(0, 0, 0) : list(0, 0, 0, hair_alpha) for(var/index in 1 to colorlist.len) colorlist[index] /= 255 @@ -1031,7 +1031,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.apply_overlay(BODY_FRONT_LAYER) H.apply_overlay(HORNS_LAYER) - /* * Equip the outfit required for life. Replaces items currently worn. */ @@ -1446,7 +1445,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) target.grabbedby(user) return 1 -/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) +/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style, unarmed_attack_flags = NONE) if(!attacker_style && HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to harm [target]!") return FALSE @@ -1458,10 +1457,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) target_message = "[target] blocks your attack!") return FALSE - if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes punching cause staminaloss but funny martial artist types get a discount - user.adjustStaminaLossBuffered(1.5) - else - user.adjustStaminaLossBuffered(3.5) + if(!(unarmed_attack_flags & UNARMED_ATTACK_PARRY)) + if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes punching cause staminaloss but funny martial artist types get a discount + user.adjustStaminaLossBuffered(1.5) + else + user.adjustStaminaLossBuffered(3.5) if(attacker_style && attacker_style.harm_act(user,target)) return TRUE @@ -1499,13 +1499,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected)) var/miss_chance = 100//calculate the odds that a punch misses entirely. considers stamina and brute damage of the puncher. punches miss by default to prevent weird cases - if(user.dna.species.punchdamagelow) - if(atk_verb == ATTACK_EFFECT_KICK) //kicks never miss (provided your species deals more than 0 damage) - miss_chance = 0 - else if(HAS_TRAIT(user, TRAIT_PUGILIST)) //pugilists have a flat 10% miss chance - miss_chance = 10 - else - miss_chance = min(10 + max(puncherstam * 0.5, puncherbrute * 0.5), 100) //probability of miss has a base of 10, and modified based on half brute total. Capped at max 100 to prevent weirdness in prob() + if(unarmed_attack_flags & UNARMED_ATTACK_PARRY) + miss_chance = 0 + else + if(user.dna.species.punchdamagelow) + if(atk_verb == ATTACK_EFFECT_KICK) //kicks never miss (provided your species deals more than 0 damage) + miss_chance = 0 + else if(HAS_TRAIT(user, TRAIT_PUGILIST)) //pugilists have a flat 10% miss chance + miss_chance = 10 + else + miss_chance = min(10 + max(puncherstam * 0.5, puncherbrute * 0.5), 100) //probability of miss has a base of 10, and modified based on half brute total. Capped at max 100 to prevent weirdness in prob() if(!damage || !affecting || prob(miss_chance))//future-proofing for species that have 0 damage/weird cases where no zone is targeted playsound(target.loc, user.dna.species.miss_sound, 25, TRUE, -1) @@ -1683,7 +1686,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) /datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) return -/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) +/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, act_intent, unarmed_attack_flags) if(!istype(M)) return CHECK_DNA_AND_SPECIES(M) @@ -1695,7 +1698,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) attacker_style = M.mind.martial_art if(attacker_style?.pacifism_check && HAS_TRAIT(M, TRAIT_PACIFISM)) // most martial arts are quite harmful, alas. attacker_style = null - switch(M.a_intent) + switch(act_intent) if("help") help(M, H, attacker_style) @@ -1703,7 +1706,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) grab(M, H, attacker_style) if("harm") - harm(M, H, attacker_style) + harm(M, H, attacker_style, unarmed_attack_flags) if("disarm") disarm(M, H, attacker_style) @@ -1730,9 +1733,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/armor_block = H.run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].",I.armour_penetration) armor_block = min(90,armor_block) //cap damage reduction at 90% var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) + var/Iwound_bonus = I.wound_bonus + + // this way, you can't wound with a surgical tool on help intent if they have a surgery active and are laying down, so a misclick with a circular saw on the wrong limb doesn't bleed them dry (they still get hit tho) + if((I.item_flags & SURGICAL_TOOL) && user.a_intent == INTENT_HELP && (H.mobility_flags & ~MOBILITY_STAND) && (LAZYLEN(H.surgeries) > 0)) + Iwound_bonus = CANT_WOUND var/weakness = H.check_weakness(I, user) - apply_damage(totitemdamage * weakness, I.damtype, def_zone, armor_block, H) //CIT CHANGE - replaces I.force with totitemdamage + 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) @@ -1947,8 +1956,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) append_message += ", causing them to drop [target_held_item]" 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) - SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone) +/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) + 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 if(!forced && hit_percent <= 0) @@ -1975,7 +1984,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.damageoverlaytemp = 20 var/damage_amount = forced ? damage : damage * hit_percent * brutemod * H.physiology.brute_mod if(BP) - if(damage > 0 ? BP.receive_damage(damage_amount, 0) : BP.heal_damage(abs(damage_amount), 0)) + if(BP.receive_damage(damage_amount, 0, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) H.update_damage_overlays() if(HAS_TRAIT(H, TRAIT_MASO) && prob(damage_amount)) H.mob_climax(forced_climax=TRUE) @@ -1986,7 +1995,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.damageoverlaytemp = 20 var/damage_amount = forced ? damage : damage * hit_percent * burnmod * H.physiology.burn_mod if(BP) - if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount))) + if(BP.receive_damage(0, damage_amount, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) H.update_damage_overlays() else H.adjustFireLoss(damage_amount) 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 0899038da4..409781efb2 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) + species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL,CAN_SCAR) inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_CHUNKYFINGERS,TRAIT_NOHUNGER,TRAIT_NOBREATH) mutanttongue = /obj/item/organ/tongue/abductor 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 1a92da3b0a..2d43c9964e 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) + species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,CAN_SCAR) 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 a79f9e2392..a51dadb523 100644 --- a/code/modules/mob/living/carbon/human/species_types/bugmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/bugmen.dm @@ -3,9 +3,9 @@ id = "insect" say_mod = "chitters" default_color = "00FF00" - species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR) + species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR,CAN_SCAR) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG - mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", + 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") attack_verb = "slash" attack_sound = 'sound/weapons/slash.ogg' 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 1d19f28aa8..4e5aa57b0a 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -3,7 +3,7 @@ id = "dullahan" default_color = "FFFFFF" species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS) - inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH) + inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH,CAN_SCAR) 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 7ca057711e..009dba7707 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) + species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,CAN_SCAR) 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 dbf097196d..c3ec8b42ea 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) + species_traits = list(NOEYES,CAN_SCAR) 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 b6d56b8e5d..d87b0c074c 100644 --- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm @@ -3,9 +3,9 @@ id = "mammal" default_color = "4B4B4B" icon_limbs = DEFAULT_BODYPART_ICON_CITADEL - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR,CAN_SCAR) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BEAST - mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None", + 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") attack_verb = "claw" attack_sound = 'sound/weapons/slash.ogg' @@ -55,7 +55,7 @@ say_mod = "hisses" default_color = "00FF00" icon_limbs = DEFAULT_BODYPART_ICON_CITADEL - species_traits = list(MUTCOLORS,EYECOLOR,LIPS) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,CAN_SCAR) mutant_bodyparts = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard", "mam_body_markings" = "Xeno","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None", "legs" = "Digitigrade") attack_verb = "slash" attack_sound = 'sound/weapons/slash.ogg' diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 958e58a8ad..7100caf178 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -422,9 +422,9 @@ else reactive_teleport(H) -/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) +/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, act_intent, unarmed_attack_flags) ..() - if(world.time > last_teleport + teleport_cooldown && M != H && M.a_intent != INTENT_HELP) + if(world.time > last_teleport + teleport_cooldown && M != H && act_intent != INTENT_HELP) reactive_teleport(H) /datum/species/golem/bluespace/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) @@ -519,9 +519,9 @@ var/golem_name = "[uppertext(clown_name)]" return golem_name -/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) +/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, act_intent, unarmed_attack_flags) ..() - if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP) + if(world.time > last_banana + banana_cooldown && M != H && act_intent != INTENT_HELP) new/obj/item/grown/bananapeel/specialpeel(get_turf(H)) last_banana = world.time @@ -830,9 +830,9 @@ if(world.time > last_gong_time + gong_cooldown) gong(H) -/datum/species/golem/bronze/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) +/datum/species/golem/bronze/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, act_intent, unarmed_attack_flags) ..() - if(world.time > last_gong_time + gong_cooldown && M.a_intent != INTENT_HELP) + if(world.time > last_gong_time + gong_cooldown && act_intent != INTENT_HELP) gong(H) /datum/species/golem/bronze/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) 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 606b7a8bfd..b164fb1ba0 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -3,8 +3,8 @@ id = "human" default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR) - mutant_bodyparts = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "taur" = "None", "deco_wings" = "None") + species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR,CAN_SCAR) + 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 disliked_food = GROSS | RAW 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 31f326fd53..e97db7aced 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -7,7 +7,7 @@ species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR) mutantlungs = /obj/item/organ/lungs/slime mutant_heart = /obj/item/organ/heart/slime - mutant_bodyparts = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None") + mutant_bodyparts = list("mcolor" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None") inherent_traits = list(TRAIT_TOXINLOVER) meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime gib_types = list(/obj/effect/gibspawner/slime, /obj/effect/gibspawner/slime/bodypartless) @@ -443,7 +443,7 @@ default_color = "00FFFF" species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR) inherent_traits = list(TRAIT_TOXINLOVER) - mutant_bodyparts = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None") + mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None") say_mod = "says" hair_color = "mutcolor" hair_alpha = 160 //a notch brighter so it blends better. 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 c42e0bf175..a424969175 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) + species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR,CAN_SCAR) 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 dcb6d868fc..8e8c65b15e 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) + species_traits = list(MUTCOLORS, NOEYES, NO_UNDERWEAR,NOGENITALS,NOAROUSAL,CAN_SCAR) 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/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index e79160da06..4806d4a6a1 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) + species_traits = list(MUTCOLORS,EYECOLOR,CAN_SCAR) attack_verb = "slash" attack_sound = 'sound/weapons/slice.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' @@ -64,7 +64,7 @@ name = "Anthromorphic Plant" id = "podweak" species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS) - mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs") + mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs") limbs_id = "pod" light_nutrition_gain_factor = 3 light_bruteheal = -0.2 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 fede67b47a..2776c6d919 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) - inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH) + species_traits = list(NOBLOOD,NOEYES,CAN_SCAR) + inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH,CAN_SCAR) dangerous_existence = 1 mutanteyes = /obj/item/organ/eyes/night_vision 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 f720aa7f8a..9c9220132c 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -5,7 +5,7 @@ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD) inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID - mutant_bodyparts = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "deco_wings" = "None") + mutant_bodyparts = list("mcolor" = "FFFFFF", "tail_human" = "None", "ears" = "None", "deco_wings" = "None") exotic_bloodtype = "U" use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM mutant_heart = /obj/item/organ/heart/vampire 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 26a99dbc2b..ab0838c873 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) + species_traits = list(NOBLOOD,NOZOMBIE,NOTRANSSTING,CAN_SCAR) 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 @@ -33,7 +33,7 @@ limbs_id = "zombie" mutanthands = /obj/item/zombie_hand armor = 20 // 120 damage to KO a zombie, which kills it - speedmod = 1.6 + speedmod = 1.6 // they're very slow mutanteyes = /obj/item/organ/eyes/night_vision/zombie var/heal_rate = 1 var/regen_cooldown = 0 @@ -41,11 +41,10 @@ /datum/species/zombie/infectious/check_roundstart_eligible() return FALSE - /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) +/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) . = ..() if(.) regen_cooldown = world.time + REGENERATION_DELAY @@ -62,6 +61,10 @@ heal_amt *= 2 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() if(!C.InCritical() && prob(4)) playsound(C, pick(spooks), 50, TRUE, 10) @@ -85,6 +88,11 @@ infection = new() infection.Insert(C) + //make their bodyparts stamina-resistant + var/incoming_stam_mult = 0.7 + for(var/obj/item/bodypart/part in C.bodyparts) + part.incoming_stam_mult = incoming_stam_mult + //todo: add negative wound resistance to all parts when wounds is merged (zombies are physically weak in terms of limbs) // Your skin falls off /datum/species/krokodil_addict diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index b40d87a68a..725feb214c 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -404,6 +404,12 @@ if(stat != DEAD || D.process_dead) D.stage_act() +/mob/living/carbon/handle_wounds() + for(var/thing in all_wounds) + var/datum/wound/W = thing + if(W.processes) // meh + W.handle_process() + //todo generalize this and move hud out /mob/living/carbon/proc/handle_changeling() if(mind && hud_used && hud_used.lingchemdisplay) diff --git a/code/modules/mob/living/carbon/monkey/punpun.dm b/code/modules/mob/living/carbon/monkey/punpun.dm index c5cb4dc713..c59218a8a3 100644 --- a/code/modules/mob/living/carbon/monkey/punpun.dm +++ b/code/modules/mob/living/carbon/monkey/punpun.dm @@ -26,6 +26,8 @@ //These have to be after the parent new to ensure that the monkey //bodyparts are actually created before we try to equip things to //those slots + if(ancestor_chain > 1) + generate_fake_scars(rand(ancestor_chain, ancestor_chain * 4)) if(relic_hat) equip_to_slot_or_del(new relic_hat, SLOT_HEAD) if(relic_mask) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 0c049ab5c1..012808647e 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) +/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) 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) +/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) adjustBruteLoss(brute, FALSE) //zero as argument for no instant health update adjustFireLoss(burn, FALSE) adjustStaminaLoss(stamina, FALSE) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 1993d86b74..fb71693534 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -3,7 +3,7 @@ * Splits off into PhysicalLife() and BiologicalLife(). Override those instead of this. */ /mob/living/proc/Life(seconds, times_fired) - set waitfor = FALSE // yeah hey we're kind of on a subsystem, no sleeping will be tolerated here! + SHOULD_NOT_SLEEP(TRUE) if(mob_transforming) return @@ -45,6 +45,8 @@ /mob/living/proc/BiologicalLife(seconds, times_fired) handle_diseases()// DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not. + handle_wounds() + // Everything after this shouldn't process while dead (as of the time of writing) if(stat == DEAD) return FALSE @@ -80,7 +82,7 @@ handle_diginvis() //AI becomes unable to see mob if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating - float(on = TRUE) + INVOKE_ASYNC(src, /atom/movable.proc/float, TRUE) if(!loc) return FALSE @@ -109,6 +111,9 @@ /mob/living/proc/handle_diseases() return +/mob/living/proc/handle_wounds() + return + /mob/living/proc/handle_diginvis() if(!digitaldisguise) src.digitaldisguise = image(loc = src) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 892518d6ba..9850afc1a3 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -636,7 +636,7 @@ TH.transfer_mob_blood_dna(src) /mob/living/carbon/human/makeTrail(turf/T) - if((NOBLOOD in dna.species.species_traits) || !bleed_rate || bleedsuppress) + if((NOBLOOD in dna.species.species_traits) || !is_bleeding() || bleedsuppress) return ..() @@ -802,7 +802,7 @@ else throw_alert("gravity", /obj/screen/alert/weightless) if(!override && !is_flying()) - float(!has_gravity) + INVOKE_ASYNC(src, /atom/movable.proc/float, !has_gravity) /mob/living/float(on) if(throwing) diff --git a/code/modules/mob/living/living_active_parry.dm b/code/modules/mob/living/living_active_parry.dm index 0dab70b045..8141603f64 100644 --- a/code/modules/mob/living/living_active_parry.dm +++ b/code/modules/mob/living/living_active_parry.dm @@ -34,7 +34,7 @@ data = mind.martial_art.block_parry_data method = MARTIAL_PARRY tool = mind.martial_art - else if(combat_flags & COMBAT_FLAG_UNARMED_PARRY) + else if((combat_flags & COMBAT_FLAG_UNARMED_PARRY) && check_unarmed_parry_activation_special()) data = block_parry_data method = UNARMED_PARRY tool = src @@ -93,6 +93,12 @@ if(I.can_active_parry()) return I +/** + * Check if we can unarmed parry + */ +/mob/living/proc/check_unarmed_parry_activation_special() + return TRUE + /** * Called via timer when the parry sequence ends. */ diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 07252b4c45..e24e9641bf 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -85,7 +85,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) + 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 @@ -138,7 +138,7 @@ 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) + apply_damage(total_damage, dtype, impacting_zone, armor, sharpness=I.sharpness) if(I.thrownby) log_combat(I.thrownby, src, "threw and hit", I) else @@ -270,10 +270,10 @@ user.set_pull_offsets(src, grab_state) return 1 -/mob/living/attack_hand(mob/user) +/mob/living/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) ..() //Ignoring parent return value here. SEND_SIGNAL(src, COMSIG_MOB_ATTACK_HAND, user) - if((user != src) && user.a_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS)) + if((user != src) && act_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE | ((unarmed_attack_flags & UNARMED_ATTACK_PARRY)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE), null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS)) log_combat(user, src, "attempted to touch") visible_message("[user] attempted to touch [src]!", "[user] attempted to touch you!", target = user, diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm index 2a03afb61a..b89f249c80 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, spread_damage = 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 = FALSE) var/hit_percent = (100-blocked)/100 if(!damage || (!forced && hit_percent <= 0)) return 0 diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index bb6c37a010..0d8a0880a8 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -2,7 +2,18 @@ //as they handle all relevant stuff like adding it to the player's screen and such //Returns the thing in our active hand (whatever is in our active module-slot, in this case) +//This proc has been butchered into a proc that overrides borg item holding for the sake of making grippers work. +//I'd be immensely thankful if anyone can figure out a less obtuse way of making grippers work without breaking functionality. /mob/living/silicon/robot/get_active_held_item() + var/item = module_active + if(istype(item, /obj/item/weapon/gripper)) + var/obj/item/weapon/gripper/G = item + if(G.wrapped) + if(G.wrapped.loc != G) + G.wrapped = null + return module_active + item = G.wrapped + return item return module_active diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 8f103c496e..badbcc4ed5 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -324,7 +324,7 @@ /obj/item/crowbar/cyborg, /obj/item/healthanalyzer, /obj/item/reagent_containers/borghypo, - /obj/item/reagent_containers/glass/beaker/large, + /obj/item/weapon/gripper/medical, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/surgical_drapes, @@ -334,9 +334,11 @@ /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/circular_saw, + /obj/item/bonesetter, /obj/item/roller/robo, /obj/item/borg/cyborghug/medical, /obj/item/stack/medical/gauze/cyborg, + /obj/item/stack/medical/bone_gel/cyborg, /obj/item/organ_storage, /obj/item/borg/lollipop, /obj/item/sensor_device, @@ -444,7 +446,7 @@ /obj/item/t_scanner, /obj/item/analyzer, /obj/item/storage/part_replacer/cyborg, - /obj/item/holosign_creator/atmos, + /obj/item/holosign_creator/combifan, /obj/item/weapon/gripper, /obj/item/lightreplacer/cyborg, /obj/item/geiger_counter/cyborg, @@ -779,9 +781,8 @@ /obj/item/toy/crayon/spraycan/borg, /obj/item/hand_labeler/borg, /obj/item/razor, - /obj/item/rsf, - /obj/item/instrument/violin, - /obj/item/instrument/guitar, + /obj/item/rsf/cyborg, + /obj/item/instrument/piano_synth, /obj/item/reagent_containers/dropper, /obj/item/lighter, /obj/item/storage/bag/tray, @@ -1051,6 +1052,8 @@ /obj/item/cautery, /obj/item/surgicaldrill, /obj/item/scalpel, + /obj/item/bonesetter, + /obj/item/stack/medical/bone_gel, /obj/item/melee/transforming/energy/sword/cyborg/saw, /obj/item/roller/robo, /obj/item/card/emag, diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index a347b04e50..3ad19deeac 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -102,6 +102,10 @@ var/can_salute = TRUE var/salute_delay = 60 SECONDS + //emotes/speech stuff + var/patrol_emote = "Engaging patrol mode." + var/patrol_fail_emote = "Unable to start patrol." + /mob/living/simple_animal/bot/proc/get_mode() if(client) //Player bots do not have modes, thus the override. Also an easy way for PDA users/AI to know when a bot is a player. if(paicard) @@ -612,7 +616,7 @@ Pass a positive integer as an argument to override a bot's default speed. if(tries >= BOT_STEP_MAX_RETRIES) //Bot is trapped, so stop trying to patrol. auto_patrol = 0 tries = 0 - speak("Unable to start patrol.") + speak(patrol_fail_emote) return @@ -628,7 +632,7 @@ Pass a positive integer as an argument to override a bot's default speed. return mode = BOT_PATROL else // no patrol target, so need a new one - speak("Engaging patrol mode.") + speak(patrol_emote) find_patrol_target() tries++ return diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 174ac869fa..5c83482bde 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -341,7 +341,7 @@ target_types = typecacheof(target_types) -/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A) +/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(istype(A, /obj/effect/decal/cleanable)) anchored = TRUE icon_state = "cleanbot-c" diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 6febb942a1..1f81e8db29 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -518,7 +518,7 @@ Auto Patrol[]"}, /mob/living/simple_animal/bot/ed209/redtag lasercolor = "r" -/mob/living/simple_animal/bot/ed209/UnarmedAttack(atom/A) +/mob/living/simple_animal/bot/ed209/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(!on) return if(iscarbon(A)) diff --git a/code/modules/mob/living/simple_animal/bot/firebot.dm b/code/modules/mob/living/simple_animal/bot/firebot.dm index a5ac2e8bca..d0e969dc4e 100644 --- a/code/modules/mob/living/simple_animal/bot/firebot.dm +++ b/code/modules/mob/living/simple_animal/bot/firebot.dm @@ -58,7 +58,7 @@ internal_ext.max_water = INFINITY internal_ext.refill() -/mob/living/simple_animal/bot/firebot/UnarmedAttack(atom/A) +/mob/living/simple_animal/bot/firebot/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(!on) return if(internal_ext) diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index 0f4608f48c..0ba4023864 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -413,7 +413,7 @@ /obj/machinery/bot_core/floorbot req_one_access = list(ACCESS_CONSTRUCTION, ACCESS_ROBOTICS) -/mob/living/simple_animal/bot/floorbot/UnarmedAttack(atom/A) +/mob/living/simple_animal/bot/floorbot/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(isturf(A)) repair(A) else diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index c3c16d5976..43f18d3890 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -141,7 +141,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"}, retaliate(Proj.firer) return ..() -/mob/living/simple_animal/bot/honkbot/UnarmedAttack(atom/A) +/mob/living/simple_animal/bot/honkbot/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(!on) return if(iscarbon(A)) @@ -367,4 +367,4 @@ Maintenance panel panel is [open ? "opened" : "closed"]"}, ..() /obj/machinery/bot_core/honkbot - req_one_access = list(ACCESS_THEATRE, ACCESS_ROBOTICS) \ No newline at end of file + req_one_access = list(ACCESS_THEATRE, ACCESS_ROBOTICS) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index cbb495bf9c..f998f58f02 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -625,7 +625,7 @@ else ..() -/mob/living/simple_animal/bot/medbot/UnarmedAttack(atom/A) +/mob/living/simple_animal/bot/medbot/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(iscarbon(A)) var/mob/living/carbon/C = A patient = C @@ -790,4 +790,4 @@ #undef MEDBOT_PANIC_HIGH #undef MEDBOT_PANIC_FUCK #undef MEDBOT_PANIC_ENDING -#undef MEDBOT_PANIC_END \ No newline at end of file +#undef MEDBOT_PANIC_END diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 6721a504c4..5e96818766 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -752,7 +752,7 @@ if(load) unload() -/mob/living/simple_animal/bot/mulebot/UnarmedAttack(atom/A) +/mob/living/simple_animal/bot/mulebot/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(isturf(A) && isturf(loc) && loc.Adjacent(A) && load) unload(get_dir(loc, A)) else diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index d199bc2ead..9d45b96831 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -33,6 +33,20 @@ var/check_records = TRUE //Does it check security records? var/arrest_type = FALSE //If true, don't handcuff + var/obj/item/clothing/head/bot_accessory + var/datum/beepsky_fashion/stored_fashion + + //emotes (BOT is replaced with bot name, CRIMINAL with criminal name, THREAT_LEVEL with threat level) + var/death_emote = "BOT blows apart!" + var/capture_one = "BOT is trying to put zipties on CRIMINAL!" + var/capture_two = "BOT is trying to put zipties on you!" + var/infraction = "Level THREAT_LEVEL infraction alert!" + var/taunt = "BOT points at CRIMINAL!" + var/attack_one = "BOT has stunned CRIMINAL!" + var/attack_two = "BOT has stunned you!" + var/list/arrest_texts = list("Detaining", "Arresting") + var/arrest_emote = "ARREST_TYPE level THREAT_LEVEL scumbag CRIMINAL in LOCATION." + /mob/living/simple_animal/bot/secbot/beepsky name = "Officer Beep O'sky" desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey." @@ -49,6 +63,103 @@ resize = 0.8 update_transform() +/mob/living/simple_animal/bot/secbot/proc/process_emote(var/emote_type, var/atom/criminal, var/threat, var/arrest = -1, var/location) + var/emote = "The continuity of space itself collapses around [src]. You should probably report that to someone higher up." + switch(emote_type) + if("DEATH") + emote = death_emote + if("CAPTURE_ONE") + emote = capture_one + if("CAPTURE_TWO") + emote = capture_two + if("INFRACTION") + emote = infraction + if("TAUNT") + emote = taunt + if("ATTACK_ONE") + emote = attack_one + if("ATTACK_TWO") + emote = attack_two + if("ARREST") + emote = arrest_emote + + //now replace pieces of the text with the information we have + if(emote_type != "TAUNT" && emote_type != "ARREST") + emote = replacetext(emote, "BOT", name) + else + emote = replacetext(emote, "BOT", "[name]") //needs to be bold if its a taunt or an arrest text + if(criminal) + emote = replacetext(emote, "CRIMINAL", criminal.name) + if(threat) + emote = replacetext(emote, "THREAT_LEVEL", threat) + if(arrest > -1) + emote = replacetext(emote, "ARREST_TYPE", arrest_texts[arrest + 1]) + if(location) + emote = replacetext(emote, "LOCATION", location) + return emote + +/mob/living/simple_animal/bot/secbot/proc/apply_fashion(var/datum/beepsky_fashion/fashion) + stored_fashion = new fashion + if(stored_fashion.name) + name = stored_fashion.name + + if(stored_fashion.desc) + desc = stored_fashion.desc + + if(stored_fashion.death_emote) + death_emote = stored_fashion.death_emote + + if(stored_fashion.capture_one) + capture_one = stored_fashion.capture_one + + if(stored_fashion.capture_two) + capture_two = stored_fashion.capture_two + + if(stored_fashion.infraction) + infraction = stored_fashion.infraction + + if(stored_fashion.taunt) + taunt = stored_fashion.taunt + + if(stored_fashion.attack_one) + attack_one = stored_fashion.attack_one + + if(stored_fashion.attack_two) + attack_two = stored_fashion.attack_two + + if(stored_fashion.patrol_emote) + patrol_emote = stored_fashion.patrol_emote + + if(stored_fashion.patrol_fail_emote) + patrol_fail_emote = stored_fashion.patrol_fail_emote + + if(stored_fashion.arrest_texts) + arrest_texts = stored_fashion.arrest_texts + + if(stored_fashion.arrest_emote) + arrest_emote = stored_fashion.arrest_emote + + regenerate_icons() + +/mob/living/simple_animal/bot/secbot/proc/reset_fashion() + bot_accessory.forceMove(get_turf(src)) + //reset all emotes/sounds and name/desc + name = initial(name) + desc = initial(desc) + death_emote = initial(death_emote) + capture_one = initial(capture_one) + capture_two = initial(capture_two) + infraction = initial(infraction) + taunt = initial(taunt) + attack_one = initial(attack_one) + attack_two = initial(attack_two) + arrest_texts = initial(arrest_texts) + arrest_emote = initial(arrest_emote) + patrol_emote = initial(patrol_emote) + arrest_texts = initial(arrest_texts) + arrest_emote = initial(arrest_emote) + bot_accessory = null + regenerate_icons() /mob/living/simple_animal/bot/secbot/beepsky/explode() var/atom/Tsec = drop_location() @@ -178,6 +289,11 @@ Auto Patrol: []"}, retaliate(H) if(special_retaliate_after_attack(H)) return + if(H.a_intent == INTENT_HELP && bot_accessory) + + to_chat(H, "You knock [bot_accessory] off of [src]'s head!") + reset_fashion() + return return ..() @@ -185,11 +301,48 @@ Auto Patrol: []"}, ..() if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry. return + if(istype(W, /obj/item/clothing/head)) + attempt_place_on_head(user, W) + return if(!istype(W, /obj/item/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass. retaliate(user) if(special_retaliate_after_attack(user)) return +/mob/living/simple_animal/bot/secbot/proc/attempt_place_on_head(mob/user, obj/item/clothing/head/H) + if(user && !user.temporarilyRemoveItemFromInventory(H)) + to_chat(user, "\The [H] is stuck to your hand, you cannot put it on [src]'s head!") + return + if(bot_accessory) + to_chat("\[src] already has an accessory, and the laws of physics disallow him from wearing a second!") + return + + if(H.beepsky_fashion) + to_chat(user, "You set [H] on [src].") + bot_accessory = H + H.forceMove(src) + apply_fashion(H.beepsky_fashion) + else + to_chat(user, "You set [H] on [src]'s head, but it falls off!") + H.forceMove(drop_location()) + +/mob/living/simple_animal/bot/secbot/regenerate_icons() + ..() + if(bot_accessory) + if(!stored_fashion) + stored_fashion = new bot_accessory.beepsky_fashion + if(!stored_fashion.obj_icon_state) + stored_fashion.obj_icon_state = bot_accessory.icon_state + if(!stored_fashion.obj_alpha) + stored_fashion.obj_alpha = bot_accessory.alpha + if(!stored_fashion.obj_color) + stored_fashion.obj_color = bot_accessory.color + add_overlay(stored_fashion.get_overlay()) + else + if(stored_fashion) + cut_overlay(stored_fashion.get_overlay()) + stored_fashion = null + /mob/living/simple_animal/bot/secbot/emag_act(mob/user) . = ..() if(emagged == 2) @@ -208,7 +361,7 @@ Auto Patrol: []"}, return ..() -/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A) +/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) if(!on) return if(iscarbon(A)) @@ -233,8 +386,8 @@ Auto Patrol: []"}, /mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C) mode = BOT_ARREST playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2) - C.visible_message("[src] is trying to put zipties on [C]!",\ - "[src] is trying to put zipties on you!") + C.visible_message("[process_emote("CAPTURE_ONE", C)]",\ + "[process_emote("CAPTURE_TWO", C)]") if(do_after(src, 60, FALSE, C)) attempt_handcuff(C) @@ -249,16 +402,22 @@ Auto Patrol: []"}, /mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C) var/judgement_criteria = judgement_criteria() - playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1) icon_state = "secbot-c" addtimer(CALLBACK(src, /atom/.proc/update_icon), 2) var/threat = 5 if(ishuman(C)) + if(stored_fashion) + stored_fashion.stun_attack(C) + if(stored_fashion.stun_sounds && !stored_fashion.ignore_sound) + playsound(src, pick(stored_fashion.stun_sounds), 50, TRUE, -1) + else + playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1) C.stuttering = 5 C.DefaultCombatKnockdown(100) var/mob/living/carbon/human/H = C threat = H.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons)) else + playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1) C.DefaultCombatKnockdown(100) C.stuttering = 5 threat = C.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons)) @@ -266,9 +425,9 @@ Auto Patrol: []"}, log_combat(src,C,"stunned") if(declare_arrests) var/area/location = get_area(src) - speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag [C] in [location].", radio_channel) - C.visible_message("[src] has stunned [C]!",\ - "[src] has stunned you!") + speak(process_emote("ARREST", C, threat, arrest_type, location), radio_channel) + C.visible_message("[process_emote("ATTACK_ONE", C)]",\ + "[process_emote("ATTACK_TWO", C)]") /mob/living/simple_animal/bot/secbot/handle_automated_action() if(!..()) @@ -355,7 +514,6 @@ Auto Patrol: []"}, look_for_perp() bot_patrol() - return /mob/living/simple_animal/bot/secbot/proc/back_to_idle() @@ -391,9 +549,9 @@ Auto Patrol: []"}, else if(threatlevel >= 4) target = C oldtarget_name = C.name - speak("Level [threatlevel] infraction alert!") + speak(process_emote("INFRACTION", target, threatlevel)) playsound(loc, pick('sound/voice/beepsky/criminal.ogg', 'sound/voice/beepsky/justice.ogg', 'sound/voice/beepsky/freeze.ogg'), 50, FALSE) - visible_message("[src] points at [C.name]!") + visible_message(process_emote("TAUNT", target, threatlevel)) mode = BOT_HUNT INVOKE_ASYNC(src, .proc/handle_automated_action) break @@ -408,7 +566,7 @@ Auto Patrol: []"}, /mob/living/simple_animal/bot/secbot/explode() walk_to(src,0) - visible_message("[src] blows apart!") + visible_message("[process_emote("DEATH")]") var/atom/Tsec = drop_location() var/obj/item/bot_assembly/secbot/Sa = new (Tsec) 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 f1916b412a..d396434708 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm @@ -87,7 +87,7 @@ detonate(user) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/guardian_bomb/attack_hand(mob/living/user) +/obj/guardian_bomb/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) detonate(user) /obj/guardian_bomb/examine(mob/user) diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 5dbf3e8e3b..dc3c90cc64 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -29,8 +29,11 @@ var/armored = FALSE obj_damage = 60 - melee_damage_lower = 20 - melee_damage_upper = 30 + melee_damage_lower = 15 // i know it's like half what it used to be, but bears cause bleeding like crazy now so it works out + melee_damage_upper = 15 + wound_bonus = -5 + bare_wound_bonus = 10 // BEAR wound bonus am i right + sharpness = TRUE attack_verb_continuous = "claws" attack_verb_simple = "claw" attack_sound = 'sound/weapons/bladeslice.ogg' @@ -69,8 +72,9 @@ icon_dead = "combatbear_dead" faction = list("russian") butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1, /obj/item/bear_armor = 1) - melee_damage_lower = 25 - melee_damage_upper = 35 + melee_damage_lower = 18 + melee_damage_upper = 20 + wound_bonus = 0 armour_penetration = 20 health = 120 maxHealth = 120 @@ -99,8 +103,9 @@ A.maxHealth += 60 A.health += 60 A.armour_penetration += 20 - A.melee_damage_lower += 5 + A.melee_damage_lower += 3 A.melee_damage_upper += 5 + A.wound_bonus += 5 A.update_icons() to_chat(user, "You strap the armor plating to [A] and sharpen [A.p_their()] claws with the nail filer. This was a great idea.") qdel(src) diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index 51f61fa158..a4edb21479 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -81,7 +81,7 @@ /obj/structure/leaper_bubble/Initialize() . = ..() - float(on = TRUE) + INVOKE_ASYNC(src, /atom/movable.proc/float, TRUE) QDEL_IN(src, 100) /obj/structure/leaper_bubble/Destroy() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 5816be2917..aa4ff328b5 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -385,7 +385,7 @@ Difficulty: Very Hard if(isliving(speaker)) ActivationReaction(speaker, ACTIVATE_SPEECH) -/obj/machinery/anomalous_crystal/attack_hand(mob/user) +/obj/machinery/anomalous_crystal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 062a4c9a43..a1ecde40b8 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -4,6 +4,11 @@ #define SWOOP_DAMAGEABLE 1 #define SWOOP_INVULNERABLE 2 +///used whenever the drake generates a hotspot +#define DRAKE_FIRE_TEMP 500 +///used whenever the drake generates a hotspot +#define DRAKE_FIRE_EXPOSURE 50 + /* ASH DRAKE @@ -148,7 +153,7 @@ Difficulty: Medium break range-- new /obj/effect/hotspot(J) - J.hotspot_expose(700,50,1) + J.hotspot_expose(DRAKE_FIRE_TEMP, DRAKE_FIRE_EXPOSURE, 1) for(var/mob/living/L in J.contents - hit_things) if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon)) continue @@ -404,7 +409,7 @@ Difficulty: Medium if(istype(T, /turf/closed)) break new /obj/effect/hotspot(T) - T.hotspot_expose(700,50,1) + T.hotspot_expose(DRAKE_FIRE_TEMP,DRAKE_FIRE_EXPOSURE,1) for(var/mob/living/L in T.contents) if(L in hit_list || L == source) continue diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index a66ee7b1de..c00d7c3130 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -643,7 +643,7 @@ Difficulty: Normal to_chat(L, "You're struck by a [name]!") var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)) var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!") - L.apply_damage(damage, BURN, limb_to_hit, armor) + L.apply_damage(damage, BURN, limb_to_hit, armor, wound_bonus=CANT_WOUND) if(ishostile(L)) var/mob/living/simple_animal/hostile/H = L //mobs find and damage you... if(H.stat == CONSCIOUS && !H.target && H.AIStatus != AI_OFF && !H.client) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 4da8a90b23..78c02fb7a7 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -52,6 +52,8 @@ Difficulty: Medium elimination = 1 appearance_flags = 0 mouse_opacity = MOUSE_OPACITY_ICON + wound_bonus = -40 + bare_wound_bonus = 20 /mob/living/simple_animal/hostile/megafauna/legion/Initialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm index ed189f052d..869f29951b 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm @@ -129,7 +129,7 @@ Difficulty: Hard to_chat(L, "[src]'s ground slam shockwave sends you flying!") var/turf/thrownat = get_ranged_target_turf_direct(src, L, 8, rand(-10, 10)) L.throw_at(thrownat, 8, 2, src, TRUE) //, force = MOVE_FORCE_OVERPOWERING, gentle = TRUE) - L.apply_damage(20, BRUTE) + L.apply_damage(20, BRUTE, wound_bonus=CANT_WOUND) shake_camera(L, 2, 1) all_turfs -= T sleep(delay) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm index 81b541dc7b..982b91c2c9 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm @@ -148,7 +148,7 @@ While using this makes the system rely on OnFire, it still gives options for tim desc = "You're not quite sure how a signal can be menacing." invisibility = 100 -/obj/structure/elite_tumor/attack_hand(mob/user) +/obj/structure/elite_tumor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(ishuman(user)) switch(activity) diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm index 1db6854f96..3620e3ee5f 100644 --- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm +++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm @@ -86,7 +86,7 @@ .=..() START_PROCESSING(SSprocessing, src) -/obj/structure/spawner/nether/attack_hand(mob/user) +/obj/structure/spawner/nether/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) user.visible_message("[user] is violently pulled into the link!", \ "Touching the portal, you are quickly pulled through into a world of unimaginable horror!") contents.Add(user) diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 9a362b680d..4ea8a3c5dc 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -77,6 +77,9 @@ /mob/living/simple_animal/hostile/syndicate/melee melee_damage_lower = 15 melee_damage_upper = 15 + wound_bonus = -10 + bare_wound_bonus = 20 + sharpness = TRUE 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 1a646ea73e..1102559aca 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -140,6 +140,13 @@ ///What kind of footstep this mob should have. Null if it shouldn't have any. var/footstep_type + //How much wounding power it has + var/wound_bonus = CANT_WOUND + //How much bare wounding power it has + var/bare_wound_bonus = 0 + //If the attacks from this are sharp + var/sharpness = FALSE + /mob/living/simple_animal/Initialize() . = ..() GLOB.simple_animals[AIStatus] += src diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 65e0b804d3..d454f85d1c 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -589,6 +589,8 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) /mob/Stat() ..() + SSvote?.render_statpanel(src) + //This is only called from client/Stat(), let's assume client exists. if(statpanel("Status")) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index de69afbe7e..6dc090a950 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -123,6 +123,9 @@ var/list/progressbars = null //for stacking do_after bars + ///For storing what do_after's someone has, in case we want to restrict them to only one of a certain do_after at a time + var/list/do_afters + var/list/mousemove_intercept_objects var/datum/click_intercept diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm index a4d2e74657..4e4c1fcdce 100644 --- a/code/modules/modular_computers/computers/item/laptop.dm +++ b/code/modules/modular_computers/computers/item/laptop.dm @@ -64,7 +64,7 @@ return M.put_in_hand(src, H.held_index) -/obj/item/modular_computer/laptop/attack_hand(mob/user) +/obj/item/modular_computer/laptop/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 67f62bbb9d..462d50eb45 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -71,6 +71,7 @@ resistance_flags = FLAMMABLE max_integrity = 50 dog_fashion = /datum/dog_fashion/head + grind_results = list(/datum/reagent/cellulose = 3) color = "white" /// What's actually written on the paper. var/info = "" diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index 0a7bf011a7..770a6682e0 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -66,7 +66,7 @@ return ..() -/obj/item/papercutter/attack_hand(mob/user) +/obj/item/papercutter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 5135e55922..d1141c9f70 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -61,7 +61,7 @@ return attack_hand(user) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/paper_bin/attack_hand(mob/user) +/obj/item/paper_bin/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.lying) return user.changeNext_move(CLICK_CD_MELEE) @@ -148,7 +148,7 @@ papertype = /obj/item/paper/natural resistance_flags = FLAMMABLE -/obj/item/paper_bin/bundlenatural/attack_hand(mob/user) +/obj/item/paper_bin/bundlenatural/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) ..() if(total_paper < 1) qdel(src) diff --git a/code/modules/photography/photos/frame.dm b/code/modules/photography/photos/frame.dm index 9e6f827629..6f7bc643c8 100644 --- a/code/modules/photography/photos/frame.dm +++ b/code/modules/photography/photos/frame.dm @@ -22,7 +22,7 @@ ..() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/wallframe/picture/attack_hand(mob/user) +/obj/item/wallframe/picture/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(user.get_inactive_held_item() != src) ..() return @@ -141,7 +141,7 @@ ..() -/obj/structure/sign/picture_frame/attack_hand(mob/user) +/obj/structure/sign/picture_frame/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/photography/photos/photo.dm b/code/modules/photography/photos/photo.dm index 07f765c123..5c78709e9b 100644 --- a/code/modules/photography/photos/photo.dm +++ b/code/modules/photography/photos/photo.dm @@ -51,6 +51,8 @@ user.examinate(src) /obj/item/photo/attackby(obj/item/P, mob/user, params) + if(try_burn(P, user)) + return if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon)) if(!user.is_literate()) to_chat(user, "You scribble illegibly on [src]!") @@ -60,6 +62,26 @@ scribble = txt ..() +/obj/item/photo/proc/try_burn(obj/item/I, mob/living/user) + var/ignition_message = I.ignition_effect(src, user) + if(!ignition_message) + return + . = TRUE + if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10) && Adjacent(user)) + user.visible_message("[user] accidentally ignites [user.p_them()]self!", \ + "You miss [src] and accidentally light yourself on fire!") + if(user.is_holding(I)) //checking if they're holding it in case TK is involved + user.dropItemToGround(I) + user.adjust_fire_stacks(1) + user.IgniteMob() + return + + if(user.is_holding(src)) //no TK shit here. + user.dropItemToGround(src) + user.visible_message(ignition_message) + add_fingerprint(user) + fire_act(I.get_temperature()) + /obj/item/photo/examine(mob/user) . = ..() if(in_range(src, user)) diff --git a/code/modules/pool/pool_drain.dm b/code/modules/pool/pool_drain.dm index 940f7cd219..8deb9b1ffe 100644 --- a/code/modules/pool/pool_drain.dm +++ b/code/modules/pool/pool_drain.dm @@ -154,7 +154,7 @@ else new /mob/living/simple_animal/hostile/shark/laser(loc) -/obj/machinery/pool/filter/attack_hand(mob/user) +/obj/machinery/pool/filter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) to_chat(user, "You search the filter.") for(var/obj/O in contents) O.forceMove(loc) diff --git a/code/modules/pool/pool_main.dm b/code/modules/pool/pool_main.dm index b45c0f36a2..30d1744b57 100644 --- a/code/modules/pool/pool_main.dm +++ b/code/modules/pool/pool_main.dm @@ -177,7 +177,7 @@ else return ..() -/turf/open/pool/attack_hand(mob/living/user) +/turf/open/pool/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/pool/pool_structures.dm b/code/modules/pool/pool_structures.dm index 4cea485237..6b71e95639 100644 --- a/code/modules/pool/pool_structures.dm +++ b/code/modules/pool/pool_structures.dm @@ -11,7 +11,7 @@ layer = ABOVE_MOB_LAYER dir = EAST -/obj/structure/pool/ladder/attack_hand(mob/living/user) +/obj/structure/pool/ladder/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -52,7 +52,7 @@ user.pixel_x = initial_px user.pixel_y = initial_py -/obj/structure/pool/Lboard/attack_hand(mob/living/user) +/obj/structure/pool/Lboard/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/jumper = user if(jumping) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 6f8a33f506..3f9ca4f1b7 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -833,7 +833,7 @@ // attack with hand - remove cell (if cover open) or interact with the APC -/obj/machinery/power/apc/attack_hand(mob/user) +/obj/machinery/power/apc/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -935,6 +935,9 @@ return "[area.name] : [equipment]/[lighting]/[environ] ([lastused_equip+lastused_light+lastused_environ]) : [cell? cell.percent() : "N/C"] ([charging])" /obj/machinery/power/apc/proc/update() + var/old_light = area.power_light + var/old_equip = area.power_equip + var/old_environ = area.power_environ if(operating && !shorted && !failure_timer) area.power_light = (lighting > 1) area.power_equip = (equipment > 1) @@ -943,7 +946,8 @@ area.power_light = FALSE area.power_equip = FALSE area.power_environ = FALSE - area.power_change() + if(old_light != area.power_light || old_equip != area.power_equip || old_environ != area.power_environ) + area.power_change() /obj/machinery/power/apc/proc/can_use(mob/user, loud = 0) //used by attack_hand() and Topic() if(IsAdminGhost(user)) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index e89507f33d..c8b02669e8 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -564,7 +564,7 @@ By design, d1 is the smallest direction and d2 is the highest icon_state = "[initial(item_state)][amount < 3 ? amount : ""]" name = "cable [amount < 3 ? "piece" : "coil"]" -/obj/item/stack/cable_coil/attack_hand(mob/user) +/obj/item/stack/cable_coil/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/power/floodlight.dm b/code/modules/power/floodlight.dm index e0b3f5f316..2bd4c04402 100644 --- a/code/modules/power/floodlight.dm +++ b/code/modules/power/floodlight.dm @@ -92,7 +92,7 @@ else . = ..() -/obj/machinery/power/floodlight/attack_hand(mob/user) +/obj/machinery/power/floodlight/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return @@ -113,4 +113,4 @@ qdel(src) /obj/machinery/power/floodlight/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - playsound(src, 'sound/effects/glasshit.ogg', 75, 1) \ No newline at end of file + playsound(src, 'sound/effects/glasshit.ogg', 75, 1) diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 935af51b93..76154907ae 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -80,7 +80,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne /obj/machinery/gravity_generator/part/get_status() return main_part?.get_status() -/obj/machinery/gravity_generator/part/attack_hand(mob/user) +/obj/machinery/gravity_generator/part/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) return main_part.attack_hand(user) /obj/machinery/gravity_generator/part/set_broken() diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index 89596eb82f..5ef66e26d9 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -22,7 +22,7 @@ return ..() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/machinery/field/containment/attack_hand(mob/user) +/obj/machinery/field/containment/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(get_dist(src, user) > 1) return FALSE else diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 025784e909..96f8b4e996 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -59,7 +59,7 @@ last_failed_movement = direct return 0 -/obj/singularity/attack_hand(mob/user) +/obj/singularity/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) consume(user) return TRUE diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 87bdfe99e2..823ba75e43 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -571,7 +571,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/attack_ai(mob/user) return -/obj/machinery/power/supermatter_crystal/attack_hand(mob/living/user) +/obj/machinery/power/supermatter_crystal/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm index ea84e23d01..b6fdef69e2 100644 --- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm +++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm @@ -8,6 +8,18 @@ projectile_type = /obj/item/projectile/bullet/shotgun_slug custom_materials = list(/datum/material/iron=4000) +obj/item/ammo_casing/shotgun/executioner + name = "executioner slug" + desc = "A 12 gauge lead slug purpose built to annihilate flesh on impact." + icon_state = "stunshell" + projectile_type = /obj/item/projectile/bullet/shotgun_slug/executioner + +/obj/item/ammo_casing/shotgun/pulverizer + name = "pulverizer slug" + desc = "A 12 gauge lead slug purpose built to annihilate bones on impact." + icon_state = "stunshell" + projectile_type = /obj/item/projectile/bullet/shotgun_slug/pulverizer + /obj/item/ammo_casing/shotgun/beanbag name = "beanbag slug" desc = "A weak beanbag slug for riot control." diff --git a/code/modules/projectiles/ammunition/energy/laser.dm b/code/modules/projectiles/ammunition/energy/laser.dm index 174645dd11..05c47fc3bb 100644 --- a/code/modules/projectiles/ammunition/energy/laser.dm +++ b/code/modules/projectiles/ammunition/energy/laser.dm @@ -37,6 +37,11 @@ select_name = "anti-vehicle" fire_sound = 'sound/weapons/lasercannonfire.ogg' +/obj/item/ammo_casing/energy/laser/hellfire + projectile_type = /obj/item/projectile/beam/laser/hellfire + e_cost = 130 + select_name = "maim" + /obj/item/ammo_casing/energy/laser/pulse projectile_type = /obj/item/projectile/beam/pulse e_cost = 200 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index b90f0aee0d..f34343debd 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -184,6 +184,11 @@ return if(target == user && user.zone_selected != BODY_ZONE_PRECISE_MOUTH) //so we can't shoot ourselves (unless mouth selected) return + if(iscarbon(target)) + var/mob/living/carbon/C = target + for(var/datum/wound/W in C.all_wounds) + if(W.try_treating(src, user)) + return // another coward cured! if(istype(user))//Check if the user can use the gun, if the user isn't alive(turrets) assume it can. var/mob/living/L = user diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 4aeefde6d4..e5dc056011 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -98,7 +98,7 @@ update_icon() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/gun/ballistic/attack_hand(mob/user) +/obj/item/gun/ballistic/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user) if(suppressed && can_unsuppress) var/obj/item/suppressor/S = suppressed diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 39956ef3e8..89e30e765b 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -328,7 +328,7 @@ update_icon() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/gun/ballistic/automatic/l6_saw/attack_hand(mob/user) +/obj/item/gun/ballistic/automatic/l6_saw/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc != user) ..() return //let them pick it up diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 72ac9620b5..8e61221cc8 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -44,6 +44,12 @@ ammo_type = list(/obj/item/ammo_casing/energy/lasergun/old) ammo_x_offset = 3 +/obj/item/gun/energy/laser/hellgun + name ="hellfire laser gun" + desc = "A relic of a weapon, built before NT began installing regulators on its laser weaponry. This pattern of laser gun became infamous for the gruesome burn wounds it caused, and was quietly discontinued once it began to affect NT's reputation." + icon_state = "hellgun" + ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire) + /obj/item/gun/energy/laser/captain name = "antique laser gun" icon_state = "caplaser" diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 7c988ca730..1e1559fc6a 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -49,7 +49,7 @@ var/pixel_move_interrupted = FALSE /// Pixels moved per second. - var/pixels_per_second = TILES_TO_PIXELS(12.5) + var/pixels_per_second = TILES_TO_PIXELS(17.5) /// The number of pixels we increment by. THIS IS NOT SPEED, DO NOT TOUCH THIS UNLESS YOU KNOW WHAT YOU ARE DOING. In general, lower values means more linetrace accuracy up to a point at cost of performance. var/pixel_increment_amount @@ -154,6 +154,10 @@ ///If TRUE, hit mobs even if they're on the floor and not our target var/hit_stunned_targets = FALSE + wound_bonus = CANT_WOUND + /// For telling whether we want to roll for bone breaking or lacerations if we're bothering with wounds + sharpness = FALSE + /obj/item/projectile/Initialize() . = ..() permutated = list() diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 2f12f0f69b..4ba72a1935 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -14,11 +14,25 @@ ricochets_max = 50 //Honk! ricochet_chance = 80 is_reflectable = TRUE + wound_bonus = -20 + bare_wound_bonus = 10 /obj/item/projectile/beam/laser tracer_type = /obj/effect/projectile/tracer/laser muzzle_type = /obj/effect/projectile/muzzle/laser impact_type = /obj/effect/projectile/impact/laser + wound_bonus = -30 + bare_wound_bonus = 40 + +//overclocked laser, does a bit more damage but has much higher wound power (-0 vs -20) +/obj/item/projectile/beam/laser/hellfire + name = "hellfire laser" + wound_bonus = 0 + damage = 25 + +/obj/item/projectile/beam/laser/hellfire/Initialize() + . = ..() + transform *= 2 /obj/item/projectile/beam/laser/heavylaser name = "heavy laser" @@ -90,6 +104,7 @@ tracer_type = /obj/effect/projectile/tracer/pulse muzzle_type = /obj/effect/projectile/muzzle/pulse impact_type = /obj/effect/projectile/impact/pulse + wound_bonus = 10 /obj/item/projectile/beam/pulse/on_hit(atom/target, blocked = FALSE) . = ..() @@ -116,6 +131,8 @@ damage = 30 impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser light_color = LIGHT_COLOR_GREEN + wound_bonus = -40 + bare_wound_bonus = 70 /obj/item/projectile/beam/emitter/singularity_pull() return diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 6d03012315..6a081f9b03 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -8,3 +8,4 @@ flag = "bullet" hitsound_wall = "ricochet" impact_effect_type = /obj/effect/temp_visual/impact_effect + sharpness = TRUE \ No newline at end of file diff --git a/code/modules/projectiles/projectile/bullets/revolver.dm b/code/modules/projectiles/projectile/bullets/revolver.dm index 5643804ac1..c793e9f95e 100644 --- a/code/modules/projectiles/projectile/bullets/revolver.dm +++ b/code/modules/projectiles/projectile/bullets/revolver.dm @@ -19,6 +19,8 @@ ricochet_chance = 50 ricochet_auto_aim_angle = 10 ricochet_auto_aim_range = 3 + wound_bonus = -35 + sharpness = TRUE /obj/item/projectile/bullet/c38/match name = ".38 Match bullet" @@ -29,6 +31,7 @@ ricochet_incidence_leeway = 50 ricochet_decay_chance = 1 ricochet_decay_damage = 1 + wound_bonus = 0 /obj/item/projectile/bullet/c38/match/bouncy name = ".38 Rubber bullet" diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm index 264df22c76..6e4a72aff0 100644 --- a/code/modules/projectiles/projectile/bullets/shotgun.dm +++ b/code/modules/projectiles/projectile/bullets/shotgun.dm @@ -2,10 +2,22 @@ name = "12g shotgun slug" damage = 60 +/obj/item/projectile/bullet/shotgun_slug/executioner + name = "executioner slug" // admin only, can dismember limbs + sharpness = TRUE + wound_bonus = 0 + +/obj/item/projectile/bullet/shotgun_slug/pulverizer + name = "pulverizer slug" // admin only, can crush bones + sharpness = FALSE + wound_bonus = 0 + /obj/item/projectile/bullet/shotgun_beanbag name = "beanbag slug" - damage = 5 + damage = 10 stamina = 70 + wound_bonus = 20 + sharpness = FALSE /obj/item/projectile/bullet/incendiary/shotgun name = "incendiary slug" @@ -77,6 +89,7 @@ /obj/item/projectile/bullet/pellet/shotgun_buckshot name = "buckshot pellet" damage = 12.5 + wound_bonus = -10 /obj/item/projectile/bullet/pellet/shotgun_rubbershot name = "rubbershot pellet" diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index b157f328c5..0c3de579b6 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -999,3 +999,18 @@ glass_name = "glass of bungo juice" glass_desc = "Exotic! You feel like you are on vacation already." value = REAGENT_VALUE_COMMON + +/datum/reagent/consumable/aloejuice + name = "Aloe Juice" + color = "#A3C48B" + description = "A healthy and refreshing juice." + taste_description = "vegetable" + glass_icon_state = "glass_yellow" + glass_name = "glass of aloe juice" + glass_desc = "A healthy and refreshing juice." + +/datum/reagent/consumable/aloejuice/on_mob_life(mob/living/M) + if(M.getToxLoss() && prob(30)) + M.adjustToxLoss(-1, 0) + ..() + . = TRUE \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index f80cd10792..d449fa310c 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -115,11 +115,11 @@ /datum/reagent/consumable/cooking_oil/reaction_obj(obj/O, reac_volume) if(holder && holder.chem_temp >= fry_temperature) - if(isitem(O) && !istype(O, /obj/item/reagent_containers/food/snacks/deepfryholder) && !(O.resistance_flags & (FIRE_PROOF|INDESTRUCTIBLE))) + if(isitem(O) && !O.GetComponent(/datum/component/fried) && !(O.resistance_flags & (FIRE_PROOF|INDESTRUCTIBLE)) && (!O.reagents || isfood(O))) //don't fry stuff we shouldn't O.loc.visible_message("[O] rapidly fries as it's splashed with hot oil! Somehow.") - var/obj/item/reagent_containers/food/snacks/deepfryholder/F = new(O.drop_location(), O) - F.fry(volume) - F.reagents.add_reagent(/datum/reagent/consumable/cooking_oil, reac_volume) + O.fry(volume) + if(O.reagents) + O.reagents.add_reagent(/datum/reagent/consumable/cooking_oil, reac_volume) /datum/reagent/consumable/cooking_oil/reaction_mob(mob/living/M, method = TOUCH, reac_volume, show_message = 1, touch_protection = 0) if(!istype(M)) @@ -141,10 +141,9 @@ /datum/reagent/consumable/cooking_oil/reaction_turf(turf/open/T, reac_volume) if(!istype(T) || isgroundlessturf(T)) return - if(reac_volume >= 5) + if(reac_volume >= 5 && holder && holder.chem_temp >= fry_temperature) T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume * 1.5 SECONDS) - T.name = "deep-fried [initial(T.name)]" - T.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY) + T.fry(reac_volume/4) /datum/reagent/consumable/sugar name = "Sugar" diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index b9da8271ab..050b1f29b5 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -144,6 +144,9 @@ M.adjustFireLoss(-power, 0) 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) REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration . = 1 metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5) @@ -192,6 +195,9 @@ M.adjustFireLoss(-1.5 * power, 0) 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) REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) . = 1 ..() @@ -231,7 +237,7 @@ /datum/reagent/medicine/spaceacillin name = "Spaceacillin" - description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with." + description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with. Also reduces infection in serious burns." color = "#f2f2f2" metabolization_rate = 0.1 * REAGENTS_METABOLISM pH = 8.1 @@ -403,7 +409,7 @@ /datum/reagent/medicine/mine_salve name = "Miner's Salve" - description = "A powerful painkiller. Restores bruising and burns in addition to making the patient believe they are fully healed." + description = "A powerful painkiller. Restores bruising and burns in addition to making the patient believe they are fully healed. Also great for treating severe burn wounds in a pinch." reagent_state = LIQUID color = "#6D6374" metabolization_rate = 0.4 * REAGENTS_METABOLISM @@ -432,7 +438,7 @@ // +10% success propability on each step, useful while operating in less-than-perfect conditions if(show_message) - to_chat(M, "You feel your wounds fade away to nothing!" ) + to_chat(M, "You feel your injuries fade away to nothing!" ) ..() /datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M) @@ -453,10 +459,10 @@ /datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M)) - if (M.stat == DEAD) + var/mob/living/carbon/C = M + if(M.stat == DEAD) show_message = 0 if(method in list(INGEST, VAPOR)) - var/mob/living/carbon/C = M C.losebreath++ C.emote("cough") to_chat(M, "You feel your throat closing up!") @@ -465,6 +471,8 @@ 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) 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) @@ -1552,10 +1560,6 @@ /datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all. M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25) M.adjustBruteLoss(-0.35, 0) - if(prob(50)) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.bleed_rate = max(H.bleed_rate - 1, 0) ..() . = 1 @@ -1588,3 +1592,10 @@ to_chat(C, "[pick(GLOB.wisdoms)]") //give them a random wisdom ..() +// handled in cut wounds process +/datum/reagent/medicine/coagulant + name = "Sanguirite" + description = "A coagulant used to help open cuts clot faster." + reagent_state = LIQUID + color = "#bb2424" + metabolization_rate = 0.25 * REAGENTS_METABOLISM diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 988441fa2b..5c5821381e 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2296,3 +2296,43 @@ if(data["blood_DNA"]) S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) +/datum/reagent/determination + name = "Determination" + description = "For when you need to push on a little more. Do NOT allow near plants." + reagent_state = LIQUID + color = "#D2FFFA" + 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 + +/datum/reagent/determination/on_mob_end_metabolize(mob/living/carbon/M) + if(significant) + var/stam_crash = 0 + for(var/thing in M.all_wounds) + var/datum/wound/W = thing + stam_crash += (W.severity + 1) * 3 // spike of 3 stam damage per wound severity (moderate = 6, severe = 9, critical = 12) when the determination wears off if it was a combat rush + M.adjustStaminaLoss(stam_crash) + M.remove_status_effect(STATUS_EFFECT_DETERMINED) + ..() + +/datum/reagent/determination/on_mob_life(mob/living/carbon/M) + if(!significant && volume >= WOUND_DETERMINATION_SEVERE) + significant = TRUE + M.apply_status_effect(STATUS_EFFECT_DETERMINED) // in addition to the slight healing, limping cooldowns are divided by 4 during the combat high + + volume = min(volume, WOUND_DETERMINATION_MAX) + + for(var/thing in M.all_wounds) + var/datum/wound/W = thing + var/obj/item/bodypart/wounded_part = W.limb + if(wounded_part) + wounded_part.heal_damage(0.25, 0.25) + M.adjustStaminaLoss(-0.25*REM) // the more wounds, the more stamina regen + ..() + +/datum/reagent/cellulose + name = "Cellulose Fibers" + description = "A crystaline polydextrose polymer, plants swear by this stuff." + reagent_state = SOLID + color = "#E6E6DA" + taste_mult = 0 diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 02e4a89e1d..7da734e9c4 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -154,6 +154,11 @@ pH = 12 value = REAGENT_VALUE_RARE +/datum/reagent/toxin/carpotoxin/on_mob_life(mob/living/carbon/M) + . = ..() + for(var/i in M.all_scars) + qdel(i) + /datum/reagent/toxin/zombiepowder name = "Zombie Powder" description = "A strong neurotoxin that puts the subject into a death-like state." @@ -520,25 +525,6 @@ taste_description = "bad cooking" value = REAGENT_VALUE_NONE -/datum/reagent/toxin/condensed_cooking_oil - name = "Condensed Cooking Oil" - description = "Taste the consequences of your mistakes." - reagent_state = LIQUID - color = "#d6d6d8" - metabolization_rate = 0.25 * REAGENTS_METABOLISM - toxpwr = 0 - taste_mult = -2 - taste_description = "awful cooking" - value = REAGENT_VALUE_NONE - -/datum/reagent/toxin/condensed_cooking_oil/on_mob_life(mob/living/carbon/M) - if(prob(5)) - M.vomit() - else - if(prob(40)) - M.adjustOrganLoss(ORGAN_SLOT_HEART, 0.5) //For reference, bungotoxin does 3 - ..() - /datum/reagent/toxin/itching_powder name = "Itching Powder" description = "A powder that induces itching upon contact with the skin. Causes the victim to scratch at their itches and has a very low chance to decay into Histamine." @@ -736,22 +722,13 @@ /datum/reagent/toxin/heparin //Based on a real-life anticoagulant. I'm not a doctor, so this won't be realistic. name = "Heparin" - description = "A powerful anticoagulant. Victims will bleed uncontrollably and suffer scaling bruising." + description = "A powerful anticoagulant. All open cut wounds on the victim will open up and bleed much faster" reagent_state = LIQUID color = "#C8C8C8" //RGB: 200, 200, 200 metabolization_rate = 0.2 * REAGENTS_METABOLISM toxpwr = 0 value = REAGENT_VALUE_VERY_RARE -/datum/reagent/toxin/heparin/on_mob_life(mob/living/carbon/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.bleed_rate = min(H.bleed_rate + 2, 8) - H.adjustBruteLoss(1, 0) //Brute damage increases with the amount they're bleeding - . = 1 - return ..() || . - - /datum/reagent/toxin/rotatium //Rotatium. Fucks up your rotation and is hilarious name = "Rotatium" description = "A constantly swirling, oddly colourful fluid. Causes the consumer's sense of direction and hand-eye coordination to become wild." diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index 9cf9acb424..e591daeb8e 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -318,3 +318,19 @@ id = /datum/reagent/medicine/psicodine results = list(/datum/reagent/medicine/psicodine = 5) required_reagents = list( /datum/reagent/medicine/mannitol = 2, /datum/reagent/water = 2, /datum/reagent/impedrezene = 1) + +/datum/chemical_reaction/medsuture + required_reagents = list(/datum/reagent/cellulose = 10, /datum/reagent/toxin/formaldehyde = 20, /datum/reagent/medicine/polypyr = 15) //This might be a bit much, reagent cost should be reviewed after implementation. + +/datum/chemical_reaction/medsuture/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/stack/medical/suture/medicated(location) + +/datum/chemical_reaction/medmesh + required_reagents = list(/datum/reagent/cellulose = 20, /datum/reagent/consumable/aloejuice = 20, /datum/reagent/space_cleaner/sterilizine = 10) + +/datum/chemical_reaction/medmesh/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/stack/medical/mesh/advanced(location) \ No newline at end of file diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index a8aec91669..f32bc708d0 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -704,6 +704,14 @@ required_reagents = list(/datum/reagent/liquid_dark_matter = 5, /datum/reagent/medicine/synaptizine = 10, /datum/reagent/medicine/oculine = 10, /datum/reagent/mutationtoxin = 1) required_temp = 600 +/datum/chemical_reaction/slime_extractification + required_reagents = list(/datum/reagent/toxin/slimejelly = 30, /datum/reagent/consumable/frostoil = 5, /datum/reagent/toxin/plasma = 5) + mix_message = "The mixture condenses into a ball." + +/datum/chemical_reaction/slime_extractification/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + new /obj/item/slime_extract/grey(location) + // Liquid Carpets /datum/chemical_reaction/carpet @@ -825,3 +833,8 @@ required_reagents = list(/datum/reagent/medicine/salglu_solution = 1, /datum/reagent/iron = 1, /datum/reagent/stable_plasma = 1) mix_message = "The mixture congeals and gives off a faint copper scent." required_temp = 350 + +/datum/chemical_reaction/cellulose_carbonization + results = list(/datum/reagent/carbon = 1) + required_reagents = list(/datum/reagent/cellulose = 1) + required_temp = 512 \ No newline at end of file diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index ead47e2a42..2c3f25e73a 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -165,10 +165,7 @@ var/chosen = getbork() var/obj/B = new chosen(T) if(prob(5))//Fry it! - var/obj/item/reagent_containers/food/snacks/deepfryholder/fried - fried = new(T, B) - fried.fry() // actually set the name and colour it - B = fried + B.fry() // actually set the name and colour it if(prob(50)) for(var/j in 1 to rand(1, 3)) step(B, pick(NORTH,SOUTH,EAST,WEST)) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 799a6db9f5..7dcf996cab 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -90,12 +90,12 @@ item_state = "medipen" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - amount_per_transfer_from_this = 13 - volume = 13 + amount_per_transfer_from_this = 15 + volume = 15 ignore_flags = 1 //so you can medipen through hardsuits reagent_flags = DRAWABLE flags_1 = null - list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/preservahyde = 3) + list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/preservahyde = 3, /datum/reagent/medicine/coagulant = 2) custom_premium_price = PRICE_ALMOST_EXPENSIVE /obj/item/reagent_containers/hypospray/medipen/suicide_act(mob/living/carbon/user) @@ -133,6 +133,13 @@ else . += "It is spent." +/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." + 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/stimulants name = "illegal stimpack medipen" desc = "A highly illegal medipen due to its load and small injections, allow for five uses before being drained" @@ -354,7 +361,7 @@ obj_flags |= EMAGGED return TRUE -/obj/item/hypospray/mkii/attack_hand(mob/user) +/obj/item/hypospray/mkii/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() //Don't bother changing this or removing it from containers will break. /obj/item/hypospray/mkii/attack(obj/item/I, mob/user, params) diff --git a/code/modules/reagents/reagent_containers/maunamug.dm b/code/modules/reagents/reagent_containers/maunamug.dm index 18e6cfa847..1600699226 100644 --- a/code/modules/reagents/reagent_containers/maunamug.dm +++ b/code/modules/reagents/reagent_containers/maunamug.dm @@ -88,7 +88,7 @@ user.visible_message("[user] inserts a power cell into [src].", "You insert the power cell into [src].") update_icon() -/obj/item/reagent_containers/glass/maunamug/attack_hand(mob/living/user) +/obj/item/reagent_containers/glass/maunamug/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) if(cell && open) cell.update_icon() user.put_in_hands(cell) diff --git a/code/modules/reagents/reagent_containers/rags.dm b/code/modules/reagents/reagent_containers/rags.dm index c6903ff7b4..afa188e9f6 100644 --- a/code/modules/reagents/reagent_containers/rags.dm +++ b/code/modules/reagents/reagent_containers/rags.dm @@ -36,15 +36,19 @@ var/reagentlist = pretty_string_from_reagent_list(reagents) var/log_object = "a damp rag containing [reagentlist]" if(user.a_intent == INTENT_HARM && !C.is_mouth_covered()) - reagents.reaction(C, INGEST) - reagents.trans_to(C, 5) - C.visible_message("[user] has smothered \the [C] with \the [src]!", "[user] has smothered you with \the [src]!", "You hear some struggling and muffled cries of surprise.") - log_combat(user, C, "smothered", log_object) + C.visible_message("[user] is trying to smother \the [C] with \the [src]!", "[user] is trying to smother you with \the [src]!", "You hear some struggling and muffled cries of surprise.") + if(do_after(user, 20, target = C)) + reagents.reaction(C, INGEST) + reagents.trans_to(C, 5) + C.visible_message("[user] has smothered \the [C] with \the [src]!", "[user] has smothered you with \the [src]!", "You hear some struggling and a heavy breath taken.") + log_combat(user, C, "smothered", log_object) else - reagents.reaction(C, TOUCH) - reagents.remove_all(5) - C.visible_message("[user] has touched \the [C] with \the [src].") - log_combat(user, C, "touched", log_object) + C.visible_message("[user] is trying to wipe \the [C] with \the [src].") + if(do_after(user, 20, target = C)) + reagents.reaction(C, TOUCH) + reagents.remove_all(5) + C.visible_message("[user] has wiped \the [C] with \the [src].") + log_combat(user, C, "touched", log_object) else if(istype(A) && (src in user)) user.visible_message("[user] starts to wipe down [A] with [src]!", "You start to wipe down [A] with [src]...") diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 2b79533e31..0131e6d028 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -79,7 +79,7 @@ else . += "There are no paper cups left." -/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user) +/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index f66d687a92..d8cb462c97 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -174,7 +174,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) return ..() // attack with hand, move pulled object onto conveyor -/obj/machinery/conveyor/attack_hand(mob/user) +/obj/machinery/conveyor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm index 76ec6224b8..574c7c9282 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm @@ -119,6 +119,24 @@ category = list("initial", "Medical","Tool Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE +/datum/design/bonesetter + name = "Bonesetter" + id = "bonesetter" + build_type = AUTOLATHE | PROTOLATHE + materials = list(/datum/material/iron = 1000) + build_path = /obj/item/bonesetter + category = list("initial", "Medical", "Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/sticky_tape/surgical + name = "Surgical Tape" + id = "surgical_tape" + build_type = PROTOLATHE + materials = list(/datum/material/plastic = 500) + build_path = /obj/item/stack/sticky_tape/surgical + category = list("initial", "Medical") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + /datum/design/beaker name = "Beaker" id = "beaker" diff --git a/code/modules/research/nanites/nanite_programs/utility.dm b/code/modules/research/nanites/nanite_programs/utility.dm index ebe623d73d..f5372738db 100644 --- a/code/modules/research/nanites/nanite_programs/utility.dm +++ b/code/modules/research/nanites/nanite_programs/utility.dm @@ -51,7 +51,7 @@ rogue_types = list(/datum/nanite_program/toxic) /datum/nanite_program/self_scan/register_extra_settings() - extra_settings[NES_SCAN_TYPE] = new /datum/nanite_extra_setting/type("Medical", list("Medical", "Chemical", "Nanite")) + extra_settings[NES_SCAN_TYPE] = new /datum/nanite_extra_setting/type("Medical", list("Medical", "Chemical", "Wound", "Nanite")) /datum/nanite_program/self_scan/on_trigger(comm_message) if(host_mob.stat == DEAD) @@ -62,6 +62,8 @@ healthscan(host_mob, host_mob) if("Chemical") chemscan(host_mob, host_mob) + if("Wound") + woundscan(host_mob, host_mob) if("Nanite") SEND_SIGNAL(host_mob, COMSIG_NANITE_SCAN, host_mob, TRUE) diff --git a/code/modules/research/techweb/nodes/medical_nodes.dm b/code/modules/research/techweb/nodes/medical_nodes.dm index 71dd7c943c..3a9e654b81 100644 --- a/code/modules/research/techweb/nodes/medical_nodes.dm +++ b/code/modules/research/techweb/nodes/medical_nodes.dm @@ -104,7 +104,7 @@ display_name = "Advanced Surgery Tools" description = "Refined and improved redesigns for the run-of-the-mill medical utensils." prereq_ids = list("adv_biotech", "adv_surgery") - design_ids = list("drapes", "retractor_adv", "surgicaldrill_adv", "scalpel_adv") + design_ids = list("drapes", "retractor_adv", "surgicaldrill_adv", "scalpel_adv", "bonesetter", "surgical_tape") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) /datum/techweb_node/adv_surgery diff --git a/code/modules/research/xenobiology/crossbreeding/_clothing.dm b/code/modules/research/xenobiology/crossbreeding/_clothing.dm index 795a57b82c..996b84131f 100644 --- a/code/modules/research/xenobiology/crossbreeding/_clothing.dm +++ b/code/modules/research/xenobiology/crossbreeding/_clothing.dm @@ -57,7 +57,7 @@ Slimecrossing Armor light_color = newcolor set_light(5) -/obj/structure/light_prism/attack_hand(mob/user) +/obj/structure/light_prism/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) to_chat(user, "You dispel [src]") qdel(src) @@ -118,7 +118,7 @@ Slimecrossing Armor ..() REMOVE_TRAIT(user, TRAIT_PACIFISM, "peaceflower_[REF(src)]") -/obj/item/clothing/head/peaceflower/attack_hand(mob/user) +/obj/item/clothing/head/peaceflower/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/C = user if(src == C.head) diff --git a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm index c80b4d972c..e6f87eea13 100644 --- a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm +++ b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm @@ -88,7 +88,7 @@ return QDEL_HINT_LETMELIVE //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/necropolis_gate/attack_hand(mob/user) +/obj/structure/necropolis_gate/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(locked || uses == 0) to_chat(user, "It's [open ? "stuck open":"locked"].") return @@ -167,7 +167,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate) return QDEL_HINT_LETMELIVE //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/necropolis_gate/legion_gate/attack_hand(mob/user) +/obj/structure/necropolis_gate/legion_gate/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!open && !changing_openness) var/safety = alert(user, "You think this might be a bad idea...", "Knock on the door?", "Proceed", "Abort") if(safety == "Abort" || !in_range(src, user) || !src || open || changing_openness || user.incapacitated()) diff --git a/code/modules/ruins/objects_and_mobs/sin_ruins.dm b/code/modules/ruins/objects_and_mobs/sin_ruins.dm index 76897b5276..8a98a1939f 100644 --- a/code/modules/ruins/objects_and_mobs/sin_ruins.dm +++ b/code/modules/ruins/objects_and_mobs/sin_ruins.dm @@ -57,7 +57,7 @@ canvas rotting away and contents vanishing.
") qdel(src) -/obj/structure/cursed_money/attack_hand(mob/living/user) +/obj/structure/cursed_money/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/ruins/spaceruin_code/hilbertshotel.dm index d4ee2d5c7c..b74b32009f 100644 --- a/code/modules/ruins/spaceruin_code/hilbertshotel.dm +++ b/code/modules/ruins/spaceruin_code/hilbertshotel.dm @@ -263,7 +263,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) /turf/closed/indestructible/hoteldoor/attack_tk(mob/user) return //need to be close. -/turf/closed/indestructible/hoteldoor/attack_hand(mob/user) +/turf/closed/indestructible/hoteldoor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) promptExit(user) /turf/closed/indestructible/hoteldoor/attack_animal(mob/user) diff --git a/code/modules/shuttle/custom_shuttle.dm b/code/modules/shuttle/custom_shuttle.dm index 6e06e3fefe..6ff15c628e 100644 --- a/code/modules/shuttle/custom_shuttle.dm +++ b/code/modules/shuttle/custom_shuttle.dm @@ -257,7 +257,7 @@ return ..() -/obj/machinery/computer/camera_advanced/shuttle_docker/custom/attack_hand(mob/user) +/obj/machinery/computer/camera_advanced/shuttle_docker/custom/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!shuttleId) to_chat(user, "You must link the console to a shuttle first.") return diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index 4f53e5d9d0..0cf348a95b 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -29,7 +29,7 @@ . = ..() GLOB.navigation_computers -= src -/obj/machinery/computer/camera_advanced/shuttle_docker/attack_hand(mob/user) +/obj/machinery/computer/camera_advanced/shuttle_docker/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(jammed) to_chat(user, "The Syndicate is jamming the console!") return diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm index f5ddf12182..9af6d7fe9f 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_console.dm @@ -61,7 +61,7 @@ if(user?.client) user.client.images -= eyeobj.user_image -/obj/machinery/computer/camera_advanced/shuttle_creator/attack_hand(mob/user) +/obj/machinery/computer/camera_advanced/shuttle_creator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!is_operational()) //you cant use broken machine you chumbis return if(current_user) diff --git a/code/modules/spells/spell_types/bloodcrawl.dm b/code/modules/spells/spell_types/bloodcrawl.dm index e59fc2049d..39b0f1709e 100644 --- a/code/modules/spells/spell_types/bloodcrawl.dm +++ b/code/modules/spells/spell_types/bloodcrawl.dm @@ -25,6 +25,11 @@ /obj/effect/proc_holder/spell/bloodcrawl/perform(obj/effect/decal/cleanable/target, recharge = 1, mob/living/user = usr) if(istype(user)) + if(istype(user, /mob/living/simple_animal/slaughter)) + var/mob/living/simple_animal/slaughter/slaught = user + slaught.current_hitstreak = 0 + slaught.wound_bonus = initial(slaught.wound_bonus) + slaught.bare_wound_bonus = initial(slaught.bare_wound_bonus) if(phased) if(user.phasein(target)) phased = 0 diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm index a8f9c8bce5..e513865246 100644 --- a/code/modules/spells/spell_types/shapeshift.dm +++ b/code/modules/spells/spell_types/shapeshift.dm @@ -105,7 +105,7 @@ var/damage_percent = (stored.maxHealth - stored.health)/stored.maxHealth; var/damapply = damage_percent * shape.maxHealth; - shape.apply_damage(damapply, source.convert_damage_type, forced = TRUE); + shape.apply_damage(damapply, source.convert_damage_type, forced = TRUE, wound_bonus=CANT_WOUND); slink = soullink(/datum/soullink/shapeshift, stored , shape) slink.source = src @@ -158,7 +158,7 @@ var/damage_percent = (shape.maxHealth - shape.health)/shape.maxHealth; var/damapply = stored.maxHealth * damage_percent - stored.apply_damage(damapply, source.convert_damage_type, forced = TRUE) + stored.apply_damage(damapply, source.convert_damage_type, forced = TRUE, wound_bonus=CANT_WOUND) qdel(shape) qdel(src) diff --git a/code/modules/spells/spell_types/spacetime_distortion.dm b/code/modules/spells/spell_types/spacetime_distortion.dm index 3af4d3883f..bec0f7871a 100644 --- a/code/modules/spells/spell_types/spacetime_distortion.dm +++ b/code/modules/spells/spell_types/spacetime_distortion.dm @@ -111,7 +111,7 @@ walk_link(user) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/cross_action/spacetime_dist/attack_hand(mob/user) +/obj/effect/cross_action/spacetime_dist/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) walk_link(user) /obj/effect/cross_action/spacetime_dist/attack_paw(mob/user) diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index b104c2182a..13c47ab9ac 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -371,7 +371,7 @@ if(isliving(hit_atom)) var/mob/living/M = hit_atom if(!M.anti_magic_check()) - M.electrocute_act(80, src, SHOCK_ILLUSION) + M.electrocute_act(80, src, null, SHOCK_ILLUSION) qdel(src) /obj/item/spellpacket/lightningbolt/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm similarity index 71% rename from code/modules/surgery/bodyparts/bodyparts.dm rename to code/modules/surgery/bodyparts/_bodyparts.dm index fcdb07ca17..07c80322ae 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -71,6 +71,28 @@ var/medium_burn_msg = "blistered" var/heavy_burn_msg = "peeling away" + /// The wounds currently afflicting this body part + var/list/wounds + + /// The scars currently afflicting this body part + var/list/scars + /// Our current stored wound damage multiplier + var/wound_damage_multiplier = 1 + + /// This number is subtracted from all wound rolls on this bodypart, higher numbers mean more defense, negative means easier to wound + var/wound_resistance = 0 + /// When this bodypart hits max damage, this number is added to all wound rolls. Obviously only relevant for bodyparts that have damage caps. + var/disabled_wound_penalty = 15 + + /// 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 + /obj/item/bodypart/examine(mob/user) . = ..() if(brute_dam > DAMAGE_PRECISION) @@ -149,7 +171,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, updating_health = TRUE) +/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 if(owner && (owner.status_flags & GODMODE)) return FALSE //godmode var/dmg_mlt = CONFIG_GET(number/damage_multiplier) @@ -163,20 +185,38 @@ if(!brute && !burn && !stamina) return FALSE + brute *= wound_damage_multiplier + burn *= wound_damage_multiplier + switch(animal_origin) 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) + 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 + check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus) + var/can_inflict = max_damage - get_damage() - if(can_inflict <= 0) - return FALSE var/total_damage = brute + burn - if(total_damage > can_inflict) + if(total_damage > can_inflict && total_damage > 0) // TODO: the second part of this check should be removed once disabling is all done brute = round(brute * (max_damage / total_damage),DAMAGE_PRECISION) burn = round(burn * (max_damage / total_damage),DAMAGE_PRECISION) + 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 @@ -196,6 +236,107 @@ update_disabled() return update_bodypart_damage_state() +/** + * 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 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. + * * 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 + */ +/obj/item/bodypart/proc/check_wounding(woundtype, damage, wound_bonus, bare_wound_bonus) + // actually roll wounds if applicable + if(HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE)) + damage *= 1.5 + + var/base_roll = rand(1, 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 + + 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 + + //cycle through the wounds of the relevant category from the most severe down + for(var/PW in wounds_checking) + var/datum/wound/possible_wound = PW + var/datum/wound/replaced_wound + for(var/i in wounds) + var/datum/wound/existing_wound = i + if(existing_wound.type in wounds_checking) + if(existing_wound.severity >= initial(possible_wound.severity)) + return + else + replaced_wound = existing_wound + + if(initial(possible_wound.threshold_minimum) < injury_roll) + 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) + else + var/datum/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 + +// 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.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 + + var/datum/wound/new_wound = new potential_wound + new_wound.apply_wound(src, smited = smited) + +/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) + for(var/c in clothing) + 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) + 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) + + if(!armor_ablation) + injury_mod += bare_wound_bonus + + injury_mod -= armor_ablation + injury_mod += wound_bonus + + for(var/thing in wounds) + var/datum/wound/W = thing + injury_mod += W.threshold_penalty + + var/part_mod = -wound_resistance + if(is_disabled()) + part_mod += disabled_wound_penalty + + injury_mod += part_mod + + return injury_mod + //Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all. //Damage cannot go below zero. //Cannot remove negative damage (i.e. apply damage) @@ -227,16 +368,29 @@ //Checks disabled status thresholds /obj/item/bodypart/proc/update_disabled() + if(!owner) + return set_disabled(is_disabled()) /obj/item/bodypart/proc/is_disabled() + if(!owner) + return if(HAS_TRAIT(owner, TRAIT_PARALYSIS)) return BODYPART_DISABLED_PARALYSIS + for(var/i in wounds) + var/datum/wound/W = i + if(W.disabling) + 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% - return BODYPART_DISABLED_DAMAGE - if(disabled && (get_damage(TRUE) <= (max_damage * 0.5))) + if(!last_maxed) + owner.emote("scream") + last_maxed = TRUE + if(!is_organic_limb()) + 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 return BODYPART_NOT_DISABLED else return BODYPART_NOT_DISABLED @@ -251,9 +405,11 @@ /obj/item/bodypart/proc/set_disabled(new_disabled) - if(disabled == new_disabled) + if(disabled == new_disabled || !owner) return FALSE disabled = new_disabled + if(disabled && owner.get_item_for_held_index(held_index)) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) owner.update_health_hud() //update the healthdoll owner.update_body() owner.update_mobility() @@ -334,9 +490,9 @@ //body marking memes var/list/colorlist = list() colorlist.Cut() - colorlist += ReadRGB("[H.dna.features["mcolor"]]0") - colorlist += ReadRGB("[H.dna.features["mcolor2"]]0") - colorlist += ReadRGB("[H.dna.features["mcolor3"]]0") + colorlist += ReadRGB("[H.dna.features["mcolor"]]00") + colorlist += ReadRGB("[H.dna.features["mcolor2"]]00") + colorlist += ReadRGB("[H.dna.features["mcolor3"]]00") colorlist += list(0,0,0, S.hair_alpha) for(var/index=1, index<=colorlist.len, index++) colorlist[index] = colorlist[index]/255 @@ -581,293 +737,41 @@ drop_organs() qdel(src) -/obj/item/bodypart/chest - name = BODY_ZONE_CHEST - desc = "It's impolite to stare at a person's chest." - icon_state = "default_human_chest" - max_damage = 200 - body_zone = BODY_ZONE_CHEST - body_part = CHEST - px_x = 0 - px_y = 0 - stam_damage_coeff = 1 - max_stamina_damage = 200 - var/obj/item/cavity_item - -/obj/item/bodypart/chest/can_dismember(obj/item/I) - if(!((owner.stat == DEAD) || owner.InFullCritical())) - return FALSE - return ..() - -/obj/item/bodypart/chest/Destroy() - if(cavity_item) - qdel(cavity_item) - return ..() - -/obj/item/bodypart/chest/drop_organs(mob/user) - if(cavity_item) - cavity_item.forceMove(user.loc) - cavity_item = null - ..() - -/obj/item/bodypart/chest/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_chest" - animal_origin = MONKEY_BODYPART - -/obj/item/bodypart/chest/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_chest" - dismemberable = 0 - max_damage = 500 - animal_origin = ALIEN_BODYPART - -/obj/item/bodypart/chest/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART - -/obj/item/bodypart/chest/larva - icon = 'icons/mob/animal_parts.dmi' - icon_state = "larva_chest" - dismemberable = 0 - max_damage = 50 - animal_origin = LARVA_BODYPART - -/obj/item/bodypart/l_arm - name = "left arm" - desc = "Did you know that the word 'sinister' stems originally from the \ - Latin 'sinestra' (left hand), because the left hand was supposed to \ - be possessed by the devil? This arm appears to be possessed by no \ - one though." - icon_state = "default_human_l_arm" - attack_verb = list("slapped", "punched") - max_damage = 50 - max_stamina_damage = 50 - body_zone = BODY_ZONE_L_ARM - body_part = ARM_LEFT - aux_icons = list(BODY_ZONE_PRECISE_L_HAND = HANDS_PART_LAYER, "l_hand_behind" = BODY_BEHIND_LAYER) - body_damage_coeff = 0.75 - held_index = 1 - px_x = -6 - px_y = 0 - stam_heal_tick = STAM_RECOVERY_LIMB - -/obj/item/bodypart/l_arm/is_disabled() - if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM)) - return BODYPART_DISABLED_PARALYSIS - return ..() - -/obj/item/bodypart/l_arm/set_disabled(new_disabled) - . = ..() - if(!.) +/// Get whatever wound of the given type is currently attached to this limb, if any +/obj/item/bodypart/proc/get_wound_type(checking_type) + if(isnull(wounds)) return - if(owner.stat < UNCONSCIOUS) - switch(disabled) - if(BODYPART_DISABLED_DAMAGE) - owner.emote("scream") - to_chat(owner, "Your [name] is too damaged to function!") - if(BODYPART_DISABLED_PARALYSIS) - to_chat(owner, "You can't feel your [name]!") - if(held_index) - owner.dropItemToGround(owner.get_item_for_held_index(held_index)) - if(owner.hud_used) - var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"] - if(L) - L.update_icon() + for(var/thing in wounds) + var/datum/wound/W = thing + if(istype(W, checking_type)) + return W -/obj/item/bodypart/l_arm/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_l_arm" - animal_origin = MONKEY_BODYPART - px_x = -5 - px_y = -3 +/// 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() + 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 + wound_damage_multiplier = dam_mul + update_disabled() -/obj/item/bodypart/l_arm/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_l_arm" - px_x = 0 - px_y = 0 - dismemberable = 0 - max_damage = 100 - animal_origin = ALIEN_BODYPART - -/obj/item/bodypart/l_arm/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART - -/obj/item/bodypart/r_arm - name = "right arm" - desc = "Over 87% of humans are right handed. That figure is much lower \ - among humans missing their right arm." - icon_state = "default_human_r_arm" - attack_verb = list("slapped", "punched") - max_damage = 50 - body_zone = BODY_ZONE_R_ARM - body_part = ARM_RIGHT - aux_icons = list(BODY_ZONE_PRECISE_R_HAND = HANDS_PART_LAYER, "r_hand_behind" = BODY_BEHIND_LAYER) - body_damage_coeff = 0.75 - held_index = 2 - px_x = 6 - px_y = 0 - stam_heal_tick = STAM_RECOVERY_LIMB - max_stamina_damage = 50 - -/obj/item/bodypart/r_arm/is_disabled() - if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM)) - return BODYPART_DISABLED_PARALYSIS - return ..() - -/obj/item/bodypart/r_arm/set_disabled(new_disabled) - . = ..() - if(!.) +/obj/item/bodypart/proc/get_bleed_rate() + if(status != BODYPART_ORGANIC) // maybe in the future we can bleed oil from aug parts, but not now return - if(owner.stat < UNCONSCIOUS) - switch(disabled) - if(BODYPART_DISABLED_DAMAGE) - owner.emote("scream") - to_chat(owner, "Your [name] is too damaged to function!") - if(BODYPART_DISABLED_PARALYSIS) - to_chat(owner, "You can't feel your [name]!") - if(held_index) - owner.dropItemToGround(owner.get_item_for_held_index(held_index)) - if(owner.hud_used) - var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"] - if(R) - R.update_icon() + 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) + for(var/obj/item/embeddies in embedded_objects) + if(!embeddies.isEmbedHarmless()) + bleed_rate += 0.5 -/obj/item/bodypart/r_arm/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_r_arm" - animal_origin = MONKEY_BODYPART - px_x = 5 - px_y = -3 + for(var/thing in wounds) + var/datum/wound/W = thing + bleed_rate += W.blood_flow -/obj/item/bodypart/r_arm/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_r_arm" - px_x = 0 - px_y = 0 - dismemberable = 0 - max_damage = 100 - animal_origin = ALIEN_BODYPART - -/obj/item/bodypart/r_arm/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART - -/obj/item/bodypart/l_leg - name = "left leg" - desc = "Some athletes prefer to tie their left shoelaces first for good \ - luck. In this instance, it probably would not have helped." - icon_state = "default_human_l_leg" - attack_verb = list("kicked", "stomped") - max_damage = 50 - body_zone = BODY_ZONE_L_LEG - body_part = LEG_LEFT - body_damage_coeff = 0.75 - px_x = -2 - px_y = 12 - stam_heal_tick = STAM_RECOVERY_LIMB - max_stamina_damage = 50 - -/obj/item/bodypart/l_leg/is_disabled() - if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG)) - return BODYPART_DISABLED_PARALYSIS - return ..() - -/obj/item/bodypart/l_leg/set_disabled(new_disabled) - . = ..() - if(!. || owner.stat >= UNCONSCIOUS) - return - switch(disabled) - if(BODYPART_DISABLED_DAMAGE) - owner.emote("scream") - to_chat(owner, "Your [name] is too damaged to function!") - if(BODYPART_DISABLED_PARALYSIS) - to_chat(owner, "You can't feel your [name]!") - - -/obj/item/bodypart/l_leg/digitigrade - name = "left digitigrade leg" - use_digitigrade = FULL_DIGITIGRADE - -/obj/item/bodypart/l_leg/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_l_leg" - animal_origin = MONKEY_BODYPART - px_y = 4 - -/obj/item/bodypart/l_leg/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_l_leg" - px_x = 0 - px_y = 0 - dismemberable = 0 - max_damage = 100 - animal_origin = ALIEN_BODYPART - -/obj/item/bodypart/l_leg/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART - -/obj/item/bodypart/r_leg - name = "right leg" - desc = "You put your right leg in, your right leg out. In, out, in, out, \ - shake it all about. And apparently then it detaches.\n\ - The hokey pokey has certainly changed a lot since space colonisation." - // alternative spellings of 'pokey' are availible - icon_state = "default_human_r_leg" - attack_verb = list("kicked", "stomped") - max_damage = 50 - body_zone = BODY_ZONE_R_LEG - body_part = LEG_RIGHT - body_damage_coeff = 0.75 - px_x = 2 - px_y = 12 - max_stamina_damage = 50 - stam_heal_tick = STAM_RECOVERY_LIMB - -/obj/item/bodypart/r_leg/is_disabled() - if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG)) - return BODYPART_DISABLED_PARALYSIS - return ..() - -/obj/item/bodypart/r_leg/set_disabled(new_disabled) - . = ..() - if(!. || owner.stat >= UNCONSCIOUS) - return - switch(disabled) - if(BODYPART_DISABLED_DAMAGE) - owner.emote("scream") - to_chat(owner, "Your [name] is too damaged to function!") - if(BODYPART_DISABLED_PARALYSIS) - to_chat(owner, "You can't feel your [name]!") - -/obj/item/bodypart/r_leg/digitigrade - name = "right digitigrade leg" - use_digitigrade = FULL_DIGITIGRADE - -/obj/item/bodypart/r_leg/monkey - icon = 'icons/mob/animal_parts.dmi' - icon_state = "default_monkey_r_leg" - animal_origin = MONKEY_BODYPART - px_y = 4 - -/obj/item/bodypart/r_leg/alien - icon = 'icons/mob/animal_parts.dmi' - icon_state = "alien_r_leg" - px_x = 0 - px_y = 0 - dismemberable = 0 - max_damage = 100 - animal_origin = ALIEN_BODYPART - -/obj/item/bodypart/r_leg/devil - dismemberable = 0 - max_damage = 5000 - animal_origin = DEVIL_BODYPART + return bleed_rate diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index f654270df7..2ce6ca8862 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -15,7 +15,7 @@ if(HAS_TRAIT(C, TRAIT_NODISMEMBER)) 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)) //Damage the chest based on limb's existing damage + 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!") C.emote("scream") SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered) @@ -83,11 +83,12 @@ //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) +/obj/item/bodypart/proc/drop_limb(special, dismembered) if(!owner) return var/atom/Tsec = owner.drop_location() var/mob/living/carbon/C = owner + SEND_SIGNAL(C, COMSIG_CARBON_REMOVE_LIMB, src, dismembered) update_limb(1) C.bodyparts -= src @@ -95,6 +96,15 @@ C.dropItemToGround(owner.get_item_for_held_index(held_index), 1) C.hand_bodyparts[held_index] = null + for(var/thing in scars) + var/datum/scar/S = thing + S.victim = null + LAZYREMOVE(owner.all_scars, S) + + for(var/thing in wounds) + var/datum/wound/W = thing + W.remove_wound(TRUE) + owner = null for(var/X in C.surgeries) //if we had an ongoing surgery on that limb, we stop it. @@ -298,6 +308,15 @@ for(var/obj/item/organ/O in contents) O.Insert(C) + for(var/thing in scars) + var/datum/scar/S = thing + S.victim = C + LAZYADD(C.all_scars, thing) + + for(var/i in wounds) + var/datum/wound/W = i + W.apply_wound(src, TRUE) + update_bodypart_damage_state() update_disabled() diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index a74b1dad28..a67f16b934 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -35,6 +35,10 @@ //If the head is a special sprite 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())) return FALSE diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index 29aca7166f..3161419449 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -10,6 +10,16 @@ if(L.body_zone == zone) return L +///Get the bodypart for whatever hand we have active, Only relevant for carbons +/mob/proc/get_active_hand() + return FALSE + +/mob/living/carbon/get_active_hand() + var/which_hand = BODY_ZONE_PRECISE_L_HAND + if(!(active_hand_index % 2)) + which_hand = BODY_ZONE_PRECISE_R_HAND + return get_bodypart(check_zone(which_hand)) + /mob/living/carbon/has_hand_for_held_index(i) if(i) var/obj/item/bodypart/L = hand_bodyparts[i] diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm new file mode 100644 index 0000000000..a18b31e4c1 --- /dev/null +++ b/code/modules/surgery/bodyparts/parts.dm @@ -0,0 +1,289 @@ +/obj/item/bodypart/chest + name = BODY_ZONE_CHEST + desc = "It's impolite to stare at a person's chest." + icon_state = "default_human_chest" + max_damage = 200 + body_zone = BODY_ZONE_CHEST + body_part = CHEST + px_x = 0 + px_y = 0 + stam_damage_coeff = 1 + max_stamina_damage = 200 + var/obj/item/cavity_item + +/obj/item/bodypart/chest/can_dismember(obj/item/I) + if(!((owner.stat == DEAD) || owner.InFullCritical())) + return FALSE + return ..() + +/obj/item/bodypart/chest/Destroy() + if(cavity_item) + qdel(cavity_item) + return ..() + +/obj/item/bodypart/chest/drop_organs(mob/user) + if(cavity_item) + cavity_item.forceMove(user.loc) + cavity_item = null + ..() + +/obj/item/bodypart/chest/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_chest" + animal_origin = MONKEY_BODYPART + +/obj/item/bodypart/chest/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_chest" + dismemberable = 0 + max_damage = 500 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/chest/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART + +/obj/item/bodypart/chest/larva + icon = 'icons/mob/animal_parts.dmi' + icon_state = "larva_chest" + dismemberable = 0 + max_damage = 50 + animal_origin = LARVA_BODYPART + +/obj/item/bodypart/l_arm + name = "left arm" + desc = "Did you know that the word 'sinister' stems originally from the \ + Latin 'sinestra' (left hand), because the left hand was supposed to \ + be possessed by the devil? This arm appears to be possessed by no \ + one though." + icon_state = "default_human_l_arm" + attack_verb = list("slapped", "punched") + max_damage = 50 + max_stamina_damage = 50 + body_zone = BODY_ZONE_L_ARM + body_part = ARM_LEFT + aux_icons = list(BODY_ZONE_PRECISE_L_HAND = HANDS_PART_LAYER, "l_hand_behind" = BODY_BEHIND_LAYER) + body_damage_coeff = 0.75 + held_index = 1 + px_x = -6 + px_y = 0 + stam_heal_tick = STAM_RECOVERY_LIMB + +/obj/item/bodypart/l_arm/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/l_arm/set_disabled(new_disabled) + . = ..() + if(!.) + return + if(owner.stat < UNCONSCIOUS) + switch(disabled) + if(BODYPART_DISABLED_DAMAGE) + owner.emote("scream") + to_chat(owner, "Your [name] is too damaged to function!") + if(BODYPART_DISABLED_PARALYSIS) + to_chat(owner, "You can't feel your [name]!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + if(owner.hud_used) + var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"] + if(L) + L.update_icon() + +/obj/item/bodypart/l_arm/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_l_arm" + animal_origin = MONKEY_BODYPART + px_x = -5 + px_y = -3 + +/obj/item/bodypart/l_arm/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_l_arm" + px_x = 0 + px_y = 0 + dismemberable = 0 + max_damage = 100 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/l_arm/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART + +/obj/item/bodypart/r_arm + name = "right arm" + desc = "Over 87% of humans are right handed. That figure is much lower \ + among humans missing their right arm." + icon_state = "default_human_r_arm" + attack_verb = list("slapped", "punched") + max_damage = 50 + body_zone = BODY_ZONE_R_ARM + body_part = ARM_RIGHT + aux_icons = list(BODY_ZONE_PRECISE_R_HAND = HANDS_PART_LAYER, "r_hand_behind" = BODY_BEHIND_LAYER) + body_damage_coeff = 0.75 + held_index = 2 + px_x = 6 + px_y = 0 + stam_heal_tick = STAM_RECOVERY_LIMB + max_stamina_damage = 50 + +/obj/item/bodypart/r_arm/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/r_arm/set_disabled(new_disabled) + . = ..() + if(!.) + return + if(owner.stat < UNCONSCIOUS) + switch(disabled) + if(BODYPART_DISABLED_DAMAGE) + owner.emote("scream") + to_chat(owner, "Your [name] is too damaged to function!") + if(BODYPART_DISABLED_PARALYSIS) + to_chat(owner, "You can't feel your [name]!") + if(held_index) + owner.dropItemToGround(owner.get_item_for_held_index(held_index)) + if(owner.hud_used) + var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"] + if(R) + R.update_icon() + + +/obj/item/bodypart/r_arm/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_r_arm" + animal_origin = MONKEY_BODYPART + px_x = 5 + px_y = -3 + +/obj/item/bodypart/r_arm/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_r_arm" + px_x = 0 + px_y = 0 + dismemberable = 0 + max_damage = 100 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/r_arm/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART + +/obj/item/bodypart/l_leg + name = "left leg" + desc = "Some athletes prefer to tie their left shoelaces first for good \ + luck. In this instance, it probably would not have helped." + icon_state = "default_human_l_leg" + attack_verb = list("kicked", "stomped") + max_damage = 50 + body_zone = BODY_ZONE_L_LEG + body_part = LEG_LEFT + body_damage_coeff = 0.75 + px_x = -2 + px_y = 12 + stam_heal_tick = STAM_RECOVERY_LIMB + max_stamina_damage = 50 + +/obj/item/bodypart/l_leg/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/l_leg/set_disabled(new_disabled) + . = ..() + if(!. || owner.stat >= UNCONSCIOUS) + return + switch(disabled) + if(BODYPART_DISABLED_DAMAGE) + owner.emote("scream") + to_chat(owner, "Your [name] is too damaged to function!") + if(BODYPART_DISABLED_PARALYSIS) + to_chat(owner, "You can't feel your [name]!") + +/obj/item/bodypart/l_leg/digitigrade + name = "left digitigrade leg" + use_digitigrade = FULL_DIGITIGRADE + +/obj/item/bodypart/l_leg/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_l_leg" + animal_origin = MONKEY_BODYPART + px_y = 4 + +/obj/item/bodypart/l_leg/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_l_leg" + px_x = 0 + px_y = 0 + dismemberable = 0 + max_damage = 100 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/l_leg/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART + +/obj/item/bodypart/r_leg + name = "right leg" + desc = "You put your right leg in, your right leg out. In, out, in, out, \ + shake it all about. And apparently then it detaches.\n\ + The hokey pokey has certainly changed a lot since space colonisation." + // alternative spellings of 'pokey' are availible + icon_state = "default_human_r_leg" + attack_verb = list("kicked", "stomped") + max_damage = 50 + body_zone = BODY_ZONE_R_LEG + body_part = LEG_RIGHT + body_damage_coeff = 0.75 + px_x = 2 + px_y = 12 + max_stamina_damage = 50 + stam_heal_tick = STAM_RECOVERY_LIMB + +/obj/item/bodypart/r_leg/is_disabled() + if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG)) + return BODYPART_DISABLED_PARALYSIS + return ..() + +/obj/item/bodypart/r_leg/set_disabled(new_disabled) + . = ..() + if(!. || owner.stat >= UNCONSCIOUS) + return + switch(disabled) + if(BODYPART_DISABLED_DAMAGE) + owner.emote("scream") + to_chat(owner, "Your [name] is too damaged to function!") + if(BODYPART_DISABLED_PARALYSIS) + to_chat(owner, "You can't feel your [name]!") + +/obj/item/bodypart/r_leg/digitigrade + name = "right digitigrade leg" + use_digitigrade = FULL_DIGITIGRADE + +/obj/item/bodypart/r_leg/monkey + icon = 'icons/mob/animal_parts.dmi' + icon_state = "default_monkey_r_leg" + animal_origin = MONKEY_BODYPART + px_y = 4 + +/obj/item/bodypart/r_leg/alien + icon = 'icons/mob/animal_parts.dmi' + icon_state = "alien_r_leg" + px_x = 0 + px_y = 0 + dismemberable = 0 + max_damage = 100 + animal_origin = ALIEN_BODYPART + +/obj/item/bodypart/r_leg/devil + dismemberable = 0 + max_damage = 5000 + animal_origin = DEVIL_BODYPART diff --git a/code/modules/surgery/bone_mending.dm b/code/modules/surgery/bone_mending.dm new file mode 100644 index 0000000000..81d9fa8d97 --- /dev/null +++ b/code/modules/surgery/bone_mending.dm @@ -0,0 +1,139 @@ + +/////BONE FIXING SURGERIES////// + +///// Repair Hairline Fracture (Severe) +/datum/surgery/repair_bone_hairline + name = "Repair bone fracture (hairline)" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/repair_bone_hairline, /datum/surgery_step/close) + 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 + +/datum/surgery/repair_bone_hairline/can_start(mob/living/user, mob/living/carbon/target) + if(..()) + var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected) + return(targeted_bodypart.get_wound_type(targetable_wound)) + + +///// Repair Compound Fracture (Critical) +/datum/surgery/repair_bone_compound + name = "Repair Compound Fracture" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/reset_compound_fracture, /datum/surgery_step/repair_bone_compound, /datum/surgery_step/close) + 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 + +/datum/surgery/repair_bone_compound/can_start(mob/living/user, mob/living/carbon/target) + if(..()) + var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected) + return(targeted_bodypart.get_wound_type(targetable_wound)) + + + +//SURGERY STEPS + +///// Repair Hairline Fracture (Severe) +/datum/surgery_step/repair_bone_hairline + name = "repair hairline fracture (bonesetter/bone gel/tape)" + implements = list(/obj/item/bonesetter = 100, /obj/item/stack/medical/bone_gel = 100, /obj/item/stack/sticky_tape/surgical = 100, /obj/item/stack/sticky_tape/super = 50, /obj/item/stack/sticky_tape = 30) + time = 40 + +/datum/surgery_step/repair_bone_hairline/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(surgery.operated_wound) + display_results(user, target, "You begin to repair the fracture in [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/repair_bone_hairline/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + if(surgery.operated_wound) + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + display_results(user, target, "You successfully repair the fracture in [target]'s [parse_zone(target_zone)].", + "[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)]!") + log_combat(user, target, "repaired a hairline fracture in", addition="INTENT: [uppertext(user.a_intent)]") + qdel(surgery.operated_wound) + else + to_chat(user, "[target] has no hairline fracture there!") + return ..() + +/datum/surgery_step/repair_bone_hairline/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + + + +///// Reset Compound Fracture (Crticial) +/datum/surgery_step/reset_compound_fracture + name = "reset bone" + implements = list(/obj/item/bonesetter = 100, /obj/item/stack/sticky_tape/surgical = 60, /obj/item/stack/sticky_tape/super = 40, /obj/item/stack/sticky_tape = 20) + time = 40 + +/datum/surgery_step/reset_compound_fracture/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(surgery.operated_wound) + display_results(user, target, "You begin to reset the bone in [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to reset the bone in [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to reset the bone in [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/reset_compound_fracture/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + if(surgery.operated_wound) + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + display_results(user, target, "You successfully reset the bone in [target]'s [parse_zone(target_zone)].", + "[user] successfully resets the bone in [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully resets the bone in [target]'s [parse_zone(target_zone)]!") + log_combat(user, target, "reset a compound fracture in", addition="INTENT: [uppertext(user.a_intent)]") + else + to_chat(user, "[target] has no compound fracture there!") + return ..() + +/datum/surgery_step/reset_compound_fracture/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + + +///// Repair Compound Fracture (Crticial) +/datum/surgery_step/repair_bone_compound + name = "repair compound fracture (bone gel/tape)" + implements = list(/obj/item/stack/medical/bone_gel = 100, /obj/item/stack/sticky_tape/surgical = 100, /obj/item/stack/sticky_tape/super = 50, /obj/item/stack/sticky_tape = 30) + time = 40 + +/datum/surgery_step/repair_bone_compound/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(surgery.operated_wound) + display_results(user, target, "You begin to repair the fracture in [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/repair_bone_compound/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + if(surgery.operated_wound) + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) + display_results(user, target, "You successfully repair the fracture in [target]'s [parse_zone(target_zone)].", + "[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)]!") + log_combat(user, target, "repaired a compound fracture in", addition="INTENT: [uppertext(user.a_intent)]") + qdel(surgery.operated_wound) + else + to_chat(user, "[target] has no compound fracture there!") + return ..() + +/datum/surgery_step/repair_bone_compound/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) diff --git a/code/modules/surgery/burn_dressing.dm b/code/modules/surgery/burn_dressing.dm new file mode 100644 index 0000000000..1688f7b5d1 --- /dev/null +++ b/code/modules/surgery/burn_dressing.dm @@ -0,0 +1,106 @@ + +/////BURN FIXING SURGERIES////// + +///// Debride burnt flesh +/datum/surgery/debride + name = "Debride infected flesh" + steps = list(/datum/surgery_step/debride, /datum/surgery_step/dress) + 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/burn + +/datum/surgery/debride/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/burn_wound = targeted_bodypart.get_wound_type(targetable_wound) + return(burn_wound && burn_wound.infestation > 0) + +//SURGERY STEPS + +///// Debride +/datum/surgery_step/debride + name = "excise infection" + implements = list(TOOL_HEMOSTAT = 100, TOOL_SCALPEL = 85, TOOL_SAW = 60, TOOL_WIRECUTTER = 40) + time = 30 + repeatable = TRUE + +/datum/surgery_step/debride/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(surgery.operated_wound) + var/datum/wound/burn/burn_wound = surgery.operated_wound + if(burn_wound.infestation <= 0) + to_chat(user, "[target]'s [parse_zone(user.zone_selected)] has no infected flesh to remove!") + surgery.status++ + repeatable = FALSE + return + display_results(user, target, "You begin to excise infected flesh from [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to excise infected flesh from [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to excise infected flesh from [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/debride/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + var/datum/wound/burn/burn_wound = surgery.operated_wound + if(burn_wound) + display_results(user, target, "You successfully excise some of the infected flesh from [target]'s [parse_zone(target_zone)].", + "[user] successfully excises some of the infected flesh from [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully excises some of the infected flesh from [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) + burn_wound.infestation -= 0.5 + burn_wound.sanitization += 0.5 + if(burn_wound.infestation <= 0) + repeatable = FALSE + else + to_chat(user, "[target] has no infected flesh there!") + return ..() + +/datum/surgery_step/debride/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + display_results(user, target, "You carve away some of the healthy flesh from [target]'s [parse_zone(target_zone)].", + "[user] carves away some of the healthy flesh from [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] carves away some of the healthy flesh from [target]'s [parse_zone(target_zone)]!") + surgery.operated_bodypart.receive_damage(brute=rand(4,8), sharpness=TRUE) + +/datum/surgery_step/debride/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE) + if(!..()) + return + var/datum/wound/burn/burn_wound = surgery.operated_wound + while(burn_wound && burn_wound.infestation > 0.25) + if(!..()) + break + +///// Dressing burns +/datum/surgery_step/dress + name = "bandage burns" + implements = list(/obj/item/stack/medical/gauze = 100, /obj/item/stack/sticky_tape/surgical = 100) + time = 40 + +/datum/surgery_step/dress/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/datum/wound/burn/burn_wound = surgery.operated_wound + if(burn_wound) + display_results(user, target, "You begin to dress the burns on [target]'s [parse_zone(user.zone_selected)]...", + "[user] begins to dress the burns on [target]'s [parse_zone(user.zone_selected)] with [tool].", + "[user] begins to dress the burns on [target]'s [parse_zone(user.zone_selected)].") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + +/datum/surgery_step/dress/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + var/datum/wound/burn/burn_wound = surgery.operated_wound + if(burn_wound) + display_results(user, target, "You successfully wrap [target]'s [parse_zone(target_zone)] with [tool].", + "[user] successfully wraps [target]'s [parse_zone(target_zone)] with [tool]!", + "[user] successfully wraps [target]'s [parse_zone(target_zone)]!") + 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) + else + to_chat(user, "[target] has no burns there!") + return ..() + +/datum/surgery_step/dress/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0) + ..() + if(istype(tool, /obj/item/stack)) + var/obj/item/stack/used_stack = tool + used_stack.use(1) diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm index af736e393c..d1d478ddfe 100644 --- a/code/modules/surgery/coronary_bypass.dm +++ b/code/modules/surgery/coronary_bypass.dm @@ -31,7 +31,8 @@ display_results(user, target, "Blood pools around the incision in [H]'s heart.", "Blood pools around the incision in [H]'s heart.", "") - H.bleed_rate += 10 + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + BP.generic_bleedstacks += 10 H.adjustBruteLoss(10) return TRUE @@ -41,7 +42,8 @@ display_results(user, target, "You screw up, cutting too deeply into the heart!", "[user] screws up, causing blood to spurt out of [H]'s chest!", "[user] screws up, causing blood to spurt out of [H]'s chest!") - H.bleed_rate += 20 + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + BP.generic_bleedstacks += 10 H.adjustOrganLoss(ORGAN_SLOT_HEART, 10) H.adjustBruteLoss(10) @@ -73,5 +75,6 @@ "[user] screws up, causing blood to spurt out of [H]'s chest profusely!", "[user] screws up, causing blood to spurt out of [H]'s chest profusely!") H.adjustOrganLoss(ORGAN_SLOT_HEART, 20) - H.bleed_rate += 30 + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + BP.generic_bleedstacks += 30 return FALSE diff --git a/code/modules/surgery/experimental_dissection.dm b/code/modules/surgery/experimental_dissection.dm index 6110bb6202..b9d877d0c1 100644 --- a/code/modules/surgery/experimental_dissection.dm +++ b/code/modules/surgery/experimental_dissection.dm @@ -78,7 +78,7 @@ "[user] dissects [target]!") SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points_earned)) var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST) - target.apply_damage(80, BRUTE, L) + target.apply_damage(80, BRUTE, L, wound_bonus=CANT_WOUND) ADD_TRAIT(target, TRAIT_DISSECTED, "[surgery.name]") repeatable = FALSE return TRUE @@ -89,7 +89,7 @@ "[user] dissects [target], but looks a little dissapointed.") SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = (round(check_value(target, surgery) * 0.01)))) var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST) - target.apply_damage(80, BRUTE, L) + target.apply_damage(80, BRUTE, L, wound_bonus=CANT_WOUND) return TRUE /datum/surgery/advanced/experimental_dissection/adv diff --git a/code/modules/surgery/healing.dm b/code/modules/surgery/healing.dm index 4069199864..0680dda404 100644 --- a/code/modules/surgery/healing.dm +++ b/code/modules/surgery/healing.dm @@ -87,7 +87,7 @@ urdamageamt_brute += round((target.getBruteLoss()/ (missinghpbonus*2)),0.1) urdamageamt_burn += round((target.getFireLoss()/ (missinghpbonus*2)),0.1) - target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn) + target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn, wound_bonus=CANT_WOUND) return FALSE /***************************BRUTE***************************/ diff --git a/code/modules/surgery/organic_steps.dm b/code/modules/surgery/organic_steps.dm index 0b38ecc2fe..8e893875a9 100644 --- a/code/modules/surgery/organic_steps.dm +++ b/code/modules/surgery/organic_steps.dm @@ -21,7 +21,9 @@ display_results(user, target, "Blood pools around the incision in [H]'s [parse_zone(target_zone)].", "Blood pools around the incision in [H]'s [parse_zone(target_zone)].", "") - H.bleed_rate += 3 + var/obj/item/bodypart/BP = target.get_bodypart(target_zone) + if(BP) + BP.generic_bleedstacks += 10 return TRUE /datum/surgery_step/incise/nobleed //silly friendly! @@ -50,7 +52,9 @@ target.heal_bodypart_damage(20,0) if (ishuman(target)) var/mob/living/carbon/human/H = target - H.bleed_rate = max( (H.bleed_rate - 3), 0) + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + if(BP) + BP.generic_bleedstacks -= 3 return ..() //retract skin /datum/surgery_step/retract_skin @@ -86,7 +90,9 @@ target.heal_bodypart_damage(45,0) if (ishuman(target)) var/mob/living/carbon/human/H = target - H.bleed_rate = max( (H.bleed_rate - 3), 0) + var/obj/item/bodypart/BP = H.get_bodypart(target_zone) + if(BP) + BP.generic_bleedstacks -= 3 return ..() //saw bone /datum/surgery_step/saw @@ -100,7 +106,7 @@ "[user] begins to saw through the bone in [target]'s [parse_zone(target_zone)].") /datum/surgery_step/saw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - target.apply_damage(50, BRUTE, "[target_zone]") + target.apply_damage(50, BRUTE, "[target_zone]", wound_bonus=CANT_WOUND) display_results(user, target, "You saw [target]'s [parse_zone(target_zone)] open.", "[user] saws [target]'s [parse_zone(target_zone)] open!", "[user] saws [target]'s [parse_zone(target_zone)] open!") diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index fa49e3eff5..b6b74efe32 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -318,13 +318,14 @@ cooldown = COOLDOWN_DAMAGE for(var/V in listeners) var/mob/living/L = V - L.apply_damage(15 * power_multiplier, def_zone = BODY_ZONE_CHEST) + L.apply_damage(15 * power_multiplier, def_zone = BODY_ZONE_CHEST, wound_bonus=CANT_WOUND) //BLEED else if((findtext(message, bleed_words))) cooldown = COOLDOWN_DAMAGE for(var/mob/living/carbon/human/H in listeners) - H.bleed_rate += (5 * power_multiplier) + var/obj/item/bodypart/BP = pick(H.bodyparts) + BP.generic_bleedstacks += 5 //FIRE else if((findtext(message, burn_words))) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 51ce2726b0..4d42cb6c23 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -18,6 +18,8 @@ var/lying_required = TRUE //Does the vicitm needs to be lying down. var/requires_tech = FALSE var/replaced_by + var/datum/wound/operated_wound //The actual wound datum instance we're targeting + var/datum/wound/targetable_wound //The wound type this surgery targets /datum/surgery/New(surgery_target, surgery_location, surgery_bodypart) ..() @@ -28,8 +30,13 @@ location = surgery_location if(surgery_bodypart) operated_bodypart = surgery_bodypart + if(targetable_wound) + operated_wound = operated_bodypart.get_wound_type(targetable_wound) + operated_wound.attached_surgery = src /datum/surgery/Destroy() + if(operated_wound) + operated_wound.attached_surgery = null if(target) target.surgeries -= src target = null diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 584a0a189a..150016f570 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -166,6 +166,7 @@ sharpness = IS_SHARP_ACCURATE tool_behaviour = TOOL_SCALPEL toolspeed = 1 + bare_wound_bonus = 20 /obj/item/scalpel/Initialize() . = ..() @@ -247,6 +248,8 @@ sharpness = IS_SHARP tool_behaviour = TOOL_SAW toolspeed = 1 + wound_bonus = 10 + bare_wound_bonus = 15 /obj/item/circular_saw/Initialize() . = ..() @@ -374,3 +377,18 @@ advanced_surgeries |= OC.advanced_surgeries return TRUE return + +/obj/item/bonesetter + name = "bonesetter" + desc = "For setting things right." + icon = 'icons/obj/surgery.dmi' + icon_state = "bone setter" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2500) + flags_1 = CONDUCT_1 + item_flags = SURGICAL_TOOL + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("corrected", "properly set") + tool_behaviour = TOOL_BONESET + toolspeed = 1 diff --git a/code/modules/tgui/states/hands.dm b/code/modules/tgui/states/hands.dm index aedae477dd..d73d1058ea 100644 --- a/code/modules/tgui/states/hands.dm +++ b/code/modules/tgui/states/hands.dm @@ -19,7 +19,7 @@ GLOBAL_DATUM_INIT(hands_state, /datum/ui_state/hands_state, new) return UI_INTERACTIVE return UI_CLOSE -/mob/living/silicon/robot/hands_can_use_topic(src_object) - if(activated(src_object)) +/mob/living/silicon/robot/hands_can_use_topic(obj/src_object) + if(activated(src_object) || istype(src_object.loc, /obj/item/weapon/gripper)) return UI_INTERACTIVE return UI_CLOSE diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm index df6373b8de..ccaa998cf7 100644 --- a/code/modules/uplink/uplink_items/uplink_devices.dm +++ b/code/modules/uplink/uplink_items/uplink_devices.dm @@ -230,17 +230,9 @@ /datum/uplink_item/device_tools/surgerybag_adv name = "Advanced Syndicate Surgery Duffel Bag" - desc = "The Syndicate surgery duffel bag is a toolkit containing all advanced surgery tools, surgical drapes, \ - a Syndicate brand MMI, a straitjacket, a muzzle, and an outdated, yet still useful Combat Medic Kit." + desc = "A Syndicate surgery duffel bag, with a set of upgraded surgery tools to boot." item = /obj/item/storage/backpack/duffelbag/syndie/surgery_adv - cost = 10 - -/datum/uplink_item/device_tools/brainwash_disk - name = "Brainwashing Surgery Program" - desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \ - Insert into an Operating Console to enable the procedure." - item = /obj/item/disk/surgery/brainwashing - cost = 3 + cost = 6 /datum/uplink_item/device_tools/encryptionkey name = "Syndicate Encryption Key" diff --git a/code/modules/uplink/uplink_items/uplink_roles.dm b/code/modules/uplink/uplink_items/uplink_roles.dm index da25cf5298..859c8c0bd7 100644 --- a/code/modules/uplink/uplink_items/uplink_roles.dm +++ b/code/modules/uplink/uplink_items/uplink_roles.dm @@ -39,6 +39,14 @@ cost = 12 restricted_roles = list("Research Director", "Scientist", "Roboticist") +/datum/uplink_item/device_tools/brainwash_disk + name = "Brainwashing Surgery Program" + desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \ + Insert into an Operating Console to enable the procedure." + item = /obj/item/disk/surgery/brainwashing + restricted_roles = list("Medical Doctor", "Roboticist") + cost = 5 + /datum/uplink_item/role_restricted/clown_bomb name = "Clown Bomb" desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ diff --git a/code/modules/uplink/uplink_items/uplink_stealth.dm b/code/modules/uplink/uplink_items/uplink_stealth.dm index b4933b30ba..c60d4ef177 100644 --- a/code/modules/uplink/uplink_items/uplink_stealth.dm +++ b/code/modules/uplink/uplink_items/uplink_stealth.dm @@ -51,7 +51,7 @@ gain skin as hard as steel and swat bullets from the air, but you also refuse to use dishonorable ranged weaponry." item = /obj/item/book/granter/martial/carp cost = 17 - player_minimum = 30 + player_minimum = 20 surplus = 0 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) @@ -61,7 +61,7 @@ and dodging all ranged weapon fire, but you will refuse to use dishonorable ranged weaponry." item = /obj/item/book/granter/martial/bass cost = 18 - player_minimum = 30 + player_minimum = 20 surplus = 0 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm index d45cb8d26f..fb30e66f97 100644 --- a/code/modules/vehicles/cars/car.dm +++ b/code/modules/vehicles/cars/car.dm @@ -57,7 +57,7 @@ return FALSE return ..() -/obj/vehicle/sealed/car/attack_hand(mob/living/user) +/obj/vehicle/sealed/car/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(!(car_traits & CAN_KIDNAP)) return diff --git a/code/modules/vehicles/pimpin_ride.dm b/code/modules/vehicles/pimpin_ride.dm index ef374f5db0..547eef7af2 100644 --- a/code/modules/vehicles/pimpin_ride.dm +++ b/code/modules/vehicles/pimpin_ride.dm @@ -62,7 +62,7 @@ if(floorbuffer) . += "cart_buffer" -/obj/vehicle/ridden/janicart/attack_hand(mob/user) +/obj/vehicle/ridden/janicart/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) return diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index fca137a87d..a7b9b6a298 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -479,7 +479,7 @@ GLOBAL_LIST_EMPTY(vending_products) var/crit_case if(crit) - crit_case = rand(1,5) + crit_case = rand(1,6) if(forcecrit) crit_case = forcecrit @@ -491,7 +491,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(istype(C)) var/crit_rebate = 0 // lessen the normal damage we deal for some of the crits - if(crit_case != 5) // the head asplode case has its own description + if(crit_case < 5) // the head asplode case has its own description C.visible_message("[C] is crushed by [src]!", \ "You are crushed by [src]!") @@ -501,10 +501,10 @@ GLOBAL_LIST_EMPTY(vending_products) C.bleed(150) var/obj/item/bodypart/l_leg/l = C.get_bodypart(BODY_ZONE_L_LEG) if(l) - l.receive_damage(brute=200, updating_health=TRUE) + l.receive_damage(brute=200) var/obj/item/bodypart/r_leg/r = C.get_bodypart(BODY_ZONE_R_LEG) if(r) - r.receive_damage(brute=200, updating_health=TRUE) + r.receive_damage(brute=200) if(l || r) C.visible_message("[C]'s legs shatter with a sickening crunch!", \ "Your legs shatter with a sickening crunch!") @@ -526,7 +526,18 @@ GLOBAL_LIST_EMPTY(vending_products) // the new paraplegic gets like 4 lines of losing their legs so skip them visible_message("[C]'s spinal cord is obliterated with a sickening crunch!", ignored_mobs = list(C)) C.gain_trauma(/datum/brain_trauma/severe/paralysis/spinesnapped) - if(5) // skull squish! + if(5) // limb squish! + 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)) + squish_part.force_wound_upwards(type_wound) + else + squish_part.receive_damage(brute=30) + C.visible_message("[C]'s body is maimed underneath the mass of [src]!", \ + "Your body is maimed underneath the mass of [src]!") + if(6) // skull squish! var/obj/item/bodypart/head/O = C.get_bodypart(BODY_ZONE_HEAD) if(O) C.visible_message("[O] explodes in a shower of gore beneath [src]!", \ @@ -536,7 +547,11 @@ GLOBAL_LIST_EMPTY(vending_products) qdel(O) new /obj/effect/gibspawner/human/bodypartless(get_turf(C)) - C.apply_damage(max(0, squish_damage - crit_rebate), forced=TRUE, spread_damage=TRUE) + if(prob(30)) + C.apply_damage(max(0, squish_damage - crit_rebate), forced=TRUE, spread_damage=TRUE) // the 30% chance to spread the damage means you escape breaking any bones + else + C.take_bodypart_damage((squish_damage - crit_rebate)*0.5, wound_bonus = 5) // otherwise, deal it to 2 random limbs (or the same one) which will likely shatter something + C.take_bodypart_damage((squish_damage - crit_rebate)*0.5, wound_bonus = 5) C.AddElement(/datum/element/squish, 18 SECONDS) else L.visible_message("[L] is crushed by [src]!", \ diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index 9dfb4c76a0..260b124283 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -84,8 +84,10 @@ /obj/item/clothing/suit/poncho = 1, /obj/item/clothing/suit/poncho/green = 1, /obj/item/clothing/suit/poncho/red = 1, + /obj/item/clothing/head/maid = 1, /obj/item/clothing/under/costume/maid = 1, /obj/item/clothing/under/rank/civilian/janitor/maid = 1, + /obj/item/clothing/gloves/evening = 1, /obj/item/clothing/glasses/cold=1, /obj/item/clothing/glasses/heat=1, /obj/item/clothing/suit/whitedress = 1, diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 963fff9368..2691906af4 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -150,7 +150,8 @@ /obj/item/clothing/under/costume/qipao/red = 3, /obj/item/clothing/under/costume/cheongsam = 3, /obj/item/clothing/under/costume/cheongsam/white = 3, - /obj/item/clothing/under/costume/cheongsam/red = 3) + /obj/item/clothing/under/costume/cheongsam/red = 3, + /obj/item/storage/backpack/snail = 3) contraband = list(/obj/item/clothing/under/syndicate/tacticool = 3, /obj/item/clothing/under/syndicate/tacticool/skirt = 3, /obj/item/clothing/mask/balaclava = 3, diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index 7bed27b0bd..7fd8246dd6 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -4,7 +4,7 @@ product_ads = "Escape to a fantasy world!;Fuel your gambling addiction!;Ruin your friendships!;Roll for initiative!;Elves and dwarves!;Paranoid computers!;Totally not satanic!;Fun times forever!" icon_state = "games" products = list(/obj/item/toy/cards/deck = 5, - /obj/item/storage/pill_bottle/dice = 10, + /obj/item/storage/box/dice = 10, /obj/item/toy/cards/deck/cas = 3, /obj/item/toy/cards/deck/cas/black = 3, /obj/item/toy/cards/deck/unum = 3) diff --git a/code/modules/vending/kinkmate.dm b/code/modules/vending/kinkmate.dm index c416d87439..df8a4e8a96 100644 --- a/code/modules/vending/kinkmate.dm +++ b/code/modules/vending/kinkmate.dm @@ -6,8 +6,10 @@ product_slogans = "Kinky!;Sexy!;Check me out, big boy!" vend_reply = "Have fun, you shameless pervert!" products = list( + /obj/item/clothing/head/maid = 5, /obj/item/clothing/under/costume/maid = 5, /obj/item/clothing/under/rank/civilian/janitor/maid = 5, + /obj/item/clothing/gloves/evening = 5, /obj/item/clothing/neck/petcollar = 5, /obj/item/clothing/neck/petcollar/choker = 5, /obj/item/clothing/neck/petcollar/leather = 5, diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index fbd9a10bf2..34de3b490c 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -29,7 +29,12 @@ /obj/item/storage/hypospraykit/brute = 2, /obj/item/storage/hypospraykit/enlarge = 2, /obj/item/reagent_containers/glass/bottle/vial/small = 5, - /obj/item/storage/briefcase/medical = 2) + /obj/item/storage/briefcase/medical = 2, + /obj/item/stack/sticky_tape/surgical = 3, + /obj/item/healthanalyzer/wound = 4, + /obj/item/stack/medical/ointment = 2, + /obj/item/stack/medical/suture = 2, + /obj/item/stack/medical/bone_gel = 4) contraband = list(/obj/item/reagent_containers/pill/tox = 3, /obj/item/reagent_containers/pill/morphine = 4, /obj/item/reagent_containers/pill/charcoal = 6) diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index 09719e1d56..31f3dc49f1 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -11,6 +11,8 @@ /obj/item/reagent_containers/medspray/silver_sulf = 2, /obj/item/reagent_containers/pill/charcoal = 2, /obj/item/reagent_containers/medspray/sterilizine = 1, + /obj/item/healthanalyzer/wound = 2, + /obj/item/stack/medical/bone_gel = 2, /obj/item/reagent_containers/syringe/dart = 10) contraband = list(/obj/item/reagent_containers/pill/tox = 2, /obj/item/reagent_containers/pill/morphine = 2) diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm index 2eb68aaf4a..45199298ca 100644 --- a/code/modules/vending/megaseed.dm +++ b/code/modules/vending/megaseed.dm @@ -4,7 +4,8 @@ product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds" - products = list(/obj/item/seeds/ambrosia = 3, + products = list(/obj/item/seeds/aloe = 3, + /obj/item/seeds/ambrosia = 3, /obj/item/seeds/apple = 3, /obj/item/seeds/banana = 3, /obj/item/seeds/berry = 3, diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index d4d92f54c4..7038e9df7c 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -11,9 +11,13 @@ var/icon_left = "bloodhand_left" var/icon_right = "bloodhand_right" hitsound = 'sound/hallucinations/growl1.ogg' - force = 21 // Just enough to break airlocks with melee attacks + force = 18 + sharpness = IS_SHARP_ACCURATE //it's a claw, they're sharp. damtype = "brute" total_mass = TOTAL_MASS_HAND_REPLACEMENT + sharpness = IS_SHARP + wound_bonus = -30 + bare_wound_bonus = 15 /obj/item/zombie_hand/Initialize() . = ..() @@ -32,11 +36,15 @@ . = ..() if(!proximity_flag) return - else if(isliving(target)) - if(ishuman(target)) - try_to_zombie_infect(target) + else + if(istype(target, /obj/)) //do far more damage to non mobs so we can get through airlocks + var/obj/target_object = target + target_object.take_damage(force * 3, BRUTE, "melee", 0) else - check_feast(target, user) + if(isliving(target) && ishuman(target)) + try_to_zombie_infect(target) + else + check_feast(target, user) /proc/try_to_zombie_infect(mob/living/carbon/human/target) CHECK_DNA_AND_SPECIES(target) @@ -52,8 +60,6 @@ infection = new() infection.Insert(target) - - /obj/item/zombie_hand/suicide_act(mob/user) user.visible_message("[user] is ripping [user.p_their()] brains out! It looks like [user.p_theyre()] trying to commit suicide!") if(isliving(user)) diff --git a/html/changelog.html b/html/changelog.html index 1442691167..d0731d740c 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,144 @@ -->
+

23 July 2020

+

DeltaFire15 updated:

+ +

Putnam3145 updated:

+ +

kappa-sama updated:

+ +

zeroisthebiggay updated:

+ + +

22 July 2020

+

Ludox updated:

+ +

kappa-sama updated:

+ + +

21 July 2020

+

Arturlang updated:

+ +

CameronWoof updated:

+ +

Chiirno updated:

+ +

DeltaFire15 updated:

+ +

Funce updated:

+ +

Kraseo updated:

+ +

SiliconMain updated:

+ +

TheSpaghetti updated:

+ +

kappa-sama updated:

+ +

silicons updated:

+ +

timothyteakettle updated:

+ + +

20 July 2020

+

lolman360 updated:

+ + +

19 July 2020

+

Arturlang updated:

+ +

EmeraldSundisk updated:

+ +

MrJWhit updated:

+ +

Putnam3145 updated:

+ +

TheObserver-sys updated:

+ +

Yakumo Chen updated:

+ +

b1tt3r1n0 updated:

+ +

silicons updated:

+ +

timothyteakettle updated:

+ +

zeroisthebiggay updated:

+ +

17 July 2020

ShizCalev, Fikou updated: