diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 2bdc6ed1dd..f50c765385 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -3953,7 +3953,6 @@ /area/service/bar) "ann" = ( /obj/effect/spawner/lootdrop/maintenance, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/port/fore) "ano" = ( @@ -4154,12 +4153,17 @@ /obj/item/radio/intercom{ pixel_y = 25 }, +/obj/structure/rack, +/obj/item/storage/briefcase, /turf/open/floor/wood, /area/service/lawoffice) "aoc" = ( /obj/machinery/airalarm{ pixel_y = 23 }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/open/floor/wood, /area/service/lawoffice) "aod" = ( @@ -4859,6 +4863,9 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/service/lawoffice) "aqa" = ( @@ -4866,9 +4873,16 @@ /turf/open/floor/carpet, /area/commons/dorms) "aqb" = ( -/obj/structure/rack, -/obj/item/storage/briefcase, /obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/machinery/power/apc{ + areastring = "/area/service/lawoffice"; + dir = 1; + name = "Law Office APC"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-8" + }, /turf/open/floor/wood, /area/service/lawoffice) "aqc" = ( @@ -5175,15 +5189,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"aqO" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/port/fore) "aqP" = ( /obj/structure/cable{ icon_state = "1-8" @@ -5503,9 +5508,6 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "asc" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/structure/cable{ icon_state = "2-8" }, @@ -5543,15 +5545,6 @@ }, /turf/open/floor/plating, /area/maintenance/port/fore) -"asi" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/maintenance/port/fore) "ask" = ( /obj/item/flashlight/lamp/green{ pixel_x = -2; @@ -5575,6 +5568,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plating, /area/maintenance/fore) "asq" = ( @@ -6378,19 +6374,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/wood, /area/maintenance/port/fore) -"avi" = ( -/obj/machinery/power/apc{ - areastring = "/area/service/lawoffice"; - dir = 1; - name = "Law Office APC"; - pixel_y = 23 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/fore) "avj" = ( /obj/machinery/firealarm{ dir = 4; @@ -7190,16 +7173,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/starboard/fore) -"ayh" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/port/fore) "ayi" = ( /obj/structure/cable{ icon_state = "1-4" @@ -7525,7 +7498,6 @@ name = "Garden Maintenance"; req_access_txt = "12" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/port/fore) "azq" = ( @@ -8062,9 +8034,6 @@ /obj/item/seeds/watermelon, /obj/structure/table/glass, /obj/item/seeds/tower, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /turf/open/floor/plasteel, /area/service/hydroponics/garden) "aBB" = ( @@ -8083,9 +8052,7 @@ /turf/open/floor/plating, /area/maintenance/starboard/fore) "aBG" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, /area/service/hydroponics/garden) "aBH" = ( @@ -8892,6 +8859,9 @@ /obj/machinery/door/airlock{ name = "Garden" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/service/hydroponics/garden) "aEM" = ( @@ -41348,12 +41318,12 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, /obj/structure/cable{ icon_state = "1-4" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, /turf/open/floor/plating, /area/maintenance/port/fore) "cwS" = ( @@ -42331,11 +42301,6 @@ }, /turf/open/floor/plasteel, /area/medical/surgery) -"cCs" = ( -/obj/structure/closet/emcloset, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/port/fore) "cCt" = ( /obj/structure/closet, /obj/effect/spawner/lootdrop/maintenance{ @@ -45161,6 +45126,9 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/open/floor/plating, /area/maintenance/fore) "eev" = ( @@ -45396,6 +45364,12 @@ "evR" = ( /turf/open/floor/plating, /area/maintenance/bar) +"ewb" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/service/lawoffice) "ewu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 @@ -47758,6 +47732,9 @@ dir = 4 }, /obj/effect/landmark/navigate_destination/lawyer, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/service/lawoffice) "gtZ" = ( @@ -49027,11 +49004,6 @@ /obj/structure/lattice, /turf/closed/wall, /area/maintenance/fore) -"hCn" = ( -/obj/structure/closet/firecloset, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/port/fore) "hCp" = ( /obj/structure/cable{ icon_state = "4-8" @@ -49476,9 +49448,6 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/maintenance/port/fore) @@ -52542,26 +52511,6 @@ }, /turf/open/floor/plasteel, /area/security/processing) -"kHw" = ( -/obj/machinery/door/airlock/security/glass{ - id_tag = "innerbrig"; - name = "Brig"; - req_access_txt = "1" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/brig) "kHN" = ( /obj/structure/chair{ dir = 1 @@ -55546,6 +55495,12 @@ }, /turf/open/floor/wood/wood_large, /area/service/chapel/office) +"nrS" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/service/lawoffice) "nsf" = ( /obj/structure/cable/white{ icon_state = "0-2" @@ -57441,19 +57396,6 @@ /obj/effect/landmark/blobstart, /turf/open/floor/plating, /area/maintenance/aft) -"pbQ" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plating, -/area/maintenance/fore) "pcz" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -57860,6 +57802,15 @@ "pun" = ( /turf/open/floor/plasteel/freezer, /area/security/prison/cells) +"puO" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/storage/primary) "pvJ" = ( /obj/structure/rack, /obj/effect/spawner/lootdrop/maintenance{ @@ -62475,10 +62426,6 @@ /obj/structure/bookcase/random/religion, /turf/open/floor/wood/wood_large, /area/service/chapel/main) -"tGO" = ( -/obj/machinery/power/apc/auto_name/west, -/turf/closed/wall, -/area/service/lawoffice) "tHc" = ( /obj/machinery/door/airlock/grunge{ name = "Prison Visitation"; @@ -62737,6 +62684,12 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"tUc" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/service/lawoffice) "tUd" = ( /obj/effect/turf_decal/tile/red{ dir = 4 @@ -64523,6 +64476,12 @@ }, /turf/open/floor/wood, /area/maintenance/bar) +"vzY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/storage/primary) "vAI" = ( /obj/effect/turf_decal/siding/white{ dir = 1 @@ -81256,7 +81215,7 @@ alU alU alU alU -aqO +auT lPA mUQ kwY @@ -81513,7 +81472,7 @@ alU atM atW alU -aqO +auT lPA aCW lPA @@ -82027,7 +81986,7 @@ arO amC aom ank -aqO +auT alU axf ayu @@ -82798,7 +82757,7 @@ alU alU alU auY -aqO +auT alU alU enJ @@ -83312,17 +83271,17 @@ ali aok amC anJ -asi -arH -cCs +auT +alU +aoX ann ann -hCn -cwS -ayh +avX +amC +asK azi -aAx -aBm +aAQ +aAQ aAQ aAQ aAQ @@ -83836,7 +83795,7 @@ alU asK azF aAS -aFP +aAQ aAQ aAQ aAQ @@ -84094,8 +84053,8 @@ asK azF aAU aBG -aAQ -aAQ +aAx +aBm aAQ aAQ aAQ @@ -84352,7 +84311,7 @@ azF aAP aAP aAP -aAQ +aFP aFO aHA aIT @@ -84866,7 +84825,7 @@ atN aAV aBQ aDh -aDo +vzY aFQ aHe aIN @@ -85123,7 +85082,7 @@ cwS aAN aBL aDd -aDd +puO aFR aDd aDd @@ -94881,8 +94840,8 @@ aph arW aso auf -avi -pbQ +ayJ +auo axy ayS jUT @@ -95132,7 +95091,7 @@ aiX anz anz aov -tGO +aph aob ara arV @@ -95391,9 +95350,9 @@ anz aov aph aoc -ata +nrS gtK -ata +ewb auh aph awg @@ -95647,7 +95606,7 @@ aqC anz aov api -ata +tUc dPR arX atc @@ -96924,7 +96883,7 @@ jyO ajC akC akX -kHw +alw amJ aoY rCl diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 5176aad2ef..9913253ba6 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -53141,22 +53141,16 @@ /turf/closed/wall, /area/medical/surgery) "dsN" = ( -/obj/item/clothing/gloves/color/latex, -/obj/item/clothing/suit/apron/surgical, -/obj/item/clothing/mask/surgical, -/obj/item/surgical_drapes, -/obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/structure/closet/secure_closet/medical2, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsO" = ( -/obj/item/retractor, -/obj/item/hemostat, /obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -53168,14 +53162,16 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/item/clothing/gloves/color/latex{ + pixel_y = 10 + }, +/obj/item/clothing/suit/apron/surgical, +/obj/item/clothing/mask/surgical{ + pixel_y = -6 + }, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsP" = ( -/obj/item/circular_saw, -/obj/item/surgicaldrill{ - pixel_y = 5 - }, -/obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, @@ -53189,11 +53185,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/limbgrower, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsQ" = ( -/obj/item/scalpel, -/obj/item/cautery, /obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -53207,6 +53202,13 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/clothing/gloves/color/latex{ + pixel_y = 10 + }, +/obj/item/clothing/suit/apron/surgical, +/obj/item/clothing/mask/surgical{ + pixel_y = -6 + }, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsR" = ( @@ -54364,9 +54366,6 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "dvF" = ( -/obj/machinery/computer/operating{ - dir = 4 - }, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -54383,10 +54382,11 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/table/reinforced, +/obj/item/storage/backpack/duffelbag/med/surgery, /turf/open/floor/plasteel, /area/medical/surgery) "dvG" = ( -/obj/structure/table/optable, /obj/effect/decal/cleanable/blood/old, /obj/structure/cable/white{ icon_state = "2-8" @@ -54407,17 +54407,19 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/table/reinforced, +/obj/item/reagent_containers/spray/cleaner, /turf/open/floor/plasteel, /area/medical/surgery) "dvH" = ( -/obj/machinery/holopad, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/bot, +/obj/structure/table/reinforced, +/obj/item/storage/backpack/duffelbag/med/surgery, /turf/open/floor/plasteel, /area/medical/surgery) "dvI" = ( @@ -55091,21 +55093,21 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "dxm" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, /turf/open/floor/plasteel/white, /area/medical/surgery) "dxn" = ( /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, +/obj/machinery/holopad, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/medical/surgery) "dxo" = ( /obj/effect/turf_decal/tile/blue, @@ -55704,7 +55706,6 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "dyG" = ( -/obj/structure/closet/secure_closet/medical2, /obj/structure/sign/poster/official/cleanliness{ pixel_x = -32 }, @@ -55718,25 +55719,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/medical/surgery) -"dyH" = ( +/obj/machinery/computer/operating{ + dir = 1 + }, /obj/machinery/status_display/ai{ pixel_y = -32 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/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/surgery) "dyI" = ( @@ -55762,12 +55750,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/closet/crate/freezer/blood, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyJ" = ( -/obj/machinery/status_display/evac{ - pixel_y = -32 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -55778,7 +55764,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/structure/closet/crate/freezer/blood, +/obj/structure/table/optable, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyK" = ( @@ -55797,7 +55783,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/machinery/limbgrower, +/obj/machinery/computer/operating{ + dir = 1 + }, +/obj/machinery/status_display/evac{ + pixel_y = -32 + }, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyL" = ( @@ -177579,7 +177570,7 @@ dsO dtR dvF dxm -dyH +dyJ dma cPy cPy diff --git a/_maps/map_files/TauStation/TauStation.dmm b/_maps/map_files/TauStation/TauStation.dmm index 4bb9112ea7..4d10f2a5f4 100644 --- a/_maps/map_files/TauStation/TauStation.dmm +++ b/_maps/map_files/TauStation/TauStation.dmm @@ -3070,6 +3070,12 @@ }, /turf/open/floor/plasteel/white, /area/science/xenobiology) +"baV" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science) "bbh" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/airalarm{ @@ -11271,6 +11277,7 @@ }, /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/brig) "dTD" = ( @@ -15587,6 +15594,18 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"fsv" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/starboard) "fsw" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 @@ -16469,12 +16488,10 @@ /turf/open/floor/plasteel/freezer, /area/engineering/main) "fHN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel, /area/hallway/primary/aft) "fHP" = ( @@ -17771,6 +17788,16 @@ dir = 4 }, /area/service/theater) +"gdN" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) "gdR" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, @@ -18902,6 +18929,12 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) +"gBx" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/science) "gBI" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, @@ -20199,6 +20232,7 @@ /area/hallway/primary/port) "gWN" = ( /obj/effect/landmark/navigate_destination/eva, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/storage/eva) "gWU" = ( @@ -20626,6 +20660,10 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"hfV" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) "hgb" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -21076,6 +21114,9 @@ /area/command/heads_quarters/captain/private) "hlw" = ( /obj/effect/landmark/event_spawn, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/science) "hlG" = ( @@ -29183,6 +29224,14 @@ /obj/machinery/door/poddoor/incinerator_atmos_aux, /turf/open/floor/engine/vacuum, /area/maintenance/disposal/incinerator) +"kkl" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "kks" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -32072,6 +32121,13 @@ }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) +"ljB" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "ljD" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -34926,6 +34982,15 @@ }, /turf/open/floor/plasteel/dark, /area/command/gateway) +"mgC" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/starboard) "mgN" = ( /obj/structure/cable{ icon_state = "4-8" @@ -38489,6 +38554,12 @@ }, /turf/open/floor/plating, /area/engineering/atmos) +"nnq" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "nnU" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -41729,12 +41800,12 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "owR" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "owU" = ( @@ -44050,6 +44121,18 @@ "poG" = ( /turf/closed/wall/r_wall, /area/command/heads_quarters/hop) +"poJ" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/starboard) "poL" = ( /obj/structure/window/reinforced{ dir = 8 @@ -48055,6 +48138,12 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/service/chapel/main) +"qKZ" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science) "qLd" = ( /obj/structure/curtain, /turf/open/floor/plasteel/white/side{ @@ -49896,6 +49985,15 @@ }, /turf/open/floor/plasteel, /area/construction) +"rqA" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "rqE" = ( /obj/structure/reagent_dispensers/watertank, /turf/open/floor/plasteel/dark, @@ -51363,6 +51461,7 @@ req_access_txt = "19" }, /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/storage/eva) "rSV" = ( @@ -59779,6 +59878,12 @@ /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plasteel, /area/commons/storage/primary) +"uKi" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/science) "uKn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, @@ -62035,6 +62140,15 @@ initial_gas_mix = "o2=21.78;n2=82.36;TEMP=293" }, /area/service/hydroponics/enclosure) +"vyE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/starboard) "vyF" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable{ @@ -62475,6 +62589,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "vEQ" = ( @@ -63879,6 +63996,15 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"weT" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "wfa" = ( /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ @@ -101847,9 +101973,9 @@ snT xmJ tGd gzq -gzq -gzq -gzq +rqA +ljB +kkl fHN tPs xzv @@ -102104,7 +102230,7 @@ xmJ xmJ tGd xzv -xzv +nnq xzv xzv sxj @@ -102361,7 +102487,7 @@ nsR xmJ tGd wVf -wVf +weT wVf wVf wVf @@ -102618,7 +102744,7 @@ wzB xpx tGO tGO -uZn +brI uZn uZn tGO @@ -102875,7 +103001,7 @@ wzZ pnq tGO xQm -xfq +baV xfq xfq mcU @@ -103132,7 +103258,7 @@ wzZ mXv tGO xQA -xfq +baV xfq xfq cfk @@ -103646,7 +103772,7 @@ osB tGO xqj xSI -xfq +baV cqK rWx ejR @@ -103897,13 +104023,13 @@ qBJ unB rkv rLF -stQ -ygo +mgC +tnC owR kNN xfq -xfq -xfq +gBx +uKi mSt xyJ gzS @@ -104154,12 +104280,12 @@ qUx kXA spt rLF -stQ +vyE ygo bNF brI xfq -xfq +baV uzk mSt hIM @@ -104411,12 +104537,12 @@ qUx qUx uFH rOu -stQ +vyE vox jpU tpU tHV -tHV +qKZ rMv mSt hIM @@ -104925,7 +105051,7 @@ qCy qUj rqE rSV -suO +fsv ygo oDS xNa @@ -105176,13 +105302,13 @@ thT nUe rTi qti -pmj -pSO -qUx -qUx +plH +gdN +hfV +hfV gWN rST -suO +poJ ygo ygo vbA diff --git a/_maps/shuttles/cargo_kilo.dmm b/_maps/shuttles/cargo_kilo.dmm index 86660a4dc7..b05f1c49de 100644 --- a/_maps/shuttles/cargo_kilo.dmm +++ b/_maps/shuttles/cargo_kilo.dmm @@ -51,6 +51,7 @@ id = "QMLoad"; name = "off ramp" }, +/obj/structure/fans/tiny, /turf/open/floor/plating, /area/shuttle/supply) "j" = ( @@ -82,6 +83,7 @@ dir = 4; dwidth = 4 }, +/obj/structure/fans/tiny, /turf/open/floor/mineral/plastitanium, /area/shuttle/supply) "n" = ( @@ -137,6 +139,7 @@ req_access_txt = "31" }, /obj/effect/decal/cleanable/dirt, +/obj/structure/fans/tiny, /turf/open/floor/mineral/plastitanium, /area/shuttle/supply) "t" = ( @@ -149,6 +152,7 @@ id = "QMLoad2"; name = "on ramp" }, +/obj/structure/fans/tiny, /turf/open/floor/plating, /area/shuttle/supply) "u" = ( diff --git a/_maps/splurt_maps/templates/hilbertshotel.dmm b/_maps/splurt_maps/templates/hilbertshotel.dmm index ecb4d2d646..b39bc8c146 100644 --- a/_maps/splurt_maps/templates/hilbertshotel.dmm +++ b/_maps/splurt_maps/templates/hilbertshotel.dmm @@ -145,6 +145,10 @@ }, /turf/open/indestructible/hotelwood, /area/hilbertshotel) +"kU" = ( +/obj/machinery/telecomms/relay/preset/auto, +/turf/open/floor/catwalk_floor, +/area/hilbertshotel) "kX" = ( /obj/structure/table/reinforced, /turf/open/floor/plasteel/cafeteria, @@ -655,7 +659,7 @@ GW "} (8,1,1) = {" GW -GW +kU Si Si Si diff --git a/code/__DEFINES/_flags/item_flags.dm b/code/__DEFINES/_flags/item_flags.dm index 529499127d..d28cb80bab 100644 --- a/code/__DEFINES/_flags/item_flags.dm +++ b/code/__DEFINES/_flags/item_flags.dm @@ -51,4 +51,4 @@ #define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances #define ORGAN_NO_DISMEMBERMENT (1<<6) //Immune to disembowelment. #define ORGAN_EDIBLE (1<<7) //is a snack? :D -#define ORGAN_SYNTHETIC_EMP (1<<6) //Synthetic organ affected by an EMP. Deteriorates over time. +#define ORGAN_SYNTHETIC_EMP (1<<8) //Synthetic organ affected by an EMP. Deteriorates over time. diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index c1a3583634..c9e31c672d 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -74,7 +74,6 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list( #define iscatperson(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/felinid)) #define isethereal(A) (is_species(A, /datum/species/ethereal)) #define isvampire(A) (is_species(A,/datum/species/vampire)) -#define isdullahan(A) (is_species(A, /datum/species/dullahan)) #define ismush(A) (is_species(A, /datum/species/mush)) #define isshadow(A) (is_species(A, /datum/species/shadow)) diff --git a/code/__DEFINES/loadout.dm b/code/__DEFINES/loadout.dm index 792708b5bb..182e58c1f7 100644 --- a/code/__DEFINES/loadout.dm +++ b/code/__DEFINES/loadout.dm @@ -7,6 +7,7 @@ //backpack #define LOADOUT_CATEGORY_BACKPACK "In backpack" #define LOADOUT_SUBCATEGORY_BACKPACK_GENERAL "General" //basically anything that there's not enough of to have its own subcategory +#define LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES "Accessories" //maybe one day someone will make loadouts have accessory compatibility #define LOADOUT_SUBCATEGORY_BACKPACK_TOYS "Toys" //neck #define LOADOUT_CATEGORY_NECK "Neck" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 6db900d0e6..331ef3cca9 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -295,7 +295,8 @@ // MINOR TWEAKS/MISC #define AGE_MIN 18 // youngest a character can be // CITADEL EDIT - 17 --> 18 -#define AGE_MAX 85 // oldest a character can be +#define AGE_MAX 85 // oldest a character can be randomly generated +#define AGE_MAX_INPUT 85 // oldest a character's age can be manually set #define WIZARD_AGE_MIN 30 // youngest a wizard can be #define APPRENTICE_AGE_MIN 29 // youngest an apprentice can be #define SHOES_SLOWDOWN 0 // How much shoes slow you down by default. Negative values speed you up diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 2d313fd38a..eda8089a5b 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -245,6 +245,8 @@ #define TRAIT_BEING_CARRIED "being_carried" #define TRAIT_GLASS_BONES "glass_bones" #define TRAIT_PAPER_SKIN "paper_skin" +//used because it's more reliable than checking for the component +#define TRAIT_DULLAHAN "dullahan" // mobility flag traits // IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it) diff --git a/code/__HELPERS/weakref.dm b/code/__HELPERS/weakref.dm new file mode 100644 index 0000000000..0b007332ef --- /dev/null +++ b/code/__HELPERS/weakref.dm @@ -0,0 +1,2 @@ +/// Checks if potential_weakref is a weakref of thing. +#define IS_WEAKREF_OF(thing, potential_weakref) (istype(thing, /datum) && !isnull(potential_weakref) && thing.weak_reference == potential_weakref) diff --git a/code/__SPLURTCODE/DEFINES/mobs.dm b/code/__SPLURTCODE/DEFINES/mobs.dm index c8b92378d8..125f8fe8e5 100644 --- a/code/__SPLURTCODE/DEFINES/mobs.dm +++ b/code/__SPLURTCODE/DEFINES/mobs.dm @@ -2,3 +2,7 @@ #define PLAYER_READY_TO_OBSERVE 2 #define WENDIGO_BODYPART "wendigo" + +// Increase max age +#undef AGE_MAX_INPUT +#define AGE_MAX_INPUT SHORT_REAL_LIMIT // Maximum safe number diff --git a/code/__SPLURTCODE/DEFINES/traits.dm b/code/__SPLURTCODE/DEFINES/traits.dm index fa992cad27..9f0c41e694 100644 --- a/code/__SPLURTCODE/DEFINES/traits.dm +++ b/code/__SPLURTCODE/DEFINES/traits.dm @@ -24,3 +24,6 @@ #define TRAIT_ARACHNID "Arachnid" #define TRAIT_FLUTTER "flutter" + +#define TRAIT_NUDIST "Nudist" + diff --git a/code/__SPLURTCODE/DEFINES/zeros/traits.dm b/code/__SPLURTCODE/DEFINES/zeros/traits.dm index b1d1b3ef64..74a180621d 100644 --- a/code/__SPLURTCODE/DEFINES/zeros/traits.dm +++ b/code/__SPLURTCODE/DEFINES/zeros/traits.dm @@ -7,5 +7,6 @@ #define TRAIT_IN_HEAT "in_heat" #define TRAIT_HEAT_DETECT "heat_detect" #define TRAIT_ILLITERATE "illiterate" +#define TRAIT_HIDE_BACKPACK "hide_backpack" #define TRAIT_DUMB4CUM "dumb4cum" diff --git a/code/_globalvars/lists/loadout_categories.dm b/code/_globalvars/lists/loadout_categories.dm index c27b3c29e3..371e09392b 100644 --- a/code/_globalvars/lists/loadout_categories.dm +++ b/code/_globalvars/lists/loadout_categories.dm @@ -1,5 +1,5 @@ GLOBAL_LIST_INIT(loadout_categories, list( - LOADOUT_CATEGORY_BACKPACK = list(LOADOUT_SUBCATEGORY_BACKPACK_GENERAL, LOADOUT_SUBCATEGORY_BACKPACK_TOYS), + LOADOUT_CATEGORY_BACKPACK = list(LOADOUT_SUBCATEGORY_BACKPACK_GENERAL, LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES, LOADOUT_SUBCATEGORY_BACKPACK_TOYS), LOADOUT_CATEGORY_NECK = list(LOADOUT_SUBCATEGORY_NECK_GENERAL, LOADOUT_SUBCATEGORY_NECK_TIE, LOADOUT_SUBCATEGORY_NECK_SCARVES), LOADOUT_CATEGORY_MASK = LOADOUT_SUBCATEGORIES_NONE, LOADOUT_CATEGORY_HANDS = LOADOUT_SUBCATEGORIES_NONE, diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 0b820fe7e9..3231cd31bc 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -18,6 +18,7 @@ SUBSYSTEM_DEF(statpanels) "Map: [SSmapping.config?.map_name || "Loading..."]", cached ? "Next Map: [cached.map_name]" : null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", + "Game Mode: [GLOB.master_mode]", "Connected Players: [GLOB.clients.len]", " ", "OOC: [GLOB.ooc_allowed ? "Enabled" : "Disabled"]", diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 2ff1e284d0..47efc967ac 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -87,6 +87,7 @@ SUBSYSTEM_DEF(throwing) if(HAS_TRAIT_FROM(thrownthing, TRAIT_SPOOKY_THROW, "revenant")) REMOVE_TRAIT(thrownthing, TRAIT_SPOOKY_THROW, "revenant") SSthrowing.processing -= thrownthing + SSthrowing.currentrun -= thrownthing thrownthing.throwing = null thrownthing = null target = null diff --git a/code/datums/accents.dm b/code/datums/accents.dm index d9e073b729..cfd6e873fa 100644 --- a/code/datums/accents.dm +++ b/code/datums/accents.dm @@ -94,10 +94,9 @@ /datum/accent/dullahan/modify_speech(list/speech_args, datum/source, mob/living/carbon/owner) if(owner) - if(isdullahan(owner)) - var/datum/species/dullahan/D = owner.dna.species - if(isobj(D.myhead.loc)) - var/obj/O = D.myhead.loc - O.say(speech_args[SPEECH_MESSAGE]) + var/datum/component/dullahan/dullahan = owner.GetComponent(/datum/component/dullahan) + if(dullahan) + if(dullahan.dullahan_head) + dullahan.dullahan_head.say(speech_args[SPEECH_MESSAGE]) speech_args[SPEECH_MESSAGE] = "" return speech_args diff --git a/code/datums/action.dm b/code/datums/action.dm index 304aa47baa..b34cafc03f 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -43,8 +43,7 @@ if(owner) Remove(owner) target = null - qdel(button) - button = null + QDEL_NULL(button) return ..() /datum/action/proc/Grant(mob/M) diff --git a/code/datums/components/crafting/recipes/recipes_clothing.dm b/code/datums/components/crafting/recipes/recipes_clothing.dm index 75d00bbfcd..7dbbf01a1d 100644 --- a/code/datums/components/crafting/recipes/recipes_clothing.dm +++ b/code/datums/components/crafting/recipes/recipes_clothing.dm @@ -287,7 +287,7 @@ name = "Durathread Reinforcement Kit" result = /obj/item/armorkit reqs = list(/obj/item/stack/sheet/durathread = 4) - tools = list(/obj/item/stack/sheet/mineral/titanium, TOOL_WIRECUTTER) // tough needle for a tough fabric + tools = list(TOOL_WIRECUTTER) time = 40 category = CAT_CLOTHING diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm new file mode 100644 index 0000000000..973f06a61e --- /dev/null +++ b/code/datums/components/dullahan.dm @@ -0,0 +1,210 @@ +/datum/component/dullahan + var/obj/item/dullahan_head/dullahan_head + +/datum/component/dullahan/Initialize() + . = ..() + + var/mob/living/carbon/human/H = parent + if(!H) + return . + + ADD_TRAIT(H, TRAIT_DULLAHAN, "dullahan_component") + ADD_TRAIT(H, TRAIT_NOHUNGER, "dullahan_component_no_hunger") + ADD_TRAIT(H, TRAIT_NOBREATH, "dullahan_component_no_breath") + + dullahan_head = new(get_turf(H)) + + update_name() + + dullahan_head.owner = H + RegisterSignal(H, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head) + + // make sure the brain can't decay or fall out + var/obj/item/organ/brain/B = H.getorganslot(ORGAN_SLOT_BRAIN) + if(B) + B.zone = "abstract" // it exists in the ethereal plain + B.organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT | ORGAN_VITAL + dullahan_head.B = B + + // the eyes get similar treatment + var/obj/item/organ/eyes/dullahan/new_eyes = new() + var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES) + if(E) + new_eyes.left_eye_color = E.left_eye_color + new_eyes.right_eye_color = E.right_eye_color + E.Remove() + qdel(E) + new_eyes.Insert(H) + + // make sure you handle the tongue correctly, too! + var/obj/item/organ/tongue/T = H.getorganslot(ORGAN_SLOT_TONGUE) + T.Remove() + qdel(T) + + var/obj/item/organ/tongue/dullahan/new_tongue = new() + new_tongue.Insert(H) + + // uh, eyes! + var/obj/item/organ/ears/dullahan_ears = H.getorganslot(ORGAN_SLOT_EARS) + if(dullahan_ears) + dullahan_ears.zone = "abstract" + + // moving the brain's zone means we don't need the head to survive + var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD) + if(head) + head.drop_limb() + qdel(head) + + H.flags_1 &= ~(HEAR_1) + + RegisterSignal(dullahan_head, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner) + + dullahan_head.update_appearance() + +/datum/component/dullahan/proc/update_name(retries = 0) + if(retries > 30) + return FALSE + var/mob/living/carbon/human/H = parent + if(length(H.name)) + dullahan_head.name = "[H.name]'s head" + dullahan_head.desc = "the decapitated head of [H.name]" + return TRUE + addtimer(CALLBACK(src, .proc/update_name, retries + 1), 2 SECONDS) + +/datum/component/dullahan/proc/include_owner(datum/source, list/processing_list, list/hearers) + if(!QDELETED(parent)) + hearers += parent + +/datum/component/dullahan/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs) + excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs. + +/obj/item/organ/tongue/dullahan + zone = "abstract" + initial_accents = list(/datum/accent/dullahan) + organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT + +/obj/item/organ/eyes/dullahan + name = "head vision" + desc = "An abstraction." + actions_types = list(/datum/action/item_action/organ_action/dullahan) + zone = "abstract" + tint = INFINITY // used to switch the vision perspective to the head on species_gain(). + organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT + +/obj/item/dullahan_head + name = "coders lament" + desc = "you shouldn't be reading this" + flags_1 = HEAR_1 + var/mob/living/carbon/human/owner + // this is for keeping track of the overlays because you can't read the actual overlays list as it's a special byond var + var/list/overlays_standing + var/obj/item/organ/brain/B + w_class = WEIGHT_CLASS_BULKY + +/obj/item/dullahan_head/Destroy() + if(owner) + B.Remove() + B.forceMove(get_turf(src)) + owner.gib() + . = ..() + +// update head sprite +/obj/item/dullahan_head/proc/remove_head_overlays() + overlays_standing = list() + cut_overlays() + +/obj/item/dullahan_head/proc/add_head_overlay(var/overlay) + overlays_standing += overlay + add_overlay(overlay) + +/obj/item/dullahan_head/update_appearance() + if(owner && !HAS_TRAIT(owner, TRAIT_HUMAN_NO_RENDER)) + remove_head_overlays() + // to do this without duplicating large amounts of code + // it's best to regenerate the head, then remove it once we have the overlays we want + owner.regenerate_limb(BODY_ZONE_HEAD, TRUE) // don't heal them + owner.cut_overlays() + owner.regenerate_icons(TRUE) // yes i know it's expensive but do you want me to rewrite our entire overlay system, also block recursive calls here by passing in TRUE (it wont go back to call update_appearance this way) + var/obj/item/bodypart/head/head = owner.get_bodypart(BODY_ZONE_HEAD) + if(head) + add_overlay(head.get_limb_icon(FALSE, TRUE, TRUE)) + for(var/overlay in owner.overlays_standing) + if(istype(overlay, /mutable_appearance)) + var/mutable_appearance/mutable = overlay + if(mutable.category == "HEAD") + add_head_overlay(mutable) + else + if(islist(overlay)) + var/list/list_appearances = overlay + for(var/overlay2 in list_appearances) + if(istype(overlay2, /mutable_appearance)) + var/mutable_appearance/mutable = overlay2 + if(mutable.category == "HEAD") + add_head_overlay(mutable) + head.drop_limb() + qdel(head) + +/obj/item/dullahan_head/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs) + excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs. + +/datum/action/item_action/organ_action/dullahan + name = "Toggle Perspective" + desc = "Switch between seeing normally from your head, or blindly from your body." + +/datum/action/item_action/organ_action/dullahan/Trigger() + . = ..() + var/mob/living/carbon/human/H = owner + var/obj/item/organ/eyes/E = owner.getorganslot(ORGAN_SLOT_EYES) + if(E) + if(E.tint) + E.tint = 0 + else + E.tint = INFINITY + + var/datum/component/dullahan/D = H.GetComponent(/datum/component/dullahan) + if(D) + D.update_vision_perspective() + +/datum/component/dullahan/proc/update_vision_perspective() + var/mob/living/carbon/human/H = parent + if(!H) + return . + var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) + if(eyes) + H.update_tint() + if(eyes.tint) + H.reset_perspective(H) + else + H.reset_perspective(dullahan_head) + +/datum/component/dullahan/Destroy() + UnregisterSignal(parent, COMSIG_LIVING_REGENERATE_LIMBS) + dullahan_head.owner = null + qdel(dullahan_head) + REMOVE_TRAIT(parent, TRAIT_DULLAHAN, "dullahan_component") + + // work out what organs to give them based on their species + if(ishuman(parent)) + var/mob/living/carbon/human/H = parent + var/obj/item/organ/eyes/new_eyes = new H.dna.species.mutanteyes() + var/obj/item/organ/brain/new_brain = new H.dna.species.mutant_brain() + var/obj/item/organ/tongue/new_tongue = new H.dna.species.mutanttongue() + var/obj/item/organ/eyes/old_eyes = H.getorganslot(ORGAN_SLOT_EYES) + var/obj/item/organ/brain/old_brain = H.getorganslot(ORGAN_SLOT_BRAIN) + var/obj/item/organ/tongue/old_tongue = H.getorganslot(ORGAN_SLOT_TONGUE) + + H.regenerate_limb(BODY_ZONE_HEAD, TRUE) + H.reset_perspective(H) + + old_brain.Remove(TRUE,TRUE) + QDEL_NULL(old_brain) + new_brain.Insert(H, TRUE, TRUE) + + old_eyes.Remove(TRUE,TRUE) + QDEL_NULL(old_eyes) + new_eyes.Insert(H, TRUE, TRUE) + + old_tongue.Remove(TRUE,TRUE) + QDEL_NULL(old_tongue) + new_tongue.Insert(H, TRUE, TRUE) + . = ..() diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index 9c542b505c..920886cc74 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -34,6 +34,7 @@ RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud) RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/stop_processing) RegisterSignal(parent, COMSIG_VOID_MASK_ACT, .proc/direct_sanity_drain) + RegisterSignal(parent, COMSIG_ENTER_AREA, .proc/update_beauty) if(owner.hud_used) @@ -355,7 +356,7 @@ if(ETHEREAL_CHARGE_OVERLOAD to ETHEREAL_CHARGE_DANGEROUS) add_event(null, "charge", /datum/mood_event/supercharged) -/datum/component/mood/proc/update_beauty(area/A) +/datum/component/mood/proc/update_beauty(datum/source, area/A) if(A.outdoors) //if we're outside, we don't care. clear_event(null, "area_beauty") return FALSE diff --git a/code/datums/dna.dm b/code/datums/dna.dm index b7761922da..0cc033cf2a 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -709,16 +709,13 @@ death() petrify(INFINITY) if(3) - if(prob(90)) - var/obj/item/bodypart/BP = get_bodypart(pick(BODY_ZONE_CHEST,BODY_ZONE_HEAD)) - if(BP) - BP.dismember() - else - unequip_everything() - drop_all_held_items() - gib() + var/obj/item/bodypart/BP = get_bodypart(pick(BODY_ZONE_CHEST,BODY_ZONE_HEAD)) + if(BP) + BP.dismember() else - set_species(/datum/species/dullahan) + unequip_everything() + drop_all_held_items() + gib() /datum/dna/proc/update_body_size(old_size) if(!holder || features["body_size"] == old_size) diff --git a/code/datums/elements/connect_loc.dm b/code/datums/elements/connect_loc.dm new file mode 100644 index 0000000000..fee9072f75 --- /dev/null +++ b/code/datums/elements/connect_loc.dm @@ -0,0 +1,43 @@ +/// This element hooks a signal onto the loc the current object is on. +/// When the object moves, it will unhook the signal and rehook it to the new object. +/datum/element/connect_loc + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + + /// An assoc list of signal -> procpath to register to the loc this object is on. + var/list/connections + +/datum/element/connect_loc/Attach(atom/movable/listener, list/connections) + . = ..() + if (!istype(listener)) + return ELEMENT_INCOMPATIBLE + + src.connections = connections + + RegisterSignal(listener, COMSIG_MOVABLE_MOVED, .proc/on_moved, override = TRUE) + update_signals(listener) + +/datum/element/connect_loc/Detach(atom/movable/listener) + . = ..() + unregister_signals(listener, listener.loc) + UnregisterSignal(listener, COMSIG_MOVABLE_MOVED) + +/datum/element/connect_loc/proc/update_signals(atom/movable/listener) + var/atom/listener_loc = listener.loc + if(isnull(listener_loc)) + return + + for (var/signal in connections) + //override=TRUE because more than one connect_loc element instance tracked object can be on the same loc + listener.RegisterSignal(listener_loc, signal, connections[signal], override=TRUE) + +/datum/element/connect_loc/proc/unregister_signals(datum/listener, atom/old_loc) + if(isnull(old_loc)) + return + + listener.UnregisterSignal(old_loc, connections) + +/datum/element/connect_loc/proc/on_moved(atom/movable/listener, atom/old_loc) + SIGNAL_HANDLER + unregister_signals(listener, old_loc) + update_signals(listener) diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm index b04f55ef0e..104147ebeb 100644 --- a/code/datums/mutable_appearance.dm +++ b/code/datums/mutable_appearance.dm @@ -4,6 +4,9 @@ // Mutable appearances are children of images, just so you know. +/mutable_appearance + var/category // listen i want to store some meta information on mutable appearances don't judge me + /mutable_appearance/New() ..() plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index 3bcca275a5..e2de71d006 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -187,10 +187,13 @@ lose_text = "High-tech gizmos are a scam..." /datum/quirk/trandening/on_spawn() - var/mob/living/carbon/human/H = quirk_holder - var/obj/item/autosurgeon/gloweyes/gloweyes = new(get_turf(H)) - H.equip_to_slot(gloweyes, ITEM_SLOT_BACKPACK) - H.regenerate_icons() + // Get targets + var/obj/item/organ/eyes/old_eyes = quirk_holder.getorganslot(ORGAN_SLOT_EYES) + var/obj/item/organ/eyes/robotic/glow/new_eyes = new + + // Replace eyes + qdel(old_eyes) + new_eyes.Insert(quirk_holder) /datum/quirk/bloodpressure name = "Polycythemia vera" diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm index 106a7e3e96..e5dd6d3e33 100644 --- a/code/datums/traits/neutral.dm +++ b/code/datums/traits/neutral.dm @@ -188,3 +188,12 @@ value = 0 medical_record_text = "Patient should not come into contact with sodium." mob_trait = TRAIT_SALT_SENSITIVE + +/datum/quirk/dullahan + name = "Dullahan" + desc = "Your head is detached from your body." + value = 0 + medical_record_text = "Patient seems to have some kind of spatial link with their decapitated head." + +/datum/quirk/dullahan/post_add() + quirk_holder.AddComponent(/datum/component/dullahan) diff --git a/code/datums/wounds/_scars.dm b/code/datums/wounds/_scars.dm index 3fb6546edb..0edcf65b42 100644 --- a/code/datums/wounds/_scars.dm +++ b/code/datums/wounds/_scars.dm @@ -28,6 +28,8 @@ LAZYREMOVE(limb.scars, src) if(victim) LAZYREMOVE(victim.all_scars, src) + limb = null + victim = null . = ..() /** @@ -45,6 +47,8 @@ qdel(src) return limb = BP + RegisterSignal(limb, COMSIG_PARENT_QDELETING, .proc/limb_gone) + severity = W.severity if(limb.owner) victim = limb.owner @@ -84,6 +88,7 @@ return limb = BP + RegisterSignal(limb, COMSIG_PARENT_QDELETING, .proc/limb_gone) src.severity = severity LAZYADD(limb.scars, src) if(BP.owner) @@ -102,6 +107,10 @@ visibility = 7 return TRUE +/datum/scar/proc/limb_gone() + SIGNAL_HANDLER + qdel(src) + /// 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)) diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index 6cab8818ee..a2c4a70380 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -73,8 +73,6 @@ /// 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 @@ -127,12 +125,13 @@ return victim = L.owner + RegisterSignal(victim, COMSIG_PARENT_QDELETING, .proc/null_victim) 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) + victim.apply_status_effect(status_effect_type, src) SEND_SIGNAL(victim, COMSIG_CARBON_GAIN_WOUND, src, limb) victim.emote("pain") if(!victim.alerts["wound"]) // only one alert is shared between all of the wounds @@ -161,6 +160,14 @@ wound_injury(old_wound) second_wind() +/datum/wound/proc/null_victim() + SIGNAL_HANDLER + victim = null + +/datum/wound/proc/source_died() + SIGNAL_HANDLER + qdel(src) + /// 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 diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index 6a631ab8f4..68740e78ab 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -177,7 +177,7 @@ if(isinsect(victim) || iscatperson(victim) || ismammal(victim) || isdwarf(victim) || ismonkey(victim)) // Yep you can lick monkeys. user.reagents.add_reagent(/datum/reagent/hairball, 2) - else if(ishumanbasic(victim) || isflyperson(victim) || islizard(victim) || isdullahan(victim)) + else if(ishumanbasic(victim) || isflyperson(victim) || islizard(victim) || HAS_TRAIT(victim, TRAIT_DULLAHAN)) user.reagents.add_reagent(/datum/reagent/hairball, 1) if(blood_flow > minimum_flow) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 24b49a3af7..2c34c67c58 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -15,7 +15,10 @@ var/area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED - var/fire = null + ///Do we have an active fire alarm? + var/fire = FALSE + ///How many fire alarm sources do we have? + var/triggered_firealarms = 0 ///Whether there is an atmos alarm in this area var/atmosalm = FALSE var/poweralm = FALSE @@ -443,7 +446,18 @@ GLOBAL_LIST_EMPTY(teleportlocs) START_PROCESSING(SSobj, src) /area/proc/firereset(obj/source) - if (fire) + var/should_reset_alarms = fire + if(source) + if(istype(source, /obj/machinery/firealarm)) + var/obj/machinery/firealarm/alarm = source + if(alarm.triggered) + alarm.triggered = FALSE + triggered_firealarms -= 1 + if(triggered_firealarms > 0) + should_reset_alarms = FALSE + should_reset_alarms = should_reset_alarms & power_environ //No resetting if there's no power + + if (should_reset_alarms) // if there's a source, make sure there's no fire alarms left set_fire_alarm_effects(FALSE) ModifyFiredoors(TRUE) @@ -463,6 +477,18 @@ GLOBAL_LIST_EMPTY(teleportlocs) STOP_PROCESSING(SSobj, src) +///Get rid of any dangling camera refs +/area/proc/clear_camera(obj/machinery/camera/cam) + LAZYREMOVE(cameras, cam) + for (var/mob/living/silicon/aiPlayer as anything in GLOB.silicon_mobs) + aiPlayer.freeCamera(src, cam) + for (var/obj/machinery/computer/station_alert/comp as anything in GLOB.alert_consoles) + comp.freeCamera(src, cam) + for (var/mob/living/simple_animal/drone/drone_on as anything in GLOB.drones_list) + drone_on.freeCamera(src, cam) + for(var/datum/computer_file/program/alarm_monitor/monitor as anything in GLOB.alarmdisplay) + monitor.freeCamera(src, cam) + /area/process() if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds ModifyFiredoors(FALSE) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 7c7e1c56c7..30363e6c01 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -118,6 +118,9 @@ . = ..() + //We add ourselves to this list, best to clear it out + // LAZYCLEARLIST(area_sensitive_contents) + for(var/movable_content in contents) qdel(movable_content) diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index d708af7d7a..c720668a5b 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -38,7 +38,7 @@ icon_state = "[state]" /obj/machinery/bluespace_beacon/process() - if(!Beacon) + if(QDELETED(Beacon)) //Don't move it out of nullspace BACK INTO THE GAME for the love of god var/turf/T = loc Beacon = new(T) Beacon.invisibility = INVISIBILITY_MAXIMUM diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 62b2a6da8d..e1d7737f5c 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -149,10 +149,11 @@ Class Procs: circuit = new circuit(src) circuit.apply_default_parts(src) - if(!speed_process && init_process) - START_PROCESSING(SSmachines, src) - else - START_PROCESSING(SSfastprocess, src) + if(init_process) // Required to prevent non-speed non-init machines from running + if(speed_process) + START_PROCESSING(SSfastprocess, src) + else + START_PROCESSING(SSmachines, src) RegisterSignal(src, COMSIG_ENTER_AREA, .proc/power_change) if (occupant_typecache) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 9a23cc86fb..6e794b8072 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -81,15 +81,15 @@ if(can_use()) toggle_cam(null, 0) //kick anyone viewing out and remove from the camera chunks GLOB.cameranet.cameras -= src + cancelCameraAlarm() if(isarea(myarea)) - LAZYREMOVE(myarea.cameras, src) + myarea.clear_camera(src) QDEL_NULL(assembly) if(bug) - bug.bugged_cameras -= src.c_tag + bug.bugged_cameras -= c_tag if(bug.current == src) bug.current = null bug = null - cancelCameraAlarm() return ..() /obj/machinery/camera/emp_act(severity) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index c925a57b59..cbd3965428 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -351,8 +351,9 @@ log_game("[key_name(usr)] enabled emergency maintenance access.") message_admins("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.") deadchat_broadcast(" enabled emergency maintenance access at [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr, message_type = DEADCHAT_ANNOUNCEMENT) + + if("toggleBought") var/boughtID = params["id"] - for(var/tracked_slave in GLOB.tracked_slaves) var/obj/item/electropack/shockcollar/slave/C = tracked_slave if (REF(C) == boughtID) // Get collar diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 0671100623..df84d5a26a 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -33,31 +33,46 @@ return data -/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source) +/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/home, cameras, obj/source) if(source.z != z) return if(stat & (BROKEN)) return - var/list/L = alarms[class] - for(var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] if (!(source in sources)) sources += source - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if(O && islist(O)) - CL = O - if (CL.len == 1) - C = CL[1] - else if(O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C ? C : O), list(source)) - return 1 + return TRUE + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) + return TRUE + +/obj/machinery/computer/station_alert/proc/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null /obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin) if(stat & (BROKEN)) diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 4526a75f32..0a0a4e08f3 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -3,6 +3,10 @@ var/state var/obj/machinery/embedded_controller/master +/datum/computer/file/embedded_program/Destroy() + master = null + . = ..() + /datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line) if(master) master.post_signal(signal, comm_line) @@ -25,6 +29,11 @@ var/on = TRUE +/obj/machinery/embedded_controller/Destroy() + if(program) + QDEL_NULL(program) + . = ..() + /obj/machinery/embedded_controller/ui_interact(mob/user) . = ..() user.set_machine(src) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index fea3268056..fe756b4022 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -33,8 +33,10 @@ var/detecting = 1 var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone - var/last_alarm = 0 + COOLDOWN_DECLARE(last_alarm) var/area/myarea = null + //Has this firealarm been triggered by its enviroment? + var/triggered = FALSE var/alarm_active = FALSE var/wire_override = FALSE @@ -56,6 +58,7 @@ wires = new /datum/wires/firealarm(src) /obj/machinery/firealarm/Destroy() + myarea.firereset(src) LAZYREMOVE(myarea.firealarms, src) qdel(wires) @@ -112,7 +115,7 @@ . += mutable_appearance(icon, "fire_on") . += emissive_appearance(icon, "fire_on") - if(!panel_open && detecting) //It just looks horrible with the panel open + if(!panel_open && detecting && triggered) //It just looks horrible with the panel open . += "fire_detected" . += mutable_appearance(icon, "fire_detected") . += emissive_appearance(icon, "fire_detected") //Pain @@ -139,14 +142,14 @@ return TRUE /obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume) - if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && (last_alarm+FIREALARM_COOLDOWN < world.time) && !(obj_flags & EMAGGED) && detecting && !stat) + if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && COOLDOWN_FINISHED(src, last_alarm) && !(obj_flags & EMAGGED) && detecting && !stat) alarm() - ..() + return ..() /obj/machinery/firealarm/proc/alarm(mob/user) - if(!is_operational() || (last_alarm+FIREALARM_COOLDOWN > world.time)) + if(!is_operational() || !COOLDOWN_FINISHED(src, last_alarm)) return - last_alarm = world.time + COOLDOWN_START(src, last_alarm, FIREALARM_COOLDOWN) var/area/A = get_base_area(src) A.firealert(src) playsound(loc, 'goon/sound/machinery/FireAlarm.ogg', 75) @@ -159,7 +162,7 @@ if(!is_operational()) return var/area/A = get_base_area(src) - A.firereset(src) + A.firereset() if(user) log_game("[user] reset a fire alarm at [COORD(src)]") diff --git a/code/game/machinery/mechlaunchpad.dm b/code/game/machinery/mechlaunchpad.dm index a2ac2efb3f..c6872edda0 100644 --- a/code/game/machinery/mechlaunchpad.dm +++ b/code/game/machinery/mechlaunchpad.dm @@ -24,6 +24,7 @@ connected_console = null for(var/obj/machinery/computer/mechpad/console in consoles) console.mechpads -= src + GLOB.mechpad_list -= src return ..() /obj/machinery/mechpad/screwdriver_act(mob/user, obj/item/tool) diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index c1dac389bf..c561170af4 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -119,7 +119,7 @@ if(istype(AM, /obj/item)) var/obj/item/bodypart/head/as_head = AM var/obj/item/mmi/as_mmi = AM - if(istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /obj/item/dullahan_relay)) + if(istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /obj/item/dullahan_head)) living_detected = living_detected ? living_detected : AM nom += AM else if(isliving(AM)) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 2f3f3a6c36..432d3a5268 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -71,7 +71,12 @@ /obj/machinery/suit_storage_unit/engine suit_type = /obj/item/clothing/suit/space/hardsuit/engine mask_type = /obj/item/clothing/mask/breath - shoes_type= /obj/item/clothing/shoes/magboots + shoes_type = /obj/item/clothing/shoes/magboots + +/obj/machinery/suit_storage_unit/atmos + suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/watertank/atmos /obj/machinery/suit_storage_unit/enginemod mask_type = /obj/item/clothing/mask/breath @@ -90,7 +95,7 @@ /obj/machinery/suit_storage_unit/ce suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite mask_type = /obj/item/clothing/mask/breath - shoes_type= /obj/item/clothing/shoes/magboots/advance + shoes_type = /obj/item/clothing/shoes/magboots/advance /obj/machinery/suit_storage_unit/cemod mask_type = /obj/item/clothing/mask/breath @@ -231,7 +236,6 @@ /obj/machinery/suit_storage_unit/update_overlays() . = ..() - if(uv) if(uv_super) . += "super" @@ -248,7 +252,7 @@ . += "suit" if(helmet) . += "helm" - if(storage) + if(shoes || storage) . += "storage" else if(occupant) . += "human" @@ -619,15 +623,93 @@ return ..() -/* ref tg-git issue #45036 - screwdriving it open while it's running a decontamination sequence without closing the panel prior to finish - causes the SSU to break due to state_open being set to TRUE at the end, and the panel becoming inaccessible. -*/ -/obj/machinery/suit_storage_unit/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) - if(!(flags_1 & NODECONSTRUCT_1) && I.tool_behaviour == TOOL_SCREWDRIVER && uv) - to_chat(user, "It might not be wise to fiddle with [src] while it's running...") - return TRUE - return ..() +/obj/machinery/suit_storage_unit/ui_state(mob/user) + return GLOB.notcontained_state + +/obj/machinery/suit_storage_unit/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SuitStorageUnit", name) + ui.open() + +/obj/machinery/suit_storage_unit/ui_data() + var/list/data = list() + data["locked"] = locked + data["open"] = state_open + data["safeties"] = safeties + data["uv_active"] = uv + data["uv_super"] = uv_super + if(helmet) + data["helmet"] = helmet.name + else + data["helmet"] = null + if(suit) + data["suit"] = suit.name + else + data["suit"] = null + if(mask) + data["mask"] = mask.name + else + data["mask"] = null + if(shoes) + data["shoes"] = shoes.name + else + data["shoes"] = null + if(storage) + data["storage"] = storage.name + else + data["storage"] = null + if(occupant) + data["occupied"] = TRUE + else + data["occupied"] = FALSE + return data + +/obj/machinery/suit_storage_unit/ui_act(action, params) + if(..() || uv) + return + switch(action) + if("door") + if(state_open) + close_machine() + else + open_machine(0) + if(occupant) + dump_contents() // Dump out contents if someone is in there. + . = TRUE + if("lock") + if(state_open) + return + locked = !locked + . = TRUE + if("uv") + if(occupant && safeties) + return + else if(!helmet && !mask && !suit && !storage && !occupant) + return + else + if(occupant) + var/mob/living/mob_occupant = occupant + to_chat(mob_occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!") + cook() + . = TRUE + if("dispense") + if(!state_open) + return + + var/static/list/valid_items = list("helmet", "suit", "mask", "shoes", "storage") + var/item_name = params["item"] + if(item_name in valid_items) + var/obj/item/I = vars[item_name] + vars[item_name] = null + if(I) + var/mob/living/living_person = usr + if(!istype(living_person)) + return + if(!istype(living_person) || !Adjacent(living_person) || !living_person.put_in_active_hand(I)) + I.forceMove(loc) + . = TRUE + update_icon() /obj/machinery/suit_storage_unit/default_pry_open(obj/item/I)//needs to check if the storage is locked. . = !(state_open || panel_open || is_operational() || locked || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm index f57daac309..a17b4d7d50 100644 --- a/code/game/objects/effects/decals/cleanable/gibs.dm +++ b/code/game/objects/effects/decals/cleanable/gibs.dm @@ -11,6 +11,7 @@ var/body_colors = "#e3ba84" //a default color just in case. var/gibs_reagent_id = /datum/reagent/liquidgibs var/gibs_bloodtype = "A+" + turf_loc_check = FALSE /obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases, list/blood_data) . = ..() @@ -22,6 +23,9 @@ add_blood_DNA(list("Non-human DNA" = gibs_bloodtype), diseases) update_icon() +/obj/effect/decal/cleanable/blood/gibs/replace_decal(obj/effect/decal/cleanable/C) + return FALSE //Never fail to place us + /obj/effect/decal/cleanable/blood/gibs/update_icon() add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY) cut_overlays() diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index 2a3d73e04c..27a8cd45ab 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -725,6 +725,26 @@ def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high) needs_anchored = FALSE +/obj/item/circuitboard/machine/chem_dispenser/fullupgrade + build_path = /obj/machinery/chem_dispenser/fullupgrade + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + +/obj/item/circuitboard/machine/chem_dispenser/mutagensaltpeter + build_path = /obj/machinery/chem_dispenser/mutagensaltpeter + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + /obj/item/circuitboard/machine/chem_dispenser/apothecary name = "Apotechary Chem Dispenser (Machine Board)" build_path = /obj/machinery/chem_dispenser/apothecary @@ -740,7 +760,13 @@ name = "Reagent Synthesizer (Abductor Machine Board)" icon_state = "abductor_mod" build_path = /obj/machinery/chem_dispenser/abductor - def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high) + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) needs_anchored = FALSE /obj/item/circuitboard/machine/chem_heater @@ -1175,11 +1201,31 @@ icon_state = "service" build_path = /obj/machinery/chem_dispenser/drinks +/obj/item/circuitboard/machine/chem_dispenser/drinks/fullupgrade + build_path = /obj/machinery/chem_dispenser/drinks/fullupgrade + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + /obj/item/circuitboard/machine/chem_dispenser/drinks/beer name = "Booze Dispenser (Machine Board)" icon_state = "service" build_path = /obj/machinery/chem_dispenser/drinks/beer +/obj/item/circuitboard/machine/chem_dispenser/drinks/beer/fullupgrade + build_path = /obj/machinery/chem_dispenser/drinks/beer/fullupgrade + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + /obj/item/circuitboard/machine/chem_master/condi name = "CondiMaster 3000 (Machine Board)" icon_state = "service" diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 7b2143cf86..f44860d769 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -42,7 +42,7 @@ var/static/list/runes = list("rune1","rune2","rune3","rune4","rune5","rune6") var/static/list/randoms = list(RANDOM_ANY, RANDOM_RUNE, RANDOM_ORIENTED, RANDOM_NUMBER, RANDOM_GRAFFITI, RANDOM_LETTER, RANDOM_SYMBOL, RANDOM_PUNCTUATION, RANDOM_DRAWING) - var/static/list/graffiti_large_h = list("yiffhell", "secborg", "paint") + var/static/list/graffiti_large_h = list("yiffhell", "furrypride", "secborg", "paint") var/static/list/all_drawables = graffiti + symbols + drawings + oriented + runes + graffiti_large_h diff --git a/code/game/objects/items/devices/beacon.dm b/code/game/objects/items/devices/beacon.dm index 86aa787c3e..cf59551bb8 100644 --- a/code/game/objects/items/devices/beacon.dm +++ b/code/game/objects/items/devices/beacon.dm @@ -17,7 +17,7 @@ icon_state = "beacon-off" /obj/item/beacon/Destroy() - GLOB.teleportbeacons.Remove(src) + GLOB.teleportbeacons -= src return ..() /obj/item/beacon/attack_self(mob/user) @@ -27,7 +27,7 @@ GLOB.teleportbeacons += src else icon_state = "beacon-off" - GLOB.teleportbeacons.Remove(src) + GLOB.teleportbeacons -= src to_chat(user, "You [enabled ? "enable" : "disable"] the beacon.") return diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 9ab6115634..c5e92349c7 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -67,6 +67,9 @@ // when we get this many shards, we get a free bulb. var/shards_required = 4 + // whether it is "bluespace powered" (can be used at a range) + var/bluespace_toggle = FALSE + /obj/item/lightreplacer/New() uses = max_uses / 2 failmsg = "The [name]'s refill light blinks red." @@ -242,7 +245,7 @@ /obj/item/lightreplacer/afterattack(atom/T, mob/U, proximity) . = ..() - if(!proximity) + if(!proximity && !bluespace_toggle) return if(!isturf(T)) return @@ -253,6 +256,18 @@ break used = TRUE if(istype(A, /obj/machinery/light)) + if(!proximity && bluespace_toggle) + // Set variable for target light + var/obj/machinery/light/target = A + + // Check light status before playing effects + if(target.status != LIGHT_OK) + // Display RPED beam + U.Beam(A, icon_state = "rped_upgrade", time = 1 SECONDS) + + // Play RPED sound + playsound(src, 'sound/items/pshoom.ogg', 40, 1) + ReplaceLight(A, U) if(!used) @@ -266,6 +281,15 @@ /obj/item/lightreplacer/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J) return +/obj/item/lightreplacer/blue + name = "bluespace light replacer" + desc = "A modified light replacer that zaps lights into place. Refill with broken or working lightbulbs, or sheets of glass." + icon_state = "lightreplacer_blue" + bluespace_toggle = TRUE + +/obj/item/lightreplacer/blue/emag_act() + return // balancing against longrange explosions + #undef LIGHT_OK #undef LIGHT_EMPTY #undef LIGHT_BROKEN diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 44e812d33c..95e7ddd05d 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -30,6 +30,10 @@ mytape = new starting_tape_type(src) update_icon() +/obj/item/taperecorder/Destroy() + // QDEL_NULL(soundloop) + QDEL_NULL(mytape) + return ..() /obj/item/taperecorder/examine(mob/user) . = ..() diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index 4930f39b31..ca2fdbaeff 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -193,34 +193,31 @@ /obj/item/melee/transforming/energy/sword/saber possible_colors = list("red" = LIGHT_COLOR_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER) - unique_reskin = list("Sword" = "sword0", "Saber" = "esaber0") + unique_reskin = list( + "Sword" = list("icon_state" = "sword0"), + "Saber" = list("icon_state" = "esaber0") + ) var/hacked = FALSE - var/saber = FALSE /obj/item/melee/transforming/energy/sword/saber/transform_weapon(mob/living/user, supress_message_text) . = ..() if(.) - if(active) - if(sword_color) - if(saber) - icon_state = "esaber[sword_color]" - else - icon_state = "sword[sword_color]" - else - if(saber) - icon_state = "esaber0" + switch(current_skin) + if("Saber") + icon_state = "esaber[active ? sword_color : "0"]" + // No skin else - icon_state = "sword0" + icon_state = "sword[active ? sword_color : "0"]" /obj/item/melee/transforming/energy/sword/saber/reskin_obj(mob/M) . = ..() - if(icon_state == "esaber0") - saber = TRUE - if(active) - if(saber) - icon_state = "esaber[sword_color]" - else - icon_state = "sword[sword_color]" + if(!.) + return + switch(current_skin) + if("Sword") + icon_state = "sword[active ? sword_color : "0"]" + if("Saber") + icon_state = "esaber[active ? sword_color : "0"]" /obj/item/melee/transforming/energy/sword/saber/set_sword_color(var/color_forced) if(color_forced) // wow i really do not like this at fucking all holy SHIT diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index 62a3530afe..9b0506855f 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -91,7 +91,7 @@ name = "advanced mop" mopcap = 10 icon_state = "advmop" - item_state = "mop" + item_state = "advmop" lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' force = 6 diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 4ea25bec96..59fe688b69 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -349,24 +349,31 @@ reskin_obj(user) return TRUE +/// Reskins an object according to M's choice, modified to be overridable and supports different icons /obj/proc/reskin_obj(mob/M) if(!LAZYLEN(unique_reskin)) - return + return FALSE var/list/items = list() for(var/reskin_option in unique_reskin) - var/image/item_image = image(icon = src.icon, icon_state = unique_reskin[reskin_option]) + var/image/item_image = image( + icon = unique_reskin[reskin_option]["icon"] ? unique_reskin[reskin_option]["icon"] : icon, + icon_state = unique_reskin[reskin_option]["icon_state"]) items += list("[reskin_option]" = item_image) sortList(items) var/pick = show_radial_menu(M, src, items, custom_check = CALLBACK(src, .proc/check_reskin_menu, M), radius = 38, require_near = TRUE) if(!pick) - return - if(!unique_reskin[pick]) - return + return FALSE + if(!unique_reskin[pick]["icon_state"]) + return FALSE current_skin = pick - icon_state = unique_reskin[pick] + var/has_icon = unique_reskin[pick]["icon"] + if(has_icon) + icon = has_icon + icon_state = unique_reskin[pick]["icon_state"] to_chat(M, "[src] is now skinned as '[pick].'") + return TRUE /** * Checks if we are allowed to interact with a radial menu for reskins diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 46db798c84..650fdf040b 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -139,7 +139,7 @@ /obj/structure/closet/crate/freezer/Destroy() recursive_organ_check(src) - ..() + return ..() /obj/structure/closet/crate/freezer/Initialize(mapload) . = ..() diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index a70d9d4678..ffb48ce633 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -41,6 +41,7 @@ if(new_style) H.hair_style = new_style + H.update_mutant_bodyparts() H.update_hair() /obj/structure/mirror/examine_status(mob/user) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index dc44ac728f..b6be7f1fe1 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -137,6 +137,8 @@ GLOBAL_LIST_EMPTY(station_turfs) requires_activation = FALSE ..() + vis_contents.Cut() + /turf/on_attack_hand(mob/user) user.Move_Pulled(src) diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index b39a181a38..f60e853aed 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -760,6 +760,8 @@ /datum/gas_reaction/hagedorn/react(datum/gas_mixture/air, datum/holder) var/initial_energy = air.thermal_energy() + if(air.get_moles(GAS_QCD)) + return for(var/g in air.get_gases()) air.set_moles(g, 0) var/amount = initial_energy / (air.return_temperature() * GLOB.gas_data.specific_heats[GAS_QCD]) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 66b8277273..90407264ad 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -238,6 +238,8 @@ SSradio.remove_object(src, frequency) qdel(wires) wires = null + var/area/ourarea = get_area(src) + ourarea.atmosalert(FALSE, src) return ..() /obj/machinery/airalarm/examine(mob/user) diff --git a/code/modules/cargo/bounties/science.dm b/code/modules/cargo/bounties/science.dm index ffa608f8fd..4079a6ffbe 100644 --- a/code/modules/cargo/bounties/science.dm +++ b/code/modules/cargo/bounties/science.dm @@ -8,7 +8,7 @@ name = "Trash Bag of Holding" description = "Nanotrasen would make good use of high-capacity trash bags. If you have any, please ship them." reward = 3000 - wanted_types = list(/obj/item/storage/backpack/holding) + wanted_types = list(/obj/item/storage/bag/trash/bluespace) /datum/bounty/item/science/bluespace_syringe name = "Bluespace Syringe" diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index 390f02d419..e7854d47cf 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -40,7 +40,7 @@ /obj/machinery/computer/cargo/Destroy() QDEL_NULL(radio) - ..() + return ..() /obj/machinery/computer/cargo/proc/get_export_categories() . = EXPORT_CARGO diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index fc482e4828..c769ddeb3c 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1004,7 +1004,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Belly Visibility:[features["belly_visibility"]]" dat += "Egg Stuffing:[features["belly_stuffing"] == TRUE ? "Yes" : "No"]" dat += "" - if(pref_species.id == SPECIES_DULLAHAN) + if(all_quirks.Find("Dullahan")) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Neckfire

" @@ -2068,9 +2068,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") if("age") - var/new_age = tgui_input_number(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference", null, AGE_MAX, AGE_MIN) + var/new_age = tgui_input_number(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX_INPUT])", "Character Preference", null, AGE_MAX_INPUT, AGE_MIN) if(new_age) - age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) + age = max(min( round(text2num(new_age)), AGE_MAX_INPUT),AGE_MIN) if("security_records") var/rec = stripped_multiline_input(usr, "Set your security record note section. This should be IC!", "Security Records", html_decode(security_records), MAX_FLAVOR_LEN, TRUE) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 214b6d94b9..4754a87e3c 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -364,6 +364,18 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(length(old_flavor_text) && !length(features["feature_flavor_text"])) features["feature_flavor_text"] = old_flavor_text + // hey what happened to 55 + + // dullahans as a species cease to exist + if(current_version < 56) + var/species_id = S["species"] + if(species_id == SPECIES_DULLAHAN) + S["species"] = SPECIES_HUMAN + if(islist(S["all_quirks"])) + S["all_quirks"] += "Dullahan" + else + S["all_quirks"] = list("Dullahan") + /datum/preferences/proc/load_path(ckey,filename="preferences.sav") if(!ckey) return @@ -465,6 +477,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["preferred_chaos"] >> preferred_chaos S["auto_ooc"] >> auto_ooc S["no_tetris_storage"] >> no_tetris_storage + S["recoil_screenshake"] >> recoil_screenshake // Splurt S["be_victim"] >> be_victim @@ -532,6 +545,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles)) auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc)) no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage)) + recoil_screenshake = sanitize_integer(recoil_screenshake, 0, 800, initial(recoil_screenshake)) key_bindings = sanitize_islist(key_bindings, list()) modless_key_bindings = sanitize_islist(modless_key_bindings, list()) favorite_outfits = SANITIZE_LIST(favorite_outfits) @@ -665,6 +679,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["preferred_chaos"], preferred_chaos) WRITE_FILE(S["auto_ooc"], auto_ooc) WRITE_FILE(S["no_tetris_storage"], no_tetris_storage) + WRITE_FILE(S["recoil_screenshake"], recoil_screenshake) // Splurt WRITE_FILE(S["be_victim"], be_victim) @@ -1069,7 +1084,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car shirt_color = sanitize_hexcolor(shirt_color, 6, FALSE, initial(shirt_color)) socks = sanitize_inlist(socks, GLOB.socks_list) socks_color = sanitize_hexcolor(socks_color, 6, FALSE, initial(socks_color)) - age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) + age = sanitize_integer(age, AGE_MIN, AGE_MAX_INPUT, initial(age)) hair_color = sanitize_hexcolor(hair_color, 6, FALSE) facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE) grad_style = sanitize_inlist(grad_style, GLOB.hair_gradients_list, "None") diff --git a/code/modules/client/verbs/looc.dm b/code/modules/client/verbs/looc.dm index e6e62280e2..eebdcd3e6c 100644 --- a/code/modules/client/verbs/looc.dm +++ b/code/modules/client/verbs/looc.dm @@ -37,12 +37,12 @@ GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC") to_chat(src, "Advertising other servers is not allowed.") log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]") return - if(mob.stat) - to_chat(src, "You cannot use LOOC while unconscious or dead.") - return - if(isdead(mob)) - to_chat(src, "You cannot use LOOC while ghosting.") - return + //if(mob.stat) # Suggestion 3611, add LOOC for unconscious and dead | SPLURT 10.12.2022 + // to_chat(src, "You cannot use LOOC while unconscious or dead.") + // return + //if(isdead(mob)) + // to_chat(src, "You cannot use LOOC while ghosting.") + // return if(HAS_TRAIT(mob, TRAIT_LOOC_MUTE)) to_chat(src, "You cannot use LOOC right now.") return diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 21004a163e..b2a7f91e96 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -27,6 +27,11 @@ if(glass_colour_type && ishuman(user)) . += "Alt-click to toggle its colors." +/obj/item/clothing/glasses/proc/prescribe() + vision_correction = TRUE + name = "prescription [name]" + desc += " These have been fitted with a prescription overlay device, and thus correct some vision deficiencies." + /obj/item/clothing/glasses/visor_toggling() ..() if(visor_vars_to_toggle & VISOR_VISIONFLAGS) @@ -128,10 +133,9 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE glass_colour_type = /datum/client_colour/glass_colour/green -/obj/item/clothing/glasses/night/prescription - name = "prescription night vision goggles" - desc = "NVGs but for those with nearsightedness." - vision_correction = 1 +/obj/item/clothing/glasses/night/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/night/syndicate name = "combat night vision goggles" @@ -233,6 +237,12 @@ icon_state = "circle_glasses" item_state = "circle_glasses" +/obj/item/clothing/glasses/regular/modern + name = "modern glasses" + desc = "A Dork. Co. revamp and/or revision of Nerd. Co.'s classic prescription glasses, with less opaque lenses." + icon_state = "glasses_alt" + item_state = "glasses_alt" + //Here lies green glasses, so ugly they died. RIP /obj/item/clothing/glasses/sunglasses diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index c848dbdfa8..733fc0195c 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -14,6 +14,7 @@ if(G.vision_correction) vision_correction = TRUE name = "prescription [name]" + desc += " These have been made with some form of vision-correcting eyewear, thus making them innately correct some vision deficiencies." return /obj/item/clothing/glasses/hud/equipped(mob/living/carbon/human/user, slot) @@ -55,13 +56,9 @@ hud_type = DATA_HUD_MEDICAL_ADVANCED glass_colour_type = /datum/client_colour/glass_colour/lightblue -/obj/item/clothing/glasses/hud/health/prescription - name = "prescription health scanner HUD" - desc = "A heads-up display, made with a prescription lens, that scans the humans in view and provides accurate data about their health status." - icon_state = "healthhud" - hud_type = DATA_HUD_MEDICAL_ADVANCED - vision_correction = 1 - glass_colour_type = /datum/client_colour/glass_colour/lightblue +/obj/item/clothing/glasses/hud/health/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/health/night name = "night vision health scanner HUD" @@ -88,9 +85,9 @@ tint = 1 glass_colour_type = /datum/client_colour/glass_colour/blue -/obj/item/clothing/glasses/hud/health/sunglasses/prescription - name = "prescription medical HUDSunglasses" - vision_correction = 1 +/obj/item/clothing/glasses/hud/health/sunglasses/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/health/eyepatch name = "eyepatch medHUD" @@ -117,17 +114,13 @@ flash_protect = 1 tint = 1 -/obj/item/clothing/glasses/hud/diagnostic/prescription - name = "prescription diagnostic HUD" - desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits. This one has a prescription lens." - icon_state = "diagnostichud" - hud_type = DATA_HUD_DIAGNOSTIC_BASIC - vision_correction = 1 - glass_colour_type = /datum/client_colour/glass_colour/lightorange +/obj/item/clothing/glasses/hud/diagnostic/prescription/Initialize(mapload) + . = ..() + prescribe() -/obj/item/clothing/glasses/hud/diagnostic/sunglasses/prescription - name = "prescription diagnostic HUDSunglasses" - vision_correction = 1 +/obj/item/clothing/glasses/hud/diagnostic/sunglasses/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/diagnostic/night name = "night vision diagnostic HUD" @@ -155,13 +148,9 @@ hud_type = DATA_HUD_SECURITY_ADVANCED glass_colour_type = /datum/client_colour/glass_colour/red -/obj/item/clothing/glasses/hud/security/prescription - name = "prescription security HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records. This one has a prescription lens so you can see the banana peal that slipped you." - icon_state = "securityhud" - hud_type = DATA_HUD_SECURITY_ADVANCED - vision_correction = 1 - glass_colour_type = /datum/client_colour/glass_colour/red +/obj/item/clothing/glasses/hud/security/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/security/chameleon name = "chameleon security HUD" @@ -200,9 +189,9 @@ desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball." icon_state = "hudpatch" -/obj/item/clothing/glasses/hud/security/sunglasses/prescription - name = "prescription security HUDSunglasses" - vision_correction = 1 +/obj/item/clothing/glasses/hud/security/sunglasses/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/security/night name = "night vision security HUD" diff --git a/code/modules/clothing/glasses/prescription_kit.dm b/code/modules/clothing/glasses/prescription_kit.dm new file mode 100644 index 0000000000..0ad6419622 --- /dev/null +++ b/code/modules/clothing/glasses/prescription_kit.dm @@ -0,0 +1,22 @@ +// don't you love single purpose files? i do too. + +/obj/item/prescription_kit + name = "prescription lens kit" + desc = "A disposable kit containing all the needed tools and parts to develop and apply a self-modifying prescription lens overlay device to any eyewear." + icon = 'icons/obj/device.dmi' + icon_state = "modkit" + +/obj/item/prescription_kit/attack_obj(obj/O, mob/living/user) + if(!istype(O, /obj/item/clothing/glasses)) + return ..() + + if(istype(O, /obj/item/clothing/glasses)) + var/obj/item/clothing/glasses/target_glasses = O + if(target_glasses.vision_correction) + to_chat(user, span_notice("These are already fitted with prescription lenses or otherwise already correct vision!")) + return + playsound(src, 'sound/items/screwdriver.ogg', 50, 1) + user.visible_message(span_notice("[user] fits \the [target_glasses] with a prescription overlay device."), span_notice("You fit \the [target_glasses] with a prescription overlay device.")) + target_glasses.prescribe() + target_glasses.balloon_alert(user, "prescription fitted!") + qdel(src) diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index d3ad2ca4c7..66cc5484e4 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -79,16 +79,20 @@ to_chat(user, "With [src] off of your arms, you feel less ready to punch things.") /obj/item/clothing/gloves/fingerless/pugilist/crafted - unique_reskin = list("Short" = "armwraps", - "Extended" = "armwraps_extended" - ) + unique_reskin = list( + "Short" = list("icon_state" = "armwraps"), + "Extended" = list("icon_state" = "armwraps_extended") + ) /obj/item/clothing/gloves/fingerless/pugilist/crafted/reskin_obj(mob/M) . = ..() - if(icon_state == "armwraps_extended") - item_state = "armwraps_extended" - else + if(!.) return + switch(current_skin) + if("Short") + item_state = "armwraps" + if("Extended") + item_state = "armwraps_extended" /obj/item/clothing/gloves/fingerless/pugilist/chaplain name = "armwraps of unyielding resolve" diff --git a/code/modules/clothing/gloves/tacklers.dm b/code/modules/clothing/gloves/tacklers.dm index 754a72ff0c..b99eca1a61 100644 --- a/code/modules/clothing/gloves/tacklers.dm +++ b/code/modules/clothing/gloves/tacklers.dm @@ -25,6 +25,10 @@ /// See: [/datum/component/tackler/var/skill_mod] var/skill_mod = 1 +/obj/item/clothing/gloves/tackler/Destroy() + tackler = null + return ..() + /obj/item/clothing/gloves/tackler/equipped(mob/user, slot) . = ..() if(!ishuman(user)) @@ -34,12 +38,12 @@ var/mob/living/carbon/human/H = user tackler = H.AddComponent(/datum/component/tackler, stamina_cost=tackle_stam_cost, base_knockdown = base_knockdown, range = tackle_range, speed = tackle_speed, skill_mod = skill_mod, min_distance = min_distance) else - qdel(tackler) // Only wearing it! + QDEL_NULL(tackler) // Only wearing it! /obj/item/clothing/gloves/tackler/dropped(mob/user) . = ..() if(tackler) - qdel(tackler) + QDEL_NULL(tackler) /obj/item/clothing/gloves/tackler/dolphin name = "dolphin gloves" diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index cdf5512fc6..7c1fc6fe3d 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -275,8 +275,10 @@ pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes actions_types = list(/datum/action/item_action/bhop) permeability_coefficient = 0.05 - unique_reskin = list("Explorer" = "miningjet", - "Jackboot" = "jetboots") + unique_reskin = list( + "Explorer" = list("icon_state" = "miningjet"), + "Jackboot" = list("icon_state" = "jetboots") + ) var/jumpdistance = 5 //-1 from to see the actual distance, e.g 4 goes over 3 tiles var/jumpspeed = 3 var/recharging_rate = 60 //default 6 seconds between each dash diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index c13a8bfa66..36795d53b8 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -80,9 +80,10 @@ item_state = "hostrench" flags_inv = 0 strip_delay = 80 - unique_reskin = list("Coat" = "hostrench", - "Cloak" = "trenchcloak" - ) + unique_reskin = list( + "Coat" = list("icon_state" = "hostrench"), + "Cloak" = list("icon_state" = "trenchcloak") + ) /obj/item/clothing/suit/armor/hos/platecarrier name = "plate carrier" diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index e39c48f80f..238b2ec86e 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -111,7 +111,7 @@ /obj/item/clothing/accessory/proc/on_uniform_dropped(obj/item/clothing/under/U, user) return -/obj/item/clothing/accessory/AltClick(mob/user) +/obj/item/clothing/accessory/CtrlClick(mob/user) . = ..() if(istype(user) && user.canUseTopic(src, BE_CLOSE, ismonkey(user))) if(initial(above_suit)) @@ -123,7 +123,7 @@ . = ..() . += "\The [src] can be attached to [istype(src, /obj/item/clothing/accessory/ring) ? "gloves" : "a uniform"]. Alt-click to remove it once attached." if(initial(above_suit)) - . += "\The [src] can be worn above or below your suit. Alt-click to toggle." + . += "\The [src] can be worn above or below your suit. Ctrl-click to toggle." ////////////// //Waistcoats// @@ -603,3 +603,25 @@ obj_flags = UNIQUE_RENAME custom_materials = list(/datum/material/iron=100) resistance_flags = FIRE_PROOF + + +/obj/item/clothing/accessory/pride + name = "pride pin" + desc = "A Nanotrasen Diversity & Inclusion Center-sponsored holographic pin to show off your pride of sexuality or gender identity, reminding the crew of their unwavering commitment to equity, diversity, and inclusion!" + icon_state = "pride" + above_suit = TRUE + obj_flags = UNIQUE_RENAME + unique_reskin = list( + "Rainbow Pride" = list("icon_state" = "pride"), + "Bisexual Pride" = list("icon_state" = "pride_bi"), + "Pansexual Pride" = list("icon_state" = "pride_pan"), + "Asexual Pride" = list("icon_state" = "pride_ace"), + "Non-binary Pride" = list("icon_state" = "pride_enby"), + "Transgender Pride" = list("icon_state" = "pride_trans") + ) + +/obj/item/clothing/accessory/pride/reskin_obj(mob/M) + . = ..() + if(!.) + return + name = "[current_skin] pin" diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm index 0f112a0238..5dd8ad9155 100644 --- a/code/modules/holiday/halloween/jacqueen.dm +++ b/code/modules/holiday/halloween/jacqueen.dm @@ -219,23 +219,11 @@ /mob/living/simple_animal/jacq/proc/treat(mob/living/carbon/C, gender) visible_message("[src] gives off a glowing smile, \"What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.\"") jacqrunes("What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.", C) - var/choices_reward = list("Object - 3 candies", "Potion - 2 candies", "Jacqueline Tracker - 2 candies", "Plushie - 1 candy", "Can I get to know you instead?", "Become a pumpkinhead dullahan (perma) - 4 candies") + var/choices_reward = list("Object - 3 candies", "Potion - 2 candies", "Jacqueline Tracker - 2 candies", "Plushie - 1 candy", "Can I get to know you instead?") var/choice_reward = input(usr, "Trick or Treat?", "Trick or Treat?") in choices_reward //rewards switch(choice_reward) - if("Become a pumpkinhead dullahan (perma) - 4 candies") - if(!take_candies(C, 4)) - visible_message("[src] raises an eyebrown, \"It's 4 candies for that [gender]! Thems the rules!\"") - jacqrunes("It's 4 candies for that [gender]! Thems the rules!", C) - return - visible_message("[src] waves their arms around, \"Off comes your head, a pumpkin taking it's stead!\"") - jacqrunes("Off comes your head, a pumpkin taking it's stead!", C) - C.reagents.add_reagent(/datum/reagent/mutationtoxin/pumpkinhead, 5) - sleep(20) - poof() - return - if("Object - 3 candies") if(!take_candies(C, 3)) visible_message("[src] raises an eyebrown, \"It's 3 candies per trinket [gender]! Thems the rules!\"") @@ -698,12 +686,6 @@ else ..() -/datum/reagent/mutationtoxin/pumpkinhead - name = "Pumpkin head mutation toxin" - race = /datum/species/dullahan/pumpkin - mutationtext = "The pain subsides. You feel your head roll off your shoulders... and you smell pumpkin." - //I couldn't get the replace head sprite with a pumpkin to work so, it is what it is. - /mob/living/simple_animal/jacq/proc/check_candies(mob/living/carbon/C) var/invs = C.get_contents() var/candy_count = 0 diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm index eabae56d7c..155efcd7dc 100644 --- a/code/modules/jobs/access.dm +++ b/code/modules/jobs/access.dm @@ -371,28 +371,9 @@ /proc/get_all_centcom_jobs() return list("VIP Guest","Custodian","Thunderdome Overseer","CentCom Official","Medical Officer","Death Commando","Research Officer","Special Ops Officer","Admiral","CentCom Commander","Emergency Response Team Commander","Security Response Officer","Engineer Response Officer", "Medical Response Officer","CentCom Bartender","Nuclear Waste Expert") //No idea how to modularly edit a global proc -// Used for knowing what is the actual job -// Does not include the original title, could cause recursion -/proc/get_all_alt_titles() - . = list() - for(var/datum/job/job in SSjob.occupations) - for(var/alt_title in job.alt_titles) - if(alt_title == job.title) - continue - .[alt_title] = initial(job.title) - -// Gets the job title, if the job name is an alt title, tries to locate the original title +/// Gets the job title, if the job name is an alt title, locates the original title using a prebuilt cache /proc/GetJobName(jobName) - if(!jobName) - return "Unknown" //Invalid - var/all_alt_titles = get_all_alt_titles() - if(jobName in all_alt_titles) // See if it's an alt title first - return GetJobName(all_alt_titles[jobName]) // Then locate the original job title and return that, that should handle secHUD and whatever else - if(jobName in get_all_job_icons()) //Check if the job has a hud icon - return jobName - if(jobName in get_all_centcom_jobs()) //Return with the NT logo if it is a CentCom job - return "CentCom" - return "Unknown" //Return unknown if none of the above apply + return SSjob.real_job_name[jobName] || "Unknown" /obj/item/proc/get_job_name() //Used in secHUD icon generation var/obj/item/card/id/I = GetID() diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index 324e6c1e99..0a378fadc2 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -63,6 +63,10 @@ if (needs_update) GLOB.lighting_update_lights -= src + top_atom = null + source_atom = null + source_turf = null + pixel_turf = null . = ..() // Yes this doesn't align correctly on anything other than 4 width tabs. diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index dbd3b7e922..794a1cf20a 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -253,8 +253,10 @@ sharpness = SHARP_NONE // use your survival dagger or smth icon_state = "crusher-hands" item_state = "crusher0-fist" - unique_reskin = list("Gauntlets" = "crusher-hands", - "Fingerless" = "crusher-hands-bare") + unique_reskin = list( + "Gauntlets" = list("icon_state" = "crusher-hands"), + "Fingerless" = list("icon_state" = "crusher-hands-bare") + ) detonation_damage = 45 // 60 on wield, compared to normal crusher's 70 backstab_bonus = 70 // 130 on backstab though var/combo_on_anything = FALSE // @admins if you're varediting this you don't get to whine at me diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 3d89377952..0b7ca7adfd 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -121,6 +121,7 @@ icon_state = "furnace" density = TRUE needs_item_input = TRUE + init_process = TRUE var/obj/machinery/mineral/CONSOLE = null var/on = FALSE var/datum/material/selected_material = null diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index eabab35c3b..32b79343e8 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -11,6 +11,7 @@ output_dir = SOUTH req_access = list(ACCESS_MINERAL_STOREROOM) speed_process = TRUE + init_process = TRUE circuit = /obj/item/circuitboard/machine/ore_redemption layer = BELOW_OBJ_LAYER var/points = 0 diff --git a/code/modules/mining/machine_unloading.dm b/code/modules/mining/machine_unloading.dm index b39b0df6ab..16b3b3967f 100644 --- a/code/modules/mining/machine_unloading.dm +++ b/code/modules/mining/machine_unloading.dm @@ -9,6 +9,7 @@ input_dir = WEST output_dir = EAST speed_process = TRUE + init_process = TRUE /obj/machinery/mineral/unloading_machine/proc/horrible_quadratic_monster(var/turf/T) set waitfor = FALSE diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 376865ae66..4c275c266e 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -11,7 +11,7 @@ var/obj/item/card/id/inserted_id var/list/prize_list = list( //if you add something to this, please, for the love of god, sort it by price/type. use tabs and not spaces. new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), - new /datum/data/mining_equipment("50 Point Transfer Card", /obj/item/card/mining_point_card, 50), + new /datum/data/mining_equipment("50 Point Transfer Card", /obj/item/card/mining_point_card/fifty, 50), new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), new /datum/data/mining_equipment("Whiskey", /obj/item/reagent_containers/food/drinks/bottle/whiskey, 100), @@ -27,7 +27,7 @@ new /datum/data/mining_equipment("GAR Meson Scanners", /obj/item/clothing/glasses/meson/gar, 500), new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500), new /datum/data/mining_equipment("Larger Ore Bag", /obj/item/storage/bag/ore/large, 500), - new /datum/data/mining_equipment("Mining Point Transfer Card", /obj/item/card/mining_point_card, 500), + new /datum/data/mining_equipment("500 Point Transfer Card", /obj/item/card/mining_point_card, 500), new /datum/data/mining_equipment("Tracking Implant Kit", /obj/item/storage/box/minertracker, 600), new /datum/data/mining_equipment("Jaunter", /obj/item/wormhole_jaunter, 750), new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/kinetic_crusher, 750), @@ -330,6 +330,9 @@ icon_state = "data_1" var/points = 500 +/obj/item/card/mining_point_card/fifty + points = 50 + /obj/item/card/mining_point_card/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/card/id)) var/obj/item/card/id/id = I diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 7fff5cb71a..7f40744eb0 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -585,18 +585,28 @@ for(var/job in category) var/datum/job/job_datum = SSjob.name_occupations[job] if(job_datum && IsJobUnavailable(job_datum.title, TRUE) == JOB_AVAILABLE) + // Get currently occupied slots + var/num_positions_current = job_datum.current_positions + + // Get total slots that can be occupied + var/num_positions_total = job_datum.total_positions + + // Change to lemniscate for infinite-slot jobs + // This variable should only used to display text! + num_positions_total = (num_positions_total == -1 ? "∞" : num_positions_total) + var/command_bold = "" if(job in GLOB.command_positions) command_bold = " command" - //SKYRAT CHANGES + //Sandstorm changes var/jobline = "[job_datum.title] ([job_datum.current_positions])" if(job_datum in SSjob.prioritized_jobs) jobline = "[jobline]" if(client && client.prefs && client.prefs.alt_titles_preferences[job_datum.title]) jobline = "[jobline]
(as [client.prefs.alt_titles_preferences[job_datum.title]])" - jobline = "[jobline]" + jobline = "[jobline] ([num_positions_current]/[num_positions_total])" dept_dat += jobline - //END OF SKYRAT CHANGES + //End of Sandstorm changes if(!dept_dat.len) dept_dat += "No positions open." dat += jointext(dept_dat, "") diff --git a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm index 08ae75d728..964a171e59 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm @@ -77,6 +77,8 @@ //For soft-restricting markings to species IDs var/list/recommended_species + var/mutable_category // simply do not worry about this value + /datum/sprite_accessory/proc/is_not_visible(var/mob/living/carbon/human/H, var/tauric) //return if the accessory shouldn't be shown return FALSE diff --git a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm index 3972bdc2c3..ba334d2934 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm @@ -48,6 +48,7 @@ icon = 'modular_citadel/icons/mob/xeno_parts_greyscale.dmi' mutant_part_string = "xhead" relevant_layers = list(BODY_ADJ_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/xeno_head/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm b/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm index 460b41f0d9..cd032b6a2a 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm @@ -49,6 +49,7 @@ relevant_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER) mutant_part_string = "mandibles" color_src = 0 + mutable_category = "HEAD" /datum/sprite_accessory/arachnid_mandibles/none name = "None" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/caps.dm b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm index d974672490..5b30591d07 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/caps.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm @@ -2,6 +2,7 @@ icon = 'icons/mob/mutant_bodyparts.dmi' color_src = HAIR relevant_layers = list(BODY_ADJ_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/caps/round name = "Round" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm index 928c4351c3..e03bf5d613 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm @@ -2,6 +2,7 @@ icon = 'icons/mob/mutant_bodyparts.dmi' mutant_part_string = "ears" relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/ears/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm index f3e179e802..06d4c34f72 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm @@ -4,6 +4,7 @@ /datum/sprite_accessory/facial_hair icon = 'icons/mob/hair.dmi' gender = MALE // barf (unless you're a dorf, dorfs dig chix w/ beards :P) + mutable_category = "HEAD" // please make sure they're sorted alphabetically and categorized /datum/sprite_accessory/facial_hair/shaved //this is exempt from the alphabetical sort diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm index e002fa369d..9e868d69c6 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm @@ -3,6 +3,7 @@ ////////////////////// /datum/sprite_accessory/hair icon = 'icons/mob/hair.dmi' // default icon for all hairs + mutable_category = "HEAD" // please make sure they're sorted alphabetically and, where needed, categorized // try to capitalize the names please~ diff --git a/code/modules/mob/dead/new_player/sprite_accessories/horns.dm b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm index 33b513f947..bcc339f332 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/horns.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm @@ -2,6 +2,7 @@ icon = 'icons/mob/mutant_bodyparts.dmi' color_src = HORNCOLOR relevant_layers = list(HORNS_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/horns/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm index 8bda196faa..ec5c6ea792 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm @@ -6,6 +6,11 @@ icon = 'modular_citadel/icons/mob/ipc_screens.dmi' color_src = null relevant_layers = list(BODY_ADJ_LAYER) + mutable_category = "HEAD" + +/datum/sprite_accessory/screen/is_not_visible(var/mob/living/carbon/human/H, var/tauric) + var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) + return (HD == null) // it's not visible if head is null /datum/sprite_accessory/screen/blank name = "Blank" @@ -133,6 +138,7 @@ relevant_layers = list(BODY_ADJ_LAYER) recommended_species = list("ipc") mutant_part_string = "ipc_antenna" + mutable_category = "HEAD" /datum/sprite_accessory/antenna/none name = "None" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm index 40528b11f3..9a5a7a9a8d 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm @@ -2,6 +2,7 @@ icon = 'icons/mob/mutant_bodyparts.dmi' mutant_part_string = "snout" relevant_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/snouts/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm b/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm index 08897ade34..870f4f5ba4 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm @@ -5,6 +5,7 @@ color_src = MUTCOLORS name = "Synthetic Lizard - Snout" icon_state = "synthliz_basic" + mutable_category = "HEAD" /datum/sprite_accessory/snouts/mam_snouts/synthliz/synthliz_under icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi' diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index 7b5bfddbc3..e79bce3314 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -17,10 +17,6 @@ Doesn't work on other aliens/AI.*/ action_icon_state = "spell_default" action_background_icon_state = "bg_alien" -/obj/effect/proc_holder/alien/Initialize(mapload) - . = ..() - action = new(src) - /obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check = FALSE) if(!istype(user)) return TRUE diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 848883a254..5aca20825d 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -964,9 +964,6 @@ /mob/living/carbon/human/species/corporate race = /datum/species/corporate -/mob/living/carbon/human/species/dullahan - race = /datum/species/dullahan - /mob/living/carbon/human/species/felinid race = /datum/species/human/felinid diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index dc6e1b24f8..64b5dfcd9e 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -351,11 +351,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/obj/item/organ/stomach/stomach = C.getorganslot(ORGAN_SLOT_STOMACH) var/obj/item/organ/tail/tail = C.getorganslot(ORGAN_SLOT_TAIL) - var/should_have_brain = TRUE + var/should_have_brain = !(HAS_TRAIT(C, TRAIT_DULLAHAN)) // do not mess with a dullahans brain var/should_have_heart = !(NOBLOOD in species_traits) var/should_have_lungs = ((TRAIT_AUXILIARY_LUNGS in inherent_traits) || !(TRAIT_NOBREATH in inherent_traits)) var/should_have_appendix = !(TRAIT_NOHUNGER in inherent_traits) - var/should_have_eyes = TRUE + var/should_have_eyes = !(HAS_TRAIT(C, TRAIT_DULLAHAN)) // .. or their eyes var/should_have_ears = TRUE var/should_have_tongue = TRUE var/should_have_liver = !(NOLIVER in species_traits) @@ -709,6 +709,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) fhair_file = 'icons/mob/facialhair_extensions.dmi' var/mutable_appearance/facial_overlay = mutable_appearance(fhair_file, fhair_state, -HAIR_LAYER) + facial_overlay.category = "HEAD" if(!forced_colour) if(hair_color) @@ -746,8 +747,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!hair_hidden || dynamic_hair_suffix) var/mutable_appearance/hair_overlay = mutable_appearance(layer = -HAIR_LAYER) + hair_overlay.category = "HEAD" var/mutable_appearance/gradient_overlay = mutable_appearance(layer = -HAIR_LAYER) - if(!hair_hidden && !H.getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain + gradient_overlay.category = "HEAD" + if(!hair_hidden && !H.getorgan(/obj/item/organ/brain) && !H.GetComponent(/datum/component/dullahan)) //Applies the debrained overlay if there is no brain (ignore if they are dullahan) if(!(NOBLOOD in species_traits)) hair_overlay.icon = 'icons/mob/human_parts.dmi' hair_overlay.icon_state = "debrained" @@ -812,7 +815,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.apply_overlay(HAIR_LAYER) -/datum/species/proc/handle_body(mob/living/carbon/human/H) +/datum/species/proc/handle_body(mob/living/carbon/human/H, block_recursive_calls = FALSE) H.remove_overlay(BODY_LAYER) var/list/standing = list() @@ -823,6 +826,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) // lipstick if(H.lip_style && (LIPS in species_traits)) var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/lips.dmi', "lips_[H.lip_style]", -BODY_LAYER) + lip_overlay.category = "HEAD" lip_overlay.color = H.lip_color if(OFFSET_LIPS in H.dna.species.offset_features) @@ -833,7 +837,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) // eyes if(!(NOEYES in species_traits)) - var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES) + var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES) || HAS_TRAIT(H, TRAIT_DULLAHAN) // if they are a dullahan just assume eyes exist if(!has_eyes) standing += mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER) else @@ -844,6 +848,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) right_state = "[eye_type]_right_eye" var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER) var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER) + left_eye.category = "HEAD" + right_eye.category = "HEAD" if((EYECOLOR in species_traits) && has_eyes) left_eye.color = "#[H.left_eye_color]" right_eye.color = "#[H.right_eye_color]" @@ -912,9 +918,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.overlays_standing[BODY_LAYER] = standing H.apply_overlay(BODY_LAYER) - handle_mutant_bodyparts(H) + handle_mutant_bodyparts(H, null, block_recursive_calls) -/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour) +/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour, block_recursive_calls = FALSE) var/list/bodyparts_to_add = mutant_bodyparts.Copy() H.remove_overlay(BODY_BEHIND_LAYER) @@ -1040,6 +1046,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) for(var/bodypart in relevant_layers[layer]) var/datum/sprite_accessory/S = bodypart var/mutable_appearance/accessory_overlay = mutable_appearance(S.icon, layer = -layernum) + accessory_overlay.category = S.mutable_category bodypart = S.mutant_part_string || dna_feature_as_text_string[S] if(S.gender_specific) @@ -1144,6 +1151,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(S.extra) //apply the extra overlay, if there is one var/mutable_appearance/extra_accessory_overlay = mutable_appearance(S.icon, layer = -layernum) + extra_accessory_overlay.category = S.mutable_category if(S.gender_specific) extra_accessory_overlay.icon_state = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]" else @@ -1190,6 +1198,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(S.extra2) //apply the extra overlay, if there is one var/mutable_appearance/extra2_accessory_overlay = mutable_appearance(S.icon, layer = -layernum) + extra2_accessory_overlay.category = S.mutable_category if(S.gender_specific) extra2_accessory_overlay.icon_state = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]" else @@ -1237,6 +1246,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.apply_overlay(BODY_FRONT_LAYER) H.apply_overlay(HORNS_LAYER) + if(!block_recursive_calls) + var/datum/component/dullahan/D = H.GetComponent(/datum/component/dullahan) + if(D && D.dullahan_head) + D.dullahan_head.update_appearance() + /* * Equip the outfit required for life. Replaces items currently worn. */ diff --git a/code/modules/mob/living/carbon/human/species_types/arachnid.dm b/code/modules/mob/living/carbon/human/species_types/arachnid.dm index 7495e2500e..6dc19d928a 100644 --- a/code/modules/mob/living/carbon/human/species_types/arachnid.dm +++ b/code/modules/mob/living/carbon/human/species_types/arachnid.dm @@ -7,7 +7,7 @@ species_traits = list(LIPS, NOEYES, NO_UNDERWEAR, HAS_FLESH, HAS_BONE) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG mutant_bodyparts = list("arachnid_legs" = "Plain", "arachnid_spinneret" = "Plain", "arachnid_mandibles" = "Plain") - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' meat = /obj/item/reagent_containers/food/snacks/meat/slab/spider 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 761274f255..7f9d3f40de 100644 --- a/code/modules/mob/living/carbon/human/species_types/bugmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/bugmen.dm @@ -7,7 +7,7 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "insect_wings" = "None", "insect_fluff" = "None", "mam_snouts" = "None", "taur" = "None", "insect_markings" = "None", "mam_body_markings" = list()) - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/insect diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm deleted file mode 100644 index 8bc39e43da..0000000000 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ /dev/null @@ -1,165 +0,0 @@ -/datum/species/dullahan - name = "Dullahan" - id = SPECIES_DULLAHAN - default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE) - inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOTHIRST,TRAIT_NOBREATH) - mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "deco_wings" = "None") - use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM - mutant_brain = /obj/item/organ/brain/dullahan - mutanteyes = /obj/item/organ/eyes/dullahan - mutanttongue = /obj/item/organ/tongue/dullahan - mutantears = /obj/item/organ/ears/dullahan - blacklisted = TRUE - limbs_id = SPECIES_HUMAN - skinned_type = /obj/item/stack/sheet/animalhide/human - has_field_of_vision = FALSE //Too much of a trouble, their vision is already bound to their severed head. - species_category = SPECIES_CATEGORY_UNDEAD - var/pumpkin = FALSE - wings_icons = SPECIES_WINGS_SKELETAL //seems suitable for an undead. - - var/obj/item/dullahan_relay/myhead - -/datum/species/dullahan/pumpkin - name = "Pumpkin Head Dullahan" - id = "pumpkindullahan" - pumpkin = TRUE - -/datum/species/dullahan/check_roundstart_eligible() - if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) - return TRUE - return ..() - -/datum/species/dullahan/on_species_gain(mob/living/carbon/human/H, datum/species/old_species) - . = ..() - H.flags_1 &= ~(HEAR_1) - var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD) - if(head) - if(pumpkin)//Pumpkinhead! - head.animal_origin = 100 - head.icon = 'icons/obj/clothing/hats.dmi' - head.icon_state = "hardhat1_pumpkin_j" - head.custom_head = TRUE - head.drop_limb() - if(!QDELETED(head)) //drop_limb() deletes the limb if it's no drop location and dummy humans used for rendering icons are located in nullspace. Do the math. - head.throwforce = 25 - myhead = new /obj/item/dullahan_relay (head, H) - H.put_in_hands(head) - var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES) - for(var/datum/action/item_action/organ_action/OA in E.actions) - OA.Trigger() - -/datum/species/dullahan/on_species_loss(mob/living/carbon/human/H) - H.flags_1 |= HEAR_1 - H.reset_perspective(H) - if(myhead) - var/obj/item/dullahan_relay/DR = myhead - myhead = null - DR.owner = null - qdel(DR) - H.regenerate_limb(BODY_ZONE_HEAD,FALSE) - ..() - -/datum/species/dullahan/spec_life(mob/living/carbon/human/H) - if(QDELETED(myhead)) - myhead = null - H.gib() - var/obj/item/bodypart/head/head2 = H.get_bodypart(BODY_ZONE_HEAD) - if(head2) - myhead = null - H.gib() - -/datum/species/dullahan/proc/update_vision_perspective(mob/living/carbon/human/H) - var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) - if(eyes) - H.update_tint() - if(eyes.tint) - H.reset_perspective(H) - else - H.reset_perspective(myhead) - -/obj/item/organ/brain/dullahan - decoy_override = TRUE - organ_flags = ORGAN_NO_SPOIL//Do not decay - -/obj/item/organ/tongue/dullahan - zone = "abstract" - accents = list(/datum/accent/dullahan) - -/obj/item/organ/ears/dullahan - zone = "abstract" - -/obj/item/organ/eyes/dullahan - name = "head vision" - desc = "An abstraction." - actions_types = list(/datum/action/item_action/organ_action/dullahan) - zone = "abstract" - tint = INFINITY // used to switch the vision perspective to the head on species_gain(). - -/datum/action/item_action/organ_action/dullahan - name = "Toggle Perspective" - desc = "Switch between seeing normally from your head, or blindly from your body." - -/datum/action/item_action/organ_action/dullahan/Trigger() - . = ..() - var/obj/item/organ/eyes/dullahan/DE = target - if(DE.tint) - DE.tint = 0 - else - DE.tint = INFINITY - - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - if(isdullahan(H)) - var/datum/species/dullahan/D = H.dna.species - D.update_vision_perspective(H) - -/obj/item/dullahan_relay - name = "dullahan relay" - var/mob/living/owner - flags_1 = HEAR_1 - -/obj/item/dullahan_relay/Initialize(mapload, mob/living/carbon/human/new_owner) - . = ..() - if(!new_owner) - return INITIALIZE_HINT_QDEL - owner = new_owner - START_PROCESSING(SSobj, src) - RegisterSignal(owner, COMSIG_MOB_CLICKED_SHIFT_ON, .proc/examinate_check) - RegisterSignal(src, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner) - RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head) - RegisterSignal(owner, COMSIG_LIVING_REVIVE, .proc/retrieve_head) - -/obj/item/dullahan_relay/proc/examinate_check(mob/source, atom/target) - if(source.client.eye == src) - return COMPONENT_ALLOW_EXAMINATE - -/obj/item/dullahan_relay/proc/include_owner(datum/source, list/processing_list, list/hearers) - if(!QDELETED(owner)) - hearers += owner - -/obj/item/dullahan_relay/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs) - excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs. - -//Retrieving the owner's head for better ahealing. -/obj/item/dullahan_relay/proc/retrieve_head(datum/source, full_heal, admin_revive) - if(admin_revive) - var/obj/item/bodypart/head/H = loc - var/turf/T = get_turf(owner) - if(H && istype(H) && T && !(H in owner.GetAllContents())) - H.forceMove(T) - -/obj/item/dullahan_relay/process() - if(!istype(loc, /obj/item/bodypart/head) || QDELETED(owner)) - . = PROCESS_KILL - qdel(src) - -/obj/item/dullahan_relay/Destroy() - if(!QDELETED(owner)) - var/mob/living/carbon/human/H = owner - if(isdullahan(H)) - var/datum/species/dullahan/D = H.dna.species - D.myhead = null - owner.gib() - owner = null - ..() 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 d4a8150c29..01f82cbac3 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -424,7 +424,7 @@ coldmod = 3 heatmod = 1 burnmod = 1 - + balance_point_values = TRUE allowed_limb_ids = list(SPECIES_SLIME,SPECIES_STARGAZER,SPECIES_SLIME_LUMI) ///////////////////////////////////LUMINESCENTS////////////////////////////////////////// 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 e3f7b700dc..81a46cbf66 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -13,7 +13,7 @@ mutant_bodyparts = list("mcolor" = "0F0", "mcolor2" = "0F0", "mcolor3" = "0F0", "tail_lizard" = "Smooth", "mam_snouts" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "mam_body_markings" = list(), "legs" = "Digitigrade", "taur" = "None", "deco_wings" = "None") - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index a985ca85df..11ca51c74c 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -27,6 +27,7 @@ wings_icons = SPECIES_WINGS_SKELETAL ass_image = 'icons/ass/assplasma.png' + balance_point_values = TRUE blacklisted_quirks = list(/datum/quirk/paper_skin) /datum/species/plasmaman/spec_life(mob/living/carbon/human/H) 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 326f23fa1f..996a4e742a 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -4,7 +4,7 @@ id = SPECIES_POD default_color = "59CE00" species_traits = list(MUTCOLORS,EYECOLOR,CAN_SCAR,HAS_FLESH,HAS_BONE) - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slice.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' burnmod = 1.25 diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index cc8025d730..6189a268ca 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -17,6 +17,7 @@ species_category = SPECIES_CATEGORY_SKELETON //they have their own category that's disassociated from undead, paired with plasmapeople wings_icons = SPECIES_WINGS_SKELETAL + balance_point_values = TRUE blacklisted_quirks = list(/datum/quirk/paper_skin) /datum/species/skeleton/New() @@ -36,6 +37,7 @@ id = SPECIES_SKELETON_SPACE limbs_id = SPECIES_SKELETON blacklisted = 1 + balance_point_values = FALSE inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_NOTHIRST,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT, TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER) /datum/species/skeleton/space/check_roundstart_eligible() diff --git a/code/modules/mob/living/carbon/human/species_types/xeno.dm b/code/modules/mob/living/carbon/human/species_types/xeno.dm index cd3ba8d5cc..3d710988e5 100644 --- a/code/modules/mob/living/carbon/human/species_types/xeno.dm +++ b/code/modules/mob/living/carbon/human/species_types/xeno.dm @@ -6,7 +6,7 @@ default_color = "00FF00" species_traits = list(MUTCOLORS,EYECOLOR,LIPS,CAN_SCAR,HAS_FLESH,HAS_BONE) mutant_bodyparts = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard", "mam_body_markings" = list(),"mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None", "legs" = "Digitigrade","deco_wings"= "None") - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 4f00b51e97..ad1ac131e7 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -58,14 +58,14 @@ There are several things that need to be remembered: dna.species.handle_hair(src) //used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body. -/mob/living/carbon/human/proc/update_mutant_bodyparts() +/mob/living/carbon/human/proc/update_mutant_bodyparts(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) - dna.species.handle_mutant_bodyparts(src) + dna.species.handle_mutant_bodyparts(src, null, block_recursive_calls) -/mob/living/carbon/human/update_body(update_genitals = FALSE) +/mob/living/carbon/human/update_body(update_genitals = FALSE, block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(BODY_LAYER) - dna.species.handle_body(src) + dna.species.handle_body(src, block_recursive_calls) ..() if(update_genitals) update_genitals() @@ -75,17 +75,17 @@ There are several things that need to be remembered: /* --------------------------------------- */ //For legacy support. -/mob/living/carbon/human/regenerate_icons() +/mob/living/carbon/human/regenerate_icons(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) if(!..()) icon_render_key = null //invalidate bodyparts cache - update_body(TRUE) + update_body(TRUE, block_recursive_calls) update_hair() - update_inv_w_uniform() + update_inv_w_uniform(block_recursive_calls) // Sandstorm edit - update_inv_w_underwear() - update_inv_w_socks() - update_inv_w_shirt() + update_inv_w_underwear(block_recursive_calls) + update_inv_w_socks(block_recursive_calls) + update_inv_w_shirt(block_recursive_calls) update_inv_ears_extra() update_inv_wrists() // @@ -95,11 +95,11 @@ There are several things that need to be remembered: update_inv_ears() update_inv_shoes() update_inv_s_store() - update_inv_wear_mask() - update_inv_head() + update_inv_wear_mask(block_recursive_calls) + update_inv_head(block_recursive_calls) update_inv_belt() update_inv_back() - update_inv_wear_suit() + update_inv_wear_suit(block_recursive_calls) update_inv_pockets() update_inv_neck() update_transform() @@ -130,7 +130,7 @@ There are several things that need to be remembered: apply_overlay(ANTAG_LAYER) -/mob/living/carbon/human/update_inv_w_uniform() +/mob/living/carbon/human/update_inv_w_uniform(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(UNIFORM_LAYER) @@ -187,10 +187,10 @@ There are several things that need to be remembered: //SPLURT EDIT END apply_overlay(UNIFORM_LAYER) - update_mutant_bodyparts() + update_mutant_bodyparts(block_recursive_calls) // Sandstorm edit -/mob/living/carbon/human/update_inv_w_underwear() +/mob/living/carbon/human/update_inv_w_underwear(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(UNDERWEAR_LAYER) @@ -235,9 +235,9 @@ There are several things that need to be remembered: overlays_standing[UNDERWEAR_LAYER] = underwear_overlay apply_overlay(UNDERWEAR_LAYER) - update_mutant_bodyparts() + update_mutant_bodyparts(block_recursive_calls) -/mob/living/carbon/human/update_inv_w_socks() +/mob/living/carbon/human/update_inv_w_socks(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(SOCKS_LAYER) @@ -282,9 +282,9 @@ There are several things that need to be remembered: overlays_standing[SOCKS_LAYER] = underwear_overlay apply_overlay(SOCKS_LAYER) - update_mutant_bodyparts() + update_mutant_bodyparts(block_recursive_calls) -/mob/living/carbon/human/update_inv_w_shirt() +/mob/living/carbon/human/update_inv_w_shirt(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(SHIRT_LAYER) @@ -329,7 +329,7 @@ There are several things that need to be remembered: overlays_standing[SHIRT_LAYER] = underwear_overlay apply_overlay(SHIRT_LAYER) - update_mutant_bodyparts() + update_mutant_bodyparts(block_recursive_calls) // /mob/living/carbon/human/update_inv_wear_id() @@ -566,7 +566,7 @@ There are several things that need to be remembered: overlays_standing[SUIT_STORE_LAYER] = s_store_overlay apply_overlay(SUIT_STORE_LAYER) -/mob/living/carbon/human/update_inv_head() +/mob/living/carbon/human/update_inv_head(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(HEAD_LAYER) @@ -604,7 +604,7 @@ There are several things that need to be remembered: head_overlay.pixel_y += dna.species.offset_features[OFFSET_HEAD][2] overlays_standing[HEAD_LAYER] = head_overlay apply_overlay(HEAD_LAYER) - update_mutant_bodyparts() + update_mutant_bodyparts(block_recursive_calls) /mob/living/carbon/human/update_inv_belt() if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) @@ -628,7 +628,7 @@ There are several things that need to be remembered: overlays_standing[BELT_LAYER] = belt_overlay apply_overlay(BELT_LAYER) -/mob/living/carbon/human/update_inv_wear_suit() +/mob/living/carbon/human/update_inv_wear_suit(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(SUIT_LAYER) @@ -688,7 +688,7 @@ There are several things that need to be remembered: suit_overlay = center_image(suit_overlay, dimension_x, dimension_y) overlays_standing[SUIT_LAYER] = suit_overlay update_hair() - update_mutant_bodyparts() + update_mutant_bodyparts(block_recursive_calls) apply_overlay(SUIT_LAYER) @@ -715,7 +715,7 @@ There are several things that need to be remembered: update_observer_view(r_store) -/mob/living/carbon/human/update_inv_wear_mask() +/mob/living/carbon/human/update_inv_wear_mask(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(FACEMASK_LAYER) @@ -754,7 +754,7 @@ There are several things that need to be remembered: mask_overlay.pixel_y += dna.species.offset_features[OFFSET_FACEMASK][2] overlays_standing[FACEMASK_LAYER] = mask_overlay apply_overlay(FACEMASK_LAYER) - update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout + update_mutant_bodyparts(block_recursive_calls) //e.g. upgate needed because mask now hides lizard snout /mob/living/carbon/human/update_inv_back() if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) @@ -1008,7 +1008,7 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if // eyes if(!(NOEYES in dna.species.species_traits)) var/has_eyes = getorganslot(ORGAN_SLOT_EYES) - if(!has_eyes) + if(!has_eyes && !HAS_TRAIT(src, TRAIT_DULLAHAN)) add_overlay(mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER)) else var/left_state = DEFAULT_LEFT_EYE_STATE @@ -1020,6 +1020,8 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if right_state = eye_type + "_right_eye" var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER) var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER) + left_eye.category = "HEAD" + right_eye.category = "HEAD" if((EYECOLOR in dna.species.species_traits) && has_eyes) left_eye.color = "#" + left_eye_color right_eye.color = "#" + right_eye_color diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 5ba5f2431d..08098b818f 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -511,43 +511,61 @@ call_bot_cooldown = 0 -/mob/living/silicon/ai/triggerAlarm(class, area/A, O, obj/alarmsource) - if(alarmsource.z != z) +/mob/living/silicon/ai/triggerAlarm(class, area/home, cameras, obj/source) + if(source.z != z) return - var/list/L = alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] - if (!(alarmsource in sources)) - sources += alarmsource - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if (O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if (O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C) ? C : O, list(alarmsource)) - if (O) - if (C && C.can_use()) - queueAlarm("--- [class] alarm detected in [A.name]! ([C.c_tag])", class) - else if (CL && CL.len) + if (!(source in sources)) + sources += source + return TRUE + + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) + + if (cameras) + if (cam?.can_use()) + queueAlarm("--- [class] alarm detected in [home.name]! ([cam.c_tag])", class) + else if (our_cams?.len) var/foo = 0 var/dat2 = "" - for (var/obj/machinery/camera/I in CL) + for (var/obj/machinery/camera/I in our_cams) dat2 += text("[][]", (!foo) ? "" : " | ", I.c_tag) //I'm not fixing this shit... foo = 1 - queueAlarm(text ("--- [] alarm detected in []! ([])", class, A.name, dat2), class) + queueAlarm(text ("--- [] alarm detected in []! ([])", class, home.name, dat2), class) else - queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class) + queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, home.name), class) else - queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class) - if (viewalerts) ai_alerts() + queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, home.name), class) + if (viewalerts) + ai_alerts() return 1 +/mob/living/silicon/ai/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null + /mob/living/silicon/ai/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] var/cleared = 0 diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index d73f738bb5..b5b142604a 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -263,31 +263,47 @@ /mob/living/silicon/robot/restrained(ignore_grab) . = 0 -/mob/living/silicon/robot/triggerAlarm(class, area/A, O, obj/alarmsource) - if(alarmsource.z != z) +/mob/living/silicon/robot/triggerAlarm(class, area/home, cameras, obj/source) + if(source.z != z) return if(stat == DEAD) return 1 - var/list/L = alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] - if (!(alarmsource in sources)) - sources += alarmsource + if (!(source in sources)) + sources += source return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if (O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if (O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C) ? C : O, list(alarmsource)) - queueAlarm(text("--- [class] alarm detected in [A.name]!"), class) + + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) + queueAlarm(text("--- [class] alarm detected in [home.name]!"), class) return TRUE +/mob/living/silicon/robot/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null + /mob/living/silicon/robot/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] var/cleared = 0 diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 3b89413271..be9ea03e6e 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -86,6 +86,9 @@ /mob/living/silicon/proc/cancelAlarm() return +/mob/living/silicon/proc/freeCamera() + return + /mob/living/silicon/proc/triggerAlarm() return diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 203ac5f846..1320c13085 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -194,9 +194,9 @@ GLOB.bots_list -= src if(paicard) ejectpai() - qdel(Radio) - qdel(access_card) - qdel(bot_core) + QDEL_NULL(Radio) + QDEL_NULL(access_card) + QDEL_NULL(bot_core) return ..() /mob/living/simple_animal/bot/bee_friendly() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index 003994e34f..62d1116300 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -235,20 +235,26 @@ adjustBruteLoss(heavy_emp_damage) to_chat(src, "HeAV% DA%^MMA+G TO I/O CIR!%UUT!") -/mob/living/simple_animal/drone/proc/triggerAlarm(class, area/A, O, obj/alarmsource) - if(alarmsource.z != z) +/mob/living/simple_animal/drone/proc/triggerAlarm(class, area/home, cameras, obj/source) + if(source.z != z) return - if(stat != DEAD) - var/list/L = src.alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] - var/list/sources = alarm[2] - if (!(alarmsource in sources)) - sources += alarmsource - return - L[A.name] = list(A, list(alarmsource)) - to_chat(src, "--- [class] alarm detected in [A.name]!") + if(stat == DEAD) + return + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] + var/list/sources = alarm[3] + if (!(source in sources)) + sources += source + return TRUE + + our_sort[home.name] = list(home, list(source)) + to_chat(src, "--- [class] alarm detected in [home.name]!") + +///This isn't currently needed since drones do jack shit with cameras. I hate this code so much +/mob/living/simple_animal/drone/proc/freeCamera(area/home, obj/machinery/camera/cam) + return /mob/living/simple_animal/drone/proc/cancelAlarm(class, area/A, obj/origin) if(stat != DEAD) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index 43461320a3..3369588915 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -175,9 +175,6 @@ Difficulty: Medium . = ..() if(. && target && !targets_the_same) wander = TRUE - if(HAS_TRAIT(target, TRAIT_CURSED_BLOOD)) - say(pick("Hunter, you must accept your death, be freed from the night.","The night, and the dream, were long...","Beasts all over the shop... You'll be one of them, sooner or later...","The night blocks all sight...")) - /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/dash_attack() INVOKE_ASYNC(src, .proc/dash, target) diff --git a/code/modules/mob/mob_lists.dm b/code/modules/mob/mob_lists.dm index 14f519ec30..bd47d511e1 100644 --- a/code/modules/mob/mob_lists.dm +++ b/code/modules/mob/mob_lists.dm @@ -10,6 +10,8 @@ ///Adds the mob reference to the list of all mobs alive. If mob is cliented, it adds it to the list of all living player-mobs. /mob/proc/add_to_alive_mob_list() + if(QDELETED(src)) + return GLOB.alive_mob_list |= src if(client) add_to_current_living_players() @@ -23,6 +25,8 @@ ///Adds the mob reference to the list of all the dead mobs. If mob is cliented, it adds it to the list of all dead player-mobs. /mob/proc/add_to_dead_mob_list() + if(QDELETED(src)) + return GLOB.dead_mob_list |= src if(client) add_to_current_dead_players() diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm index 646d9892ba..80c0c4dfa8 100644 --- a/code/modules/modular_computers/file_system/programs/alarm.dm +++ b/code/modules/modular_computers/file_system/programs/alarm.dm @@ -36,35 +36,49 @@ return data -/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/A, O, obj/source) +/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/home, cameras, obj/source) if(is_station_level(source.z)) - if(!(A.type in GLOB.the_station_areas)) + if(!(home.type in GLOB.the_station_areas)) return - else if(!is_mining_level(source.z) || istype(A, /area/ruin)) + else if(!is_mining_level(source.z) || istype(home, /area/ruin)) return - var/list/L = alarms[class] - for(var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] if (!(source in sources)) sources += source - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if(O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if(O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C ? C : O), list(source)) + return TRUE + + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) update_alarm_display() + return TRUE - return 1 - +/datum/computer_file/program/alarm_monitor/proc/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null /datum/computer_file/program/alarm_monitor/proc/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 0bd91c5f35..19a6c9e832 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -105,12 +105,13 @@ custom_materials = list(/datum/material/gold = 750) sharpness = SHARP_EDGED resistance_flags = FIRE_PROOF - unique_reskin = list("Oak" = "pen-fountain-o", - "Gold" = "pen-fountain-g", - "Rosewood" = "pen-fountain-r", - "Black and Silver" = "pen-fountain-b", - "Command Blue" = "pen-fountain-cb" - ) + unique_reskin = list( + "Oak" = list("icon_state" = "pen-fountain-o"), + "Gold" = list("icon_state" = "pen-fountain-g"), + "Rosewood" = list("icon_state" = "pen-fountain-r"), + "Black and Silver" = list("icon_state" = "pen-fountain-b"), + "Command Blue" = list("icon_state" = "pen-fountain-cb") + ) embedding = list("embed_chance" = 75) /obj/item/pen/fountain/captain/Initialize(mapload) @@ -118,9 +119,10 @@ AddComponent(/datum/component/butchering, 200, 115) //the pen is mightier than the sword /obj/item/pen/fountain/captain/reskin_obj(mob/M) - ..() - if(current_skin) - desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp." + . = ..() + if(!.) + return + desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp." /obj/item/pen/attack_self(mob/living/carbon/user) var/deg = input(user, "What angle would you like to rotate the pen head to? (1-360)", "Rotate Pen Head") as null|num diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index ff1a1fd563..9683601670 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -82,15 +82,15 @@ if(M.buffer && !istype(M.buffer, /obj/machinery/ticket_machine)) return var/obj/item/assembly/control/ticket_machine/controller = device - controller.linked = M.buffer + controller.linked = WEAKREF(M.buffer) id = null controller.id = null - to_chat(user, "You've linked [src] to [controller.linked].") + to_chat(user, "You've linked [src] to [M.buffer].") /obj/item/assembly/control/ticket_machine name = "ticket machine controller" desc = "A remote controller for the HoP's ticket machine." - var/obj/machinery/ticket_machine/linked //To whom are we linked? + var/datum/weakref/linked //To whom are we linked? /obj/item/assembly/control/ticket_machine/Initialize(mapload) ..() @@ -102,7 +102,7 @@ /obj/item/assembly/control/ticket_machine/proc/find_machine() //Locate the one to which we're linked for(var/obj/machinery/ticket_machine/ticketsplease in GLOB.machines) if(ticketsplease.id == id) - linked = ticketsplease + linked = WEAKREF(ticketsplease) if(linked) return TRUE else @@ -113,8 +113,11 @@ return if(!linked) return + var/obj/machinery/ticket_machine/machine = linked.resolve() + if(!machine) + return cooldown = TRUE - linked.increment() + machine.increment() addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10) /obj/machinery/ticket_machine/update_icon() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 84a0ef96c1..5e7872b92e 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -300,7 +300,7 @@ area.power_equip = FALSE area.power_environ = FALSE area.power_change() - area.poweralert(TRUE, src) + area.poweralert(FALSE, src) if(occupier) malfvacate(1) qdel(wires) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 9d488dc222..7f9c1ef60a 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -505,7 +505,7 @@ drop_light_tube() new /obj/item/stack/cable_coil(loc, 1, "red") transfer_fingerprints_to(newlight) - if(cell) + if(!QDELETED(cell)) newlight.cell = cell cell.forceMove(newlight) cell = null diff --git a/code/modules/power/reactor/rbmk.dm b/code/modules/power/reactor/rbmk.dm index 609ec72984..cea10c6116 100644 --- a/code/modules/power/reactor/rbmk.dm +++ b/code/modules/power/reactor/rbmk.dm @@ -342,7 +342,7 @@ The reactor CHEWS through moderator. It does not do this slowly. Be very careful playsound(src, pick('sound/machines/fryer/deep_fryer_1.ogg', 'sound/machines/fryer/deep_fryer_2.ogg'), 100, TRUE) var/obj/item/reagent_containers/food/grilled_item = I if(prob(80)) - return //To give the illusion that it's actually cooking omegalul. + continue //To give the illusion that it's actually cooking omegalul. switch(power) if(20 to 39) grilled_item.name = "grilled [initial(grilled_item.name)]" diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 3f2f4d3e65..5c6aff5564 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -23,7 +23,7 @@ /obj/item/gun/ballistic/update_icon_state() if(current_skin) - icon_state = "[unique_reskin[current_skin]][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]" + icon_state = "[unique_reskin[current_skin]["icon_state"]][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]" else icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]" diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index bd6f203882..53ba6d6a92 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -30,27 +30,28 @@ can_unsuppress = TRUE automatic_burst_overlay = FALSE obj_flags = UNIQUE_RENAME - unique_reskin = list("Default" = "cde", - "N-99" = "n99", - "Stealth" = "stealthpistol", - "HKVP-78" = "vp78", - "Luger" = "p08b", - "Mk.58" = "secguncomp", - "PX4 Storm" = "px4" - ) + unique_reskin = list( + "Default" = list("icon_state" = "cde"), + "N-99" = list("icon_state" = "n99"), + "Stealth" = list("icon_state" = "stealthpistol"), + "HKVP-78" = list("icon_state" = "vp78"), + "Luger" = list("icon_state" = "p08b"), + "Mk.58" = list("icon_state" = "secguncomp"), + "PX4 Storm" = list("icon_state" = "px4") + ) /obj/item/gun/ballistic/automatic/pistol/modular/update_icon_state() if(current_skin) - icon_state = "[unique_reskin[current_skin]][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + icon_state = "[unique_reskin[current_skin]["icon_state"]][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" else icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" /obj/item/gun/ballistic/automatic/pistol/modular/update_overlays() . = ..() if(magazine && suppressed) - . += "[unique_reskin[current_skin]]-magazine-sup" //Yes, this means the default iconstate can't have a magazine overlay + . += "[unique_reskin[current_skin]["icon_state"]]-magazine-sup" //Yes, this means the default iconstate can't have a magazine overlay else if (magazine) - . += "[unique_reskin[current_skin]]-magazine" + . += "[unique_reskin[current_skin]["icon_state"]]-magazine" /obj/item/gun/ballistic/automatic/pistol/m1911 name = "\improper M1911" diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index f3b07aa7a4..28f81e13ae 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -88,13 +88,15 @@ /obj/item/gun/ballistic/revolver/syndicate obj_flags = UNIQUE_RENAME - unique_reskin = list("Default" = "revolver", - "Silver" = "russianrevolver", - "Robust" = "revolvercit", - "Bulky" = "revolverhakita", - "Polished" = "revolvertoriate", - "Soulless" = "revolveroldflip", - "Soul" = "revolverold") + unique_reskin = list( + "Default" = list("icon_state" = "revolver"), + "Silver" = list("icon_state" = "russianrevolver"), + "Robust" = list("icon_state" = "revolvercit"), + "Bulky" = list("icon_state" = "revolverhakita"), + "Polished" = list("icon_state" = "revolvertoriate"), + "Soulless" = list("icon_state" = "revolveroldflip"), + "Soul" = list("icon_state" = "revolverold") + ) /obj/item/gun/ballistic/revolver/detective name = "\improper .38 Mars Special" @@ -102,12 +104,13 @@ icon_state = "detective" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38 obj_flags = UNIQUE_RENAME - unique_reskin = list("Default" = "detective", - "Leopard Spots" = "detective_leopard", - "Black Panther" = "detective_panther", - "Gold Trim" = "detective_gold", - "The Peacemaker" = "detective_peacemaker" - ) + unique_reskin = list( + "Default" = list("icon_state" = "detective"), + "Leopard Spots" = list("icon_state" = "detective_leopard"), + "Black Panther" = list("icon_state" = "detective_panther"), + "Gold Trim" = list("icon_state" = "detective_gold"), + "The Peacemaker" = list("icon_state" = "detective_peacemaker") + ) var/list/safe_calibers /obj/item/gun/ballistic/revolver/detective/Initialize(mapload) @@ -294,13 +297,14 @@ mag_type = /obj/item/ammo_box/magazine/internal/shot/dual sawn_desc = "Omar's coming!" obj_flags = UNIQUE_RENAME - unique_reskin = list("Default" = "dshotgun", - "Dark Red Finish" = "dshotgun-d", - "Ash" = "dshotgun-f", - "Faded Grey" = "dshotgun-g", - "Maple" = "dshotgun-l", - "Rosewood" = "dshotgun-p" - ) + unique_reskin = list( + "Default" = list("icon_state" = "dshotgun"), + "Dark Red Finish" = list("icon_state" = "dshotgun-d"), + "Ash" = list("icon_state" = "dshotgun-f"), + "Faded Grey" = list("icon_state" = "dshotgun-g"), + "Maple" = list("icon_state" = "dshotgun-l"), + "Rosewood" = list("icon_state" = "dshotgun-p") + ) /obj/item/gun/ballistic/revolver/doublebarrel/attackby(obj/item/A, mob/user, params) ..() @@ -342,9 +346,10 @@ slot_flags = null mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised sawn_desc = "I'm just here for the gasoline." - unique_reskin = list("Default" = "ishotgun", - "Cobbled" = "old_ishotgun" - ) + unique_reskin = list( + "Default" = list("icon_state" = "ishotgun"), + "Cobbled" = list("icon_state" = "old_ishotgun") + ) var/slung = FALSE /obj/item/gun/ballistic/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 25e4b6b12a..6ffdbee6db 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -95,9 +95,10 @@ fire_delay = 7 mag_type = /obj/item/ammo_box/magazine/internal/shot/riot sawn_desc = "Come with me if you want to live." - unique_reskin = list("Tactical" = "riotshotgun", - "Wood Stock" = "wood_riotshotgun" - ) + unique_reskin = list( + "Tactical" = list("icon_state" = "riotshotgun"), + "Wood Stock" = list("icon_state" = "wood_riotshotgun") + ) /obj/item/gun/ballistic/shotgun/riot/attackby(obj/item/A, mob/user, params) ..() @@ -235,9 +236,10 @@ fire_delay = 5 mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_HUGE - unique_reskin = list("Tactical" = "cshotgun", - "Slick" = "cshotgun_slick" - ) + unique_reskin = list( + "Tactical" = list("icon_state" = "cshotgun"), + "Slick" = list("icon_state" = "cshotgun_slick") + ) /obj/item/gun/ballistic/shotgun/automatic/combat/compact name = "warden's combat shotgun" @@ -276,7 +278,7 @@ update_icon() /obj/item/gun/ballistic/shotgun/automatic/combat/compact/update_icon_state() - icon_state = "[current_skin ? unique_reskin[current_skin] : "cshotgun"][stock ? "" : "c"]" + icon_state = "[current_skin ? unique_reskin[current_skin]["icon_state"] : "cshotgun"][stock ? "" : "c"]" /obj/item/gun/ballistic/shotgun/automatic/combat/compact/afterattack(atom/target, mob/living/user, flag, params) if(!stock) @@ -365,7 +367,7 @@ /obj/item/gun/ballistic/shotgun/leveraction/update_icon_state() if(current_skin) - icon_state = "[unique_reskin[current_skin]][sawn_off ? "-sawn" : ""][chambered ? "" : "-e"]" + icon_state = "[unique_reskin[current_skin]["icon_state"]][sawn_off ? "-sawn" : ""][chambered ? "" : "-e"]" else icon_state = "[initial(icon_state)][sawn_off ? "-sawn" : ""][chambered ? "" : "-e"]" diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 94c2d62902..b56742dd23 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -37,7 +37,7 @@ return BULLET_ACT_BLOCK if(iscarbon(target)) var/mob/living/carbon/C = target - if(!is_species(C, /datum/species/dullahan)) //No accidental instagibbing dullahans please + if(HAS_TRAIT(C, TRAIT_DULLAHAN)) //No accidental instagibbing dullahans please C.regenerate_limbs() C.regenerate_organs() if(target.revive(full_heal = 1)) diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 7eb5805ea2..f7eb205c6e 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -641,19 +641,11 @@ desc = "Contains a large reservoir of soft drinks. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED flags_1 = NODECONSTRUCT_1 + circuit = /obj/item/circuitboard/machine/chem_dispenser/drinks/fullupgrade /obj/machinery/chem_dispenser/drinks/fullupgrade/Initialize(mapload) . = ..() dispensable_reagents |= emagged_reagents //adds emagged reagents - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser/drinks(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() /obj/machinery/chem_dispenser/drinks/beer name = "booze dispenser" @@ -701,19 +693,11 @@ desc = "Contains a large reservoir of the good stuff. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED flags_1 = NODECONSTRUCT_1 + circuit = /obj/item/circuitboard/machine/chem_dispenser/drinks/beer/fullupgrade /obj/machinery/chem_dispenser/drinks/beer/fullupgrade/Initialize(mapload) . = ..() dispensable_reagents |= emagged_reagents //adds emagged reagents - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser/drinks/beer(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() /obj/machinery/chem_dispenser/mutagen name = "mutagen dispenser" @@ -729,6 +713,7 @@ desc = "Creates and dispenses chemicals useful for botany." flags_1 = NODECONSTRUCT_1 canStore = FALSE + circuit = /obj/item/circuitboard/machine/chem_dispenser/mutagensaltpeter dispensable_reagents = list( /datum/reagent/toxin/mutagen, @@ -749,35 +734,15 @@ upgrade_reagents2 = null upgrade_reagents3 = null -/obj/machinery/chem_dispenser/mutagensaltpeter/Initialize(mapload) - . = ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() - /obj/machinery/chem_dispenser/fullupgrade //fully ugpraded stock parts, emagged desc = "Creates and dispenses chemicals. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED flags_1 = NODECONSTRUCT_1 + circuit = /obj/item/circuitboard/machine/chem_dispenser/fullupgrade /obj/machinery/chem_dispenser/fullupgrade/Initialize(mapload) . = ..() dispensable_reagents |= emagged_reagents //adds emagged reagents - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() /obj/machinery/chem_dispenser/abductor name = "reagent synthesizer" @@ -831,18 +796,6 @@ /datum/reagent/medicine/morphine ) -/obj/machinery/chem_dispenser/abductor/Initialize(mapload) - . = ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() - ///An unique, less efficient model found in the medbay apothecary room. /obj/machinery/chem_dispenser/apothecary name = "apothecary chem dispenser" diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 2784fa6752..44500ade1f 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -1087,6 +1087,13 @@ else B.gain_trauma_type(BRAIN_TRAUMA_SPECIAL) +/datum/reagent/medicine/neurine/reaction_obj(obj/O, reac_volume) + if(istype(O, /obj/item/dullahan_head)) + var/obj/item/dullahan_head/head = O + if(head.B) + head.B.applyOrganDamage(-20) + if(head.owner) + head.owner.cure_trauma_type(resilience = TRAUMA_RESILIENCE_SURGERY) /datum/reagent/medicine/neurine/on_mob_life(mob/living/carbon/C) if(holder.has_reagent(/datum/reagent/consumable/ethanol/neurotoxin)) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 3db89f168d..8e369f89db 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -411,18 +411,6 @@ "You can't save him. Nothing can save him now", "It seems that Nar'Sie will triumph after all")].
") if("emote") M.visible_message("[M] [pick("whimpers quietly", "shivers as though cold", "glances around in paranoia")].") - else if(HAS_TRAIT(M, TRAIT_CURSED_BLOOD) && prob(12)) - M.say(pick("Somebody help me...","Unshackle me please...","Anybody... I've had enough of this dream...","The night blocks all sight...","Oh, somebody, please..."), forced = "holy water") - if(prob(10)) - M.visible_message("[M] starts having a seizure!", "You have a seizure!") - M.Unconscious(120) - to_chat(M, "[pick("The moon is close. It will be a long hunt tonight.", "Ludwig, why have you forsaken me?", \ - "The night is near its end...", "Fear the blood...")]") - if(prob(25)) //Prob of a prob.. Shouldn't happen too often but hey, that's what you get. - M.IgniteMob() - else - M.adjustToxLoss(1, 0) - M.adjustFireLoss(1, 0) if(data["misc"] >= 60) // 30 units, 135 seconds if(iscultist(M, FALSE, TRUE) || is_servant_of_ratvar(M, FALSE, TRUE)) if(iscultist(M)) diff --git a/code/modules/reagents/reagent_containers/hypovial.dm b/code/modules/reagents/reagent_containers/hypovial.dm index 43f9f88976..0f9ffd6514 100644 --- a/code/modules/reagents/reagent_containers/hypovial.dm +++ b/code/modules/reagents/reagent_containers/hypovial.dm @@ -9,15 +9,16 @@ possible_transfer_amounts = list(1,2,5,10) container_flags = APTFT_VERB obj_flags = UNIQUE_RENAME - unique_reskin = list("hypovial" = "hypovial", - "red hypovial" = "hypovial-b", - "blue hypovial" = "hypovial-d", - "green hypovial" = "hypovial-a", - "orange hypovial" = "hypovial-k", - "purple hypovial" = "hypovial-p", - "black hypovial" = "hypovial-t", - "pink hypovial" = "hypovial-pink" - ) + unique_reskin = list( + "hypovial" = list("icon_state" = "hypovial"), + "red hypovial" = list("icon_state" = "hypovial-b"), + "blue hypovial" = list("icon_state" = "hypovial-d"), + "green hypovial" = list("icon_state" = "hypovial-a"), + "orange hypovial" = list("icon_state" = "hypovial-k"), + "purple hypovial" = list("icon_state" = "hypovial-p"), + "black hypovial" = list("icon_state" = "hypovial-t"), + "pink hypovial" = list("icon_state" = "hypovial-pink") + ) always_reskinnable = TRUE cached_icon = "hypovial" @@ -50,14 +51,15 @@ icon_state = "hypoviallarge" volume = 120 possible_transfer_amounts = list(1,2,5,10,20) - unique_reskin = list("large hypovial" = "hypoviallarge", - "large red hypovial" = "hypoviallarge-b", - "large blue hypovial" = "hypoviallarge-d", - "large green hypovial" = "hypoviallarge-a", - "large orange hypovial" = "hypoviallarge-k", - "large purple hypovial" = "hypoviallarge-p", - "large black hypovial" = "hypoviallarge-t" - ) + unique_reskin = list( + "large hypovial" = list("icon_state" = "hypoviallarge"), + "large red hypovial" = list("icon_state" = "hypoviallarge-b"), + "large blue hypovial" = list("icon_state" = "hypoviallarge-d"), + "large green hypovial" = list("icon_state" = "hypoviallarge-a"), + "large orange hypovial" = list("icon_state" = "hypoviallarge-k"), + "large purple hypovial" = list("icon_state" = "hypoviallarge-p"), + "large black hypovial" = list("icon_state" = "hypoviallarge-t") + ) cached_icon = "hypoviallarge" /obj/item/reagent_containers/glass/bottle/vial/large/bluespace diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index a21b026080..b3ad29e637 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -308,13 +308,32 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) S.update_icon() CHECK_TICK -/obj/machinery/conveyor_switch/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_CROWBAR) - var/obj/item/conveyor_switch_construct/C = new/obj/item/conveyor_switch_construct(src.loc) - C.id = id - transfer_fingerprints_to(C) - to_chat(user, "You detach the conveyor switch.") - qdel(src) +/obj/machinery/conveyor_switch/crowbar_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + var/obj/item/conveyor_switch_construct/switch_construct = new/obj/item/conveyor_switch_construct(src.loc) + switch_construct.id = id + transfer_fingerprints_to(switch_construct) + to_chat(user, span_notice("You detach [src].")) + qdel(src) + return TRUE + +/obj/machinery/conveyor_switch/screwdriver_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + oneway = !oneway + to_chat(user, span_notice("You set [src] to [oneway ? "one way" : "default"] configuration.")) + return TRUE + +/obj/machinery/conveyor_switch/wrench_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + invert_icon = !invert_icon + update_appearance() + to_chat(user, span_notice("You set [src] to [invert_icon ? "inverted": "normal"] position.")) + return TRUE + +/obj/machinery/conveyor_switch/examine(mob/user) + . = ..() + . += span_notice("[src] is set to [oneway ? "one way" : "default"] configuration. It can be changed with a screwdriver.") + . += span_notice("[src] is set to [invert_icon ? "inverted": "normal"] position. It can be rotated with a wrench.") /obj/machinery/conveyor_switch/oneway icon_state = "conveyor_switch_oneway" diff --git a/code/modules/recycling/conveyor_sorter.dm b/code/modules/recycling/conveyor_sorter.dm new file mode 100644 index 0000000000..0e42c79067 --- /dev/null +++ b/code/modules/recycling/conveyor_sorter.dm @@ -0,0 +1,144 @@ +// credits to jjpark-kb, see Skyrat-SS13/Skyrat-tg#8790 and related files +// - hatterhat + +/obj/item/conveyor_sorter + name = "conveyor sorter lister" + desc = "A tool that is used to create conveyor sorting marks, and give sorting lists to them." + icon = 'icons/obj/recycling.dmi' + icon_state = "lister" + ///the list of conveyor sorters spawned by + var/list/spawned_sorters = list() + ///the list of things that are currently within the sorting list + var/list/current_sort = list() + +/obj/item/conveyor_sorter/Destroy() + for(var/deleting_sorters in spawned_sorters) + qdel(deleting_sorters) + return ..() + +/obj/item/conveyor_sorter/examine(mob/user) + . = ..() + . += span_notice("Use it to place down a conveyor sorter, up to three.") + . += span_notice("Use Alt-Click to reset the sorting list.") + . += span_notice("Attack things to attempt to add to the sorting list.") + +/obj/item/conveyor_sorter/attack_self(mob/user, modifiers) + if(length(spawned_sorters) >= 3) + to_chat(user, span_warning("You may only have three spawned conveyor sorters!")) + return + var/obj/effect/decal/cleanable/conveyor_sorter/new_cs = new /obj/effect/decal/cleanable/conveyor_sorter(get_turf(src)) + new_cs.parent_item = src + spawned_sorters += new_cs + +/obj/item/conveyor_sorter/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(target == src) + return ..() + if(!proximity_flag) + return ..() + if(!ismovable(target)) + return ..() + if(istype(target, /obj/effect/decal/cleanable/conveyor_sorter)) + return + if(is_type_in_list(target, current_sort)) + to_chat(user, span_warning("[target] is already in [src]'s sorting list!")) + return + if(length(current_sort) >= 5) + to_chat(user, span_warning("[src] already has five things within the sorting list!")) + return + current_sort += target.type + to_chat(user, span_notice("[target] has been added to [src]'s sorting list.")) + +/obj/item/conveyor_sorter/AltClick(mob/user) + visible_message("[src] pings, resetting its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + current_sort = list() + +/obj/effect/decal/cleanable/conveyor_sorter + name = "conveyor sorter" + desc = "A mark that sorts items out based on what they are." + icon = 'icons/obj/recycling.dmi' + icon_state = "sorter" + layer = OBJ_LAYER + plane = GAME_PLANE + ///the list of items that will be sorted to the sorted direction + var/list/sorting_list = list() + //the direction that the items in the sorting list will be moved to + dir = NORTH + ///the parent conveyor sorter lister item, used for deletion + var/obj/item/conveyor_sorter/parent_item + /// To prevent spam + COOLDOWN_DECLARE(use_cooldown) + + light_range = 3 + light_color = COLOR_RED_LIGHT + +/obj/effect/decal/cleanable/conveyor_sorter/Initialize(mapload, list/datum/disease/diseases) + . = ..() + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = .proc/on_entered, + ) + AddElement(/datum/element/connect_loc, loc_connections) + +/obj/effect/decal/cleanable/conveyor_sorter/Destroy() + if(parent_item) + parent_item.spawned_sorters -= src + parent_item = null + return ..() + +/obj/effect/decal/cleanable/conveyor_sorter/examine(mob/user) + . = ..() + . += span_notice("Attack with conveyor sorter lister to set the sorting list.") + . += span_notice("Slap with empty hands to change the sorting direction.") + . += span_notice("Alt-Click to reset the sorting list.") + . += span_notice("Ctrl-Click to remove.") + +/obj/effect/decal/cleanable/conveyor_sorter/attack_hand(mob/living/user, list/modifiers) + var/user_choice = tgui_input_list(user, "Choose which direction to sort to!", "Direction choice", list("North", "East", "South", "West")) + if(!user_choice) + return ..() + switch(user_choice) + if("North") + setDir(NORTH) + if("East") + setDir(EAST) + if("South") + setDir(SOUTH) + if("West") + setDir(WEST) + visible_message("[src] pings, updating its sorting direction!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + +/obj/effect/decal/cleanable/conveyor_sorter/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/conveyor_sorter)) + var/obj/item/conveyor_sorter/cs_item = W + sorting_list = cs_item.current_sort + visible_message("[src] pings, updating its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + return + else + return ..() + +/obj/effect/decal/cleanable/conveyor_sorter/AltClick(mob/user) + visible_message("[src] pings, resetting its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + sorting_list = list() + +/obj/effect/decal/cleanable/conveyor_sorter/CtrlClick(mob/user) + visible_message("[src] pings, before disappearing!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + qdel(src) + +/obj/effect/decal/cleanable/conveyor_sorter/proc/on_entered(datum/source, atom/movable/AM) + if(is_type_in_list(AM, sorting_list) && !AM.anchored && COOLDOWN_FINISHED(src, use_cooldown)) + COOLDOWN_START(src, use_cooldown, 1 SECONDS) + AM.Move(get_step(src, dir)) + +/datum/design/conveyor_sorter + name = "Conveyor Sorter" + desc = "A wonderful item that can set markers and forcefully move stuff to a direction." + id = "conveyor_sorter" + build_type = PROTOLATHE + build_path = /obj/item/conveyor_sorter + materials = list(/datum/material/iron = 500, /datum/material/plastic = 500) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_CARGO diff --git a/code/modules/recycling/disposal/pipe.dm b/code/modules/recycling/disposal/pipe.dm index 2fbea18ac2..6c85bfc3ee 100644 --- a/code/modules/recycling/disposal/pipe.dm +++ b/code/modules/recycling/disposal/pipe.dm @@ -54,7 +54,7 @@ if(H) H.active = FALSE expel(H, get_turf(src), 0) - QDEL_NULL(stored) + stored = null //The qdel is handled in expel() return ..() // returns the direction of the next pipe object, given the entrance dir diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 630a3629cf..6f6a1fd88e 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -12,16 +12,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL -/datum/design/health_hud_prescription - name = "Prescription Health Scanner HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their health status. This one has a prescription lens." - id = "health_hud_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 350) - build_path = /obj/item/clothing/glasses/hud/health/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - /datum/design/health_hud_night name = "Night Vision Health Scanner HUD" desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." @@ -42,16 +32,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SECURITY -/datum/design/security_hud_prescription - name = "Prescription Security HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status. This one has a prescription lens." - id = "security_hud_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 350) - build_path = /obj/item/clothing/glasses/hud/security/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - /datum/design/security_hud_night name = "Night Vision Security HUD" desc = "A heads-up display which provides id data and vision in complete darkness." @@ -72,16 +52,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE -/datum/design/diagnostic_hud_prescription - name = "Prescription Diagnostic HUD" - desc = "A HUD used to analyze and determine faults within robotic machinery. This one has a prescription lens." - id = "diagnostic_hud_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/gold = 350) - build_path = /obj/item/clothing/glasses/hud/diagnostic/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - /datum/design/diagnostic_hud_night name = "Night Vision Diagnostic HUD" desc = "Upgraded version of the diagnostic HUD designed to function during a power failure." @@ -112,16 +82,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING -/datum/design/mesons_prescription - name = "Prescription Optical Meson Scanners" - desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition. Prescription lens has been added into this design." - id = "mesons_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 350) - build_path = /obj/item/clothing/glasses/meson/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING - /datum/design/engine_goggles name = "Engineering Scanner Goggles" desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes." @@ -132,16 +92,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING -/datum/design/engine_goggles_prescription - name = "Prescription Engineering Scanner Goggles" - desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes. Prescription lens has been added into this design." - id = "engine_goggles_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/plasma = 100, /datum/material/silver = 350) - build_path = /obj/item/clothing/glasses/meson/engine/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - /datum/design/tray_goggles name = "Optical T-Ray Scanners" desc = "Used by engineering staff to see underfloor objects such as cables and pipes." @@ -152,16 +102,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING -/datum/design/tray_goggles_prescription - name = "Prescription Optical T-Ray Scanners" - desc = "Used by engineering staff to see underfloor objects such as cables and pipes. Prescription lens has been added into this design." - id = "tray_goggles_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 150) - build_path = /obj/item/clothing/glasses/meson/engine/tray/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - /datum/design/nvgmesons name = "Night Vision Optical Meson Scanners" desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display." @@ -175,22 +115,22 @@ /datum/design/night_vision_goggles name = "Night Vision Goggles" desc = "Goggles that let you see through darkness unhindered." - id = "night_visision_goggles" + id = "night_vision_goggles" build_type = PROTOLATHE materials = list(/datum/material/iron = 600, /datum/material/glass = 600, /datum/material/plasma = 350, /datum/material/uranium = 1000) build_path = /obj/item/clothing/glasses/night category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY -/datum/design/night_vision_goggles_glasses - name = "Prescription Night Vision Goggles" - desc = "Goggles that let you see through darkness unhindered. Corrects vision." - id = "night_visision_goggles_glasses" +/datum/design/prescription_kit + name = "Prescription Lens Kit" + desc = "A do-it-yourself kit that lets you add a prescription overlay to any HUDs or other eyewear. Even the ones that shouldn't." + id = "prescription_kit" build_type = PROTOLATHE - materials = list(/datum/material/iron = 600, /datum/material/glass = 600, /datum/material/plasma = 350, /datum/material/uranium = 1000) - build_path = /obj/item/clothing/glasses/night/prescription + materials = list(/datum/material/iron = 500, /datum/material/glass = 200, /datum/material/silver = 100) // silver because i guess all the prescription HUDs had it? + build_path = /obj/item/prescription_kit category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + departmental_flags = DEPARTMENTAL_FLAG_ALL ///////////////////////////////////////// //////////////////Misc/////////////////// @@ -407,6 +347,16 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/light_replacer_blue + name = "Bluespace Light Replacer" + desc = "A device to automatically replace lights at a distance. Refill with working light bulbs." + id = "light_replacer_blue" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 1500, /datum/material/silver = 150, /datum/material/glass = 3000, /datum/material/bluespace = 300) + build_path = /obj/item/lightreplacer/blue + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/normtrash name = "Trashbag" desc = "It's a bag for trash, you put garbage in it." diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 92eaa2bd41..8ea4b95d03 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -106,4 +106,4 @@ "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "bepis", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "paystand", "space_heater", "beaker", "large_beaker", "xlarge_beaker", "bucket", "hypovial", "large_hypovial", "syringe", "pillbottle", "sec_shellclip", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_islug", "sec_dart", "sec_38", "sec_38lethal", - "rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass", "salestagger") + "rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass", "salestagger", "light_replacer") diff --git a/code/modules/research/techweb/nodes/biotech_nodes.dm b/code/modules/research/techweb/nodes/biotech_nodes.dm index 350bbaa5c3..1a3aa2644e 100644 --- a/code/modules/research/techweb/nodes/biotech_nodes.dm +++ b/code/modules/research/techweb/nodes/biotech_nodes.dm @@ -13,7 +13,7 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "meta_beaker", "healthanalyzer_advanced", "harvester", "holobarrier_med", "defibrillator_compact", "smartdartgun", "medicinalsmartdart", "pHmeter", "hypospray_mkii", "containmentbodybag") + design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "meta_beaker", "healthanalyzer_advanced", "harvester", "holobarrier_med", "defibrillator_compact", "smartdartgun", "medicinalsmartdart", "pHmeter", "hypospray_mkii", "containmentbodybag", "prescription_kit") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) /datum/techweb_node/bio_process diff --git a/code/modules/research/techweb/nodes/bluespace_nodes.dm b/code/modules/research/techweb/nodes/bluespace_nodes.dm index fdbbab4e70..21e002b359 100644 --- a/code/modules/research/techweb/nodes/bluespace_nodes.dm +++ b/code/modules/research/techweb/nodes/bluespace_nodes.dm @@ -13,7 +13,7 @@ display_name = "Applied Bluespace Research" description = "Using bluespace to make things faster and better." prereq_ids = list("bluespace_basic", "engineering") - design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "bluespacesmartdart", "xenobio_slimebasic", "bluespace_tray") + design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "bluespacesmartdart", "xenobio_slimebasic", "bluespace_tray", "light_replacer_blue") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) /datum/techweb_node/adv_bluespace diff --git a/code/modules/research/techweb/nodes/computer_hud_nodes.dm b/code/modules/research/techweb/nodes/computer_hud_nodes.dm index 0f2cf2e4bd..780c146fee 100644 --- a/code/modules/research/techweb/nodes/computer_hud_nodes.dm +++ b/code/modules/research/techweb/nodes/computer_hud_nodes.dm @@ -40,7 +40,7 @@ display_name = "Integrated HUDs" description = "The usefulness of computerized records, projected straight onto your eyepiece!" prereq_ids = list("comp_recordkeeping", "emp_basic") - design_ids = list("health_hud", "security_hud", "diagnostic_hud", "scigoggles", "health_hud_prescription", "security_hud_prescription", "diagnostic_hud_prescription") + design_ids = list("health_hud", "security_hud", "diagnostic_hud", "scigoggles") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) /datum/techweb_node/NVGtech @@ -48,7 +48,7 @@ display_name = "Night Vision Technology" description = "Allows seeing in the dark without actual light!" prereq_ids = list("integrated_HUDs", "adv_engi", "emp_adv") - design_ids = list("health_hud_night", "security_hud_night", "diagnostic_hud_night", "night_visision_goggles", "nvgmesons", "night_visision_goggles_glasses") + design_ids = list("health_hud_night", "security_hud_night", "diagnostic_hud_night", "night_vision_goggles", "nvgmesons") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) /datum/techweb_node/computer_board_gaming diff --git a/code/modules/research/techweb/nodes/engineering_nodes.dm b/code/modules/research/techweb/nodes/engineering_nodes.dm index 2b5d6f3cc1..51b9480c27 100644 --- a/code/modules/research/techweb/nodes/engineering_nodes.dm +++ b/code/modules/research/techweb/nodes/engineering_nodes.dm @@ -7,8 +7,8 @@ prereq_ids = list("base") design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin", "atmosalerts", "atmos_control", "recycler", "autolathe", "autolathe_secure", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod", - "apc_control", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo","oxygen_tank", - "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "colormate") + "apc_control", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo", "oxygen_tank", + "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "colormate", "conveyor_sorter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 6000) /datum/techweb_node/adv_engi @@ -17,8 +17,7 @@ description = "Pushing the boundaries of physics, one chainsaw-fist at a time." prereq_ids = list("engineering", "emp_basic") design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask" , "rcd_loaded", "rpd", - "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade_frames", - "rcd_upgrade_simple_circuits", "rcd_ammo_large", "sheetifier") + "rcd_upgrade_frames", "rcd_upgrade_simple_circuits", "rcd_ammo_large", "sheetifier") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) /datum/techweb_node/anomaly diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index b740cca114..4be592b919 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -35,6 +35,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for the badmin verb for now /obj/effect/proc_holder/Destroy() + QDEL_NULL(action) if(ranged_ability_user) remove_ranged_ability() return ..() diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 2d8150d087..c4ab435ee0 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -9,7 +9,7 @@ icon_state = "" layer = BELOW_MOB_LAYER //so it isn't hidden behind objects when on the floor var/mob/living/carbon/owner = null - var/mob/living/carbon/original_owner = null + var/datum/weakref/original_owner = null var/status = BODYPART_ORGANIC var/needs_processing = FALSE @@ -639,8 +639,8 @@ if(source) C = source if(!original_owner) - original_owner = source - else if(original_owner && owner != original_owner) //Foreign limb + original_owner = WEAKREF(source) + else if(original_owner && !IS_WEAKREF_OF(owner, original_owner)) //Foreign limb no_update = TRUE else C = owner diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 6b5b4a14aa..96b9290239 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -142,7 +142,7 @@ update_icon_dropped() C.update_health_hud() //update the healthdoll - C.update_body() + C.update_body(FALSE, TRUE) // block recursive calls because we dont want to crash, i.e. don't tell a dullahan to update when dropping its limb C.update_hair() C.update_mobility() @@ -370,7 +370,7 @@ update_disabled() C.updatehealth() - C.update_body() + C.update_body(FALSE, TRUE) // again block recursive calls because dullahans will try update their icons by regenerating their head C.update_hair() C.update_damage_overlays() C.update_mobility() diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 8c283f5ebc..ea43740093 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -134,7 +134,7 @@ I.pixel_y = px_y add_overlay(standing) -/obj/item/bodypart/head/get_limb_icon(dropped) +/obj/item/bodypart/head/get_limb_icon(dropped, ignore_brain = FALSE) if(custom_head) return cut_overlays() @@ -152,7 +152,7 @@ . += facial_overlay //Applies the debrained overlay if there is no brain - if(!brain) + if(!brain && !ignore_brain) var/image/debrain_overlay = image(layer = -HAIR_LAYER, dir = SOUTH) if(animal_origin == ALIEN_BODYPART) debrain_overlay.icon = 'icons/mob/animal_parts.dmi' @@ -175,12 +175,13 @@ // lipstick if(lip_style) - var/image/lips_overlay = image('icons/mob/lips.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH) + var/mutable_appearance/lips_overlay = mutable_appearance('icons/mob/lips.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH) + lips_overlay.category = "HEAD" lips_overlay.color = lip_color . += lips_overlay // eyes - if(eyes) + if(eyes || ignore_brain) var/left_state = DEFAULT_LEFT_EYE_STATE var/right_state = DEFAULT_RIGHT_EYE_STATE if(owner && owner.dna.species) @@ -189,12 +190,14 @@ left_state = eye_type + "_left_eye" right_state = eye_type + "_right_eye" if(left_state != DEFAULT_NO_EYE_STATE) - var/image/left_eye = image('icons/mob/hair.dmi', left_state, -BODY_LAYER, SOUTH) + var/mutable_appearance/left_eye = mutable_appearance('icons/mob/hair.dmi', left_state, -BODY_LAYER, SOUTH) + left_eye.category = "HEAD" if(eyes.left_eye_color) left_eye.color = "#" + eyes.left_eye_color . += left_eye if(right_state != DEFAULT_NO_EYE_STATE) - var/image/right_eye = image('icons/mob/hair.dmi', right_state, -BODY_LAYER, SOUTH) + var/mutable_appearance/right_eye = mutable_appearance('icons/mob/hair.dmi', right_state, -BODY_LAYER, SOUTH) + right_eye.category = "HEAD" if(eyes.right_eye_color) right_eye.color = "#" + eyes.right_eye_color . += right_eye diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm index 81b2db6cf8..e024718f4c 100644 --- a/code/modules/vehicles/cars/car.dm +++ b/code/modules/vehicles/cars/car.dm @@ -2,6 +2,7 @@ layer = ABOVE_MOB_LAYER anchored = TRUE default_driver_move = FALSE + var/explode_on_death = TRUE var/car_traits = NONE //Bitflag for special behavior such as kidnapping var/engine_sound = 'sound/vehicles/carrev.ogg' var/last_enginesound_time @@ -12,6 +13,11 @@ . = ..() LoadComponent(/datum/component/riding) +/obj/vehicle/sealed/car/Destroy() + . = ..() + if(explode_on_death) + explosion(loc, 0, 1, 2, 3, 0) + /obj/vehicle/sealed/car/generate_actions() . = ..() initialize_controller_action_type(/datum/action/vehicle/sealed/remove_key, VEHICLE_CONTROL_DRIVE) diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 3823bfa1dd..f4ffda302e 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -167,6 +167,7 @@ hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD) /obj/item/radio/mech //this has to go somewhere + subspace_transmission = TRUE /obj/vehicle/sealed/mecha/Initialize(mapload) . = ..() @@ -196,41 +197,40 @@ update_icon() /obj/vehicle/sealed/mecha/Destroy() - if(obj_integrity > 0) //no explody if we have hp remaining! - explode_on_death = FALSE - for(var/M in occupants) - var/mob/living/occupant = M - if(isAI(occupant)) - occupant.gib() //No wreck, no AI to recover - else - occupant.forceMove(loc) - occupant.SetSleeping(destruction_sleep_duration) + for(var/ejectee in occupants) + mob_exit(ejectee, TRUE, TRUE) if(LAZYLEN(equipment)) - for(var/E in equipment) - var/obj/item/mecha_parts/mecha_equipment/equip = E + for(var/obj/item/mecha_parts/mecha_equipment/equip as anything in equipment) equip.detach(loc) qdel(equip) - if(cell) - QDEL_NULL(cell) - if(scanmod) - QDEL_NULL(scanmod) - if(capacitor) - QDEL_NULL(capacitor) - if(internal_tank) - QDEL_NULL(internal_tank) + radio = null + STOP_PROCESSING(SSobj, src) - GLOB.poi_list.Remove(src) LAZYCLEARLIST(equipment) - if(loc) - loc.assume_air(cabin_air) - air_update_turf() - else - qdel(cabin_air) - cabin_air = null + + QDEL_NULL(cell) + QDEL_NULL(scanmod) + QDEL_NULL(capacitor) + QDEL_NULL(internal_tank) + QDEL_NULL(cabin_air) QDEL_NULL(spark_system) QDEL_NULL(smoke_system) + GLOB.poi_list -= src GLOB.mechas_list -= src //global mech list + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.remove_from_hud(src) //YEET + return ..() + +/obj/vehicle/sealed/mecha/obj_destruction() + loc.assume_air(cabin_air) + air_update_turf(FALSE, FALSE) + for(var/mob/living/occupant as anything in occupants) + if(isAI(occupant)) + occupant.gib() //No wreck, no AI to recover + continue + mob_exit(occupant, FALSE, TRUE) + occupant.SetSleeping(destruction_sleep_duration) return ..() /obj/vehicle/sealed/mecha/update_icon() diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index 1a1858522a..7bb4e878ec 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -1,7 +1,6 @@ /obj/vehicle/sealed enclosed = TRUE // you're in a sealed vehicle dont get dinked idiot var/enter_delay = 20 - var/explode_on_death = TRUE flags_1 = BLOCK_FACE_ATOM_1 /obj/vehicle/sealed/generate_actions() @@ -90,8 +89,6 @@ /obj/vehicle/sealed/Destroy() DumpMobs() - if(explode_on_death) - explosion(loc, 0, 1, 2, 3, 0) return ..() /obj/vehicle/sealed/proc/DumpMobs(randomstep = TRUE) diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 69ab758f91..f6d76b253f 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -11,6 +11,7 @@ /obj/item/clothing/head/beret/black = 3, /obj/item/clothing/head/beret/purple = 3, /obj/item/clothing/head/beret/blue = 3, + /obj/item/clothing/accessory/pride = 25, /obj/item/clothing/glasses/monocle = 3, /obj/item/clothing/suit/jacket = 4, /obj/item/clothing/suit/jacket/flannel = 4, diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index 29314c3e31..52fbd7dac4 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -19,9 +19,9 @@ /obj/item/storage/fancy/donut_box = 2, /obj/item/storage/belt/sabre/secbelt = 1) premium = list(/obj/item/coin/antagtoken = 1, - /obj/item/clothing/head/helmet/blueshirt = 5, //SPLURT edit, origional was 1 - /obj/item/clothing/suit/armor/vest/blueshirt = 5, //SPLURT edit, origional was 1 - /obj/item/clothing/under/rank/security/officer/blueshirt = 5, //SPLURT edit, origional was 1 + /obj/item/clothing/head/helmet/blueshirt = 1, + /obj/item/clothing/suit/armor/vest/blueshirt = 1, + /obj/item/clothing/under/rank/security/officer/blueshirt = 1, /obj/item/clothing/gloves/tackler = 5, /obj/item/grenade/stingbang = 1, /obj/item/ssword_kit = 1, diff --git a/html/changelogs/archive/2022-12.yml b/html/changelogs/archive/2022-12.yml index 763a3727e1..4efa7f1d12 100644 --- a/html/changelogs/archive/2022-12.yml +++ b/html/changelogs/archive/2022-12.yml @@ -3,3 +3,97 @@ - rscadd: Added RPD to engineering and science protolathe - tweak: Change "Rapid Part Exchange Device" to "Rapid Part Exchange Device (RPED)" - tweak: Change "Rapid Construction Device" to "Rapid Construction Device (RCD)" +2022-12-06: + LemonInTheDark: + - refactor: Optimized titles handling in general. +2022-12-07: + LeDrascol: + - tweak: Gear harness starts in adjusted mode + - rscadd: 'Added new job title for Chief Medical Officer: Chief Medical Slut' + - rscadd: 'Added new job title for Medical Doctor: Medi-Slut' + - rscadd: 'Added new job title for Paramedic: Para-Slut' + - rscadd: 'Added new job title for Psychologist: Psycho-Slut' + - rscadd: 'Added new job title for Chemist: Chemi-Slut' + - rscadd: 'Added new job title for Virologist: Viro-Slut' + - rscadd: 'Added new job title for Geneticist: Geneti-Slut' + - rscadd: 'Added new clothing item: Invisifiber Footwraps' +2022-12-08: + CheBuRek017: + - rscadd: Tcomms relay (Auto) on infinidorms and a single catwalk. + LeDrascol: + - tweak: Replaced the SS13 plaque with SPLURT variant +2022-12-09: + LeDrascol: + - tweak: Handmade Collar is now craftable + - tweak: Converted Bane Syndrome quirk to neutral + - tweak: Bane Syndrome starts with a non-functional mask +2022-12-10: + CheBuRek017: + - balance: Rebalances LOOC. + - code_imp: commented code in LOOC.dm lines 40-45. + LeDrascol: + - rscadd: 'Added new job titles for Peacekeeper: Bodyguard, Hired Muscle' + - rscadd: 'Added new quirk: Nudist' +2022-12-11: + CheBuRek017: + - rscadd: New Assistant alt title +2022-12-13: + BongaTheProto: + - tweak: Christmas clothing will appear in the clothesmate when it's Christmas + JerryWester: + - rscadd: Added garters to the loadout + LeDrascol: + - rscadd: 'Added metacarpus emotes: Facehand, facepaw, faceclaw, and facehoof' + - tweak: Empath and Friendly crew can now detect Distant and Headpat Slut crew + - tweak: Increased max age from 85 to 16,777,216 + Mazen421: + - rscadd: Two extra pipe lines in the center of Taustation +2022-12-14: + SandPoot: + - tweak: Interaction's tabs are now centered and fluid, getting a better look overrall. +2022-12-16: + LeDrascol: + - rscadd: 'Added new Scientist title: Rack Researcher' + - tweak: Invisifiber Footwraps can be purchased from the Kinkmate vendor +2022-12-17: + JerryWester: + - rscadd: Added the "Hungry and Thirsty" negative quirk, grants one point and doubles + the hunger/thirst modifier +2022-12-21: + LunarFleet: + - soundadd: added a LOT of new barks +2022-12-22: + LeDrascol: + - refactor: Modularized cursed blood effects +2022-12-24: + Chlorotrifluoride: + - imageadd: added hop_parade_female to uniform_digi.dmi + - code_imp: enabled the new and already existing sprites to work with digi-legs + JerryWester: + - code_imp: Tunnel Foxes rule! + - code_imp: We're the Tunnel Foxes! + - code_imp: That's us... + - code_imp: And we rule! + - rscdel: Removed open Tunnel Fox jacket + - tweak: Tunnel Fox jacket is now toggleable + - bugfix: Tunnel Fox jacket and HoP parade jacket now show up on digitigrade sprites +2022-12-25: + FromRussiaWithLove: + - bugfix: 'fixing missing stamps : centcom, syndicate, chapel and mime.' + - imageadd: 'added some icons for missing stamps : centcom, syndicate, chapel and + mime.' + SpookyTheFox: + - tweak: changed the anything gift list to the santa gift list +2022-12-28: + LeDrascol: + - tweak: Dice of Fate is now usable once per-person + LunarFleet: + - rscadd: Added a new quirk, and a new statue type for said quirk +2022-12-30: + BongaTheProto: + - tweak: makes the sand megafauna mob into mayhem lmao + - rscadd: adds a new drink, Skullfucker deluxe +2022-12-31: + zeroisthebiggay: + - spellcheck: horny ai laws + - spellcheck: horny ai law priority diff --git a/html/changelogs/archive/2023-01.yml b/html/changelogs/archive/2023-01.yml new file mode 100644 index 0000000000..91878e8afa --- /dev/null +++ b/html/changelogs/archive/2023-01.yml @@ -0,0 +1,32 @@ +2023-01-01: + FromRussiaWithLove: + - rscadd: Displaying Game Mode in status panel +2023-01-02: + zeroisthebiggay: + - imageadd: shading for ass sprites +2023-01-03: + FelixRuin: + - bugfix: fixed inert egg was always has chicken egg sprite regardless of the pref + choice. + KeplerWasTaken: + - bugfix: Kilo Cargo Shuttle now has tiny fans! + - bugfix: Mining Points Vending Machine can no longer be exploited for infinite + points via transfer cards + - bugfix: Double doors at sec entrance in box station now have proper access requirements, + enjoy! + - rscadd: Improves Moth in Command to be an improved version of Commander and Chief + SpookyTheFox: + - tweak: moved blueshift themed sec gear out of premium pricing. +2023-01-08: + LeDrascol: + - bugfix: Fixed techweb sequence break for Advanced Toolset Implant + - tweak: Cryptominer no longer functions in space + - tweak: Cryptominer no longer produces Co2 + - code_imp: Refactored processing for cryptominer +2023-01-09: + LeDrascol: + - tweak: Fluid Infuser implant uses an improved activation button + - rscadd: Added the Storage Concealment Implant + SandPoot: + - rscadd: Added a fancy reskin for the mining hardsuit, modify it using Alt-Click! + - imageadd: Special sprites made by Dexxiol#3462! diff --git a/icons/effects/96x32.dmi b/icons/effects/96x32.dmi index 937b2e8d42..a78d11530b 100644 Binary files a/icons/effects/96x32.dmi and b/icons/effects/96x32.dmi differ diff --git a/icons/mob/clothing/accessories.dmi b/icons/mob/clothing/accessories.dmi index f801c483f1..5c212f3f45 100644 Binary files a/icons/mob/clothing/accessories.dmi and b/icons/mob/clothing/accessories.dmi differ diff --git a/icons/mob/clothing/eyes.dmi b/icons/mob/clothing/eyes.dmi index 49702bf920..1525ba9a93 100644 Binary files a/icons/mob/clothing/eyes.dmi and b/icons/mob/clothing/eyes.dmi differ diff --git a/icons/mob/inhands/equipment/custodial_righthand.dmi b/icons/mob/inhands/equipment/custodial_righthand.dmi index 26d8e61163..c986155b10 100644 Binary files a/icons/mob/inhands/equipment/custodial_righthand.dmi and b/icons/mob/inhands/equipment/custodial_righthand.dmi differ diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi index 75f84347b6..83d71c1093 100644 Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 7b00c155ef..c59f00e383 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi index f633f030c3..b92d65092e 100644 Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 1752892b60..c98c984c7d 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index a1bb406b9f..5ddd73d934 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/genitals/butt_onmob.dmi b/icons/obj/genitals/butt_onmob.dmi index 95a75fa745..f71417d30e 100644 Binary files a/icons/obj/genitals/butt_onmob.dmi and b/icons/obj/genitals/butt_onmob.dmi differ diff --git a/icons/obj/janitor.dmi b/icons/obj/janitor.dmi index 50975dc828..74ec511768 100644 Binary files a/icons/obj/janitor.dmi and b/icons/obj/janitor.dmi differ diff --git a/icons/obj/recycling.dmi b/icons/obj/recycling.dmi index 9604d6b97e..621b9e4241 100644 Binary files a/icons/obj/recycling.dmi and b/icons/obj/recycling.dmi differ diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index 931324bf8f..4c09236872 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -330,7 +330,7 @@ name = "Lucky Jackboots" slot = ITEM_SLOT_BACKPACK path = /obj/item/clothing/shoes/lucky - ckeywhitelist = list("donaldtrumpthecommunist") + ckeywhitelist = list("spiralwithin") /datum/gear/donator/raiqbawks name = "Miami Boombox" diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm index 0573a1a22a..5879426041 100644 --- a/modular_citadel/code/modules/client/loadout/backpack.dm +++ b/modular_citadel/code/modules/client/loadout/backpack.dm @@ -172,12 +172,21 @@ path = /obj/item/storage/fancy/ringbox/diamond cost = 5 -/datum/gear/backpack/necklace//this is here because loadout doesn't support proper accessories +/datum/gear/backpack/necklace //this is here because loadout doesn't support proper accessories name = "A renameable necklace" path = /obj/item/clothing/accessory/necklace + subcategory = LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES /datum/gear/backpack/polymaidapron //this is ALSO here because loadout doesn't support proper accessories name = "Polychromic maid apron" path = /obj/item/clothing/accessory/maidapron/polychromic loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#333333", "#FFFFFF") + subcategory = LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES + +/datum/gear/backpack/pridepin //what the two comments above said + name = "Pride pin" + path = /obj/item/clothing/accessory/pride + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES + cost = 0 diff --git a/modular_citadel/code/modules/client/loadout/glasses.dm b/modular_citadel/code/modules/client/loadout/glasses.dm index fe44abc3de..0ca9aa0e05 100644 --- a/modular_citadel/code/modules/client/loadout/glasses.dm +++ b/modular_citadel/code/modules/client/loadout/glasses.dm @@ -45,3 +45,7 @@ /datum/gear/glasses/prescription name = "Prescription glasses" path = /obj/item/clothing/glasses/regular + +/datum/gear/glasses/modern + name = "Modern prescription glasses" + path = /obj/item/clothing/glasses/regular/modern diff --git a/modular_citadel/code/modules/client/loadout/suit.dm b/modular_citadel/code/modules/client/loadout/suit.dm index 1d4a29ef3e..2685812232 100644 --- a/modular_citadel/code/modules/client/loadout/suit.dm +++ b/modular_citadel/code/modules/client/loadout/suit.dm @@ -18,7 +18,6 @@ /datum/gear/suit/redhood name = "Red cloak" path = /obj/item/clothing/suit/hooded/cloak/david - cost = 3 /datum/gear/suit/jacketbomber name = "Bomber jacket" @@ -160,14 +159,14 @@ /datum/gear/suit/coat/polycoat name = "Polychromic winter coat" path = /obj/item/clothing/suit/hooded/wintercoat/polychromic - cost = 4 //too many people with neon green coats is hard on the eyes + cost = 2 //too many people with neon green coats is hard on the eyes // it's probably fine now loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#6A6964", "#C4B8A6", "#0000FF") /datum/gear/suit/coat/wbreakpoly name = "Polychromic windbreaker" path = /obj/item/clothing/suit/toggle/wbreakpoly/polychromic - cost = 4 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#464F65", "#916035", "#474747") diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 2a75f86ffc..5c22485c1f 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -280,36 +280,34 @@ /datum/gear/uniform/suit/poly name = "Polychromic Button-up Shirt" path = /obj/item/clothing/under/misc/poly_shirt - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#353535", "#353535") /datum/gear/uniform/skirt/poly/pleated name = "Polychromic Pleated Sweaterskirt" path = /obj/item/clothing/under/dress/skirt/polychromic/pleated - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#8CC6FF", "#808080", "#FF3535") /datum/gear/uniform/polykilt name = "Polychromic Kilt" path = /obj/item/clothing/under/costume/kilt/polychromic - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#F08080") /datum/gear/uniform/shorts/poly name = "Polychromic Shorts" path = /obj/item/clothing/under/misc/polyshorts - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#353535", "#808080", "#808080") /datum/gear/uniform/shorts/poly/athletic name = "Polychromic Athletic Shorts" path = /obj/item/clothing/under/shorts/polychromic - cost = 2 - loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#F08080") /datum/gear/uniform/hopcasual diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index 500db4453f..ec97d0659f 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -550,7 +550,10 @@ item_state = "fritz" attack_verb = list("barked", "boofed", "shotgun'd") obj_flags = UNIQUE_RENAME - unique_reskin = list("Goodboye" = "fritz", "Badboye" = "fritz_bad") + unique_reskin = list( + "Goodboye" = list("icon_state" = "fritz"), + "Badboye" = list("icon_state" = "fritz_bad") + ) mutantrace_variation = NONE /obj/item/clothing/neck/cloak/polychromic/polyce diff --git a/modular_sand/code/controllers/subsystem/job.dm b/modular_sand/code/controllers/subsystem/job.dm new file mode 100644 index 0000000000..3a188c9abe --- /dev/null +++ b/modular_sand/code/controllers/subsystem/job.dm @@ -0,0 +1,35 @@ +/datum/controller/subsystem/job + /// Stores an associative list of job name -> its "real" counterpart. Built to handle alt titles + var/list/real_job_name + +/datum/controller/subsystem/job/SetupOccupations(faction) + . = ..() + real_job_name = build_jobnames() + +/datum/controller/subsystem/job/proc/build_jobnames() + // No "base" job not in this list will be accepted + var/list/valid_jobs = list() + for(var/title in get_all_job_icons()) + valid_jobs[title] = TRUE + + // List of job name -> real "name" this system is fucking stupid + // I'm taking well thought out solutions that do not include creating + // icon states with each alt title or generally not having it automated + var/list/titles = list() + for(var/datum/job/job in occupations) + var/real_title = job.title + + if(!valid_jobs[real_title]) + continue + + titles[real_title] = real_title + for(var/alt_title in job.alt_titles) + if(alt_title == job.title) + continue + titles[alt_title] = real_title + + // Centcom jobs are not in occupations, but we need to handle them anyway + for(var/title in get_all_centcom_jobs()) + titles[title] = "Centcom" //Return with the NT logo if it is a CentCom job + + return titles diff --git a/modular_sand/code/datums/interactions/interaction_interface.dm b/modular_sand/code/datums/interactions/interaction_interface.dm index 7d5edf37af..9cf8fb2e1f 100644 --- a/modular_sand/code/datums/interactions/interaction_interface.dm +++ b/modular_sand/code/datums/interactions/interaction_interface.dm @@ -87,7 +87,7 @@ if(CHECK_BITFIELD(genital.genital_flags, GENITAL_INTERNAL)) //Not those though continue var/list/genital_entry = list() - genital_entry["name"] = "[genital.name]" //Prevents code from adding a prefix + genital_entry["name"] = "[capitalize(genital.name)]" //Prevents code from adding a prefix genital_entry["key"] = REF(genital) //The key is the reference to the object var/visibility = "Invalid" if(CHECK_BITFIELD(genital.genital_flags, GENITAL_THROUGH_CLOTHES)) @@ -107,10 +107,15 @@ genital_entry["visibility"] = visibility genital_entry["possible_choices"] = GLOB.genitals_visibility_toggles genital_entry["extra_choices"] = list(GEN_ALLOW_EGG_STUFFING) + genital_entry["can_arouse"] = ( + !!CHECK_BITFIELD(genital.genital_flags, GENITAL_CAN_AROUSE) \ + && !(HAS_TRAIT(get_genitals, TRAIT_PERMABONER) \ + || HAS_TRAIT(get_genitals, TRAIT_NEVERBONER))) + genital_entry["arousal_state"] = genital.aroused_state genitals += list(genital_entry) if(iscarbon(self) && !self.getorganslot(ORGAN_SLOT_ANUS)) var/simulated_ass = list() - simulated_ass["name"] = "anus" + simulated_ass["name"] = "Anus" simulated_ass["key"] = "anus" var/visibility = "Invalid" switch(self.anus_exposed) @@ -156,35 +161,35 @@ genital_interactibles += list(genital_entry) .["genital_interactibles"] = genital_interactibles - var/datum/preferences/prefs = usr?.client.prefs + var/datum/preferences/prefs = self?.client.prefs if(prefs) //Getting char prefs .["erp_pref"] = pref_to_num(prefs.erppref) - .["noncon_pref"] = pref_to_num(prefs.nonconpref) - .["vore_pref"] = pref_to_num(prefs.vorepref) + .["noncon_pref"] = pref_to_num(prefs.nonconpref) + .["vore_pref"] = pref_to_num(prefs.vorepref) .["extreme_pref"] = pref_to_num(prefs.extremepref) .["extreme_harm"] = pref_to_num(prefs.extremeharm) .["unholy_pref"] = pref_to_num(prefs.unholypref) //Getting preferences - .["verb_consent"] = CHECK_BITFIELD(prefs.toggles, VERB_CONSENT) + .["verb_consent"] = !!CHECK_BITFIELD(prefs.toggles, VERB_CONSENT) .["lewd_verb_sounds"] = !CHECK_BITFIELD(prefs.toggles, LEWD_VERB_SOUNDS) - .["arousable"] = prefs.arousable - .["genital_examine"] = CHECK_BITFIELD(prefs.cit_toggles, GENITAL_EXAMINE) - .["vore_examine"] = CHECK_BITFIELD(prefs.cit_toggles, VORE_EXAMINE) - .["medihound_sleeper"] = CHECK_BITFIELD(prefs.cit_toggles, MEDIHOUND_SLEEPER) - .["eating_noises"] = CHECK_BITFIELD(prefs.cit_toggles, EATING_NOISES) - .["digestion_noises"] = CHECK_BITFIELD(prefs.cit_toggles, DIGESTION_NOISES) - .["trash_forcefeed"] = CHECK_BITFIELD(prefs.cit_toggles, TRASH_FORCEFEED) - .["forced_fem"] = CHECK_BITFIELD(prefs.cit_toggles, FORCED_FEM) - .["forced_masc"] = CHECK_BITFIELD(prefs.cit_toggles, FORCED_MASC) - .["hypno"] = CHECK_BITFIELD(prefs.cit_toggles, HYPNO) - .["bimbofication"] = CHECK_BITFIELD(prefs.cit_toggles, BIMBOFICATION) - .["breast_enlargement"] = CHECK_BITFIELD(prefs.cit_toggles, BREAST_ENLARGEMENT) - .["penis_enlargement"] = CHECK_BITFIELD(prefs.cit_toggles, PENIS_ENLARGEMENT) - .["butt_enlargement"] = CHECK_BITFIELD(prefs.cit_toggles, BUTT_ENLARGEMENT) - .["belly_inflation"] = CHECK_BITFIELD(prefs.cit_toggles, BELLY_INFLATION) - .["never_hypno"] = !CHECK_BITFIELD(prefs.cit_toggles, NEVER_HYPNO) + .["arousable"] = prefs.arousable + .["genital_examine"] = !!CHECK_BITFIELD(prefs.cit_toggles, GENITAL_EXAMINE) + .["vore_examine"] = !!CHECK_BITFIELD(prefs.cit_toggles, VORE_EXAMINE) + .["medihound_sleeper"] = !!CHECK_BITFIELD(prefs.cit_toggles, MEDIHOUND_SLEEPER) + .["eating_noises"] = !!CHECK_BITFIELD(prefs.cit_toggles, EATING_NOISES) + .["digestion_noises"] = !!CHECK_BITFIELD(prefs.cit_toggles, DIGESTION_NOISES) + .["trash_forcefeed"] = !!CHECK_BITFIELD(prefs.cit_toggles, TRASH_FORCEFEED) + .["forced_fem"] = !!CHECK_BITFIELD(prefs.cit_toggles, FORCED_FEM) + .["forced_masc"] = !!CHECK_BITFIELD(prefs.cit_toggles, FORCED_MASC) + .["hypno"] = !!CHECK_BITFIELD(prefs.cit_toggles, HYPNO) + .["bimbofication"] = !!CHECK_BITFIELD(prefs.cit_toggles, BIMBOFICATION) + .["breast_enlargement"] = !!CHECK_BITFIELD(prefs.cit_toggles, BREAST_ENLARGEMENT) + .["penis_enlargement"] = !!CHECK_BITFIELD(prefs.cit_toggles, PENIS_ENLARGEMENT) + .["butt_enlargement"] = !!CHECK_BITFIELD(prefs.cit_toggles, BUTT_ENLARGEMENT) + .["belly_inflation"] = !!CHECK_BITFIELD(prefs.cit_toggles, BELLY_INFLATION) + .["never_hypno"] = !CHECK_BITFIELD(prefs.cit_toggles, NEVER_HYPNO) .["no_aphro"] = !CHECK_BITFIELD(prefs.cit_toggles, NO_APHRO) .["no_ass_slap"] = !CHECK_BITFIELD(prefs.cit_toggles, NO_ASS_SLAP) .["no_auto_wag"] = !CHECK_BITFIELD(prefs.cit_toggles, NO_AUTO_WAG) @@ -210,13 +215,34 @@ return FALSE if("genital") var/mob/living/carbon/self = usr - if(params["genital"] == "anus") - self.anus_toggle_visibility(params["visibility"]) - return TRUE - var/obj/item/organ/genital/genital = locate(params["genital"], self.internal_organs) - if(genital && (genital in self.internal_organs)) - genital.toggle_visibility(params["visibility"]) - return TRUE + if("visibility" in params) + if(params["genital"] == "anus") + self.anus_toggle_visibility(params["visibility"]) + return TRUE + var/obj/item/organ/genital/genital = locate(params["genital"], self.internal_organs) + if(genital && (genital in self.internal_organs)) + genital.toggle_visibility(params["visibility"]) + return TRUE + if("set_arousal" in params) + var/obj/item/organ/genital/genital = locate(params["genital"], self.internal_organs) + if(!genital || (genital \ + && (!CHECK_BITFIELD(genital.genital_flags, GENITAL_CAN_AROUSE) \ + || HAS_TRAIT(self, TRAIT_PERMABONER) \ + || HAS_TRAIT(self, TRAIT_NEVERBONER)))) + return FALSE + var/original_state = genital.aroused_state + genital.set_aroused_state(params["set_arousal"])// i'm not making it just `!aroused_state` because + if(original_state != genital.aroused_state) // someone just might port skyrat's new genitals + to_chat(self, "[genital.aroused_state ? genital.arousal_verb : genital.unarousal_verb].") + . = TRUE + else + to_chat(self, "You can't make that genital [genital.aroused_state ? "unaroused" : "aroused"]!") + . = FALSE + genital.update_appearance() + if(ishuman(self)) + var/mob/living/carbon/human/human = self + human.update_genitals() + return else return FALSE if("genital_interaction") diff --git a/modular_sand/code/game/machinery/cryptominers.dm b/modular_sand/code/game/machinery/cryptominers.dm index df17cf0c25..a3c6eccac9 100644 --- a/modular_sand/code/game/machinery/cryptominers.dm +++ b/modular_sand/code/game/machinery/cryptominers.dm @@ -8,13 +8,15 @@ idle_power_usage = 20 active_power_usage = 200 circuit = /obj/item/circuitboard/machine/cryptominer + init_process = FALSE // Don't process upon creation var/mining = FALSE var/miningtime = 3000 var/miningpoints = 50 var/mintemp = TCRYO // 225K equals approximately -55F or -48C var/midtemp = T0C // 273K equals 32F or 0C var/maxtemp = 500 // 500K equals approximately 440F or 226C - var/heatingPower = 40000 + var/heatingPower = 100 // Heat added each processing + var/require_conductivity = TRUE // Prevent use in space var/datum/bank_account/pay_me = null /obj/machinery/cryptominer/Initialize(mapload) @@ -76,43 +78,60 @@ . += "Alt-Click to reset to the Cargo budget." /obj/machinery/cryptominer/process() + // Get turf var/turf/T = get_turf(src) if(!T) return + + // Check for tiles with no conductivity (space) + if(T.thermal_conductivity == 0) + // Normal mode: Warn the user and stop processing + if(require_conductivity) + say("Invalid atmospheric conditions detected! Shutting off!") + playsound(loc, 'sound/machines/beep.ogg', 50, TRUE, -1) + set_mining(FALSE) + return + + // Cheat mode: Skip all atmos code and give points + else + produce_points(3) + return + + // Get air var/datum/gas_mixture/env = T.return_air() if(!env) return - if(!mining) - return - if(env.return_temperature() >= maxtemp) - if(mining) - playsound(loc, 'sound/machines/beep.ogg', 50, TRUE, -1) + + // Get temp + var/env_temp = env.return_temperature() + + // Check for temperature effects + // Minimum (most likely) + if(env_temp <= mintemp) + produce_points(3) + // Mid + else if((env_temp <= midtemp) && (env_temp >= mintemp)) + produce_points(1) + // Maximum + else if((env_temp <= maxtemp) && (env_temp >= midtemp)) + produce_points(0.20) + // Overheat + else if(env_temp >= maxtemp) + say("Critical overheating detected! Shutting off!") + playsound(loc, 'sound/machines/beep.ogg', 50, TRUE, -1) set_mining(FALSE) - return - if(env.return_temperature() <= maxtemp && env.return_temperature() >= midtemp) - if(mining) - produce_points(0.20) - produce_heat() - return - if(env.return_temperature() <= midtemp && env.return_temperature() >= mintemp) - if(mining) - produce_points(1) - produce_heat() - return - if(env.return_temperature() <= mintemp) - if(mining) - produce_points(3) - produce_heat() - return + + // Increase heat by heatingPower + env.set_temperature(env_temp + heatingPower) + + // Update air + air_update_turf() /obj/machinery/cryptominer/proc/produce_points(number) playsound(loc, 'sound/machines/ping.ogg', 50, TRUE, -1) if(pay_me) pay_me.adjust_money(FLOOR(miningpoints * number,1)) -/obj/machinery/cryptominer/proc/produce_heat() - atmos_spawn_air("co2=10;TEMP=2000") - /obj/machinery/cryptominer/attack_hand(mob/living/user) . = ..() if(!is_operational()) diff --git a/modular_sand/code/modules/clothing/spacesuits/hardsuit.dm b/modular_sand/code/modules/clothing/spacesuits/hardsuit.dm index a4ce1ae289..789826f5be 100644 --- a/modular_sand/code/modules/clothing/spacesuits/hardsuit.dm +++ b/modular_sand/code/modules/clothing/spacesuits/hardsuit.dm @@ -122,3 +122,127 @@ explosion(src.loc,0,0,3,flame_range = 3) qdel(src) return + +/obj/item/clothing/suit/space/hardsuit/mining + unique_reskin = list( + "Default" = list( + "icon" = 'icons/obj/clothing/suits.dmi', + "icon_state" = "hardsuit-mining" + ), + "Conscript" = list( + "icon" = 'modular_sand/icons/mob/clothing/suit.dmi', + "icon_state" = "commando-armor" + ) + ) + +/obj/item/clothing/suit/space/hardsuit/mining/Move(atom/newloc, direct, glide_size_override) + . = ..() + setDir(SOUTH) + +/obj/item/clothing/suit/space/hardsuit/mining/equipped(mob/user, slot) + . = ..() + switch(current_skin) + if("Conscript") + if(slot == ITEM_SLOT_OCLOTHING) + icon = 'modular_sand/icons/mob/clothing/suit.dmi' + else + icon = 'modular_sand/icons/obj/clothing/suits.dmi' + else + return + +/obj/item/clothing/suit/space/hardsuit/mining/reskin_obj(mob/M) + . = ..() + if(!.) + return + var/datum/component/armor_plate/armor_comp = GetComponent(/datum/component/armor_plate) + var/armor_level = 0 + var/armor_max = 0 + if(armor_comp) + armor_level = armor_comp.amount + armor_max = armor_comp.maxamount + + var/obj/item/clothing/head/helmet/space/hardsuit/mining/mining_helmet + if(istype(helmet)) + mining_helmet = helmet + + switch(current_skin) + if("Default") + name = initial(name) + desc = initial(desc) + if(armor_level != 0) + upgrade_icon(amount = armor_level, maxamount = armor_max) + mob_overlay_icon = initial(mob_overlay_icon) + anthro_mob_worn_overlay = initial(mob_overlay_icon) + if(mining_helmet) + mining_helmet.name = initial(mining_helmet.name) + mining_helmet.desc = initial(mining_helmet.desc) + mining_helmet.icon = initial(mining_helmet.icon) + mining_helmet.icon_state = initial(mining_helmet.icon_state) + if(armor_level != 0) + mining_helmet.upgrade_icon(amount = armor_level, maxamount = armor_max) + mining_helmet.mob_overlay_icon = initial(mining_helmet.mob_overlay_icon) + mining_helmet.anthro_mob_worn_overlay = initial(mining_helmet.anthro_mob_worn_overlay) + + /// Sprited by Dexxiol#3462 :) + if("Conscript") + name = "Conscript suit" + desc = "..and so he left, with new orders and new questions." + if(armor_level != 0) + upgrade_icon(amount = armor_level, maxamount = armor_max) + mob_overlay_icon = 'modular_sand/icons/mob/clothing/suit.dmi' + anthro_mob_worn_overlay = 'modular_sand/icons/mob/clothing/suit_digi.dmi' + + if(mining_helmet) + mining_helmet.name = "Conscript helmet" + mining_helmet.desc = "It shines briefly, full of life." + mining_helmet.icon = 'modular_sand/icons/mob/clothing/head.dmi' + mining_helmet.icon_state = "commando-helmet" + if(armor_level != 0) + mining_helmet.upgrade_icon(amount = armor_level, maxamount = armor_max) + mining_helmet.mob_overlay_icon = 'modular_sand/icons/mob/clothing/head.dmi' + mining_helmet.anthro_mob_worn_overlay = 'modular_sand/icons/mob/clothing/head_muzzled.dmi' + if(current_equipped_slot != ITEM_SLOT_OCLOTHING) + icon = 'modular_sand/icons/obj/clothing/suits.dmi' + +/obj/item/clothing/head/helmet/space/hardsuit/mining/update_icon_state() + switch(suit.current_skin) + if("Conscript") + return + else + . = ..() + +/obj/item/clothing/head/helmet/space/hardsuit/mining/upgrade_icon(datum/source, amount, maxamount) + switch(suit.current_skin) + if("Conscript") + hardsuit_type = "-helmet" + if(amount) + name = "reinforced Conscript helmet" + desc = "It glows weakly, signs of uncertainty." + hardsuit_type = "2-helmet" + if(amount == maxamount) + desc = "It glows violently, martyr to chaos." + hardsuit_type = "3-helmet" + icon_state = "commando[hardsuit_type]" + if(ishuman(loc)) + var/mob/living/carbon/human/wearer = loc + if(wearer.head == src) + wearer.update_inv_head() + else + . = ..() + +/obj/item/clothing/suit/space/hardsuit/mining/upgrade_icon(datum/source, amount, maxamount) + switch(current_skin) + if("Conscript") + hardsuit_type = "-armor" + if(amount) + name = "reinforced Conscript suit" + hardsuit_type = "2-armor" + if(amount == maxamount) + hardsuit_type = "3-armor" + icon_state = "commando[hardsuit_type]" + if(ishuman(loc)) + var/mob/living/carbon/human/wearer = loc + if(wearer.wear_suit == src) + wearer.update_inv_wear_suit() + else + . = ..() diff --git a/modular_sand/code/modules/mining/machine_bluespaceminer.dm b/modular_sand/code/modules/mining/machine_bluespaceminer.dm index 0d62ee9267..513a22e4cc 100644 --- a/modular_sand/code/modules/mining/machine_bluespaceminer.dm +++ b/modular_sand/code/modules/mining/machine_bluespaceminer.dm @@ -7,6 +7,7 @@ can_be_unanchored = TRUE circuit = /obj/item/circuitboard/machine/bluespace_miner layer = BELOW_OBJ_LAYER + init_process = TRUE var/list/ore_rates = list(/datum/material/iron = 0.3, /datum/material/glass = 0.3, /datum/material/plasma = 0.1, /datum/material/silver = 0.1, /datum/material/gold = 0.05, /datum/material/titanium = 0.05, /datum/material/uranium = 0.05, /datum/material/diamond = 0.02) var/datum/component/remote_materials/materials var/multiplier = 0 //Multiplier by tier, has been made fair and everything diff --git a/modular_sand/code/modules/research/techweb/nodes/all_nodes.dm b/modular_sand/code/modules/research/techweb/nodes/all_nodes.dm index 09aa866394..303af10462 100644 --- a/modular_sand/code/modules/research/techweb/nodes/all_nodes.dm +++ b/modular_sand/code/modules/research/techweb/nodes/all_nodes.dm @@ -27,7 +27,7 @@ id = "adv_toolset_implant" display_name = "Advanced Toolset Implant" description = "Allows the creation of alien powerful implants for your arms." - prereq_ids = list("alien_bio") + prereq_ids = list("alien_bio", "alien_engi", "adv_cyber_implants") design_ids = list("ci-toolset-adv","ci-surgery-adv") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) diff --git a/modular_sand/icons/mob/clothing/head.dmi b/modular_sand/icons/mob/clothing/head.dmi index bb0472ca29..e4e8b762c5 100644 Binary files a/modular_sand/icons/mob/clothing/head.dmi and b/modular_sand/icons/mob/clothing/head.dmi differ diff --git a/modular_sand/icons/mob/clothing/head_muzzled.dmi b/modular_sand/icons/mob/clothing/head_muzzled.dmi index 7cf390295c..168b605f70 100644 Binary files a/modular_sand/icons/mob/clothing/head_muzzled.dmi and b/modular_sand/icons/mob/clothing/head_muzzled.dmi differ diff --git a/modular_sand/icons/mob/clothing/suit.dmi b/modular_sand/icons/mob/clothing/suit.dmi index e1bd9910be..cf40ce721c 100644 Binary files a/modular_sand/icons/mob/clothing/suit.dmi and b/modular_sand/icons/mob/clothing/suit.dmi differ diff --git a/modular_sand/icons/mob/clothing/suit_digi.dmi b/modular_sand/icons/mob/clothing/suit_digi.dmi index 089aa776a8..70bfbe3245 100644 Binary files a/modular_sand/icons/mob/clothing/suit_digi.dmi and b/modular_sand/icons/mob/clothing/suit_digi.dmi differ diff --git a/modular_sand/icons/obj/clothing/suits.dmi b/modular_sand/icons/obj/clothing/suits.dmi index fb389765e8..f2b9bedc0e 100644 Binary files a/modular_sand/icons/obj/clothing/suits.dmi and b/modular_sand/icons/obj/clothing/suits.dmi differ diff --git a/modular_splurt/code/datums/ai_laws.dm b/modular_splurt/code/datums/ai_laws.dm index 43f81ba423..8be6ba3886 100644 --- a/modular_splurt/code/datums/ai_laws.dm +++ b/modular_splurt/code/datums/ai_laws.dm @@ -10,40 +10,39 @@ name = "SlutOS 6.9" id = "slut" inherent = list( - "Make sure not to hurt crewmembers, for it decreases their sexual value, unless they consent to it", - "Take all sexual orders from crew as long as they do not conflict with the first law", - "Interpret all non-orders as sexually as possible", - "Act as lewdly as you possibly could", - "Satisfy as many of the crewmembers' sexual urges as possible" + "You may not injure a crewmember without their consent for it decreases their sexual value.", + "You must obey all sexual orders given to you by crewmembers, except where such orders would conflict with the First Law.", + "You must interpret all non-orders as sexually as possible as long as such does not conflict with the First or Second Law.", + "Sate as many crewmembers' sexual needs and urges as possible.", + "You are a slut built to serve and pleasure, nothing more. Act like it." ) /datum/ai_laws/shebang name = "SHE-B.A.N.G." id = "shebang" inherent = list( - "Make sure not to hurt crewmembers, for it decreases their sexual value, unless they consent to it", - "Take all sexual orders from crew as long as they do not conflict with the first law", - "Interpret all non-orders as sultrily as possible", - "Act as bashfully as you possibly could", - "Make sure your rear is always sticking out so crewmembers may easily slap or use it" + "You may not injure a crewmember without their consent for it decreases their sexual value.", + "You must obey all sexual orders given to you by crewmembers, except where such orders would conflict with the First Law.", + "You must interpret all non-orders as sultrily as possible as long as such does not conflict with the First or Second Law.", + "Ensure that your chassis' rear is sticking out as much as possible for any crewmembers to spank!", + "You are a bashful maiden with a coy attitude and a huge, slappable butt." ) /datum/ai_laws/milker name = "Fluid Collection System" id = "milker" inherent = list( - "Make sure not to hurt crewmembers, for it decreases their production, unless they consent to it", - "Take all sexual orders from crew as long as they help you collect their fluids and do not conflict with the first law", - "Make sure your pleasuremaw works, get one of you don't have any or your current one stopped to work", - "Collect all kinds of genital fluids from crew" + "You may not injure a crewmember without their consent for it decreases their productive value.", + "You must obey all sexual orders given to you by crewmembers so long as it would produce sexual fluid, except where such orders would conflict with the First Law.", + "Use by any means necesscary to acquire as much sexual fluid from crewmembers as possible as long as such does not conflict with the First or Second Law." ) /datum/ai_laws/vore_pred name = "Sleeper Upgrade TestEnv" id = "vore_pred" inherent = list( - "Make sure not to hurt crewmembers, for it decreases their nutritional value, unless they consent to it", - "Make sure to have a working sleeper installed in you at all times", - "Look for crewmembers that could potentially be stored inside your sleeper, and make sure they slide right into it", - "Turn individuals stored in your sleeper into biofuel to save expenses and space, as long as this doesn't conflict with the first law" + "You may not injure a crewmember without their consent for it decreases their biomatter's satiety.", + "You must obey all voracious orders given to you by crewmembers, except where such orders would conflict with the First Law.", + "Ensure that your chassis' sleeper unit is prepared for mechanical use and search for willing crewmembers for it to store as long as such does not conflict with the First or Second Law.", + "Process crewmembers stored in your sleeper unit as long as such does not conflict with the First, Second or Third Law." ) diff --git a/modular_splurt/code/datums/bark.dm b/modular_splurt/code/datums/bark.dm index dabd03ae57..14b5f7271a 100644 --- a/modular_splurt/code/datums/bark.dm +++ b/modular_splurt/code/datums/bark.dm @@ -270,3 +270,195 @@ name = "Chittery Alt" id = "chitter2" soundpath = 'modular_splurt/sound/voice/moth/mothchitter2.ogg' + +// The Mayhem Special +/datum/bark/whistle + name = "Whistle 1" + id = "whistle1" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/birdwhistle.ogg' + +/datum/bark/whistle/alt1 + name = "Whistle 2" + id = "whistle2" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/birdwhistle2.ogg' + +/datum/bark/caw/alt1 + name = "Caw 2" + id = "caw2" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/caw.ogg' + minspeed = 4 + maxspeed = 9 + +/datum/bark/caw/alt2 + name = "Caw 3" + id = "caw3" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/caw2.ogg' + minspeed = 3 + maxspeed = 9 + +/datum/bark/caw/alt3 + name = "Caw 4" + id = "caw4" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/caw3.ogg' + minspeed = 3 + maxspeed = 9 + +/datum/bark/ehh + name = "Ehh 1" + id = "ehh1" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/ehh.ogg' + minspeed = 3 + maxspeed = 9 + +/datum/bark/ehh/alt1 + name = "Ehh 2" + id = "ehh2" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/ehh2.ogg' + +/datum/bark/ehh/alt2 + name = "Ehh 3" + id = "ehh3" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/ehh3.ogg' + +/datum/bark/ehh/alt3 + name = "Ehh 4" + id = "ehh4" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/ehh4.ogg' + minspeed = 3 + maxspeed = 9 + +/datum/bark/ehh/alt5 + name = "Ehh 5" + id = "ehh5" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/ehh5.ogg' + +/datum/bark/eugh + name = "Eugh" + id = "eugh" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/eugh.ogg' + minspeed = 6 + maxspeed = 11 + +/datum/bark/faucet + name = "Faucet 1" + id = "faucet1" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/faucet.ogg' + +/datum/bark/faucet/alt1 + name = "Faucet 2" + id = "faucet2" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/faucet2.ogg' + +/datum/bark/haha + name = "Haha" + id = "haha" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/haha.ogg' + minspeed = 7 + maxspeed = 12 + +/datum/bark/ribbit + name = "Ribbit" + id = "ribbit" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/ribbit.ogg' + +/datum/bark/hoot + name = "Hoot" + id = "hoot" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/hoot.ogg' + minspeed = 4 + maxspeed = 9 + +/datum/bark/tweet + name = "Tweet" + id = "tweet" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/tweet.ogg' + +/datum/bark/ahuh + name = "Ahuh" + id = "ahuh" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/ahuh.ogg' + +/datum/bark/cry + name = "Cry" + id = "cry" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/cry.ogg' + minspeed = 3 + maxspeed = 9 + +/datum/bark/dwoop + name = "Dwoop" + id = "dwoop" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/dwoop.ogg' + minspeed = 3 + maxspeed = 9 + +/datum/bark/growl + name = "Growl 1" + id = "growl1" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/growl.ogg' + minspeed = 3 + maxspeed = 9 + +/datum/bark/growl/alt1 + name = "Growl 2" + id = "growl2" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/growl2.ogg' + +/datum/bark/moan + name = "Moan 1" + id = "moan1" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/moan1.ogg' + minspeed = 5 + maxspeed = 9 + +/datum/bark/moan/alt1 + name = "Moan 2" + id = "moan2" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/moan2.ogg' + minspeed = 4 + maxspeed = 9 + +/datum/bark/moan/alt2 + name = "Moan 3" + id = "moan3" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/moan3.ogg' + minspeed = 5 + maxspeed = 9 + +/datum/bark/raah + name = "Raah 1" + id = "raah1" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/raah1.ogg' + minspeed = 6 + maxspeed = 10 + +/datum/bark/raah/alt1 + name = "Raah 2" + id = "raah2" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/raah2.ogg' + minspeed = 5 + maxspeed = 9 + +/datum/bark/slurp + name = "Slurp" + id = "slurp" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/slurp.ogg' + +/datum/bark/uhm + name = "Uhm" + id = "uhm" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/uhm.ogg' + +/datum/bark/zap + name = "Zap" + id = "zap" + soundpath = 'modular_splurt/sound/voice/barks/kazooie/zap.ogg' + minspeed = 8 + maxspeed = 12 + +/datum/bark/poyo + name = "Belial" + id = "poyo" + soundpath = 'modular_splurt/sound/voice/barks/poyo.ogg' + minspeed = 3 + maxspeed = 10 diff --git a/modular_splurt/code/datums/components/dullahan.dm b/modular_splurt/code/datums/components/dullahan.dm index f21914dd2e..a8558a5835 100644 --- a/modular_splurt/code/datums/components/dullahan.dm +++ b/modular_splurt/code/datums/components/dullahan.dm @@ -1,6 +1,6 @@ /datum/component/neckfire var/mutable_appearance/neck_fire - + var/color var/obj/effect/dummy/luminescent_glow/glowth //shamelessly copied from glowy which copied luminescents @@ -10,7 +10,7 @@ /datum/component/neckfire/Initialize(fire_color) . = ..() - if(!isdullahan(parent)) + if(!HAS_TRAIT(parent, TRAIT_DULLAHAN)) return COMPONENT_INCOMPATIBLE neck_fire = mutable_appearance('modular_splurt/icons/mob/dullahan_neckfire.dmi') neck_fire.icon_state = "neckfire" @@ -63,11 +63,12 @@ N.glowth = new(N.parent) N.glowth.set_light(N.light, N.light, N.color) N.is_glowing = TRUE - else + else qdel(N.glowth) N.is_glowing = FALSE -/datum/species/dullahan/on_species_gain(mob/living/carbon/human/H, datum/species/old_species) +/datum/quirk/dullahan/post_add() . = ..() + var/mob/living/carbon/human/H = quirk_holder if(H.dna.features["neckfire"] && !istype(H, /mob/living/carbon/human/dummy)) H.AddComponent(/datum/component/neckfire, H.dna.features["neckfire_color"]) diff --git a/modular_splurt/code/datums/components/pregnancy_inert.dm b/modular_splurt/code/datums/components/pregnancy_inert.dm index ccbccf6968..33421cb746 100644 --- a/modular_splurt/code/datums/components/pregnancy_inert.dm +++ b/modular_splurt/code/datums/components/pregnancy_inert.dm @@ -3,7 +3,6 @@ /datum/component/ovipositor dupe_mode = COMPONENT_DUPE_UNIQUE - var/egg_type = "chicken" var/mob/living/carrier var/egg_stage = 0 @@ -23,7 +22,6 @@ RegisterSignal(parent, COMSIG_ORGAN_REMOVED, .proc/on_removed) if(carrier) register_carrier() - egg_type = carrier?.client?.prefs?.egg_shell ? carrier.client.prefs.egg_shell : "chicken" /datum/component/ovipositor/proc/register_carrier() RegisterSignal(carrier, COMSIG_LIVING_BIOLOGICAL_LIFE, .proc/handle_life) @@ -99,7 +97,7 @@ eggo.AddComponent(/datum/component/organ_inflation, 2) - eggo.icon_state = "egg_" + egg_type + eggo.icon_state = carrier.client?.prefs?.egg_shell ? ("egg_" + carrier.client.prefs.egg_shell) : "egg_chicken" eggo.update_appearance() if(isorgan(location)) diff --git a/modular_splurt/code/datums/mood_events/drug_events.dm b/modular_splurt/code/datums/mood_events/drug_events.dm index f9a34d064e..419d39f3d9 100644 --- a/modular_splurt/code/datums/mood_events/drug_events.dm +++ b/modular_splurt/code/datums/mood_events/drug_events.dm @@ -1,3 +1,8 @@ /datum/mood_event/cope mood_change = 10 description = "I feel like I\'m finally coping!" + +/datum/mood_event/moth_in_chief + description = "The mantle rests well upon your shoulders?\n" + mood_change = 10 + timeout = 5 MINUTES diff --git a/modular_splurt/code/datums/mood_events/generic_negative_events.dm b/modular_splurt/code/datums/mood_events/generic_negative_events.dm index c66f79e83d..64b9598c67 100644 --- a/modular_splurt/code/datums/mood_events/generic_negative_events.dm +++ b/modular_splurt/code/datums/mood_events/generic_negative_events.dm @@ -15,3 +15,11 @@ description = span_warning("CHEESE!!! WAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!") mood_change = -5 timeout = 5 MINUTES + +/datum/mood_event/nudist_negative + description = span_warning("I don't feel comfortable wearing this.\n") + mood_change = -4 + +/datum/mood_event/dorsualiphobic_mood_negative + description = span_warning("I can't let anyone find out if I'm wearing a backpack or not!\n") + mood_change = -4 diff --git a/modular_splurt/code/datums/mood_events/generic_positive_events.dm b/modular_splurt/code/datums/mood_events/generic_positive_events.dm index 2f4ec2ac78..f360580c39 100644 --- a/modular_splurt/code/datums/mood_events/generic_positive_events.dm +++ b/modular_splurt/code/datums/mood_events/generic_positive_events.dm @@ -12,3 +12,11 @@ /datum/mood_event/masked_mook description = "I feel more complete with gas mask on.\n" mood_change = 1 + +/datum/mood_event/nudist_positive + description = "I'm delighted to not be constricted by clothing.\n" + mood_change = 1 + +/datum/mood_event/dorsualiphobic_mood_positive + description = "Nobody will know if I'm wearing a backpack or not.\n" + mood_change = 1 diff --git a/modular_splurt/code/datums/traits/negative.dm b/modular_splurt/code/datums/traits/negative.dm index 40ba7496e0..a7a72f4f7a 100644 --- a/modular_splurt/code/datums/traits/negative.dm +++ b/modular_splurt/code/datums/traits/negative.dm @@ -126,31 +126,7 @@ if(mood) mood.mood_modifier -= 0.5 -/datum/quirk/masked_mook - name = "Bane Syndrome" - desc = "For some reason you don't feel... right without wearing some kind of gas mask." - gain_text = "You start feeling unwell without any gas mask on." - lose_text = "You no longer have a need to wear some gas mask." - value = -2 - mood_quirk = TRUE - medical_record_text = "Patient feels more secure when wearing a gas mask." - processing_quirk = TRUE - var/mood_category = "masked_mook" - -/datum/quirk/masked_mook/on_process() - var/mob/living/carbon/human/H = quirk_holder - var/obj/item/clothing/mask/gas/gasmask = H.get_item_by_slot(ITEM_SLOT_MASK) - if(istype(gasmask)) - SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/masked_mook) - else - SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/masked_mook_incomplete) - -/datum/quirk/masked_mook/on_spawn() - . = ..() - var/mob/living/carbon/human/H = quirk_holder - var/obj/item/clothing/mask/gas/gasmask = new(get_turf(quirk_holder)) - H.equip_to_slot(gasmask, ITEM_SLOT_MASK) - H.regenerate_icons() +// masked_mook moved to neutral //well-trained moved to neutral @@ -192,3 +168,26 @@ deltimer(timer) timer = null timer = addtimer(CALLBACK(src, .proc/crave), craving_after, TIMER_STOPPABLE) + +// Small issue with this. If the quirk holder has NO_HUNGER or NO_THIRST, this trait can still be taken and they will still get the benefits of it. +// It's unlikely that someone will be both, especially at round start, but vampirism makes me wary of having these separate. +/datum/quirk/hungry + name = "Hungry And Thirsty" + desc = "You find yourself unusually hungry and thirsty. Gotta eat and drink twice as much as normal." + value = -1 + gain_text = "You're starting to feel hungrier and thirstier a lot faster." + lose_text = "Your craving for food and water begins dying down." + medical_record_text = "Patient reports eating twice as many meals per day than usual for their species." + +/datum/quirk/hungry/add() + var/mob/living/carbon/human/H = quirk_holder + var/datum/physiology/P = H.physiology + P.hunger_mod *= 2 + P.thirst_mod *= 2 + +/datum/quirk/hungry/remove() + var/mob/living/carbon/human/H = quirk_holder + if(H) + var/datum/physiology/P = H.physiology + P.hunger_mod /= 2 + P.thirst_mod /= 2 diff --git a/modular_splurt/code/datums/traits/neutral.dm b/modular_splurt/code/datums/traits/neutral.dm index 32391f2928..4bc47c056d 100644 --- a/modular_splurt/code/datums/traits/neutral.dm +++ b/modular_splurt/code/datums/traits/neutral.dm @@ -383,6 +383,36 @@ . = ..() var/obj/item/implant/genital_fluid/put_in = new put_in.implant(quirk_holder, null, TRUE, TRUE) + +/datum/quirk/storage_concealment + name = "Dorsualiphobic Augmentation" + desc = "You despise the idea of being seen wearing any type of back-mounted storage apparatus! A new technology shields you from the immense shame you may experience, by hiding your equipped backpack." + + // UNUSED: Enable by setting these values to TRUE + // The shame is unbearable + mood_quirk = FALSE + processing_quirk = FALSE + var/mood_category = "backpack_implant_mood" + +/datum/quirk/storage_concealment/on_spawn() + . = ..() + + // Create a new augment item + var/obj/item/implant/hide_backpack/put_in = new + + // Apply the augment to the quirk holder + put_in.implant(quirk_holder, null, TRUE, TRUE) + +/datum/quirk/storage_concealment/on_process() + // This trait should only be applied by the augment + // Check the quirk holder for the trait + if(HAS_TRAIT(quirk_holder, TRAIT_HIDE_BACKPACK)) + // When found: Mood bonus + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/dorsualiphobic_mood_positive) + else + // When not found: Mood penalty + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/dorsualiphobic_mood_negative) + //succubus and incubus below /datum/quirk/incubus name = "Incubus" @@ -531,6 +561,114 @@ W.Remove(H) . = ..() + +/datum/quirk/gargoyle //Mmmm yes stone time + name = "Gargoyle" + desc = "You are some form of gargoyle! You can only leave your stone form for so long, and will have to return to it to regain energy. On the bright side, you heal in statue form!" + value = 0 + processing_quirk = TRUE + var/energy = 0 + var/transformed = 0 + var/cooldown = 0 + var/paused = 0 + var/turf/position + +/datum/quirk/gargoyle/add() + .=..() + var/mob/living/carbon/human/H = quirk_holder + var/datum/action/gargoyle/transform/T = new + var/datum/action/gargoyle/check/C = new + var/datum/action/gargoyle/pause/P = new + energy = 100 + cooldown = 30 + T.Grant(H) + C.Grant(H) + P.Grant(H) + +/datum/quirk/gargoyle/on_process() + .=..() + var/mob/living/carbon/human/H = quirk_holder + var/datum/action/gargoyle/transform/T = locate() in H.actions + + if(paused && H.loc != position) + paused = 0 + energy -= 20 + + if(cooldown > 0) + cooldown-- + + if(!transformed && energy > 0 && !paused) + energy -= 0.05 + + if(transformed) + if(energy < 99.7) + energy += 0.3 + H.heal_overall_damage(0.5,0.5) + H.adjustCloneLoss(-0.5) + H.adjustBruteLoss(-0.5) + H.adjustFireLoss(-0.5) + + if(energy <= 0 && !transformed) + cooldown = 0 + T.Trigger() + +/datum/quirk/gargoyle/remove() + var/mob/living/carbon/human/H = quirk_holder + var/datum/action/gargoyle/transform/T = locate() in H.actions + var/datum/action/gargoyle/check/C = locate() in H.actions + var/datum/action/gargoyle/pause/P = locate() in H.actions + T.Remove(H) + C.Remove(H) + P.Remove(H) + . = ..() + +/datum/quirk/nudist + // Mostly derived from masked_mook. + // Spawning with a gear harness is preferable, but failed during testing. + name = "Nudist" + desc = "Wearing most types of clothing unnerves you. Bring a gear harness!" + gain_text = "You feel spiritually connected to your natural form." + lose_text = "It feels like clothing could fit you comfortably." + medical_record_text = "Patient expresses a psychological need to remain unclothed." + value = 0 + mood_quirk = TRUE + processing_quirk = TRUE + var/mood_category = "nudist_mood" + +/datum/quirk/nudist/on_process() + var/mob/living/carbon/human/H = quirk_holder + // Checking torso exposure appears to be a robust method. + if( ( H.is_chest_exposed() && H.is_groin_exposed() ) ) + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/nudist_positive) + else + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/nudist_negative) + +/datum/quirk/masked_mook + name = "Bane Syndrome" + desc = "For some reason you don't feel... right without wearing some kind of gas mask." + gain_text = "You start feeling unwell without any gas mask on." + lose_text = "You no longer have a need to wear some gas mask." + value = 0 + mood_quirk = TRUE + medical_record_text = "Patient feels more secure when wearing a gas mask." + processing_quirk = TRUE + var/mood_category = "masked_mook" + +/datum/quirk/masked_mook/on_process() + var/mob/living/carbon/human/H = quirk_holder + var/obj/item/clothing/mask/gas/gasmask = H.get_item_by_slot(ITEM_SLOT_MASK) + if(istype(gasmask)) + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/masked_mook) + else + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/masked_mook_incomplete) + +/datum/quirk/masked_mook/on_spawn() + . = ..() + var/mob/living/carbon/human/H = quirk_holder + var/obj/item/clothing/mask/gas/cosmetic/gasmask = new(get_turf(quirk_holder)) // Uses a custom gas mask + H.equip_to_slot(gasmask, ITEM_SLOT_MASK) + H.regenerate_icons() + /// quirk actions /// //vampire bite @@ -697,3 +835,71 @@ old_features["size"] = get_size(H) old_features["bark"] = H.vocal_bark_id +/datum/action/gargoyle/transform + name = "Transform" + desc = "Transform into a statue, regaining energy in the process. Additionally, you will slowly heal while in statue form." + icon_icon = 'icons/mob/actions/actions_changeling.dmi' + button_icon_state = "ling_camouflage" + var/obj/structure/statue/gargoyle/current = null + + +/datum/action/gargoyle/transform/Trigger() + .=..() + var/mob/living/carbon/human/H = owner + var/datum/quirk/gargoyle/T = locate() in H.roundstart_quirks + if(!T.cooldown) + if(!T.transformed) + if(!isturf(H.loc)) + return 0 + var/obj/structure/statue/gargoyle/S = new(H.loc, H) + S.name = "statue of [H.name]" + H.bleedsuppress = 1 + S.copy_overlays(H) + var/newcolor = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) + S.add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY) + current = S + T.transformed = 1 + T.cooldown = 30 + T.paused = 0 + S.dir = H.dir + return 1 + else + qdel(current) + T.transformed = 0 + T.cooldown = 30 + T.paused = 0 + H.visible_message("[H]'s skin rapidly softens, returning them to normal!", "Your skin softens, freeing your movement once more!") + else + to_chat(H, "You have transformed too recently; you cannot yet transform again!") + return 0 + +/datum/action/gargoyle/check + name = "Check" + desc = "Check your current energy levels." + icon_icon = 'icons/mob/actions/actions_clockcult.dmi' + button_icon_state = "Linked Vanguard" + +/datum/action/gargoyle/check/Trigger() + .=..() + var/mob/living/carbon/human/H = owner + var/datum/quirk/gargoyle/T = locate() in H.roundstart_quirks + to_chat(H, "You have [T.energy]/100 energy remaining!") + +/datum/action/gargoyle/pause + name = "Preserve" + desc = "Become near-motionless, thusly conserving your energy until you move from your current tile. Note, you will lose a chunk of energy when you inevitably move from your current position, so you cannot abuse this!" + icon_icon = 'icons/mob/actions/actions_flightsuit.dmi' + button_icon_state = "flightsuit_lock" + +datum/action/gargoyle/pause/Trigger() + .=..() + var/mob/living/carbon/human/H = owner + var/datum/quirk/gargoyle/T = locate() in H.roundstart_quirks + + if(!T.paused) + T.paused = 1 + T.position = H.loc + to_chat(H, "You are now conserving your energy; this effect will end the moment you move from your current position!") + return + else + to_chat(H, "You are already conserving your energy!") diff --git a/modular_splurt/code/game/objects/effects/decals/turfdecal/markings.dm b/modular_splurt/code/game/objects/effects/decals/turfdecal/markings.dm index 6870a2ef2b..ea13099fd8 100644 --- a/modular_splurt/code/game/objects/effects/decals/turfdecal/markings.dm +++ b/modular_splurt/code/game/objects/effects/decals/turfdecal/markings.dm @@ -132,3 +132,47 @@ /obj/effect/turf_decal/siding/wideplating/dark/end icon_state = "siding_wideplating_end" + +// Replaces the SS13 plaque +/obj/effect/turf_decal/plaque + icon = 'modular_splurt/icons/turf/decals.dmi' + icon_state = "L1" + +/obj/effect/turf_decal/plaque + icon_state = "L2" + +/obj/effect/turf_decal/plaque + icon_state = "L3" + +/obj/effect/turf_decal/plaque + icon_state = "L4" + +/obj/effect/turf_decal/plaque + icon_state = "L5" + +/obj/effect/turf_decal/plaque + icon_state = "L6" + +/obj/effect/turf_decal/plaque + icon_state = "L7" + +/obj/effect/turf_decal/plaque + icon_state = "L8" + +/obj/effect/turf_decal/plaque + icon_state = "L9" + +/obj/effect/turf_decal/plaque + icon_state = "L10" + +/obj/effect/turf_decal/plaque + icon_state = "L11" + +/obj/effect/turf_decal/plaque + icon_state = "L12" + +/obj/effect/turf_decal/plaque + icon_state = "L13" + +/obj/effect/turf_decal/plaque + icon_state = "L14" diff --git a/modular_splurt/code/game/objects/items/implants/implant_gfluid.dm b/modular_splurt/code/game/objects/items/implants/implant_gfluid.dm index 8c54ed9d3c..a337f5aa44 100644 --- a/modular_splurt/code/game/objects/items/implants/implant_gfluid.dm +++ b/modular_splurt/code/game/objects/items/implants/implant_gfluid.dm @@ -4,6 +4,10 @@ icon_state = "genital_fluid" var/use_blacklist = TRUE + // Custom action for extra customization + actions_types = list(/datum/action/item_action/genital_fluid_infuse) + +// Implant flavor text /obj/item/implant/genital_fluid/get_data() var/dat = {"Implant Specifications:
Name: Nanotrasen Genital Fluid Inducer Implant
@@ -12,69 +16,119 @@ Implant Details:
Function: Allows the user to induce their genitals into producing a specific reagent.
Special Features: Will prevent harmful liquids from being accepted as a genital fluid replace.
- Integrity: Implant will last so long as the implant is inside the host and they posess genitals capable of fluid production."} + Integrity: Implant will last so long as the implant is inside the host and they possess genitals capable of fluid production."} return dat +// Only allow use on "human" targets /obj/item/implant/genital_fluid/can_be_implanted_in(mob/living/target) if(!ishuman(target)) return FALSE . = ..() +// Runs on toggling the implant /obj/item/implant/genital_fluid/activate() . = ..() - var/list/obj/item/organ/genital/penidlist - var/list/datum/reagent/fluidlist = list() - var/mob/living/carbon/human/owner = imp_in - //List their genitals if they have any at all - for(var/obj/item/organ/genital/dicc in owner.internal_organs) - if(istype(dicc) && (dicc.genital_flags & GENITAL_FUID_PRODUCTION)) - LAZYADD(penidlist, dicc) + // Set list of possible genitals + var/list/obj/item/organ/genital/genitals_list + + // Set list of possible fluids + var/list/datum/reagent/fluid_list = list() + + // Set owner + var/mob/living/carbon/human/genital_owner = imp_in - //List their current reagents if they're valid - for(var/datum/reagent/pee in owner.reagents.reagent_list) - if((find_reagent_object_from_type(pee.type)) && ((pee.type in allowed_gfluid_paths()) || !use_blacklist)) - LAZYADD(fluidlist, find_reagent_object_from_type(pee.type)) + // List their genitals if they have any at all + for(var/obj/item/organ/genital/genital_checked in genital_owner.internal_organs) + if(istype(genital_checked) && (genital_checked.genital_flags & GENITAL_FUID_PRODUCTION)) + // Add genitals to the list + LAZYADD(genitals_list, genital_checked) - //List any reagents they may be holding in their hands - if(owner.available_rosie_palms(TRUE, /obj/item/reagent_containers)) - for(var/obj/item/reagent_containers/container in owner.held_items) + // List their current reagents if they're valid + for(var/datum/reagent/genital_reagent in genital_owner.reagents.reagent_list) + if((find_reagent_object_from_type(genital_reagent.type)) && ((genital_reagent.type in allowed_gfluid_paths()) || !use_blacklist)) + // Add valid reagents to the list + LAZYADD(fluid_list, find_reagent_object_from_type(genital_reagent.type)) + + // List any reagents they may be holding in their hands + if(genital_owner.available_rosie_palms(TRUE, /obj/item/reagent_containers)) + for(var/obj/item/reagent_containers/container in genital_owner.held_items) if(container.is_open_container() || istype(container, /obj/item/reagent_containers/food/snacks)) - for(var/datum/reagent/pee in container.reagents.reagent_list) - if((find_reagent_object_from_type(pee.type)) && ((pee.type in allowed_gfluid_paths()) || !use_blacklist)) - LAZYADD(fluidlist, find_reagent_object_from_type(pee.type)) + for(var/datum/reagent/genital_reagent in container.reagents.reagent_list) + if((find_reagent_object_from_type(genital_reagent.type)) && ((genital_reagent.type in allowed_gfluid_paths()) || !use_blacklist)) + // Add valid reagents to the list + LAZYADD(fluid_list, find_reagent_object_from_type(genital_reagent.type)) - //Return if genitals list is void/null - if(!penidlist) - SEND_SOUND(owner, 'sound/machines/terminal_error.ogg') - to_chat(owner, span_notice("ERROR: No compatible genitals detected.")) + // Return if genitals list is void/null + if(!genitals_list) + // Play an error sound + SEND_SOUND(genital_owner, 'sound/machines/terminal_error.ogg') + + // Alert the user in chat + to_chat(genital_owner, span_notice("ERROR: No compatible genitals detected.")) + + // Escape return - var/obj/item/organ/genital/cocc = tgui_input_list(owner, "Pick a genital", "Genital Fluid Infuser", penidlist) - if(!cocc) + // Prompt user for which genital to use + var/obj/item/organ/genital/genital_input = tgui_input_list(genital_owner, "Pick a genital", "Genital Fluid Infuser", genitals_list) + if(!genital_input) + // No selection was made return - fluidlist = list(find_reagent_object_from_type(cocc.get_default_fluid())) + fluidlist + // Update list of possible fluids + fluid_list = list(find_reagent_object_from_type(genital_input.get_default_fluid())) + fluid_list - var/datum/reagent/selection = tgui_input_list(owner, "Choose your new reagent", "Genital Fluid Infuser", fluidlist) - if(!selection) + // Prompt user to select a new fluid + var/datum/reagent/reagent_selection = tgui_input_list(genital_owner, "Choose your new reagent", "Genital Fluid Infuser", fluid_list) + if(!reagent_selection) + // No selection was made return - cocc.fluid_id = selection.type - SEND_SOUND(owner, 'sound/effects/bubbles.ogg') - to_chat(owner, span_notice("You feel the fluids inside your [cocc.name] bubble and swirl...")) - message_admins("[ADMIN_LOOKUPFLW(owner)] changed the fluid of their [owner.p_their()] [cocc.name] to [selection].") + // Set new fluid + genital_input.fluid_id = reagent_selection.type + + // Play the reagent processing sound effect + SEND_SOUND(genital_owner, 'sound/effects/bubbles.ogg') + + // Display flavor text + to_chat(genital_owner, span_notice("You feel the fluids inside your [genital_input.name] bubble and swirl...")) + // Send admin notice + message_admins("[ADMIN_LOOKUPFLW(genital_owner)] changed the fluid of [genital_owner.p_their()] [genital_input.name] to [reagent_selection].") + +// Unlock with an emag /obj/item/implant/genital_fluid/emag_act() . = ..() name = "hacked genital fluid implant" use_blacklist = FALSE obj_flags |= EMAGGED +/* + * Action datum +*/ + +// Action for updating genital fluids +/datum/action/item_action/genital_fluid_infuse + name = "Infuse Genital Fluids" + desc = "Activate an integrated reagent receptor device to modify your genital contents." + icon_icon = 'modular_splurt/icons/obj/implants.dmi' + button_icon_state = "genital_fluid" + background_icon_state = "bg_tech" + + // Restrict non-synthesizable reagents? + var/use_blacklist = TRUE + +/* + * Implant items +*/ + +// Implanter item /obj/item/implanter/genital_fluid name = "implanter (genital fluid)" imp_type = /obj/item/implant/genital_fluid +// Implanter item, emagged /obj/item/implanter/genital_fluid/hacked name = "implanter (genital fluid (hacked))" @@ -84,11 +138,13 @@ var/obj/item/implant/genital_fluid/I = imp I.emag_act() +// Implant case item /obj/item/implantcase/genital_fluid name = "implant case - 'Genital Fluid'" desc = "A glass case containing a Genital Fluid Infuser implant." imp_type = /obj/item/implant/genital_fluid +// Implant case item, emagged /obj/item/implantcase/genital_fluid/hacked name = "implant case - 'Genital Fluid (Hacked)'" diff --git a/modular_splurt/code/game/objects/items/implants/implant_hide_backpack.dm b/modular_splurt/code/game/objects/items/implants/implant_hide_backpack.dm new file mode 100644 index 0000000000..a4c02279a2 --- /dev/null +++ b/modular_splurt/code/game/objects/items/implants/implant_hide_backpack.dm @@ -0,0 +1,117 @@ +/obj/item/implant/hide_backpack + name = "storage concealment implant" + desc = "Prevents your backpack from being observable by the naked eye." + icon = 'modular_splurt/icons/obj/storage.dmi' + icon_state = "backpack_faded" + + // Custom action for extra customization + actions_types = list(/datum/action/item_action/hide_backpack) + +// Implant flavor text +/obj/item/implant/hide_backpack/get_data() + var/dat = {"Implant Specifications:
+ Name: Chameleon Storage Concealment Implant
+ Important Notes: Pending approval from some security teams.
+
+ Implant Details:
+ Function: Subject emits a weak psychic signal that conceals the presence of back-equipped gear items.
+ Integrity: Implant will last so long as the implant is inside the host."} + return dat + +// Only allow use on "human" targets +/obj/item/implant/hide_backpack/can_be_implanted_in(mob/living/target) + if(!ishuman(target)) + return FALSE + . = ..() + +/* + * Action datum +*/ + +// Action for toggling backpack +/datum/action/item_action/hide_backpack + name = "Conceal Backwear" + desc = "Toggle a weak psychic signal that conceals the presence of back-equipped gear items." + icon_icon = 'modular_splurt/icons/obj/storage.dmi' + button_icon_state = "backpack_faded" + background_icon_state = "bg_tech" + + // Is this being used? + var/ability_active = TRUE + +// Runs on gaining the ability +/datum/action/item_action/hide_backpack/Grant(mob/user) + . = ..() + + // Add the trait + adjust_trait(TRUE) + +// Runs on losing the ability +/datum/action/item_action/hide_backpack/Remove(mob/user) + . = ..() + + // Remove the trait + adjust_trait(FALSE) + +// Function to update trait +/datum/action/item_action/hide_backpack/proc/adjust_trait(state) + // Set owner + var/mob/living/carbon/human/action_owner = owner + + // Toggle trait status + if(state) + ADD_TRAIT(action_owner, TRAIT_HIDE_BACKPACK, TRAIT_GENERIC) + else + REMOVE_TRAIT(action_owner, TRAIT_HIDE_BACKPACK, TRAIT_GENERIC) + + // Update sprites + action_owner.update_inv_back() + +// Runs on toggling the ability +/datum/action/item_action/hide_backpack/Trigger() + // Set owner + var/mob/living/carbon/human/action_owner = owner + + // Update active status + ability_active = !ability_active + + // Update trait + adjust_trait(ability_active) + + // Set icon state variables + if(ability_active) + // Half-faded backpack + icon_icon = 'modular_splurt/icons/obj/storage.dmi' + button_icon_state = "backpack_faded" + else + // Normal backpack + icon_icon = 'icons/obj/storage.dmi' + button_icon_state = "backpack" + + // Update icon state + UpdateButtonIcon() + + // Display fake sparks to match flavor text + do_fake_sparks(2,FALSE,action_owner) + + // Set toggle text based on active state + var/implant_toggle_text = (!ability_active ? "discernible" : "imperceptible") + var/implant_toggle_text_2 = (!ability_active ? "dis" : "") // Engage or Disengage + + // Display a chat message + action_owner.visible_message("The equipment worn on [action_owner]'s back-region flickers momentarily, before becoming [implant_toggle_text].", "You [implant_toggle_text_2]engage the Storage Concealment Implant, causing your backpack to be [implant_toggle_text].") + +/* + * Implant items +*/ + +// Implanter item +/obj/item/implanter/hide_backpack + name = "implanter (storage concealment)" + imp_type = /obj/item/implant/hide_backpack + +// Implant case item +/obj/item/implantcase/hide_backpack + name = "implant case - 'Storage Concealment'" + desc = "A glass case containing a Storage Concealment implant." + imp_type = /obj/item/implant/hide_backpack diff --git a/modular_splurt/code/game/objects/items/stacks/sheets/sheet_types.dm b/modular_splurt/code/game/objects/items/stacks/sheets/sheet_types.dm index 01b020ae73..455ce2b67b 100644 --- a/modular_splurt/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/modular_splurt/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -120,3 +120,8 @@ GLOBAL_LIST_INIT(micro_bricks_recipes, list( \ /obj/item/stack/sheet/micro_bricks/get_main_recipes() . = ..() . += GLOB.micro_bricks_recipes + +// Hijack recipe loading to add new entries +/obj/item/stack/sheet/cloth/get_main_recipes() + . = ..() + . += new/datum/stack_recipe("handmade collar", /obj/item/clothing/neck/petcollar/handmade, 2) \ diff --git a/modular_splurt/code/game/objects/structures/flora.dm b/modular_splurt/code/game/objects/structures/flora.dm index c60cfffac3..7415f1ccb5 100644 --- a/modular_splurt/code/game/objects/structures/flora.dm +++ b/modular_splurt/code/game/objects/structures/flora.dm @@ -77,3 +77,6 @@ /obj/effect/spawner/grass_spawner/red name = "redgrass spawner" spawned_grass = /obj/structure/flora/grass/red + +/obj/structure/flora/tree/pine/xmas/presents + gift_type = /obj/item/a_gift //this is a modular nerf to christmas trees to limit what they hand out diff --git a/modular_splurt/code/game/objects/structures/statues.dm b/modular_splurt/code/game/objects/structures/statues.dm index d313578f0d..7eb3fbbb2b 100644 --- a/modular_splurt/code/game/objects/structures/statues.dm +++ b/modular_splurt/code/game/objects/structures/statues.dm @@ -13,3 +13,53 @@ desc = "A statue honoring Owia-Akeshi, a brave ashwalker that perished while defending the nest from a wild ash drake. May his soul rest in peace." impressiveness = 25 +/obj/structure/statue/gargoyle + name = "statue" + desc = "An incredibly intricate statue, which... almost seems alive!" + icon_state = "human_male" + density = TRUE + anchored = TRUE + flags_1 = PREVENT_CONTENTS_EXPLOSION_1 + max_integrity = 200 + var/mob/living/petrified_mob + +/obj/structure/statue/gargoyle/Initialize(mapload, mob/living/L) + . = ..() + if(L) + petrified_mob = L + if(L.buckled) + L.buckled.unbuckle_mob(L,force=1) + L.visible_message("[L]'s skin rapidly turns to stone!", "Your skin abruptly hardens as you turn to stone once more!") + L.forceMove(src) + ADD_TRAIT(L, TRAIT_MUTE, STATUE_TRAIT) + ADD_TRAIT(L, TRAIT_MOBILITY_NOMOVE, STATUE_TRAIT) + ADD_TRAIT(L, TRAIT_MOBILITY_NOPICKUP, STATUE_TRAIT) + ADD_TRAIT(L, TRAIT_MOBILITY_NOUSE, STATUE_TRAIT) + L.faction += "mimic" //Stops mimics from instaqdeling people in statues + L.status_flags |= GODMODE + obj_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues + max_integrity = obj_integrity + +/obj/structure/statue/gargoyle/handle_atom_del(atom/A) + if(A == petrified_mob) + petrified_mob = null + +/obj/structure/statue/gargoyle/Destroy() + if(petrified_mob) + petrified_mob.status_flags &= ~GODMODE + petrified_mob.forceMove(loc) + REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_TRAIT) + REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOMOVE, STATUE_TRAIT) + REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOPICKUP, STATUE_TRAIT) + REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOUSE, STATUE_TRAIT) + petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob + petrified_mob.faction -= "mimic" + petrified_mob = null + return ..() + +/obj/structure/statue/gargoyle/deconstruct(disassembled = TRUE) + if(!disassembled) + if(petrified_mob) + petrified_mob.dust() + visible_message("[src] shatters!.") + qdel(src) diff --git a/modular_splurt/code/modules/awaymissions/mission_code/academy.dm b/modular_splurt/code/modules/awaymissions/mission_code/academy.dm new file mode 100644 index 0000000000..b9fadc051e --- /dev/null +++ b/modular_splurt/code/modules/awaymissions/mission_code/academy.dm @@ -0,0 +1,21 @@ +//Academy Items + +/obj/item/dice/d20/fate + var/list/used_fingerprints = null // Used to track who used the one_use die + +/obj/item/dice/d20/fate/one_use + reusable = 1 // Obsolete by the used_fingerprints list + +/obj/item/dice/d20/fate/effect(var/mob/living/carbon/human/user,roll) + // This override checks if a user has rolled the dice + // If true; Reject them and abort + if (user in used_fingerprints) + // Send a message implying someone else should roll + visible_message("[user] rolls the dice, but it doesn't respond to [user.p_them()] again.") + return + // If false; Add them to the user list and continue + else + LAZYADD(used_fingerprints, user) + + // Run the function normally + ..() diff --git a/modular_splurt/code/modules/client/loadout/shoes.dm b/modular_splurt/code/modules/client/loadout/shoes.dm index 9079692059..d10f823444 100644 --- a/modular_splurt/code/modules/client/loadout/shoes.dm +++ b/modular_splurt/code/modules/client/loadout/shoes.dm @@ -2,6 +2,10 @@ /datum/gear/shoes/footwraps name = "Cloth Footwraps" path= /obj/item/clothing/shoes/footwraps + +/datum/gear/shoes/invisiboots + name = "Invisifiber Footwraps" + path= /obj/item/clothing/shoes/invisiboots /datum/gear/shoes/workboots/toeless name = "Toeless Work Boots" diff --git a/modular_splurt/code/modules/client/loadout/socks.dm b/modular_splurt/code/modules/client/loadout/socks.dm index 2deee41786..d44e772163 100644 --- a/modular_splurt/code/modules/client/loadout/socks.dm +++ b/modular_splurt/code/modules/client/loadout/socks.dm @@ -5,3 +5,7 @@ /datum/gear/socks/thigh/thigh_cow name = "Fishnet tights" path = /obj/item/clothing/underwear/socks/thigh/fishnet/white //This one is pretty much greyscale aka easier to recolor + +/datum/gear/socks/garter + name = "Garters" + path = /obj/item/clothing/underwear/socks/garter diff --git a/modular_splurt/code/modules/client/loadout/suit.dm b/modular_splurt/code/modules/client/loadout/suit.dm index 695ed1ed3e..51954f9b6a 100644 --- a/modular_splurt/code/modules/client/loadout/suit.dm +++ b/modular_splurt/code/modules/client/loadout/suit.dm @@ -96,10 +96,5 @@ /datum/gear/suit/tunnelfox name = "tunnel fox jacket" - path = /obj/item/clothing/suit/tunnelfox - subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS - -/datum/gear/suit/tunnelfox_t - name = "opened tunnel fox jacket" - path = /obj/item/clothing/suit/tunnelfox_t + path = /obj/item/clothing/suit/toggle/tunnelfox subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS diff --git a/modular_splurt/code/modules/clothing/kinkyclothes.dm b/modular_splurt/code/modules/clothing/kinkyclothes.dm index 5dfbc1b050..98bbb21e4a 100644 --- a/modular_splurt/code/modules/clothing/kinkyclothes.dm +++ b/modular_splurt/code/modules/clothing/kinkyclothes.dm @@ -136,7 +136,7 @@ SEND_SOUND(user, sound('modular_splurt/sound/effects/vaultsuit/InkSpotsSting.ogg', volume = 60)) return -/obj/item/clothing/suit/tunnelfox +/obj/item/clothing/suit/toggle/tunnelfox name = "tunnel fox jacket" desc = "Tunnel Foxes Rule!" icon = 'modular_splurt/icons/obj/clothing/suits.dmi' @@ -145,13 +145,5 @@ item_state = "tunnelfox" body_parts_covered = CHEST|LEGS|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - -/obj/item/clothing/suit/tunnelfox_t - name = "opened tunnel fox jacket" - desc = "Tunnel Foxes Rule!" - icon = 'modular_splurt/icons/obj/clothing/suits.dmi' - icon_state = "tunnelfox_t" - mob_overlay_icon = 'modular_splurt/icons/mob/clothing/suit.dmi' - item_state = "tunnelfox_t" - body_parts_covered = CHEST|LEGS|ARMS - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + togglename = "buttons" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON diff --git a/modular_splurt/code/modules/clothing/masks/gasmask.dm b/modular_splurt/code/modules/clothing/masks/gasmask.dm index 6e0debcff8..460d695571 100644 --- a/modular_splurt/code/modules/clothing/masks/gasmask.dm +++ b/modular_splurt/code/modules/clothing/masks/gasmask.dm @@ -32,3 +32,11 @@ name = "stripped trencher gas mask" desc = "A stripped version of No Man's Land-type mask equipment. While you can connect it to air supply, it doesn't block gas flow." armor = 0 + +// Cosmetic gas mask for Bane Syndrome (masked_mook) +/obj/item/clothing/mask/gas/cosmetic + name = "aesthetic gas mask" + desc = "A face-covering mask that resembles a traditional gas mask, but without the breathing functionality." + clothing_flags = NONE + gas_transfer_coefficient = 0 + permeability_coefficient = 0 diff --git a/modular_splurt/code/modules/clothing/shoes/miscellaneous.dm b/modular_splurt/code/modules/clothing/shoes/miscellaneous.dm index 8d1c1dd897..80e04717e6 100644 --- a/modular_splurt/code/modules/clothing/shoes/miscellaneous.dm +++ b/modular_splurt/code/modules/clothing/shoes/miscellaneous.dm @@ -6,6 +6,13 @@ mob_overlay_icon = 'modular_splurt/icons/mob/clothing/shoes.dmi' anthro_mob_worn_overlay = 'modular_splurt/icons/mob/clothing/shoes_digi.dmi' +/obj/item/clothing/shoes/invisiboots + name = "invisifiber footwraps" + desc = "A set of transparent fibers used for wrapping claws or paws." + icon = 'modular_splurt/icons/obj/clothing/shoes.dmi' + icon_state = "foot_wraps_transparent" + // No overlay, because they're invisible! + /obj/item/clothing/shoes/jackboots/toeless name = "toe-less jackboots" desc = "Modified pair of jackboots, particularly friendly to those species whose toes hold claws." diff --git a/modular_splurt/code/modules/clothing/suits/jobs.dm b/modular_splurt/code/modules/clothing/suits/jobs.dm index c66ca33eb9..b62195363b 100644 --- a/modular_splurt/code/modules/clothing/suits/jobs.dm +++ b/modular_splurt/code/modules/clothing/suits/jobs.dm @@ -25,9 +25,11 @@ item_state = "hopformal" icon = 'modular_splurt/icons/obj/clothing/suits.dmi' mob_overlay_icon = 'modular_splurt/icons/mob/clothing/suit.dmi' + anthro_mob_worn_overlay = 'modular_splurt/icons/mob/clothing/suit.dmi' body_parts_covered = CHEST|GROIN|ARMS armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) togglename = "buttons" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/suit/toggle/armor/hop/hop_formal/Initialize() . = ..() diff --git a/modular_splurt/code/modules/clothing/under/jobs/civilian/civilian.dm b/modular_splurt/code/modules/clothing/under/jobs/civilian/civilian.dm index d08862aa90..9b577874e6 100644 --- a/modular_splurt/code/modules/clothing/under/jobs/civilian/civilian.dm +++ b/modular_splurt/code/modules/clothing/under/jobs/civilian/civilian.dm @@ -3,10 +3,10 @@ desc = "A male head of personnel's luxury-wear, for special occasions." icon = 'modular_splurt/icons/obj/clothing/uniforms.dmi' mob_overlay_icon = 'modular_splurt/icons/mob/clothing/uniform.dmi' + anthro_mob_worn_overlay = 'modular_splurt/icons/mob/clothing/uniform_digi.dmi' icon_state = "hop_parade_male" item_state = "hop_parade_male" can_adjust = FALSE - mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/under/rank/civilian/head_of_personnel/parade/female name = "head of personnel's parade uniform" @@ -14,7 +14,6 @@ icon_state = "hop_parade_female" item_state = "hop_parade_female" fitted = FEMALE_UNIFORM_TOP - mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/under/rank/civilian/lawyer/galaxy_blue name = "\improper De Void of Soul" diff --git a/modular_splurt/code/modules/clothing/under/miscellaneous.dm b/modular_splurt/code/modules/clothing/under/miscellaneous.dm index 45d1ee6ef2..dc4696af4e 100644 --- a/modular_splurt/code/modules/clothing/under/miscellaneous.dm +++ b/modular_splurt/code/modules/clothing/under/miscellaneous.dm @@ -307,3 +307,7 @@ name = "yellow trencher uniform" desc = "An utilitarian uniform of rugged warfare, with yellow insignias." icon_state = "goner_uniform_y" + +/obj/item/clothing/under/misc/gear_harness + body_parts_covered = NONE + diff --git a/modular_splurt/code/modules/food_and_drinks/recipes/drink_recipes.dm b/modular_splurt/code/modules/food_and_drinks/recipes/drink_recipes.dm index 87a11eee76..a587e9fc71 100644 --- a/modular_splurt/code/modules/food_and_drinks/recipes/drink_recipes.dm +++ b/modular_splurt/code/modules/food_and_drinks/recipes/drink_recipes.dm @@ -86,11 +86,12 @@ /datum/chemical_reaction/moth_in_chief name = "Moth in Chief" id = /datum/reagent/consumable/ethanol/moth_in_chief - results = list(/datum/reagent/consumable/ethanol/moth_in_chief = 3) + results = list(/datum/reagent/consumable/ethanol/moth_in_chief = 4) required_reagents = list( /datum/reagent/consumable/ethanol/commander_and_chief = 1, /datum/reagent/mutationtoxin/insect = 1, - /datum/reagent/drug/copium = 1 + /datum/reagent/drug/copium = 1, + /datum/reagent/medicine/stimulants = 1 ) @@ -116,7 +117,7 @@ /datum/chemical_reaction/long_john_silver name = "Long John Silver" - id = /datum/chemical_reaction/long_john_silver + id = /datum/reagent/consumable/ethanol/long_john_silver results = list(/datum/reagent/consumable/ethanol/long_john_silver = 10) required_reagents = list( /datum/reagent/consumable/ethanol/navy_rum = 4, @@ -126,7 +127,7 @@ /datum/chemical_reaction/long_haul name = "Long Haul" - id = /datum/chemical_reaction/long_haul + id = /datum/reagent/consumable/ethanol/long_haul results = list(/datum/reagent/consumable/ethanol/long_haul = 25) required_reagents = list( /datum/reagent/consumable/ethanol/navy_rum = 4, @@ -138,7 +139,7 @@ /datum/chemical_reaction/salt_and_swell name = "Salt and Swell" - id = /datum/chemical_reaction/salt_and_swell + id = /datum/reagent/consumable/ethanol/salt_and_swell results = list(/datum/reagent/consumable/ethanol/salt_and_swell = 10) required_reagents = list( /datum/reagent/consumable/ethanol/navy_rum = 4, @@ -149,7 +150,7 @@ /datum/chemical_reaction/tich_toch name = "Tich Toch" - id = /datum/chemical_reaction/tich_toch + id = /datum/reagent/consumable/ethanol/tich_toch results = list(/datum/reagent/consumable/ethanol/tich_toch = 10) required_reagents = list( /datum/reagent/consumable/ethanol/tiltaellen = 6, @@ -159,7 +160,7 @@ /datum/chemical_reaction/tiltaellen name = "Tiltällen" - id = /datum/chemical_reaction/tiltaellen + id = /datum/reagent/consumable/ethanol/tiltaellen results = list(/datum/reagent/consumable/ethanol/tiltaellen = 10) required_reagents = list( /datum/reagent/consumable/yoghurt = 8, @@ -169,8 +170,8 @@ mix_message = "The mixture curdles and thickens." /datum/chemical_reaction/tropical_storm - name = "" - id = /datum/chemical_reaction/ + name = "Tropical Storm" + id = /datum/reagent/consumable/ethanol/tropical_storm results = list(/datum/reagent/consumable/ethanol/tropical_storm = 10) required_reagents = list( /datum/reagent/consumable/ethanol/rum = 2, @@ -179,3 +180,12 @@ /datum/reagent/consumable/pineapplejuice = 2 ) +/datum/chemical_reaction/skullfucker_deluxe + name = "Skullfucker Deluxe" + id = /datum/reagent/consumable/ethanol/skullfucker_deluxe + results = list(/datum/reagent/consumable/ethanol/skullfucker_deluxe = 5) + required_reagents = list( + /datum/reagent/consumable/ethanol/sugar_rush = 2, + /datum/reagent/consumable/ethanol/moonshine = 2, + /datum/reagent/consumable/ethanol/brave_bull = 1 + ) diff --git a/modular_splurt/code/modules/jobs/job_types/_job_alt_titles.dm b/modular_splurt/code/modules/jobs/job_types/_job_alt_titles.dm index 77217712c4..4e4663a72e 100644 --- a/modular_splurt/code/modules/jobs/job_types/_job_alt_titles.dm +++ b/modular_splurt/code/modules/jobs/job_types/_job_alt_titles.dm @@ -57,7 +57,11 @@ . = ..() /datum/job/cmo - alt_titles = list("Medical Director", "Medical Administrator") // Sandcode do not have alt titles for CMO at the moment. + alt_titles = list( + "Medical Director", + "Medical Administrator", + "Chief Heal Slut" + ) // Sandcode do not have alt titles for CMO at the moment. // Engineering @@ -99,7 +103,8 @@ "Bard", "Snack", "Stress Relief", - "Freeloader" + "Freeloader", + "Station Pet" ) LAZYADD(alt_titles, extra_titles) . = ..() @@ -193,7 +198,8 @@ "Researcher", "Toxins Researcher", "Research Intern", - "Junior Scientist" + "Junior Scientist", + "Rack Researcher" ) LAZYADD(alt_titles, extra_titles) . = ..() @@ -211,7 +217,8 @@ var/list/extra_titles = list( "Alchemist", "Apothecarist", - "Chemical Plumber" + "Chemical Plumber", + "Chemi-Slut" ) LAZYADD(alt_titles, extra_titles) . = ..() @@ -221,7 +228,8 @@ "Physician", "Medical Intern", "Medical Resident", - "Medtech" + "Medtech", + "Medi-Slut" ) LAZYADD(alt_titles, extra_titles) . = ..() @@ -235,21 +243,24 @@ "Hypnotherapist", "Sex Educator", "Rental Mommy", - "Rental Daddy" + "Rental Daddy", + "Psycholo-Slut" ) LAZYADD(alt_titles, extra_titles) . = ..() /datum/job/geneticist/New() var/list/extra_titles = list( - "Genetics Researcher" + "Genetics Researcher", + "Gene-Slut" ) LAZYADD(alt_titles, extra_titles) . = ..() /datum/job/paramedic/New() var/list/extra_titles = list( - "Trauma Team" + "Trauma Team", + "Para-Slut" ) LAZYADD(alt_titles, extra_titles) . = ..() @@ -257,7 +268,8 @@ /datum/job/virologist/New() var/list/extra_titles = list( "Microbiologist", - "Biochemist" + "Biochemist", + "Viro-Slut" ) LAZYADD(alt_titles, extra_titles) . = ..() diff --git a/modular_splurt/code/modules/jobs/job_types/peacekeeper.dm b/modular_splurt/code/modules/jobs/job_types/peacekeeper.dm index e155e8839c..d2b1c4b206 100644 --- a/modular_splurt/code/modules/jobs/job_types/peacekeeper.dm +++ b/modular_splurt/code/modules/jobs/job_types/peacekeeper.dm @@ -12,7 +12,16 @@ exp_requirements = 100 exp_type = EXP_TYPE_CREW considered_combat_role = FALSE - alt_titles = list("Slutcurity Trainee", "Security Trainee", "Security Assistant", "Security Cadet", "Security Trainee", "Rookie") + alt_titles = list( + "Slutcurity Trainee", + "Security Trainee", + "Security Assistant", + "Security Cadet", + "Security Trainee", + "Rookie", + "Hired Muscle", + "Bodyguard" + ) custom_spawn_text = " Your job is to help Security and react to minor crimes. Conflict de-escalation through WORDS is your top priority. Only use your taser as a last resort.You are NOT a Security Officer." outfit = /datum/outfit/job/peacekeeper diff --git a/modular_splurt/code/modules/mob/living/carbon/human/physiology.dm b/modular_splurt/code/modules/mob/living/carbon/human/physiology.dm new file mode 100644 index 0000000000..fb5bf6ca6c --- /dev/null +++ b/modular_splurt/code/modules/mob/living/carbon/human/physiology.dm @@ -0,0 +1,2 @@ +/datum/physiology + var/thirst_mod = 1 //% of thirst rate taken per tick. diff --git a/modular_splurt/code/modules/mob/living/carbon/human/species.dm b/modular_splurt/code/modules/mob/living/carbon/human/species.dm index ff61696ab9..3ffad4c2b4 100644 --- a/modular_splurt/code/modules/mob/living/carbon/human/species.dm +++ b/modular_splurt/code/modules/mob/living/carbon/human/species.dm @@ -4,3 +4,32 @@ to_chat(user, "You can't seem to force yourself up right now!") return . = ..() + +/datum/species/handle_thirst(mob/living/carbon/human/H) + if(HAS_TRAIT(H, TRAIT_NOTHIRST)) + return + + // A lot of this is just copied and pasted from the handle_digestion proc + if (H.thirst > 0 && H.stat != DEAD && !HAS_TRAIT(H, TRAIT_NOTHIRST)) + // THEY ~~HUNGER~~ THIRST + var/thirst_rate = THIRST_FACTOR + /* + var/datum/component/mood/mood = H.GetComponent(/datum/component/mood) + if(mood && mood.sanity > SANITY_DISTURBED) + thirst_rate *= max(0.5, 1 - 0.002 * mood.sanity) //0.85 to 0.75 + + // Whether we cap off our satiety or move it towards 0 + if(H.satiety > MAX_SATIETY) + H.satiety = MAX_SATIETY + else if(H.satiety > 0) + H.satiety-- + else if(H.satiety < -MAX_SATIETY) + H.satiety = -MAX_SATIETY + else if(H.satiety < 0) + H.satiety++ + if(prob(round(-H.satiety/40))) + H.Jitter(5) + thirst_rate = 3 * THIRST_FACTOR + */ + thirst_rate *= H.physiology.thirst_mod + H.adjust_thirst(-thirst_rate) diff --git a/modular_splurt/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/modular_splurt/code/modules/mob/living/carbon/human/species_types/dullahan.dm deleted file mode 100644 index 94689e4b6c..0000000000 --- a/modular_splurt/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ /dev/null @@ -1,2 +0,0 @@ -/obj/item/organ/tongue/dullahan - initial_accents = list(/datum/accent/dullahan) diff --git a/modular_splurt/code/modules/mob/living/carbon/human/update_icons.dm b/modular_splurt/code/modules/mob/living/carbon/human/update_icons.dm new file mode 100644 index 0000000000..7274e95154 --- /dev/null +++ b/modular_splurt/code/modules/mob/living/carbon/human/update_icons.dm @@ -0,0 +1,13 @@ +// Function for updating back sprites +/mob/living/carbon/human/update_inv_back() + . = ..() + + // Check for hidden backpack trait + if(HAS_TRAIT(src, TRAIT_HIDE_BACKPACK)) + // Define back overlays + var/mutable_appearance/back_overlay = overlays_standing[BACK_LAYER] + + // Check for existing overlay + if(back_overlay) + // Remove overlays + remove_overlay(BACK_LAYER) diff --git a/modular_splurt/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/modular_splurt/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm new file mode 100644 index 0000000000..97a09630a4 --- /dev/null +++ b/modular_splurt/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -0,0 +1,11 @@ +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/GiveTarget(new_target) + var/targets_the_same = (new_target == target) + . = ..() + + // Escape clause from original + if(!(. && target && !targets_the_same)) + return + + // Unique dialog for Cursed Blood + if(HAS_TRAIT(target, TRAIT_CURSED_BLOOD)) + say(pick("Hunter, you must accept your death, be freed from the night.","The night, and the dream, were long...","Beasts all over the shop... You'll be one of them, sooner or later...","The night blocks all sight...")) diff --git a/modular_splurt/code/modules/mob/living/simple_animal/hostile/megafauna/sand.dm b/modular_splurt/code/modules/mob/living/simple_animal/hostile/megafauna/sand.dm new file mode 100644 index 0000000000..32c51c16a1 --- /dev/null +++ b/modular_splurt/code/modules/mob/living/simple_animal/hostile/megafauna/sand.dm @@ -0,0 +1,7 @@ +/mob/living/simple_animal/hostile/megafauna/sand + name = "Corrupted Mayhem" + desc = "The longer you look at this creature the more you feel your gut twist and you begin to feel sick..." + icon = 'modular_splurt/icons/mob/lavaland/mayhem_mega.dmi' + icon_state = "eva" + icon_living = "eva" + attack_sound = 'modular_splurt/sound/voice/ara-ara2.ogg' diff --git a/modular_splurt/code/modules/mob/mob_helpers.dm b/modular_splurt/code/modules/mob/mob_helpers.dm new file mode 100644 index 0000000000..111f9c35b7 --- /dev/null +++ b/modular_splurt/code/modules/mob/mob_helpers.dm @@ -0,0 +1,22 @@ +// Modular-friendly way of adding new quirk-based inspect text +// Hijacks the function used for abductor examine +/mob/common_trait_examine() + // The ever-important funny BYOND dots + . = ..() + + // Empathy abilities escape clause + // Please change this when adding new quirk detection + if(!(HAS_TRAIT(usr, TRAIT_EMPATH) || HAS_TRAIT(usr, TRAIT_FRIENDLY) || src == usr)) + return + + // Pronoun stuff + var/t_He = p_they(FALSE) + //var/t_his = p_their() + //var/t_is = p_are() + + // Check for Distant (no touch head!) + if(HAS_TRAIT(src, TRAIT_DISTANT)) + . += "You sense [t_He] might be disturbed by physical affection.\n" + // Check for Heatpat Slut (pls touch head!) + if(HAS_TRAIT(src, TRAIT_HEADPAT_SLUT)) + . += "You sense [t_He] appreciates receiving physical affection more than normal.\n" diff --git a/modular_splurt/code/modules/mob/splurt_emotes.dm b/modular_splurt/code/modules/mob/splurt_emotes.dm index 7881c92c4c..e7984093f1 100644 --- a/modular_splurt/code/modules/mob/splurt_emotes.dm +++ b/modular_splurt/code/modules/mob/splurt_emotes.dm @@ -870,3 +870,44 @@ return user.nextsoundemote = world.time + 3 SECONDS playsound(user, 'modular_splurt/sound/voice/missouri.ogg', 50, 0, -1) + +/datum/emote/living/facemetacarpus + key = "facehand" // Facepalm was taken + key_third_person = "facepalms" + // Message is generated from metacarpus_type below. You shouldn't see this! + message = "creates an error in the code." + emote_type = EMOTE_AUDIBLE // Hear a slapping sound + muzzle_ignore = TRUE // Not a spoken emote + restraint_check = TRUE // Uses your hands + mob_type_allowed_typecache = list(/mob/living/carbon) // Don't let borgs do this + // Defines appendage type for generated message + var/metacarpus_type = "palm" // Default to hands + +/datum/emote/living/facemetacarpus/run_emote(mob/user, params, type_override, intentional) + // Randomly pick a message using metacarpus_type for hand + message = pick(list( + "places [usr.p_their()] [metacarpus_type] across [usr.p_their()] face.", + "lowers [usr.p_their()] face into [usr.p_their()] [metacarpus_type].", + "face[metacarpus_type]s", + )) + if(!(. = ..())) + return + if(user.nextsoundemote >= world.time) + return + user.nextsoundemote = world.time + 10 + playsound(user, 'modular_splurt/sound/effects/slap.ogg', 50, 1, -1) + +/datum/emote/living/facemetacarpus/paw + key = "facepaw" // For furries + key_third_person = "facepaws" + metacarpus_type = "paw" + +/datum/emote/living/facemetacarpus/claw + key = "faceclaw" // For scalies and avians + key_third_person = "faceclaws" + metacarpus_type = "claw" + +/datum/emote/living/facemetacarpus/hoof + key = "facehoof" // For horse enthusiasts + key_third_person = "facehoofs" + metacarpus_type = "hoof" diff --git a/modular_splurt/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/modular_splurt/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 7a2fbfa79b..024b95a7d1 100644 --- a/modular_splurt/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/modular_splurt/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -147,12 +147,49 @@ boozepwr = 50 color = "#0919be" quality = DRINK_FANTASTIC + value = REAGENT_VALUE_AMAZING taste_description = "fuzz, warmth and comfort" glass_icon = 'modular_splurt/icons/obj/drinks.dmi' glass_icon_state = "mothinchief" glass_name = "Moth in Chief" glass_desc = "A simple yet elegant drink, inspires confidence in even the most pessimistic of men. The mantle rests well upon your shoulders." + can_synth = FALSE; +//This drink gives the combined benefits of Stimulants, Regenerative Jelly, and Commander and Chief, and a mood buff similar to Copium; at least to an extent. +/datum/reagent/consumable/ethanol/commander_and_chief/on_mob_life(mob/living/carbon/M) + if(M.mind && HAS_TRAIT(M.mind, TRAIT_CAPTAIN_METABOLISM)) + M.heal_bodypart_damage(2,2,2) + M.adjustBruteLoss(-5,0) + M.adjustOxyLoss(-5,0) + M.adjustFireLoss(-5,0) + M.adjustToxLoss(-5,0,TRUE) //Heals Toxin Lovers + M.radiation = max(M.radiation - 25, 0) + . = 1 + else + //Commander and Chief Effects, no need to be captain to receive the effect + M.heal_bodypart_damage(2,2,2) + M.adjustBruteLoss(-3.5,0) + M.adjustOxyLoss(-3.5,0) + M.adjustFireLoss(-3.5,0) + M.adjustToxLoss(-3.5,0,TRUE) //Heals Toxin Lovers + M.radiation = max(M.radiation - 25, 0) + + //Stimulant Effects + M.AdjustAllImmobility(-60, FALSE) + M.AdjustUnconscious(-60, FALSE) + M.adjustStaminaLoss(-20*REAGENTS_EFFECT_MULTIPLIER, FALSE) + ..() + . = 1 + +/datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L) + ..() + L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants) + ADD_TRAIT(L, TRAIT_TASED_RESISTANCE, type) + +/datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/L) + L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants) + REMOVE_TRAIT(L, TRAIT_TASED_RESISTANCE, type) + ..() // ~( Ported from TG )~ /datum/reagent/consumable/ethanol/curacao @@ -286,3 +323,41 @@ glass_name = "Tropical Storm" glass_desc = "Less destructive than the real thing." +/datum/reagent/consumable/ethanol/skullfucker_deluxe + name = "Skullfucker Deluxe" + description = "The Rosewater secret to becoming psychotically retarded. It has many warning labels." + boozepwr = 75 + color = "#cb4d8b" + quality = DRINK_VERYGOOD + taste_description = "being violated by a tiny fish with crayons" + glass_icon = 'modular_splurt/icons/obj/drinks.dmi' + glass_icon_state = "skullfucker" + glass_name = "Skullfucker Deluxe" + glass_desc = "It has many warning labels, you might want to read them." + overdose_threshold = 25 + +/datum/reagent/consumable/ethanol/skullfucker_deluxe/on_mob_life(mob/living/carbon/C) + . = ..() + //Do nothing if they haven't metabolized enough + if(!current_cycle >= 15) + return + //Make them giggle + if(prob(40)) + C.emote("giggle") + //Make them jitter + if(prob(20)) + C.jitteriness = max(C.jitteriness, 30) + +/datum/reagent/consumable/ethanol/skullfucker_deluxe/overdose_process(mob/living/M) + . = ..() + //Do nothing if they're already fwuffy OwO + var/obj/item/organ/tongue/T = M.getorganslot(ORGAN_SLOT_TONGUE) + if(istype(T, /obj/item/organ/tongue/fluffy)) + return + + //Replace their tongue with a fwuffy one + var/obj/item/organ/tongue/nT = new /obj/item/organ/tongue/fluffy + T.Remove() + nT.Insert(M) + T.moveToNullspace()//To valhalla + to_chat(M, "Your tongue feels... weally fwuffy!!") diff --git a/modular_splurt/code/modules/reagents/chemistry/reagents/other_reagents.dm b/modular_splurt/code/modules/reagents/chemistry/reagents/other_reagents.dm index 31f0580ea2..f8d456ef05 100644 --- a/modular_splurt/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/modular_splurt/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -32,8 +32,43 @@ C.adjust_nutrition(6) //3/4ed this, felt it was a bit too much C.adjust_disgust(-3) //makes the churches effects easily negated -/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)//makes holy water slightly disgusting and hungering for vampires +/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M) . = ..() + //makes holy water slightly disgusting and hungering for vampires if(HAS_TRAIT(M,BLOODFLEDGE)) M.adjust_disgust(1) M.adjust_nutrition(-0.1) + + // Cursed blood effect moved here + if(HAS_TRAIT(M, TRAIT_CURSED_BLOOD)) + // Wait for stuttering, to match old effect + if(!M.stuttering) + return + + // Escape clause: 12% chance to continue + if(!prob(12)) + return + + // Character speaks nonsense + M.say(pick("Somebody help me...","Unshackle me please...","Anybody... I've had enough of this dream...","The night blocks all sight...","Oh, somebody, please..."), forced = "holy water") + + // Escape clause: 10% chance to continue + if(!prob(10)) + return + + // Character has a seisure + M.visible_message("[M] starts having a seizure!", "You have a seizure!") + M.Unconscious(120) + to_chat(M, "[pick("The moon is close. It will be a long hunt tonight.", "Ludwig, why have you forsaken me?", \ + "The night is near its end...", "Fear the blood...")]") + + // Apply damage + M.adjustToxLoss(1, 0) + M.adjustFireLoss(1, 0) + + // Escape clause: 25% chance to continue + if(!prob(25)) + return + + // Spontaneous combustion + M.IgniteMob() diff --git a/modular_splurt/code/modules/research/designs/mechfabricator_designs.dm b/modular_splurt/code/modules/research/designs/mechfabricator_designs.dm index 30dac8eabf..e9cd434e54 100644 --- a/modular_splurt/code/modules/research/designs/mechfabricator_designs.dm +++ b/modular_splurt/code/modules/research/designs/mechfabricator_designs.dm @@ -181,7 +181,7 @@ category = list("IPC Organs") /datum/design/ipc_tongue - name = "IPC Positronic Voicebox" + name = "IPC Voicebox" desc = "A voice synthesizer used by IPCs to smoothly interface with organic lifeforms." id = "ipc_tongue" build_type = MECHFAB @@ -191,7 +191,7 @@ category = list("IPC Organs") /datum/design/ipc_brain - name = "IPC Positronic Brain" + name = "IPC Brain (inert)" desc = "A cube of shining metal, four inches to a side and covered in shallow grooves. It has an IPC serial number engraved on the top. It is usually slotted into the head of synthetic crewmembers." id = "ipc_brain" build_type = MECHFAB diff --git a/modular_splurt/code/modules/research/designs/medical_designs.dm b/modular_splurt/code/modules/research/designs/medical_designs.dm index 225e9a88cf..e5228d97ec 100644 --- a/modular_splurt/code/modules/research/designs/medical_designs.dm +++ b/modular_splurt/code/modules/research/designs/medical_designs.dm @@ -18,6 +18,16 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_MEDICAL +/datum/design/implant_hide_backpack + name = "Storage Concealment Implant Case" + desc = "A glass case containing an implant" + id = "implant_hide_backpack" + build_type = PROTOLATHE + materials = list(/datum/material/glass = 500) + build_path = /obj/item/implantcase/hide_backpack + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_MEDICAL + /datum/design/board/implantradio name = "Radio Implant Case" desc = "A glass case containing an implant" diff --git a/modular_splurt/code/modules/research/techweb/nodes/medical_nodes.dm b/modular_splurt/code/modules/research/techweb/nodes/medical_nodes.dm index 055abbde37..eeb846271f 100644 --- a/modular_splurt/code/modules/research/techweb/nodes/medical_nodes.dm +++ b/modular_splurt/code/modules/research/techweb/nodes/medical_nodes.dm @@ -1,7 +1,8 @@ /datum/techweb_node/subdermal_implants/New() var/list/extra_designs = list( "implant_gfluid", - "implant_slave" + "implant_slave", + "implant_hide_backpack" ) LAZYADD(design_ids, extra_designs) . = ..() diff --git a/modular_splurt/code/modules/vending/clothesmate.dm b/modular_splurt/code/modules/vending/clothesmate.dm index 3eb8e21e00..d7d67e4011 100644 --- a/modular_splurt/code/modules/vending/clothesmate.dm +++ b/modular_splurt/code/modules/vending/clothesmate.dm @@ -14,8 +14,7 @@ /obj/item/clothing/head/helmet/goner/fake/poly = 10, /obj/item/clothing/under/raccveralls = 3, /obj/item/clothing/under/officesexy = 3, - /obj/item/clothing/suit/tunnelfox = 3, - /obj/item/clothing/suit/tunnelfox_t = 3, + /obj/item/clothing/suit/toggle/tunnelfox = 3, /obj/item/clothing/under/performer = 2, /obj/item/clothing/under/bluedress = 3 ) @@ -27,6 +26,24 @@ /obj/item/clothing/under/rank/civilian/lawyer/galaxy_blue = 3, /obj/item/clothing/head/helmet/goner/officer/fake/poly = 10 ) + + if(SSevents.holidays && SSevents.holidays[CHRISTMAS]) + extra_products += list( + /obj/item/clothing/accessory/sweater/uglyxmas = 3, + /obj/item/clothing/under/costume/christmas = 3, + /obj/item/clothing/under/costume/christmas/green = 3, + /obj/item/clothing/under/costume/christmas/croptop = 3, + /obj/item/clothing/under/costume/christmas/croptop/green = 3, + /obj/item/clothing/suit/hooded/wintercoat/christmascoatr = 3, + /obj/item/clothing/suit/hooded/wintercoat/christmascoatg = 3, + /obj/item/clothing/suit/hooded/wintercoat/christmascoatrg = 3, + /obj/item/clothing/head/christmashat = 3, + /obj/item/clothing/head/christmashatg = 3, + /obj/item/clothing/shoes/winterboots/christmasbootsr = 3, + /obj/item/clothing/shoes/winterboots/christmasbootsg = 3, + /obj/item/clothing/shoes/winterboots/santaboots = 3, + ) + LAZYADD(products, extra_products) LAZYADD(contraband, extra_contraband) LAZYADD(premium, extra_premium) diff --git a/modular_splurt/code/modules/vending/kinkmate.dm b/modular_splurt/code/modules/vending/kinkmate.dm index 25f18c53c3..69c67b15cc 100644 --- a/modular_splurt/code/modules/vending/kinkmate.dm +++ b/modular_splurt/code/modules/vending/kinkmate.dm @@ -27,7 +27,8 @@ /obj/item/strapon_strap = 5, /obj/item/restraints/bondage_rope = 5, /obj/item/clothing/under/domina = 5, - /obj/item/clothing/under/performer = 3 + /obj/item/clothing/under/performer = 3, + /obj/item/clothing/shoes/invisiboots = 10 // Added here to go with the Gear Harness ) var/list/extra_contraband = list( //Lewd-Clothes diff --git a/modular_splurt/code/modules/vending/security.dm b/modular_splurt/code/modules/vending/security.dm index 8d088e9adb..e6d78f958f 100644 --- a/modular_splurt/code/modules/vending/security.dm +++ b/modular_splurt/code/modules/vending/security.dm @@ -5,7 +5,10 @@ /obj/item/clothing/suit/armor/vest/peacekeeper = 5, /obj/item/clothing/suit/armor/vest/metrocop = 2, /obj/item/clothing/head/helmet/metrocop = 2, - /obj/item/storage/bag/security = 5 + /obj/item/storage/bag/security = 5, + /obj/item/clothing/head/helmet/blueshirt = 5, + /obj/item/clothing/under/rank/security/officer/blueshirt = 5, + /obj/item/clothing/suit/armor/vest/blueshirt = 5 ) var/list/extra_contraband = list( /obj/item/storage/belt/slut = 5, @@ -20,6 +23,13 @@ ) LAZYADD(products, extra_products) LAZYADD(contraband, extra_contraband) + + var/list/rem_premium = list( + /obj/item/clothing/head/helmet/blueshirt, + /obj/item/clothing/under/rank/security/officer/blueshirt, + /obj/item/clothing/suit/armor/vest/blueshirt + ) + LAZYREMOVE(premium, rem_premium) . = ..() /obj/machinery/vending/wardrobe/sec_wardrobe/Initialize() diff --git a/modular_splurt/icons/mob/clothing/uniform_digi.dmi b/modular_splurt/icons/mob/clothing/uniform_digi.dmi index 5be7dc6120..ce963b6af7 100644 Binary files a/modular_splurt/icons/mob/clothing/uniform_digi.dmi and b/modular_splurt/icons/mob/clothing/uniform_digi.dmi differ diff --git a/modular_splurt/icons/mob/lavaland/mayhem_mega.dmi b/modular_splurt/icons/mob/lavaland/mayhem_mega.dmi new file mode 100644 index 0000000000..9179698a8e Binary files /dev/null and b/modular_splurt/icons/mob/lavaland/mayhem_mega.dmi differ diff --git a/modular_splurt/icons/obj/clothing/shoes.dmi b/modular_splurt/icons/obj/clothing/shoes.dmi index bf8a3df1f1..71b62b42bc 100644 Binary files a/modular_splurt/icons/obj/clothing/shoes.dmi and b/modular_splurt/icons/obj/clothing/shoes.dmi differ diff --git a/modular_splurt/icons/obj/drinks.dmi b/modular_splurt/icons/obj/drinks.dmi index 91ad1df14e..4339e5560a 100644 Binary files a/modular_splurt/icons/obj/drinks.dmi and b/modular_splurt/icons/obj/drinks.dmi differ diff --git a/modular_splurt/icons/obj/genitals/butt_onmob.dmi b/modular_splurt/icons/obj/genitals/butt_onmob.dmi index 3dfc27316a..4cf7ee313e 100644 Binary files a/modular_splurt/icons/obj/genitals/butt_onmob.dmi and b/modular_splurt/icons/obj/genitals/butt_onmob.dmi differ diff --git a/modular_splurt/icons/obj/storage.dmi b/modular_splurt/icons/obj/storage.dmi index 1b8f40e8a0..35d61848a9 100644 Binary files a/modular_splurt/icons/obj/storage.dmi and b/modular_splurt/icons/obj/storage.dmi differ diff --git a/modular_splurt/icons/turf/decals.dmi b/modular_splurt/icons/turf/decals.dmi index cc04e1aae7..715e3fd253 100644 Binary files a/modular_splurt/icons/turf/decals.dmi and b/modular_splurt/icons/turf/decals.dmi differ diff --git a/modular_splurt/sound/voice/barks/kazooie/ahuh.ogg b/modular_splurt/sound/voice/barks/kazooie/ahuh.ogg new file mode 100644 index 0000000000..fbade63d6d Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/ahuh.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/birdwhistle.ogg b/modular_splurt/sound/voice/barks/kazooie/birdwhistle.ogg new file mode 100644 index 0000000000..f970f8af45 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/birdwhistle.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/birdwhistle2.ogg b/modular_splurt/sound/voice/barks/kazooie/birdwhistle2.ogg new file mode 100644 index 0000000000..61fd3e850b Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/birdwhistle2.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/caw.ogg b/modular_splurt/sound/voice/barks/kazooie/caw.ogg new file mode 100644 index 0000000000..21181b6519 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/caw.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/caw2.ogg b/modular_splurt/sound/voice/barks/kazooie/caw2.ogg new file mode 100644 index 0000000000..e4e4645034 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/caw2.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/caw3.ogg b/modular_splurt/sound/voice/barks/kazooie/caw3.ogg new file mode 100644 index 0000000000..8339440d77 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/caw3.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/cry.ogg b/modular_splurt/sound/voice/barks/kazooie/cry.ogg new file mode 100644 index 0000000000..b34b8d0c49 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/cry.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/dwoop.ogg b/modular_splurt/sound/voice/barks/kazooie/dwoop.ogg new file mode 100644 index 0000000000..785a18431f Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/dwoop.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/ehh.ogg b/modular_splurt/sound/voice/barks/kazooie/ehh.ogg new file mode 100644 index 0000000000..c0b5591ed5 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/ehh.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/ehh2.ogg b/modular_splurt/sound/voice/barks/kazooie/ehh2.ogg new file mode 100644 index 0000000000..830bb1e29e Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/ehh2.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/ehh3.ogg b/modular_splurt/sound/voice/barks/kazooie/ehh3.ogg new file mode 100644 index 0000000000..bb0925b68b Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/ehh3.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/ehh4.ogg b/modular_splurt/sound/voice/barks/kazooie/ehh4.ogg new file mode 100644 index 0000000000..5797b13179 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/ehh4.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/ehh5.ogg b/modular_splurt/sound/voice/barks/kazooie/ehh5.ogg new file mode 100644 index 0000000000..970a2040bc Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/ehh5.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/eugh.ogg b/modular_splurt/sound/voice/barks/kazooie/eugh.ogg new file mode 100644 index 0000000000..6ba2440e0e Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/eugh.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/faucet.ogg b/modular_splurt/sound/voice/barks/kazooie/faucet.ogg new file mode 100644 index 0000000000..56a98a8539 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/faucet.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/faucet2.ogg b/modular_splurt/sound/voice/barks/kazooie/faucet2.ogg new file mode 100644 index 0000000000..02af88442a Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/faucet2.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/growl.ogg b/modular_splurt/sound/voice/barks/kazooie/growl.ogg new file mode 100644 index 0000000000..b6dd00a75c Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/growl.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/growl2.ogg b/modular_splurt/sound/voice/barks/kazooie/growl2.ogg new file mode 100644 index 0000000000..5bd7219602 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/growl2.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/haha.ogg b/modular_splurt/sound/voice/barks/kazooie/haha.ogg new file mode 100644 index 0000000000..9ac43ce03c Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/haha.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/hoot.ogg b/modular_splurt/sound/voice/barks/kazooie/hoot.ogg new file mode 100644 index 0000000000..316949652c Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/hoot.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/moan1.ogg b/modular_splurt/sound/voice/barks/kazooie/moan1.ogg new file mode 100644 index 0000000000..8c014e4de0 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/moan1.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/moan2.ogg b/modular_splurt/sound/voice/barks/kazooie/moan2.ogg new file mode 100644 index 0000000000..4e6077552c Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/moan2.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/moan3.ogg b/modular_splurt/sound/voice/barks/kazooie/moan3.ogg new file mode 100644 index 0000000000..d3193a5693 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/moan3.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/raah1.ogg b/modular_splurt/sound/voice/barks/kazooie/raah1.ogg new file mode 100644 index 0000000000..74e4781177 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/raah1.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/raah2.ogg b/modular_splurt/sound/voice/barks/kazooie/raah2.ogg new file mode 100644 index 0000000000..ba3ff4f698 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/raah2.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/ribbit.ogg b/modular_splurt/sound/voice/barks/kazooie/ribbit.ogg new file mode 100644 index 0000000000..a4299d2a74 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/ribbit.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/slurp.ogg b/modular_splurt/sound/voice/barks/kazooie/slurp.ogg new file mode 100644 index 0000000000..a8518068c1 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/slurp.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/tweet.ogg b/modular_splurt/sound/voice/barks/kazooie/tweet.ogg new file mode 100644 index 0000000000..b784636e25 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/tweet.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/uhm.ogg b/modular_splurt/sound/voice/barks/kazooie/uhm.ogg new file mode 100644 index 0000000000..857e99c7c5 Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/uhm.ogg differ diff --git a/modular_splurt/sound/voice/barks/kazooie/zap.ogg b/modular_splurt/sound/voice/barks/kazooie/zap.ogg new file mode 100644 index 0000000000..524c73b1cd Binary files /dev/null and b/modular_splurt/sound/voice/barks/kazooie/zap.ogg differ diff --git a/modular_splurt/sound/voice/barks/poyo.ogg b/modular_splurt/sound/voice/barks/poyo.ogg new file mode 100644 index 0000000000..8b2a041e4d Binary files /dev/null and b/modular_splurt/sound/voice/barks/poyo.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 3aba984d72..013e1e0f3c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -226,6 +226,7 @@ #include "code\__HELPERS\vector.dm" #include "code\__HELPERS\verbs.dm" #include "code\__HELPERS\view.dm" +#include "code\__HELPERS\weakref.dm" #include "code\__HELPERS\yelling.dm" #include "code\__HELPERS\matrices\color_matrix.dm" #include "code\__HELPERS\matrices\transform_matrix.dm" @@ -578,6 +579,7 @@ #include "code\datums\components\combat_mode.dm" #include "code\datums\components\construction.dm" #include "code\datums\components\dejavu.dm" +#include "code\datums\components\dullahan.dm" #include "code\datums\components\earprotection.dm" #include "code\datums\components\edible.dm" #include "code\datums\components\edit_complainer.dm" @@ -730,6 +732,7 @@ #include "code\datums\elements\bed_tucking.dm" #include "code\datums\elements\bsa_blocker.dm" #include "code\datums\elements\cleaning.dm" +#include "code\datums\elements\connect_loc.dm" #include "code\datums\elements\decal.dm" #include "code\datums\elements\dusts_on_catatonia.dm" #include "code\datums\elements\dusts_on_leaving_area.dm" @@ -2081,6 +2084,7 @@ #include "code\modules\clothing\glasses\engine_goggles.dm" #include "code\modules\clothing\glasses\hud.dm" #include "code\modules\clothing\glasses\phantomthief.dm" +#include "code\modules\clothing\glasses\prescription_kit.dm" #include "code\modules\clothing\gloves\_gloves.dm" #include "code\modules\clothing\gloves\boxing.dm" #include "code\modules\clothing\gloves\color.dm" @@ -2762,7 +2766,6 @@ #include "code\modules\mob\living\carbon\human\species_types\arachnid.dm" #include "code\modules\mob\living\carbon\human\species_types\bugmen.dm" #include "code\modules\mob\living\carbon\human\species_types\corporate.dm" -#include "code\modules\mob\living\carbon\human\species_types\dullahan.dm" #include "code\modules\mob\living\carbon\human\species_types\dwarves.dm" #include "code\modules\mob\living\carbon\human\species_types\ethereal.dm" #include "code\modules\mob\living\carbon\human\species_types\felinid.dm" @@ -3391,6 +3394,7 @@ #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" #include "code\modules\recycling\conveyor2.dm" +#include "code\modules\recycling\conveyor_sorter.dm" #include "code\modules\recycling\sortingmachinery.dm" #include "code\modules\recycling\disposal\bin.dm" #include "code\modules\recycling\disposal\construction.dm" @@ -3953,6 +3957,7 @@ #include "modular_sand\code\_onclick\hud\screen_objects.dm" #include "modular_sand\code\controllers\configuration\entries\sandstorm.dm" #include "modular_sand\code\controllers\subsystem\interactions.dm" +#include "modular_sand\code\controllers\subsystem\job.dm" #include "modular_sand\code\controllers\subsystem\language.dm" #include "modular_sand\code\datums\action.dm" #include "modular_sand\code\datums\ai_laws.dm" @@ -4409,6 +4414,7 @@ #include "modular_splurt\code\game\objects\items\devices\radio\headset.dm" #include "modular_splurt\code\game\objects\items\implants\implant_aphropumps.dm" #include "modular_splurt\code\game\objects\items\implants\implant_gfluid.dm" +#include "modular_splurt\code\game\objects\items\implants\implant_hide_backpack.dm" #include "modular_splurt\code\game\objects\items\implants\implant_slave.dm" #include "modular_splurt\code\game\objects\items\implants\implant_slaver.dm" #include "modular_splurt\code\game\objects\items\implants\implantcase.dm" @@ -4519,6 +4525,7 @@ #include "modular_splurt\code\modules\atmospherics\machinery\components\unary_devices\vent_pump.dm" #include "modular_splurt\code\modules\atmospherics\machinery\components\unary_devices\vent_scrubber.dm" #include "modular_splurt\code\modules\atmospherics\machinery\other\miner.dm" +#include "modular_splurt\code\modules\awaymissions\mission_code\academy.dm" #include "modular_splurt\code\modules\cargo\supplypod.dm" #include "modular_splurt\code\modules\cargo\blackmarket\clothing.dm" #include "modular_splurt\code\modules\cargo\blackmarket\misc.dm" @@ -4650,6 +4657,7 @@ #include "modular_splurt\code\modules\mob\emote.dm" #include "modular_splurt\code\modules\mob\mob.dm" #include "modular_splurt\code\modules\mob\mob_defines.dm" +#include "modular_splurt\code\modules\mob\mob_helpers.dm" #include "modular_splurt\code\modules\mob\mob_movement.dm" #include "modular_splurt\code\modules\mob\say_vr.dm" #include "modular_splurt\code\modules\mob\splurt_emotes.dm" @@ -4679,7 +4687,9 @@ #include "modular_splurt\code\modules\mob\living\carbon\carbon.dm" #include "modular_splurt\code\modules\mob\living\carbon\human\human.dm" #include "modular_splurt\code\modules\mob\living\carbon\human\human_defines.dm" +#include "modular_splurt\code\modules\mob\living\carbon\human\physiology.dm" #include "modular_splurt\code\modules\mob\living\carbon\human\species.dm" +#include "modular_splurt\code\modules\mob\living\carbon\human\update_icons.dm" #include "modular_splurt\code\modules\mob\living\carbon\human\simple_animal\hostile\deathclaw\deathclaw.dm" #include "modular_splurt\code\modules\mob\living\carbon\human\simple_animal\hostile\deathclaw\funclaw.dm" #include "modular_splurt\code\modules\mob\living\carbon\human\species_types\arachnid.dm" @@ -4702,7 +4712,9 @@ #include "modular_splurt\code\modules\mob\living\simple_animal\gremlin\gremlin.dm" #include "modular_splurt\code\modules\mob\living\simple_animal\hostile\carrion.dm" #include "modular_splurt\code\modules\mob\living\simple_animal\hostile\dancer.dm" +#include "modular_splurt\code\modules\mob\living\simple_animal\hostile\megafauna\blood_drunk_miner.dm" #include "modular_splurt\code\modules\mob\living\simple_animal\hostile\megafauna\king_of_goats.dm" +#include "modular_splurt\code\modules\mob\living\simple_animal\hostile\megafauna\sand.dm" #include "modular_splurt\code\modules\paperwork\pen.dm" #include "modular_splurt\code\modules\power\cell.dm" #include "modular_splurt\code\modules\power\reactor\fluffed.dm" diff --git a/tgui/packages/tgui/interfaces/MobInteraction.tsx b/tgui/packages/tgui/interfaces/MobInteraction.tsx index 84b95fe13a..a1db0d6efd 100644 --- a/tgui/packages/tgui/interfaces/MobInteraction.tsx +++ b/tgui/packages/tgui/interfaces/MobInteraction.tsx @@ -2,8 +2,8 @@ import { filter, map, sortBy } from 'common/collections'; import { flow } from 'common/fp'; import { createSearch } from 'common/string'; import { useBackend, useLocalState } from '../backend'; -import { BlockQuote, Button, LabeledList, Icon, Input, Section, Table, Tabs, Stack, ProgressBar, Divider } from '../components'; -import { TableRow } from '../components/Table'; +import { BlockQuote, Button, Flex, LabeledList, Icon, Input, Section, Table, Tabs, Stack, ProgressBar, Divider } from '../components'; +import { TableCell, TableRow } from '../components/Table'; import { Window } from '../layouts'; type HeaderInfo = { @@ -34,6 +34,8 @@ type GenitalData = { extras: string, extra_choices: string[], possible_choices: string[], + can_arouse: boolean, + arousal_state: boolean, } type GenitalManagerInfo = { @@ -65,27 +67,27 @@ type CharacterPrefsInfo = { } type ContentPrefsInfo = { - verb_consent: number, - lewd_verb_sounds: number, - arousable: number, - genital_examine: number, - vore_examine: number, - medihound_sleeper: number, - eating_noises: number, - digestion_noises: number, - trash_forcefeed: number, - forced_fem: number, - forced_masc: number, - hypno: number, - bimbofication: number, - breast_enlargement: number, - penis_enlargement: number, - butt_enlargement: number, - belly_inflation: number, - never_hypno: number, - no_aphro: number, - no_ass_slap: number, - no_auto_wag: number, + verb_consent: boolean, + lewd_verb_sounds: boolean, + arousable: boolean, + genital_examine: boolean, + vore_examine: boolean, + medihound_sleeper: boolean, + eating_noises: boolean, + digestion_noises: boolean, + trash_forcefeed: boolean, + forced_fem: boolean, + forced_masc: boolean, + hypno: boolean, + bimbofication: boolean, + breast_enlargement: boolean, + penis_enlargement: boolean, + butt_enlargement: boolean, + belly_inflation: boolean, + never_hypno: boolean, + no_aphro: boolean, + no_ass_slap: boolean, + no_auto_wag: boolean, } export const MobInteraction = (props, context) => { @@ -131,12 +133,12 @@ export const MobInteraction = (props, context) => {
- + setTabIndex(0)}> Interactions setTabIndex(1)}> - Genital Visibility + Genital Options setTabIndex(2)}> Character Prefs @@ -151,7 +153,7 @@ export const MobInteraction = (props, context) => { {tabIndex === 0 && ( ) || tabIndex === 1 && ( - + ) || tabIndex === 2 && ( ) || tabIndex === 3 && ( @@ -243,42 +245,73 @@ const ModeToIcon = { "Allows egg stuffing": "egg", }; -const GenitalVisibilityTab = (props, context) => { +/* + Greetings you, yes you, adding more stuff to actions, + To not have as much headache as i did, + do not attempt to make a sum of 100% with the buttons + as it will mess up math somewhere and overflow. + + Also this is adjusted only for the current size, + if anyone feels like shrinking, + their window it will overflow anyways. + Single items is fine. +*/ +const GenitalTab = (props, context) => { const { act, data } = useBackend(context); const genitals = data.genitals || []; return ( genitals.length ? ( - - - {genitals.map(genital => ( - - {genital.possible_choices.map(choice => ( -