diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm index e2b11a02964eb..228c55292fbb0 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm @@ -90,6 +90,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) +"bp" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "bu" = ( /obj/effect/turf_decal/siding/wood, /obj/structure/table/wood, @@ -216,9 +223,15 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 5 }, -/obj/machinery/smartfridge/organ, -/obj/item/organ/alien/resinspinner, -/obj/item/organ/eyes/night_vision, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/item/clothing/gloves/latex/coroner{ + pixel_x = -1; + pixel_y = 8 + }, +/obj/item/clothing/mask/surgical{ + pixel_x = 6; + pixel_y = 10 + }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "cE" = ( @@ -498,9 +511,10 @@ /obj/effect/decal/cleanable/blood/gibs/down, /turf/open/floor/iron/cafeteria, /area/ruin/syndibiodome) -"gX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/warm/directional/west, +"gZ" = ( +/obj/machinery/door/airlock/maintenance_hatch, +/obj/structure/cable/layer1, +/obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "ha" = ( @@ -509,10 +523,10 @@ /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/noteleport) "he" = ( -/mob/living/basic/gorilla/genetics, /obj/effect/turf_decal/siding/wood/corner{ dir = 1 }, +/mob/living/basic/gorilla/hostile, /turf/open/floor/wood, /area/ruin/syndibiodome) "hf" = ( @@ -527,8 +541,8 @@ /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "hm" = ( -/mob/living/basic/gorilla/genetics, /obj/effect/decal/cleanable/dirt/dust, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark/small, /area/ruin/syndibiodome) "hr" = ( @@ -639,14 +653,12 @@ }, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) -"iq" = ( -/obj/structure/flora/rock/pile/style_random, -/mob/living/carbon/human/species/monkey/angry, -/turf/open/floor/grass, -/area/ruin/syndibiodome) "ir" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/dim/directional/east, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "iG" = ( @@ -723,16 +735,6 @@ }, /obj/effect/decal/cleanable/blood/drip, /obj/effect/decal/cleanable/dirt, -/obj/structure/table/reinforced/plastitaniumglass, -/obj/item/surgery_tray/full, -/obj/item/clothing/gloves/latex/coroner{ - pixel_x = -1; - pixel_y = 8 - }, -/obj/item/clothing/mask/surgical{ - pixel_x = 6; - pixel_y = 10 - }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "jd" = ( @@ -771,9 +773,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) -"jQ" = ( -/turf/closed/indestructible/syndicate/nodiagonal, -/area/icemoon/surface/outdoors/noteleport) "jR" = ( /obj/effect/decal/cleanable/blood/trails{ dir = 4 @@ -1025,9 +1024,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) -"mK" = ( -/turf/open/misc/asteroid/snow/icemoon, -/area/ruin/syndibiodome) "mV" = ( /obj/effect/turf_decal/siding/wideplating/dark, /obj/effect/decal/cleanable/dirt/dust, @@ -1040,6 +1036,9 @@ "mW" = ( /obj/effect/spawner/random/trash, /obj/effect/decal/cleanable/dirt, +/obj/structure/cable/layer3, +/obj/structure/cable/layer1, +/obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "mZ" = ( @@ -1113,6 +1112,13 @@ /obj/effect/turf_decal/trimline/dark_red/line, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) +"on" = ( +/obj/machinery/door/airlock/maintenance_hatch, +/obj/structure/cable/layer3, +/obj/structure/cable/layer1, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "oq" = ( /obj/effect/decal/cleanable/blood/trails{ dir = 10 @@ -1147,7 +1153,7 @@ /obj/machinery/light/warm/directional/west, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/dirt, -/mob/living/basic/gorilla/genetics, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "oH" = ( @@ -1346,7 +1352,6 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 1 }, -/mob/living/carbon/human/species/monkey/angry, /obj/machinery/light/warm/directional/north, /obj/machinery/digital_clock/directional/north, /obj/effect/decal/cleanable/dirt, @@ -1354,8 +1359,8 @@ /area/ruin/syndibiodome) "rQ" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/basic/gorilla/genetics, /obj/effect/decal/cleanable/dirt/dust, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "rX" = ( @@ -1434,7 +1439,6 @@ }, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt/dust, -/obj/effect/mapping_helpers/broken_machine, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) "td" = ( @@ -1701,12 +1705,20 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) +"vH" = ( +/obj/effect/spawner/random/trash, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "vJ" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/basic/gorilla/genetics, /obj/effect/turf_decal/trimline/purple/corner, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/dirt, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) "vK" = ( @@ -1959,7 +1971,6 @@ /obj/effect/turf_decal/trimline/dark/line{ dir = 1 }, -/mob/living/carbon/human/species/monkey/angry, /obj/effect/turf_decal/siding/wideplating/dark{ dir = 1 }, @@ -2100,7 +2111,6 @@ /turf/open/floor/grass, /area/ruin/syndibiodome) "yU" = ( -/mob/living/carbon/human/species/monkey/angry, /obj/effect/turf_decal/weather/dirt{ dir = 9 }, @@ -2235,6 +2245,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) +"Az" = ( +/obj/machinery/door/airlock/maintenance_hatch, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "AA" = ( /obj/effect/turf_decal/siding/wideplating/dark{ dir = 5 @@ -2262,9 +2279,9 @@ /obj/effect/decal/cleanable/dirt/dust, /obj/item/storage/belt/security/webbing, /obj/item/storage/toolbox/syndicate, -/obj/item/gun/ballistic/automatic/pistol, -/obj/item/ammo_box/magazine/m10mm, -/obj/item/ammo_box/magazine/m10mm, +/obj/item/gun/ballistic/automatic/pistol/contraband, +/obj/item/ammo_box/magazine/m9mm, +/obj/item/ammo_box/magazine/m9mm, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "Ba" = ( @@ -2496,7 +2513,6 @@ /turf/open/floor/iron/white/small, /area/ruin/syndibiodome) "EE" = ( -/mob/living/carbon/human/species/monkey/angry, /obj/effect/decal/cleanable/blood/trails{ dir = 1 }, @@ -2727,7 +2743,6 @@ "Hs" = ( /obj/structure/flora/bush/flowers_br/style_3, /obj/structure/flora/bush/flowers_yw/style_3, -/mob/living/carbon/human/species/monkey/angry, /obj/effect/gibspawner/human/bodypartless, /obj/effect/mob_spawn/corpse/human/syndicatecommando/lessenedgear, /turf/open/floor/grass, @@ -2810,6 +2825,14 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) +"Iq" = ( +/obj/machinery/light/small/dim/directional/west, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/layer3, +/obj/structure/cable/layer1, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "IF" = ( /obj/effect/mob_spawn/corpse/human/syndicatecommando/lessenedgear, /obj/effect/turf_decal/siding/wideplating/dark/end{ @@ -2947,6 +2970,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) +"Kl" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/layer3, +/obj/structure/cable/layer1, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/ruin/syndibiodome) "Kn" = ( /obj/effect/decal/cleanable/blood/footprints{ dir = 2 @@ -3087,6 +3117,9 @@ "LA" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/dim/directional/west, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "LB" = ( @@ -3192,6 +3225,8 @@ /turf/open/floor/iron/cafeteria, /area/ruin/syndibiodome) "Mr" = ( +/obj/machinery/light/warm/directional/west, +/obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "Mt" = ( @@ -3266,7 +3301,6 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 1 }, -/mob/living/carbon/human/species/monkey/angry, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/trimline/dark/line, /obj/effect/decal/cleanable/dirt/dust, @@ -3348,7 +3382,7 @@ /obj/effect/turf_decal/weather/dirt{ dir = 6 }, -/mob/living/basic/gorilla/genetics, +/mob/living/basic/gorilla/hostile, /turf/open/floor/grass, /area/ruin/syndibiodome) "NN" = ( @@ -3364,7 +3398,6 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 6 }, -/obj/effect/gibspawner/generic, /obj/machinery/digital_clock/directional/east, /obj/effect/decal/cleanable/dirt, /turf/open/floor/mineral/plastitanium/red, @@ -3379,11 +3412,8 @@ /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "Os" = ( -/obj/structure/bodycontainer/morgue/beeper_off{ - dir = 8 - }, /obj/effect/turf_decal/trimline/tram/filled, -/turf/open/floor/pod/dark, +/turf/closed/indestructible/syndicate/nodiagonal, /area/ruin/syndibiodome) "Oy" = ( /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, @@ -3392,13 +3422,6 @@ }, /turf/open/floor/plating, /area/ruin/syndibiodome) -"OD" = ( -/mob/living/carbon/human/species/monkey/angry, -/obj/effect/turf_decal/weather/dirt{ - dir = 6 - }, -/turf/open/floor/grass, -/area/ruin/syndibiodome) "OH" = ( /obj/effect/decal/cleanable/blood/trails{ dir = 8 @@ -3428,8 +3451,8 @@ /obj/machinery/light/warm/directional/east, /obj/item/storage/belt/security/webbing, /obj/item/gun/ballistic/automatic/pistol/contraband, -/obj/item/ammo_box/magazine/m10mm, -/obj/item/ammo_box/magazine/m10mm, +/obj/item/ammo_box/magazine/m9mm, +/obj/item/ammo_box/magazine/m9mm, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "OM" = ( @@ -3446,6 +3469,9 @@ "ON" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/dim/directional/south, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/structure/cable/layer3, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "OO" = ( @@ -3640,7 +3666,6 @@ /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "RK" = ( -/mob/living/carbon/human/species/monkey/angry, /obj/structure/chair/office/tactical{ dir = 4 }, @@ -3659,8 +3684,9 @@ /area/icemoon/surface/outdoors/noteleport) "RX" = ( /obj/effect/turf_decal/siding/wideplating/dark, -/mob/living/basic/gorilla/genetics, /obj/effect/decal/cleanable/dirt, +/obj/effect/gibspawner/generic, +/mob/living/basic/gorilla/hostile, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "Se" = ( @@ -3823,6 +3849,10 @@ dir = 1 }, /area/ruin/syndibiodome) +"To" = ( +/obj/machinery/door/airlock/maintenance_hatch, +/turf/open/floor/iron/dark, +/area/ruin/syndibiodome) "Tu" = ( /obj/structure/table/reinforced/plastitaniumglass, /obj/effect/turf_decal/siding/wideplating/dark{ @@ -3897,6 +3927,7 @@ /obj/item/stack/sheet/mineral/uranium/five, /obj/item/stack/sheet/mineral/uranium/five, /obj/effect/decal/cleanable/dirt, +/obj/machinery/light/warm/directional/east, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndibiodome) "TL" = ( @@ -3971,12 +4002,12 @@ /turf/open/floor/iron/dark/small, /area/ruin/syndibiodome) "Ux" = ( -/mob/living/basic/gorilla/genetics, /obj/effect/gibspawner/human/bodypartless, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/trimline/blue/corner{ dir = 4 }, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark, /area/ruin/syndibiodome) "Uz" = ( @@ -4223,8 +4254,8 @@ /obj/effect/decal/cleanable/blood/tracks{ dir = 4 }, -/mob/living/basic/gorilla/genetics, /obj/effect/decal/cleanable/dirt, +/mob/living/basic/gorilla/hostile, /turf/open/floor/iron/dark/herringbone, /area/ruin/syndibiodome) "XG" = ( @@ -4362,13 +4393,13 @@ /area/ruin/syndibiodome) "YZ" = ( /obj/effect/turf_decal/siding/wideplating/dark, -/mob/living/basic/gorilla/genetics, /obj/structure/fluff/fake_vent, /obj/effect/decal/cleanable/blood/trails{ dir = 1 }, /obj/effect/decal/cleanable/dirt, /obj/effect/gibspawner/human/bodypartless, +/mob/living/basic/gorilla/hostile, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) "Zd" = ( @@ -4690,7 +4721,7 @@ oq Mc zM zM -mK +ys ys ys tL @@ -4727,8 +4758,8 @@ ck ys ys zM -Ut -vx +Kl +on xi kw wL @@ -4820,8 +4851,8 @@ jS ys ys zM -Ut -Ut +Kl +Kl zM Sr zM @@ -4867,7 +4898,7 @@ pg pg zM zM -Ut +Kl zM zM Ab @@ -4914,7 +4945,7 @@ zd ys zM Db -Ut +Kl zM kK MB @@ -4961,7 +4992,7 @@ pg pg zM ic -Ut +Kl zM rK YZ @@ -5008,7 +5039,7 @@ uD ys zM wY -Ut +Kl zM cB ja @@ -5102,10 +5133,10 @@ AI ys ys zM -Ut -Ut -zM -zM +Kl +Kl +Iq +Ro zM zM zM @@ -5151,8 +5182,8 @@ Hi zM zM Ut -LA -Ro +Kl +Ut zM qN qU @@ -5198,10 +5229,10 @@ ys ys zM zM -Ut -Ut -Ut -vx +Kl +Kl +Kl +gZ je kt XC @@ -5582,7 +5613,7 @@ Fl qN IU vu -iq +MH YD Fp xz @@ -5664,13 +5695,13 @@ ys ck zM zM -mW -Ut +vH +bp ir -Ut -Ut -Ut -vx +bp +bp +bp +Az kw Eq CV @@ -5711,7 +5742,7 @@ ys ys zM MP -Ut +bp zM zM Ut @@ -5758,7 +5789,7 @@ ys ys zM qa -Ut +bp zM zM dS @@ -5805,7 +5836,7 @@ ys zM zM Sv -Ut +bp zM wx RH @@ -5852,7 +5883,7 @@ zM zM rZ Ut -Ut +bp zM Ra RX @@ -5899,7 +5930,7 @@ zM zM zM zM -Ut +bp zM Pw Oi @@ -5993,12 +6024,12 @@ Uc qp sR zM -Ut -Ut +bp +bp LA -mW -Ut -vx +vH +bp +Az Nt uW Vv @@ -6049,7 +6080,7 @@ qN pY XC XC -qN +To Ut zM Vj @@ -6060,7 +6091,7 @@ XE Mt WB iX -OD +cN zM ys uD @@ -6188,8 +6219,8 @@ zM zM zM zM -Vv zM +To zM LU qN @@ -6235,8 +6266,8 @@ zM ek Dc zM -zM -zM +Mr +Ut Mr Ut qN @@ -6283,7 +6314,7 @@ MM bu zM Kz -gX +Ut Ut Ut zM @@ -6428,7 +6459,7 @@ zM zM zM ys -jQ +zM zM zM zM diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index ed07ca2ba6784..b251d9f463ed6 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -2837,6 +2837,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "bfe" = ( @@ -2858,6 +2859,7 @@ /obj/structure/disposalpipe/junction/flip{ dir = 8 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "bfU" = ( @@ -6737,6 +6739,7 @@ /area/space/nearstation) "cCM" = ( /obj/structure/cable, +/obj/structure/sink/kitchen/directional/east, /turf/open/floor/iron/kitchen/small, /area/station/service/kitchen) "cCP" = ( @@ -10712,15 +10715,12 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/aft) "dZa" = ( -/obj/structure/table/reinforced, /obj/machinery/camera/directional/west, /obj/effect/decal/cleanable/cobweb, -/obj/item/retractor, -/obj/item/hemostat, -/obj/item/cautery, /obj/machinery/camera/autoname/directional/north, /obj/structure/sign/poster/official/random/directional/north, /obj/machinery/status_display/ai/directional/west, +/obj/item/surgery_tray/full/deployed, /turf/open/floor/iron/showroomfloor, /area/station/medical/surgery/theatre) "dZk" = ( @@ -13995,13 +13995,13 @@ /turf/open/floor/iron/small, /area/station/security/office) "fhp" = ( -/obj/structure/table, /obj/effect/spawner/random/food_or_drink/donkpockets{ pixel_y = 6 }, /obj/effect/turf_decal/siding{ dir = 8 }, +/obj/structure/table, /turf/open/floor/iron/dark/textured_large, /area/station/service/kitchen) "fhT" = ( @@ -14979,6 +14979,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "fyZ" = ( @@ -15861,6 +15862,7 @@ dir = 1 }, /obj/machinery/power/apc/auto_name/directional/south, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "fMg" = ( @@ -17874,10 +17876,6 @@ pixel_y = 8 }, /obj/item/clothing/mask/surgical, -/obj/item/surgical_drapes{ - pixel_x = -1; - pixel_y = 4 - }, /obj/machinery/status_display/evac/directional/west, /turf/open/floor/iron/showroomfloor, /area/station/medical/surgery/theatre) @@ -20068,6 +20066,11 @@ name = "Pharmacy Shutters Control"; req_access = list("pharmacy") }, +/obj/item/reagent_containers/cup/bottle/multiver, +/obj/item/reagent_containers/cup/bottle/epinephrine, +/obj/item/reagent_containers/cup/bottle/formaldehyde, +/obj/item/reagent_containers/cup/bottle/acidic_buffer, +/obj/item/reagent_containers/cup/bottle/basic_buffer, /turf/open/floor/iron/dark, /area/station/medical/pharmacy) "hdT" = ( @@ -24186,6 +24189,7 @@ pixel_y = 18 }, /obj/structure/extinguisher_cabinet/directional/east, +/obj/item/circuitboard/mecha/ripley/main, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) "ivC" = ( @@ -25595,6 +25599,16 @@ }, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) +"iPx" = ( +/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ + dir = 1; + filter_type = list(/datum/gas/nitrogen) + }, +/obj/effect/turf_decal/bot{ + dir = 1 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter/room) "iPy" = ( /obj/structure/cable, /turf/open/floor/iron, @@ -26328,6 +26342,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "jab" = ( @@ -35514,7 +35529,7 @@ "mae" = ( /obj/structure/cable, /turf/closed/wall, -/area/station/service/bar) +/area/station/maintenance/central/greater) "maf" = ( /turf/closed/wall/rust, /area/station/hallway/primary/fore) @@ -40681,6 +40696,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "nSd" = ( @@ -43687,6 +43703,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "oYj" = ( @@ -46106,6 +46123,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron/small, /area/station/hallway/primary/port) "pOQ" = ( @@ -51221,10 +51239,10 @@ pixel_y = 2 }, /obj/item/holosign_creator/robot_seat/restaurant, -/obj/structure/table, /obj/effect/turf_decal/siding{ dir = 9 }, +/obj/structure/table, /turf/open/floor/iron/dark/textured_large, /area/station/service/kitchen) "rya" = ( @@ -52583,7 +52601,7 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) "rVI" = ( -/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped{ +/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped/inverse{ dir = 8 }, /turf/open/floor/iron, @@ -54601,13 +54619,7 @@ /turf/open/misc/sandy_dirt, /area/station/security/tram) "sGt" = ( -/obj/structure/table/reinforced, -/obj/item/scalpel{ - pixel_y = 12 - }, -/obj/item/blood_filter, -/obj/item/circular_saw, -/obj/item/bonesetter, +/obj/structure/closet/crate/freezer/surplus_limbs, /turf/open/floor/iron/showroomfloor, /area/station/medical/surgery/theatre) "sGE" = ( @@ -61586,6 +61598,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "uQT" = ( @@ -62426,15 +62439,12 @@ /turf/open/floor/iron/smooth_large, /area/station/science/robotics/mechbay) "vfI" = ( -/obj/machinery/microwave{ - pixel_y = 5 - }, /obj/machinery/light_switch/directional/north, /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/structure/table, /obj/effect/turf_decal/siding/end, +/obj/machinery/smartfridge/drying, /turf/open/floor/iron/dark/textured_large, /area/station/service/kitchen) "vfK" = ( @@ -65162,9 +65172,15 @@ /turf/open/floor/iron/dark, /area/station/command/corporate_dock) "vTP" = ( -/obj/structure/sink/kitchen/directional/east, /obj/machinery/firealarm/directional/west, -/turf/open/floor/iron/kitchen/small, +/obj/structure/table, +/obj/machinery/microwave{ + pixel_y = 5 + }, +/obj/effect/turf_decal/siding/end{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured_large, /area/station/service/kitchen) "vTV" = ( /turf/closed/wall/r_wall, @@ -67829,7 +67845,7 @@ /obj/effect/spawner/random/maintenance, /obj/structure/rack, /turf/open/floor/plating, -/area/station/service/bar) +/area/station/maintenance/central/greater) "wKO" = ( /obj/structure/disposalpipe/segment, /obj/machinery/camera/directional/east, @@ -69552,6 +69568,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/port) "xiT" = ( @@ -90216,7 +90233,7 @@ jNV guh cBl fJe -aJb +iPx cay fMB maK @@ -98003,8 +98020,8 @@ xRV jVM xjQ jVM -tGq -tGq +jVM +jVM xmt xmt xmt @@ -100316,7 +100333,7 @@ jVM jVM jVM jVM -vkh +jVM lnD fzw bKO @@ -101344,7 +101361,7 @@ jgb hRc jVM kXC -vkh +jVM dxV jDT fOq @@ -101601,7 +101618,7 @@ vGe xno jVM kXC -vkh +jVM vkh kWF wtw @@ -102115,7 +102132,7 @@ xHD xHD jVM jBu -vkh +jVM vkh vkh vkh diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 5b3d50cdadd17..26baf69940954 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -115,7 +115,7 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list( #define ismoth(A) (is_species(A, /datum/species/moth)) #define isfelinid(A) (is_species(A, /datum/species/human/felinid)) #define isethereal(A) (is_species(A, /datum/species/ethereal)) -#define isvampire(A) (is_species(A,/datum/species/vampire)) +#define isvampire(A) (is_species(A,/datum/species/human/vampire)) #define isdullahan(A) (is_species(A, /datum/species/dullahan)) #define ismonkey(A) (is_species(A, /datum/species/monkey)) #define isandroid(A) (is_species(A, /datum/species/android)) diff --git a/code/__DEFINES/tracy.dm b/code/__DEFINES/tracy.dm new file mode 100644 index 0000000000000..0a9ab8d68ee24 --- /dev/null +++ b/code/__DEFINES/tracy.dm @@ -0,0 +1,5 @@ +/// File path used for the "enable tracy next round" functionality +#define TRACY_ENABLE_PATH "data/enable_tracy" + +/// The DLL path for byond-tracy. +#define TRACY_DLL_PATH (world.system_type == MS_WINDOWS ? "prof.dll" : "./libprof.so") diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index f4f5688819bb2..a0448be48c039 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -391,6 +391,12 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_DETECT_STORM "detect_storm" #define TRAIT_PRIMITIVE "primitive" #define TRAIT_GUNFLIP "gunflip" +/// eignore blindness or blurriness or nearsightedness +#define TRAIT_SIGHT_BYPASS "perfect_sight" +/// ignore traumas that make you 'hallucinate' something +#define TRAIT_PERCEPTUAL_TRAUMA_BYPASS "trauma_bypass" +/// mob is immune to hallucinations +#define TRAIT_HALLUCINATION_IMMUNE "hallucination_immune" /// Increases chance of getting special traumas, makes them harder to cure #define TRAIT_SPECIAL_TRAUMA_BOOST "special_trauma_boost" #define TRAIT_SPACEWALK "spacewalk" diff --git a/code/__HELPERS/atoms.dm b/code/__HELPERS/atoms.dm index d54b29b3f4ac9..e94d58dd69399 100644 --- a/code/__HELPERS/atoms.dm +++ b/code/__HELPERS/atoms.dm @@ -316,6 +316,46 @@ rough example of the "cone" made by the 3 dirs checked loc = loc.loc return null +/** + * Line of sight check! + * Spawns a dummy object and then iterates through each turf to see if it's blocked by something not handled by pass_args. + * Contains a mid_los_check, meant to be overriden by subtypes. + * args: + * * user = Origin to start at. + * * target = End point. + * * pass_args = pass_flags given to dummy object to allow it to ignore certain types of blockades. + */ +/proc/los_check(atom/movable/user, mob/target, pass_args = PASSTABLE|PASSGLASS|PASSGRILLE, datum/callback/mid_check) + var/turf/user_turf = user.loc + if(!istype(user_turf)) + return FALSE + var/obj/dummy = new(user_turf) + dummy.pass_flags |= pass_args //Grille/Glass so it can be used through common windows + var/turf/previous_step = user_turf + var/first_step = TRUE + for(var/turf/next_step as anything in (get_line(user_turf, target) - user_turf)) + if(first_step) + for(var/obj/blocker in user_turf) + if(!blocker.density || !(blocker.flags_1 & ON_BORDER_1)) + continue + if(blocker.CanPass(dummy, get_dir(user_turf, next_step))) + continue + return FALSE // Could not leave the first turf. + first_step = FALSE + if(next_step.density) + qdel(dummy) + return FALSE + for(var/atom/movable/movable as anything in next_step) + if(!movable.CanPass(dummy, get_dir(next_step, previous_step))) + qdel(dummy) + return FALSE + if(mid_check?.Invoke(user, target, pass_args, next_step, dummy) == FALSE) // specify false as it may return null if there's no check + qdel(dummy) + return FALSE + previous_step = next_step + qdel(dummy) + return TRUE + ///Returns true if the src countain the atom target /atom/proc/contains(atom/target) if(!target) diff --git a/code/_compile_options.dm b/code/_compile_options.dm index c42754644bb1a..7947c8c3d14ba 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -85,9 +85,13 @@ // If this is uncommented, will attempt to load and initialize prof.dll/libprof.so by default. // Even if it's not defined, you can pass "tracy" via -params in order to try to load it. -// We do not ship byond-tracy. Build it yourself here: https://github.com/mafemergency/byond-tracy/ +// We do not ship byond-tracy. Build it yourself here: https://github.com/mafemergency/byond-tracy, +// or the fork which writes profiling data to a file: https://github.com/ParadiseSS13/byond-tracy // #define USE_BYOND_TRACY +// If uncommented, will display info about byond-tracy's status in the MC tab. +// #define MC_TAB_TRACY_INFO + // If defined, we will compile with FULL timer debug info, rather then a limited scope // Be warned, this increases timer creation cost by 5x // #define TIMER_DEBUG diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 46a91854931ef..f7556662b97f1 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -275,6 +275,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_GREENTEXT_CURSED" = TRAIT_GREENTEXT_CURSED, "TRAIT_GUNFLIP" = TRAIT_GUNFLIP, "TRAIT_GUN_NATURAL" = TRAIT_GUN_NATURAL, + "TRAIT_HALLUCINATION_IMMUNE" = TRAIT_HALLUCINATION_IMMUNE, "TRAIT_HALT_RADIATION_EFFECTS" = TRAIT_HALT_RADIATION_EFFECTS, "TRAIT_HANDS_BLOCKED" = TRAIT_HANDS_BLOCKED, "TRAIT_HARDLY_WOUNDED" = TRAIT_HARDLY_WOUNDED, @@ -416,6 +417,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_PASSTABLE" = TRAIT_PASSTABLE, "TRAIT_PASSWINDOW" = TRAIT_PASSWINDOW, "TRAIT_PERCEIVED_AS_CLOWN" = TRAIT_PERCEIVED_AS_CLOWN, + "TRAIT_PERCEPTUAL_TRAUMA_BYPASS" = TRAIT_PERCEPTUAL_TRAUMA_BYPASS, "TRAIT_PERFECT_ATTACKER" = TRAIT_PERFECT_ATTACKER, "TRAIT_PERMANENTLY_MORTAL" = TRAIT_PERMANENTLY_MORTAL, "TRAIT_PHOTOGRAPHER" = TRAIT_PHOTOGRAPHER, @@ -465,6 +467,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SHAVED" = TRAIT_SHAVED, "TRAIT_SHIFTY_EYES" = TRAIT_SHIFTY_EYES, "TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE, + "TRAIT_SIGHT_BYPASS" = TRAIT_SIGHT_BYPASS, "TRAIT_SIGN_LANG" = TRAIT_SIGN_LANG, "TRAIT_SILENT_FOOTSTEPS" = TRAIT_SILENT_FOOTSTEPS, "TRAIT_SILICON_ACCESS" = TRAIT_SILICON_ACCESS, diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index f92bb4682e1c8..a2185b0386d2e 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -151,8 +151,16 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/hud/proc/client_refresh(datum/source) SIGNAL_HANDLER - RegisterSignal(mymob.canon_client, COMSIG_CLIENT_SET_EYE, PROC_REF(on_eye_change)) - on_eye_change(null, null, mymob.canon_client.eye) + var/client/client = mymob.canon_client + if(client.rebuild_plane_masters) + var/new_relay_loc = (client.byond_version > 515) ? "1,1" : "CENTER" + for(var/group_key as anything in master_groups) + var/datum/plane_master_group/group = master_groups[group_key] + group.relay_loc = new_relay_loc + group.rebuild_plane_masters() + client.rebuild_plane_masters = FALSE + RegisterSignal(client, COMSIG_CLIENT_SET_EYE, PROC_REF(on_eye_change)) + on_eye_change(null, null, client.eye) /datum/hud/proc/clear_client(datum/source) SIGNAL_HANDLER diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index e1ed3284441f6..3648a1b564e8c 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -762,3 +762,11 @@ default = 100 min_val = 0 max_val = 100 + +/// If admins with +DEBUG can initialize byond-tracy midround. +/datum/config_entry/flag/allow_tracy_start + protection = CONFIG_ENTRY_LOCKED + +/// If admins with +DEBUG can queue byond-tracy to run the next round. +/datum/config_entry/flag/allow_tracy_queue + protection = CONFIG_ENTRY_LOCKED diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 83c666de64ac4..e869f21c61560 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -88,7 +88,7 @@ SUBSYSTEM_DEF(blackbox) for(var/player_key in GLOB.player_details) var/datum/player_details/PD = GLOB.player_details[player_key] - record_feedback("tally", "client_byond_version", 1, PD.byond_version) + record_feedback("tally", "client_byond_version", 1, PD.full_byond_version()) /datum/controller/subsystem/blackbox/Shutdown() sealed = FALSE diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index cf158586ce497..9d33e977e2b7f 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -173,6 +173,24 @@ SUBSYSTEM_DEF(statpanels) list("Failsafe Controller:", Failsafe.stat_entry(), text_ref(Failsafe)), list("","") ) +#if defined(MC_TAB_TRACY_INFO) || defined(SPACEMAN_DMM) + var/static/tracy_dll + var/static/tracy_present + if(isnull(tracy_dll)) + tracy_dll = TRACY_DLL_PATH + tracy_present = fexists(tracy_dll) + if(tracy_present) + if(GLOB.tracy_initialized) + mc_data.Insert(2, list(list("byond-tracy:", "Active (reason: [GLOB.tracy_init_reason || "N/A"])"))) + else if(GLOB.tracy_init_error) + mc_data.Insert(2, list(list("byond-tracy:", "Errored ([GLOB.tracy_init_error])"))) + else if(fexists(TRACY_ENABLE_PATH)) + mc_data.Insert(2, list(list("byond-tracy:", "Queued for next round"))) + else + mc_data.Insert(2, list(list("byond-tracy:", "Inactive"))) + else + mc_data.Insert(2, list(list("byond-tracy:", "[tracy_dll] not present"))) +#endif for(var/datum/controller/subsystem/sub_system as anything in Master.subsystems) mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), text_ref(sub_system)) mc_data[++mc_data.len] = list("Camera Net", "Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]", text_ref(GLOB.cameranet)) diff --git a/code/datums/components/earprotection.dm b/code/datums/components/earprotection.dm index 6439e49b831f5..6dfa7d9568baf 100644 --- a/code/datums/components/earprotection.dm +++ b/code/datums/components/earprotection.dm @@ -2,10 +2,13 @@ signals = list(COMSIG_CARBON_SOUNDBANG) mobtype = /mob/living/carbon proctype = PROC_REF(reducebang) + var/reduce_amount = 1 -/datum/component/wearertargeting/earprotection/Initialize(_valid_slots) +/datum/component/wearertargeting/earprotection/Initialize(valid_slots, reduce_amount = 1) . = ..() - valid_slots = _valid_slots + src.valid_slots = valid_slots + if(reduce_amount) + src.reduce_amount = reduce_amount /datum/component/wearertargeting/earprotection/proc/reducebang(datum/source, list/reflist) - reflist[1]-- + reflist[1] -= reduce_amount diff --git a/code/datums/elements/cuffsnapping.dm b/code/datums/elements/cuffsnapping.dm index df445f4acc971..1abdc4a7a6bd2 100644 --- a/code/datums/elements/cuffsnapping.dm +++ b/code/datums/elements/cuffsnapping.dm @@ -42,13 +42,20 @@ src.snap_time_strong = snap_time_strong RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(target, COMSIG_ITEM_ATTACK , PROC_REF(try_cuffsnap_target)) + RegisterSignal(target, COMSIG_ITEM_ATTACK_SECONDARY, PROC_REF(try_cuffsnap_target)) + RegisterSignal(target, COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET, PROC_REF(add_item_context)) /datum/element/cuffsnapping/Detach(datum/target) - UnregisterSignal(target, list(COMSIG_ITEM_ATTACK, COMSIG_ATOM_EXAMINE)) - + UnregisterSignal(target, list(COMSIG_ITEM_ATTACK_SECONDARY, COMSIG_ATOM_EXAMINE, COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET)) return ..() +/datum/element/cuffsnapping/proc/add_item_context(obj/item/source, list/context, mob/living/carbon/target, mob/living/user) + SIGNAL_HANDLER + if(!iscarbon(target) || !target.handcuffed) + return NONE + context[SCREENTIP_CONTEXT_RMB] = "Cut Restraints" + return CONTEXTUAL_SCREENTIP_SET + ///signal called on parent being examined /datum/element/cuffsnapping/proc/on_examine(datum/target, mob/user, list/examine_list) SIGNAL_HANDLER @@ -56,7 +63,7 @@ var/examine_string if(isnull(snap_time_weak)) return - examine_string = "It looks like it could cut zipties or cable restraints off someone in [snap_time_weak] seconds" + examine_string = "It looks like it could be used to cut zipties or cable restraints off someone in [snap_time_weak] seconds" if(!isnull(snap_time_strong)) examine_string += ", and handcuffs in [snap_time_strong] seconds." @@ -65,7 +72,7 @@ examine_list += span_notice(examine_string) -/datum/element/cuffsnapping/proc/try_cuffsnap_target(obj/item/cutter, mob/living/carbon/target, mob/cutter_user, params) +/datum/element/cuffsnapping/proc/try_cuffsnap_target(obj/item/cutter, mob/living/carbon/target, mob/living/cutter_user, params) SIGNAL_HANDLER if(!istype(target)) //we aren't the kind of mob that can even have cuffs, so we skip. diff --git a/code/datums/elements/tenacious.dm b/code/datums/elements/tenacious.dm index 4d906812c13ab..35dd5774cf4be 100644 --- a/code/datums/elements/tenacious.dm +++ b/code/datums/elements/tenacious.dm @@ -18,6 +18,9 @@ /datum/element/tenacious/Detach(datum/target) UnregisterSignal(target, COMSIG_MOB_STATCHANGE) REMOVE_TRAIT(target, TRAIT_TENACIOUS, ELEMENT_TRAIT(type)) + var/mob/living/carbon/human/valid_target = target + if(valid_target.remove_movespeed_modifier(/datum/movespeed_modifier/tenacious)) + valid_target.balloon_alert(valid_target, "your tenacity wears off") return ..() ///signal called by the stat of the target changing @@ -27,6 +30,5 @@ if(new_stat == SOFT_CRIT) target.balloon_alert(target, "your tenacity kicks in") target.add_movespeed_modifier(/datum/movespeed_modifier/tenacious) - else + else if(target.remove_movespeed_modifier(/datum/movespeed_modifier/tenacious)) target.balloon_alert(target, "your tenacity wears off") - target.remove_movespeed_modifier(/datum/movespeed_modifier/tenacious) diff --git a/code/datums/status_effects/debuffs/blindness.dm b/code/datums/status_effects/debuffs/blindness.dm index 06a5a46b9427b..edb10d27ba44b 100644 --- a/code/datums/status_effects/debuffs/blindness.dm +++ b/code/datums/status_effects/debuffs/blindness.dm @@ -11,7 +11,12 @@ // fullheal should instead remove all the sources and in turn cure this /// Static list of signals that, when received, we force an update to our nearsighted overlay - var/static/list/update_signals = list(SIGNAL_ADDTRAIT(TRAIT_NEARSIGHTED_CORRECTED), SIGNAL_REMOVETRAIT(TRAIT_NEARSIGHTED_CORRECTED)) + var/static/list/update_signals = list( + SIGNAL_ADDTRAIT(TRAIT_NEARSIGHTED_CORRECTED), + SIGNAL_REMOVETRAIT(TRAIT_NEARSIGHTED_CORRECTED), + SIGNAL_ADDTRAIT(TRAIT_SIGHT_BYPASS), + SIGNAL_REMOVETRAIT(TRAIT_SIGHT_BYPASS), + ) /// How severe is our nearsightedness right now var/overlay_severity = 2 @@ -37,7 +42,11 @@ var/mob/living/carbon/human/human_owner = owner if (human_owner.get_eye_scars()) return TRUE - return !HAS_TRAIT(owner, TRAIT_NEARSIGHTED_CORRECTED) + if(HAS_TRAIT(owner, TRAIT_NEARSIGHTED_CORRECTED)) + return FALSE + if(HAS_TRAIT(owner, TRAIT_SIGHT_BYPASS)) + return FALSE + return TRUE /// Updates our nearsightd overlay, either removing it if we have the trait or adding it if we don't /datum/status_effect/grouped/nearsighted/proc/update_nearsighted_overlay() @@ -61,6 +70,10 @@ id = "blindness" tick_interval = STATUS_EFFECT_NO_TICK alert_type = /atom/movable/screen/alert/status_effect/blind + var/static/list/update_signals = list( + SIGNAL_REMOVETRAIT(TRAIT_SIGHT_BYPASS), + SIGNAL_ADDTRAIT(TRAIT_SIGHT_BYPASS), + ) // This is not "remove on fullheal" as in practice, // fullheal should instead remove all the sources and in turn cure this @@ -68,14 +81,34 @@ if(!CAN_BE_BLIND(owner)) return FALSE + RegisterSignals(owner, update_signals, PROC_REF(update_blindness)) + + update_blindness() + + return ..() + +/datum/status_effect/grouped/blindness/proc/update_blindness() + if(!CAN_BE_BLIND(owner)) // future proofing + qdel(src) + return + + if(HAS_TRAIT(owner, TRAIT_SIGHT_BYPASS)) + make_unblind() + return + make_blind() + +/datum/status_effect/grouped/blindness/proc/make_blind() owner.overlay_fullscreen(id, /atom/movable/screen/fullscreen/blind) // You are blind - at most, able to make out shapes near you owner.add_client_colour(/datum/client_colour/monochrome/blind) - return ..() -/datum/status_effect/grouped/blindness/on_remove() +/datum/status_effect/grouped/blindness/proc/make_unblind() owner.clear_fullscreen(id) owner.remove_client_colour(/datum/client_colour/monochrome/blind) + +/datum/status_effect/grouped/blindness/on_remove() + make_unblind() + UnregisterSignal(owner, update_signals) return ..() /atom/movable/screen/alert/status_effect/blind diff --git a/code/datums/status_effects/debuffs/hallucination.dm b/code/datums/status_effects/debuffs/hallucination.dm index 3f24ab02e60ac..66e85f1900a23 100644 --- a/code/datums/status_effects/debuffs/hallucination.dm +++ b/code/datums/status_effects/debuffs/hallucination.dm @@ -14,27 +14,39 @@ /// The cooldown for when the next hallucination can occur COOLDOWN_DECLARE(hallucination_cooldown) -/datum/status_effect/hallucination/on_creation(mob/living/new_owner, duration) +/datum/status_effect/hallucination/on_creation(mob/living/new_owner, duration, lower_tick_interval, upper_tick_interval) if(isnum(duration)) src.duration = duration + if(isnum(lower_tick_interval)) + src.lower_tick_interval = lower_tick_interval + if(isnum(upper_tick_interval)) + src.upper_tick_interval = upper_tick_interval return ..() /datum/status_effect/hallucination/on_apply() if(owner.mob_biotypes & barred_biotypes) return FALSE + if(HAS_TRAIT(owner, TRAIT_HALLUCINATION_IMMUNE)) + return FALSE RegisterSignal(owner, COMSIG_LIVING_HEALTHSCAN, PROC_REF(on_health_scan)) + RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_HALLUCINATION_IMMUNE), PROC_REF(delete_self)) if(iscarbon(owner)) RegisterSignal(owner, COMSIG_CARBON_CHECKING_BODYPART, PROC_REF(on_check_bodypart)) RegisterSignal(owner, COMSIG_CARBON_BUMPED_AIRLOCK_OPEN, PROC_REF(on_bump_airlock)) return TRUE +/datum/status_effect/hallucination/proc/delete_self() + SIGNAL_HANDLER + qdel(src) + /datum/status_effect/hallucination/on_remove() UnregisterSignal(owner, list( COMSIG_LIVING_HEALTHSCAN, COMSIG_CARBON_CHECKING_BODYPART, COMSIG_CARBON_BUMPED_AIRLOCK_OPEN, + SIGNAL_ADDTRAIT(TRAIT_HALLUCINATION_IMMUNE), )) /// Signal proc for [COMSIG_LIVING_HEALTHSCAN]. Show we're hallucinating to (advanced) scanners. diff --git a/code/datums/status_effects/debuffs/screen_blur.dm b/code/datums/status_effects/debuffs/screen_blur.dm index abdd07d3cd59b..acdce13b5a08a 100644 --- a/code/datums/status_effects/debuffs/screen_blur.dm +++ b/code/datums/status_effects/debuffs/screen_blur.dm @@ -18,7 +18,8 @@ return FALSE // Refresh the blur when a client jumps into the mob, in case we get put on a clientless mob with no hud - RegisterSignal(owner, COMSIG_MOB_LOGIN, PROC_REF(update_blur)) + RegisterSignals(owner, list(COMSIG_MOB_LOGIN, SIGNAL_ADDTRAIT(TRAIT_SIGHT_BYPASS), SIGNAL_REMOVETRAIT(TRAIT_SIGHT_BYPASS)), PROC_REF(update_blur)) + // Apply initial blur update_blur() return TRUE @@ -43,10 +44,13 @@ if(!owner.hud_used) return + var/atom/movable/plane_master_controller/game_plane_master_controller = owner.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] + if(HAS_TRAIT(owner, TRAIT_SIGHT_BYPASS)) + game_plane_master_controller.remove_filter("eye_blur") + return + var/time_left_in_seconds = (duration - world.time) / (1 SECONDS) var/amount_of_blur = clamp(time_left_in_seconds * BLUR_DURATION_TO_INTENSITY, 0.6, 3) - - var/atom/movable/plane_master_controller/game_plane_master_controller = owner.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] game_plane_master_controller.add_filter("eye_blur", 1, gauss_blur_filter(amount_of_blur)) #undef BLUR_DURATION_TO_INTENSITY diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 96233e59405b9..856c1204c720f 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -693,10 +693,12 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/on_preattack(datum/source, obj/item/thing, mob/user, params) SIGNAL_HANDLER - if(!istype(thing) || !allow_quick_gather || thing.atom_storage) + if(!istype(thing) || thing == parent.loc || !allow_quick_gather || thing.atom_storage) return if(collection_mode == COLLECT_ONE) + if(thing.loc == user) + user.dropItemToGround(thing, silent = TRUE) //this is nessassary to update any inventory slot it is attached to attempt_insert(thing, user) return COMPONENT_CANCEL_ATTACK_CHAIN diff --git a/code/datums/wires/mulebot.dm b/code/datums/wires/mulebot.dm index beb58fb1ce3b4..ec38d72898196 100644 --- a/code/datums/wires/mulebot.dm +++ b/code/datums/wires/mulebot.dm @@ -29,18 +29,24 @@ if(WIRE_MOTOR1, WIRE_MOTOR2) if(is_cut(WIRE_MOTOR1) && is_cut(WIRE_MOTOR2)) ADD_TRAIT(mule, TRAIT_IMMOBILIZED, MOTOR_LACK_TRAIT) + holder.audible_message(span_hear("The motors of [src] go silent."), null, 1) else REMOVE_TRAIT(mule, TRAIT_IMMOBILIZED, MOTOR_LACK_TRAIT) + holder.audible_message(span_hear("The motors of [src] whir to life!"), null, 1) if(is_cut(WIRE_MOTOR1)) mule.set_varspeed(FAST_MOTOR_SPEED) + holder.audible_message(span_hear("The motors of [src] speed up!"), null, 1) else if(is_cut(WIRE_MOTOR2)) mule.set_varspeed(AVERAGE_MOTOR_SPEED) + holder.audible_message(span_hear("The motors of [src] whir."), null, 1) else mule.set_varspeed(SLOW_MOTOR_SPEED) + holder.audible_message(span_hear("The motors of [src] move gently."), null, 1) if(WIRE_AVOIDANCE) if (!isnull(source)) log_combat(source, mule, "[is_cut(WIRE_AVOIDANCE) ? "cut" : "mended"] the MULE safety wire of") + holder.audible_message(span_hear("Something inside [src] clicks ominously!"), null, 1) /datum/wires/mulebot/on_pulse(wire) var/mob/living/simple_animal/bot/mulebot/mule = holder diff --git a/code/game/machinery/computer/orders/order_computer/order_computer.dm b/code/game/machinery/computer/orders/order_computer/order_computer.dm index 1b20e876ce583..edd7b7239047f 100644 --- a/code/game/machinery/computer/orders/order_computer/order_computer.dm +++ b/code/game/machinery/computer/orders/order_computer/order_computer.dm @@ -120,7 +120,8 @@ GLOBAL_LIST_EMPTY(order_console_products) "cat" = item.category_index, "ref" = REF(item), "cost" = round(item.cost_per_order * cargo_cost_multiplier), - "product_icon" = icon2base64(getFlatIcon(image(icon = initial(item.item_path.icon), icon_state = initial(item.item_path.icon_state)), no_anim=TRUE)) + "icon" = item.item_path::icon, + "icon_state" = item.item_path::icon_state, )) return data diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 858f2dffefff2..36828273f1944 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -548,18 +548,20 @@ if(welded || operating) return + var/atom/crowbar_owner = acting_object.loc //catchs mechs and any other non-mob using a crowbar + if(density) being_held_open = TRUE - user.balloon_alert_to_viewers("holding firelock open", "holding firelock open") + crowbar_owner.balloon_alert_to_viewers("holding firelock open", "holding firelock open") COOLDOWN_START(src, activation_cooldown, REACTIVATION_DELAY) open() - if(QDELETED(user)) + if(QDELETED(crowbar_owner)) being_held_open = FALSE return - RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(handle_held_open_adjacency)) - RegisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(handle_held_open_adjacency)) - RegisterSignal(user, COMSIG_QDELETING, PROC_REF(handle_held_open_adjacency)) - handle_held_open_adjacency(user) + RegisterSignal(crowbar_owner, COMSIG_MOVABLE_MOVED, PROC_REF(handle_held_open_adjacency)) + RegisterSignal(crowbar_owner, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(handle_held_open_adjacency)) + RegisterSignal(crowbar_owner, COMSIG_QDELETING, PROC_REF(handle_held_open_adjacency)) + handle_held_open_adjacency(crowbar_owner) else close() diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index 18f633504264f..21a51ba9bcb42 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -130,29 +130,35 @@ linked = null return ..() -/obj/effect/portal/attack_ghost(mob/dead/observer/O) - if(!teleport(O, TRUE)) +/obj/effect/portal/attack_ghost(mob/dead/observer/ghost) + if(!teleport(ghost, force = TRUE)) return ..() + return BULLET_ACT_FORCE_PIERCE -/obj/effect/portal/proc/teleport(atom/movable/M, force = FALSE) - if(!force && (!istype(M) || iseffect(M) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M)))) //Things that shouldn't teleport. +/obj/effect/portal/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit) + if (!teleport(hitting_projectile, force = TRUE)) + return ..() + return BULLET_ACT_FORCE_PIERCE + +/obj/effect/portal/proc/teleport(atom/movable/moving, force = FALSE) + if(!force && (!istype(moving) || iseffect(moving) || (ismecha(moving) && !mech_sized) || (!isobj(moving) && !ismob(moving)))) //Things that shouldn't teleport. return var/turf/real_target = get_link_target_turf() if(!istype(real_target)) return FALSE - if(!force && (!ismecha(M) && !isprojectile(M) && M.anchored && !allow_anchored)) + if(!force && (!ismecha(moving) && !isprojectile(moving) && moving.anchored && !allow_anchored)) return var/no_effect = FALSE if(last_effect == world.time || sparkless) no_effect = TRUE else last_effect = world.time - var/turf/start_turf = get_turf(M) - if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel, forced = force_teleport)) - if(isprojectile(M)) - var/obj/projectile/P = M + var/turf/start_turf = get_turf(moving) + if(do_teleport(moving, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel, forced = force_teleport)) + if(isprojectile(moving)) + var/obj/projectile/P = moving P.ignore_source_check = TRUE - new /obj/effect/temp_visual/portal_animation(start_turf, src, M) + new /obj/effect/temp_visual/portal_animation(start_turf, src, moving) playsound(start_turf, SFX_PORTAL_ENTER, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) playsound(real_target, SFX_PORTAL_ENTER, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) return TRUE @@ -189,7 +195,7 @@ linked = P break -/obj/effect/portal/permanent/teleport(atom/movable/M, force = FALSE) +/obj/effect/portal/permanent/teleport(atom/movable/moving, force = FALSE) set_linked() // update portal links . = ..() @@ -213,9 +219,9 @@ name = "one-use portal" desc = "This is probably the worst decision you'll ever make in your life." -/obj/effect/portal/permanent/one_way/one_use/teleport(atom/movable/M, force = FALSE) +/obj/effect/portal/permanent/one_way/one_use/teleport(atom/movable/moving, force = FALSE) . = ..() - if (. && !isdead(M)) + if (. && !isdead(moving)) expire() /** diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 0d4393efea6a4..ef3ddb77c0e44 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -41,6 +41,8 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \ merge_type = /obj/item/stack/sheet/mineral/sandstone walltype = /turf/closed/wall/mineral/sandstone material_type = /datum/material/sandstone + drop_sound = SFX_STONE_DROP + pickup_sound = SFX_STONE_PICKUP /obj/item/stack/sheet/mineral/sandstone/get_main_recipes() . = ..() diff --git a/code/game/objects/structures/ore_containers.dm b/code/game/objects/structures/ore_containers.dm index 6bc6f680116f4..75c7a03cfcfa9 100644 --- a/code/game/objects/structures/ore_containers.dm +++ b/code/game/objects/structures/ore_containers.dm @@ -23,25 +23,16 @@ ui.open() /obj/structure/ore_container/ui_data(mob/user) - var/list/data = list() - data["ores"] = list() + var/list/ores = list() for(var/obj/item/stack/ore/ore_item in contents) - data["ores"] += list(list( + ores += list(list( "id" = REF(ore_item), "name" = ore_item.name, "amount" = ore_item.amount, + "icon" = ore_item::icon, + "icon_state" = ore_item::icon_state, )) - return data - -/obj/structure/ore_container/ui_static_data(mob/user) - var/list/data = list() - data["ore_images"] = list() - for(var/obj/item/stack/ore_item as anything in subtypesof(/obj/item/stack/ore)) - data["ore_images"] += list(list( - "name" = initial(ore_item.name), - "icon" = icon2base64(getFlatIcon(image(icon = initial(ore_item.icon), icon_state = initial(ore_item.icon_state)), no_anim=TRUE)) - )) - return data + return list("ores" = ores) /obj/structure/ore_container/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() diff --git a/code/game/world.dm b/code/game/world.dm index fe55b3963b504..48ab5b1bd7c24 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -8,6 +8,13 @@ GLOBAL_VAR(restart_counter) GLOBAL_VAR(tracy_log) +GLOBAL_PROTECT(tracy_log) +GLOBAL_VAR(tracy_initialized) +GLOBAL_PROTECT(tracy_initialized) +GLOBAL_VAR(tracy_init_error) +GLOBAL_PROTECT(tracy_init_error) +GLOBAL_VAR(tracy_init_reason) +GLOBAL_PROTECT(tracy_init_reason) /** * WORLD INITIALIZATION @@ -66,15 +73,29 @@ GLOBAL_VAR(tracy_log) /world/proc/Genesis(tracy_initialized = FALSE) RETURN_TYPE(/datum/controller/master) + GLOB.tracy_initialized = FALSE +#ifndef OPENDREAM + if(!tracy_initialized) #ifdef USE_BYOND_TRACY #warn USE_BYOND_TRACY is enabled - if(!tracy_initialized) + var/should_init_tracy = TRUE + GLOB.tracy_init_reason = "USE_BYOND_TRACY defined" #else - if(!tracy_initialized && (USE_TRACY_PARAMETER in params)) + var/should_init_tracy = FALSE + if(USE_TRACY_PARAMETER in params) + should_init_tracy = TRUE + GLOB.tracy_init_reason = "world.params" + if(fexists(TRACY_ENABLE_PATH)) + GLOB.tracy_init_reason ||= "enabled for round" + SEND_TEXT(world.log, "[TRACY_ENABLE_PATH] exists, initializing byond-tracy!") + should_init_tracy = TRUE + fdel(TRACY_ENABLE_PATH) +#endif + if(should_init_tracy) + init_byond_tracy() + Genesis(tracy_initialized = TRUE) + return #endif - GLOB.tracy_log = init_byond_tracy() - Genesis(tracy_initialized = TRUE) - return Profile(PROFILE_RESTART) Profile(PROFILE_RESTART, type = "sendmaps") @@ -331,6 +352,7 @@ GLOBAL_VAR(tracy_log) if(do_hard_reboot) log_world("World hard rebooted at [time_stamp()]") shutdown_logging() // See comment below. + shutdown_byond_tracy() auxcleanup() TgsEndProcess() return ..() @@ -338,6 +360,7 @@ GLOBAL_VAR(tracy_log) log_world("World rebooted at [time_stamp()]") shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. + shutdown_byond_tracy() auxcleanup() TgsReboot() // TGS can decide to kill us right here, so it's important to do it last @@ -351,6 +374,7 @@ GLOBAL_VAR(tracy_log) call_ext(debug_server, "auxtools_shutdown")() /world/Del() + shutdown_byond_tracy() auxcleanup() . = ..() @@ -483,21 +507,31 @@ GLOBAL_VAR(tracy_log) DREAMLUAU_SET_EXECUTION_LIMIT_MILLIS(tick_lag * 100) /world/proc/init_byond_tracy() - var/library - - switch (system_type) - if (MS_WINDOWS) - library = "prof.dll" - if (UNIX) - library = "libprof.so" - else - CRASH("Unsupported platform: [system_type]") + if(!fexists(TRACY_DLL_PATH)) + SEND_TEXT(world.log, "Error initializing byond-tracy: [TRACY_DLL_PATH] not found!") + CRASH("Error initializing byond-tracy: [TRACY_DLL_PATH] not found!") - var/init_result = call_ext(library, "init")("block") + var/init_result = call_ext(TRACY_DLL_PATH, "init")("block") if(length(init_result) != 0 && init_result[1] == ".") // if first character is ., then it returned the output filename - return init_result + SEND_TEXT(world.log, "byond-tracy initialized (logfile: [init_result])") + GLOB.tracy_initialized = TRUE + return GLOB.tracy_log = init_result + else if(init_result == "already initialized") // not gonna question it. + GLOB.tracy_initialized = TRUE + SEND_TEXT(world.log, "byond-tracy already initialized ([GLOB.tracy_log ? "logfile: [GLOB.tracy_log]" : "no logfile"])") else if(init_result != "0") + GLOB.tracy_init_error = init_result + SEND_TEXT(world.log, "Error initializing byond-tracy: [init_result]") CRASH("Error initializing byond-tracy: [init_result]") + else + GLOB.tracy_initialized = TRUE + SEND_TEXT(world.log, "byond-tracy initialized (no logfile)") + +/world/proc/shutdown_byond_tracy() + if(GLOB.tracy_initialized) + SEND_TEXT(world.log, "Shutting down byond-tracy") + GLOB.tracy_initialized = FALSE + call_ext(TRACY_DLL_PATH, "destroy")() /world/proc/init_debugger() var/dll = GetConfig("env", "AUXTOOLS_DEBUG_DLL") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index b6c5e10ca1d81..13f1995c9ba3d 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -852,3 +852,42 @@ ADMIN_VERB(check_missing_sprites, R_DEBUG, "Debug Worn Item Sprites", "We're can actual_file_name = 'icons/mob/clothing/belt_mirror.dmi' if(!(sprite.icon_state in icon_states(actual_file_name))) to_chat(user, span_warning("ERROR sprites for [sprite.type]. Suit Storage slot."), confidential = TRUE) + +#ifndef OPENDREAM +ADMIN_VERB(start_tracy, R_DEBUG, "Run Tracy Now", "Start running the byond-tracy profiler immediately", ADMIN_CATEGORY_DEBUG) + if(GLOB.tracy_initialized) + to_chat(user, span_warning("byond-tracy is already running!"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + return + else if(GLOB.tracy_init_error) + to_chat(user, span_danger("byond-tracy failed to initialize during an earlier attempt: [GLOB.tracy_init_error]"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + return + message_admins(span_adminnotice("[key_name_admin(user)] is trying to start the byond-tracy profiler.")) + log_admin("[key_name(user)] is trying to start the byond-tracy profiler.") + GLOB.tracy_initialized = FALSE + GLOB.tracy_init_reason = "[user.ckey]" + world.init_byond_tracy() + if(GLOB.tracy_init_error) + to_chat(user, span_danger("byond-tracy failed to initialize: [GLOB.tracy_init_error]"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + message_admins(span_adminnotice("[key_name_admin(user)] tried to start the byond-tracy profiler, but it failed to initialize ([GLOB.tracy_init_error])")) + log_admin("[key_name(user)] tried to start the byond-tracy profiler, but it failed to initialize ([GLOB.tracy_init_error])") + return + to_chat(user, span_notice("byond-tracy successfully started!"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + message_admins(span_adminnotice("[key_name_admin(user)] started the byond-tracy profiler.")) + log_admin("[key_name(user)] started the byond-tracy profiler.") + if(GLOB.tracy_log) + rustg_file_write("[GLOB.tracy_log]", "[GLOB.log_directory]/tracy.loc") + +ADMIN_VERB_CUSTOM_EXIST_CHECK(start_tracy) + return CONFIG_GET(flag/allow_tracy_start) && fexists(TRACY_DLL_PATH) + +ADMIN_VERB(queue_tracy, R_DEBUG, "Toggle Tracy Next Round", "Toggle running the byond-tracy profiler next round", ADMIN_CATEGORY_DEBUG) + if(fexists(TRACY_ENABLE_PATH)) + fdel(TRACY_ENABLE_PATH) + else + rustg_file_write("[user.ckey]", TRACY_ENABLE_PATH) + message_admins(span_adminnotice("[key_name_admin(user)] [fexists(TRACY_ENABLE_PATH) ? "enabled" : "disabled"] the byond-tracy profiler for next round.")) + log_admin("[key_name(user)] [fexists(TRACY_ENABLE_PATH) ? "enabled" : "disabled"] the byond-tracy profiler for next round.") + +ADMIN_VERB_CUSTOM_EXIST_CHECK(queue_tracy) + return CONFIG_GET(flag/allow_tracy_queue) && fexists(TRACY_DLL_PATH) +#endif diff --git a/code/modules/antagonists/heretic/magic/star_touch.dm b/code/modules/antagonists/heretic/magic/star_touch.dm index d9cd5a05eab2b..e8e824cc71851 100644 --- a/code/modules/antagonists/heretic/magic/star_touch.dm +++ b/code/modules/antagonists/heretic/magic/star_touch.dm @@ -201,35 +201,6 @@ if(current_target) on_beam_hit(current_target) -/// Checks if the beam is going through an invalid turf -/datum/status_effect/cosmic_beam/proc/los_check(atom/movable/user, mob/target) - var/turf/user_turf = user.loc - if(!istype(user_turf)) - return FALSE - var/obj/dummy = new(user_turf) - dummy.pass_flags |= PASSTABLE|PASSGLASS|PASSGRILLE //Grille/Glass so it can be used through common windows - var/turf/previous_step = user_turf - var/first_step = TRUE - for(var/turf/next_step as anything in (get_line(user_turf, target) - user_turf)) - if(first_step) - for(var/obj/blocker in user_turf) - if(!blocker.density || !(blocker.flags_1 & ON_BORDER_1)) - continue - if(blocker.CanPass(dummy, get_dir(user_turf, next_step))) - continue - return FALSE // Could not leave the first turf. - first_step = FALSE - if(next_step.density) - qdel(dummy) - return FALSE - for(var/atom/movable/movable as anything in next_step) - if(!movable.CanPass(dummy, get_dir(next_step, previous_step))) - qdel(dummy) - return FALSE - previous_step = next_step - qdel(dummy) - return TRUE - /// What to add when the beam connects to a target /datum/status_effect/cosmic_beam/proc/on_beam_hit(mob/living/target) if(!istype(target, /mob/living/basic/heretic_summon/star_gazer)) diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm index 4ca500a9e7198..08e79c305a454 100644 --- a/code/modules/client/client_colour.dm +++ b/code/modules/client/client_colour.dm @@ -220,6 +220,9 @@ /datum/client_colour/malfunction colour = list(/*R*/ 0,0,0,0, /*G*/ 0,175,0,0, /*B*/ 0,0,0,0, /*A*/ 0,0,0,1, /*C*/0,-130,0,0) // Matrix colors +/datum/client_colour/perceptomatrix + colour = list(/*R*/ 1,0,0,0, /*G*/ 0,1,0,0, /*B*/ 0,0,1,0, /*A*/ 0,0,0,1, /*C*/0,-0.02,-0.02,0) // veeery slightly pink + /datum/client_colour/monochrome colour = COLOR_MATRIX_GRAYSCALE priority = PRIORITY_HIGH //we can't see colors anyway! diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index c8e9e9a64c270..fe559b2b71bfa 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -269,3 +269,7 @@ ///Which ambient sound this client is currently being provided. var/current_ambient_sound + + /// Does this client's mob need to rebuild its plane masters after login? + /// This is currently only used so a client can switch between 515 and 516 without breaking their rendering. + var/rebuild_plane_masters = FALSE diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index e0f359ac1e639..bc720ddb1dcc5 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -329,10 +329,20 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(GLOB.player_details[ckey]) reconnecting = TRUE player_details = GLOB.player_details[ckey] - player_details.byond_version = full_version + var/old_version = player_details.byond_version + player_details.byond_version = byond_version + player_details.byond_build = byond_build + +#if MIN_COMPILER_VERSION > 516 + #warn Fully change default relay_loc to "1,1", rather than changing it based on client version +#endif + if(old_version != byond_version) + rebuild_plane_masters = TRUE + else player_details = new(ckey) - player_details.byond_version = full_version + player_details.byond_version = byond_version + player_details.byond_build = byond_build GLOB.player_details[ckey] = player_details diff --git a/code/modules/client/player_details.dm b/code/modules/client/player_details.dm index 3a880dcdbb550..d0982a0c31268 100644 --- a/code/modules/client/player_details.dm +++ b/code/modules/client/player_details.dm @@ -1,6 +1,6 @@ ///assoc list of ckey -> /datum/player_details -GLOBAL_LIST_EMPTY(player_details) +GLOBAL_LIST_EMPTY_TYPED(player_details, /datum/player_details) /// Tracks information about a client between log in and log outs /datum/player_details @@ -18,8 +18,10 @@ GLOBAL_LIST_EMPTY(player_details) /// Lazylist of preference slots this client has joined the round under /// Numbers are stored as strings var/list/joined_as_slots - /// Version of byond this client is using - var/byond_version = "Unknown" + /// Major version of BYOND this client is using. + var/byond_version + /// Build number of BYOND this client is using. + var/byond_build /// Tracks achievements they have earned var/datum/achievement_data/achievements /// World.time this player last died @@ -35,6 +37,12 @@ GLOBAL_LIST_EMPTY(player_details) previous_names += html_encode("[previous_name] ([played_names[previous_name]])") return previous_names.Join("; ") +/// Returns the full version string (i.e 515.1642) of the BYOND version and build. +/datum/player_details/proc/full_byond_version() + if(!byond_version) + return "Unknown" + return "[byond_version].[byond_build || "xxx"]" + /// Adds the new names to the player's played_names list on their /datum/player_details for use of admins. /// `ckey` should be their ckey, and `data` should be an associative list with the keys being the names they played under and the values being the unique mob ID tied to that name. /proc/log_played_names(ckey, data) diff --git a/code/modules/clothing/head/perceptomatrix.dm b/code/modules/clothing/head/perceptomatrix.dm new file mode 100644 index 0000000000000..f11bad99eaf5b --- /dev/null +++ b/code/modules/clothing/head/perceptomatrix.dm @@ -0,0 +1,248 @@ + +#define PERCEPTOMATRIX_INACTIVE_FLAGS SNUG_FIT|STACKABLE_HELMET_EXEMPT|STOPSPRESSUREDAMAGE|BLOCK_GAS_SMOKE_EFFECT +#define PERCEPTOMATRIX_ACTIVE_FLAGS PERCEPTOMATRIX_INACTIVE_FLAGS|CASTING_CLOTHES // we love casting spells + +/// Belt which can turn you into a beast, once an anomaly core is inserted +/obj/item/clothing/head/helmet/perceptomatrix + name = "perceptomatrix helm" + desc = "This piece of headgear harnesses the energies of a hallucinative anomaly to create a safe audiovisual replica of -all- external stimuli directly into the cerebral cortex, \ + granting the user effective immunity to both psychic threats, and anything that would affect their perception - be it ear, eye, or even brain damage. \ + It can also violently discharge said energy, inducing hallucinations in others." + icon_state = "perceptomatrix_helmet_inactive" + worn_icon_state = "perceptomatrix_helmet_inactive" + base_icon_state = "perceptomatrix_helmet" + force = 10 + dog_fashion = null + cold_protection = HEAD + min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT + heat_protection = HEAD + max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT + strip_delay = 8 SECONDS + clothing_flags = PERCEPTOMATRIX_ACTIVE_FLAGS + clothing_traits = list( + /* eye/ear protection */ + TRAIT_NOFLASH, + TRAIT_TRUE_NIGHT_VISION, + TRAIT_SIGHT_BYPASS, + TRAIT_EXPANDED_FOV, + TRAIT_GOOD_HEARING, + /* mental protection */ + TRAIT_PERCEPTUAL_TRAUMA_BYPASS, + TRAIT_RDS_SUPPRESSED, + TRAIT_MADNESS_IMMUNE, + TRAIT_HALLUCINATION_IMMUNE, + /* psychic protection */ + TRAIT_NO_MINDSWAP, + TRAIT_UNCONVERTABLE, + ) + flags_cover = HEADCOVERSEYES|EARS_COVERED + flags_inv = HIDEHAIR|HIDEFACE + flash_protect = FLASH_PROTECTION_WELDER_SENSITIVE + resistance_flags = FIRE_PROOF | ACID_PROOF + equip_sound = 'sound/items/handling/helmet/helmet_equip1.ogg' + pickup_sound = 'sound/items/handling/helmet/helmet_pickup1.ogg' + drop_sound = 'sound/items/handling/helmet/helmet_drop1.ogg' + armor_type = /datum/armor/head_helmet_matrix + actions_types = list(/datum/action/cooldown/spell/pointed/percept_hallucination) + + /// If we have a core or not + var/core_installed = FALSE + /// Active components to add onto the mob, deleted and created on core installation/removal + var/list/active_components = list() + +// weaker overall but better against energy +/datum/armor/head_helmet_matrix + melee = 15 + bullet = 15 + laser = 45 + energy = 60 + bomb = 15 + fire = 50 + acid = 50 + wound = 10 + +/obj/item/clothing/head/helmet/perceptomatrix/Initialize(mapload) + . = ..() + + update_appearance(UPDATE_ICON_STATE) + update_anomaly_state() + +/obj/item/clothing/head/helmet/perceptomatrix/equipped(mob/living/user, slot) + . = ..() + if(slot & ITEM_SLOT_HEAD) + RegisterSignal(user, COMSIG_MOB_BEFORE_SPELL_CAST, PROC_REF(pre_cast_core_check)) + +/obj/item/clothing/head/helmet/perceptomatrix/dropped(mob/living/user, silent) + UnregisterSignal(user, COMSIG_MOB_BEFORE_SPELL_CAST) + ..() + +// Prevent casting the spell w/o the core. +/obj/item/clothing/head/helmet/perceptomatrix/proc/pre_cast_core_check(mob/caster, datum/action/cooldown/spell/spell) + SIGNAL_HANDLER + if((!core_installed) && spell.school == SCHOOL_PSYCHIC) + to_chat(caster, span_warning("You can't zap minds through [src]'s shielding without a core installed!")) + return SPELL_CANCEL_CAST + +/obj/item/clothing/head/helmet/perceptomatrix/proc/update_anomaly_state() + + // If the core isn't installed, or it's temporarily deactivated, disable special functions. + if(!core_installed) + clothing_flags = PERCEPTOMATRIX_INACTIVE_FLAGS + detach_clothing_traits(clothing_traits) + QDEL_LIST(active_components) + RemoveElement(/datum/element/wearable_client_colour, /datum/client_colour/perceptomatrix, ITEM_SLOT_HEAD, forced = TRUE) + return + + clothing_flags = PERCEPTOMATRIX_ACTIVE_FLAGS + attach_clothing_traits(initial(clothing_traits)) + + // When someone makes TRAIT_DEAF an element, or status effect, or whatever, give this item a way to bypass said deafness. + // just blocking future instances of deafness isn't what the item is meant to do but there's no proper way to do it otherwise at the moment. + active_components += AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_HEAD), reduce_amount = 2) // should be same as highest value + active_components += AddComponent( + /datum/component/anti_magic, \ + antimagic_flags = MAGIC_RESISTANCE_MIND, \ + inventory_flags = ITEM_SLOT_HEAD, \ + ) + AddElement(/datum/element/wearable_client_colour, /datum/client_colour/perceptomatrix, ITEM_SLOT_HEAD, forced = TRUE) + + update_icon_state() + +/obj/item/clothing/head/helmet/perceptomatrix/Destroy(force) + QDEL_LIST(active_components) + return ..() + +/obj/item/clothing/head/helmet/perceptomatrix/examine(mob/user) + . = ..() + if (!core_installed) + . += span_warning("It requires a hallucination anomaly core in order to function.") + +/obj/item/clothing/head/helmet/perceptomatrix/item_action_slot_check(slot, mob/user, datum/action/action) + return slot & ITEM_SLOT_HEAD + +/obj/item/clothing/head/helmet/perceptomatrix/update_icon_state() + icon_state = base_icon_state + (core_installed ? "" : "_inactive") + worn_icon_state = base_icon_state + (core_installed ? "" : "_inactive") + return ..() + +/obj/item/clothing/head/helmet/perceptomatrix/item_interaction(mob/user, obj/item/weapon, params) + if (!istype(weapon, /obj/item/assembly/signaler/anomaly/hallucination)) + return NONE + balloon_alert(user, "inserting...") + if (!do_after(user, delay = 3 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + qdel(weapon) + core_installed = TRUE + update_anomaly_state() + update_appearance(UPDATE_ICON_STATE) + playsound(src, 'sound/machines/crate/crate_open.ogg', 50, FALSE) + return ITEM_INTERACT_SUCCESS + +/obj/item/clothing/head/helmet/perceptomatrix/functioning + core_installed = TRUE + +/datum/action/cooldown/spell/pointed/percept_hallucination + name = "Hallucinate" + desc = "Redirect perceptual energies towards a target, staggering them." + button_icon_state = "blind" + ranged_mousepointer = 'icons/effects/mouse_pointers/blind_target.dmi' + + sound = 'sound/items/weapons/emitter2.ogg' + school = SCHOOL_PSYCHIC + cooldown_time = 15 SECONDS + + invocation_type = INVOCATION_NONE + spell_requirements = NONE + antimagic_flags = MAGIC_RESISTANCE_MIND + + active_msg = "You prepare to zap a target with hallucinations..." + + /// The amount of blurriness to apply + var/eye_blur_duration = 7 SECONDS + /// The amount of stagger to apply + var/stagger_duration = 3 SECONDS + /// The amount of hallucination to apply + var/hallucination_duration = 25 SECONDS + /// Spark system + var/datum/effect_system/spark_spread/quantum/spark_sys + +/datum/action/cooldown/spell/pointed/percept_hallucination/New(Target) + . = ..() + + spark_sys = new /datum/effect_system/spark_spread/quantum + +/datum/action/cooldown/spell/pointed/percept_hallucination/Destroy() + QDEL_NULL(spark_sys) + return ..() + +/datum/action/cooldown/spell/pointed/percept_hallucination/is_valid_target(atom/cast_on) + . = ..() + if(!.) + return FALSE + if(ishuman(cast_on)) + return TRUE + if(istype(cast_on, /obj/item/food/pancakes)) + return TRUE + + return FALSE + +/datum/action/cooldown/spell/pointed/percept_hallucination/proc/blows_up_pancakes_with_mind(obj/item/food/pancakes/pancakes) + + owner.visible_message( + span_userdanger("[owner] blows up [pancakes] with [owner.p_their()] mind!"), + span_userdanger("You blow up [pancakes] with your mind!") + ) + + for(var/mob/chef in get_hearers_in_view(7, pancakes)) + if(!chef.mind) + continue + // if cooked by chef, or if EITHER 5% chance OR its april fools. a || (b || c) + if(HAS_TRAIT_FROM(pancakes, TRAIT_FOOD_CHEF_MADE, REF(chef.mind)) || (prob(5) || check_holidays(APRIL_FOOLS))) + chef.say("Ma fuckin' pancakes!") + + playsound(pancakes, 'sound/effects/fuse.ogg', 80) + animate(pancakes, time = 1, pixel_z = 12, easing = ELASTIC_EASING) + animate(time = 1, pixel_z = 0, easing = BOUNCE_EASING) + for(var/i in 1 to 15) + animate(color = (i % 2) ? "#ffffff": "#ff6739", time = 1, easing = QUAD_EASING, flags = ANIMATION_CONTINUE) + + addtimer(CALLBACK(src, PROC_REF(pancake_explosion), pancakes), 1.5 SECONDS) + +/datum/action/cooldown/spell/pointed/percept_hallucination/proc/pancake_explosion(obj/pancakes) + explosion(pancakes, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 1, flame_range = 2) + qdel(pancakes) + StartCooldown() + +/datum/action/cooldown/spell/pointed/percept_hallucination/proc/cast_fx(atom/cast_on) + owner.Beam(cast_on, icon_state = "greyscale_lightning", beam_color = COLOR_FADED_PINK, time = 0.5 SECONDS) + + spark_sys.set_up(2, 1, get_turf(owner)) + spark_sys.start() + spark_sys.set_up(4, 1, get_turf(cast_on)) + spark_sys.start() + +/datum/action/cooldown/spell/pointed/percept_hallucination/cast(mob/living/carbon/human/cast_on) + . = ..() + + cast_fx(cast_on) + + if(istype(cast_on, /obj/item/food/pancakes)) + blows_up_pancakes_with_mind(cast_on) + return + + if(cast_on.can_block_magic(antimagic_flags)) + to_chat(cast_on, span_notice("You feel psychic energies reflecting off you.")) + to_chat(owner, span_warning("[cast_on] deflects the energy!")) + return + + to_chat(cast_on, span_warning("Your brain feels like it's on fire!")) + cast_on.emote("scream") + cast_on.set_eye_blur_if_lower(eye_blur_duration) + cast_on.adjust_staggered(stagger_duration) + cast_on.apply_status_effect(/datum/status_effect/hallucination, hallucination_duration, \ + hallucination_duration * 0.2, hallucination_duration) // lower/upper hallucination freq. bound + + return + +#undef PERCEPTOMATRIX_INACTIVE_FLAGS +#undef PERCEPTOMATRIX_ACTIVE_FLAGS diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index afbdeef519224..a59280ff04517 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -94,9 +94,6 @@ GLOBAL_LIST_INIT(clown_mask_options, list( var/valid_wearer = ismob(loc) var/mob/wearer = loc if(istype(tool, /obj/item/cigarette)) - if(flags_cover & MASKCOVERSMOUTH) - balloon_alert(user, "mask's mouth is covered!") - return ..() if(max_filters <= 0 || cig) balloon_alert(user, "can't hold that!") diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm index c81852958b4a8..59e2f0feb86b1 100644 --- a/code/modules/detectivework/evidence.dm +++ b/code/modules/detectivework/evidence.dm @@ -18,23 +18,13 @@ max_slots = 1, max_specific_storage = WEIGHT_CLASS_NORMAL, ) + atom_storage.allow_quick_gather = TRUE + atom_storage.collection_mode = COLLECT_ONE RegisterSignal(atom_storage, COMSIG_STORAGE_STORED_ITEM, PROC_REF(on_insert)) RegisterSignal(atom_storage, COMSIG_STORAGE_REMOVED_ITEM, PROC_REF(on_remove)) atom_storage.rustle_sound = 'sound/items/evidence_bag/evidence_bag_zip.ogg' atom_storage.remove_rustle_sound = 'sound/items/evidence_bag/evidence_bag_unzip.ogg' -/obj/item/evidencebag/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) - if(interacting_with == loc || !isitem(interacting_with) || HAS_TRAIT(interacting_with, TRAIT_COMBAT_MODE_SKIP_INTERACTION)) - return NONE - if(atom_storage.attempt_insert(interacting_with, user)) - return ITEM_INTERACT_SUCCESS - return NONE - -/obj/item/evidencebag/item_interaction(mob/living/user, obj/item/tool, list/modifiers) - if(atom_storage.attempt_insert(tool, user)) - return ITEM_INTERACT_SUCCESS - return NONE - /obj/item/evidencebag/update_desc(updates) . = ..() if(!atom_storage.get_total_weight()) @@ -65,12 +55,15 @@ /obj/item/evidencebag/proc/on_insert(datum/storage/storage, obj/item/to_insert, mob/user, force) SIGNAL_HANDLER + update_weight_class(to_insert.w_class) /obj/item/evidencebag/proc/on_remove(datum/storage/storage, obj/item/to_remove, atom/remove_to_loc, silent) SIGNAL_HANDLER + if(!atom_storage.get_total_weight()) return + update_weight_class(WEIGHT_CLASS_TINY) /obj/item/evidencebag/attack_self(mob/user) diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm index 83028d129c4a8..5db33818d1276 100644 --- a/code/modules/events/wormholes.dm +++ b/code/modules/events/wormholes.dm @@ -65,7 +65,7 @@ GLOBAL_LIST_EMPTY(all_wormholes) // So we can pick wormholes to teleport to . = ..() GLOB.all_wormholes -= src -/obj/effect/portal/wormhole/teleport(atom/movable/M) +/obj/effect/portal/wormhole/teleport(atom/movable/M, force = FALSE) if(iseffect(M)) //sparks don't teleport return if(M.anchored) diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm index 6ffcfa7bc6752..fa9b63a4658a7 100644 --- a/code/modules/mining/equipment/wormhole_jaunter.dm +++ b/code/modules/mining/equipment/wormhole_jaunter.dm @@ -103,7 +103,7 @@ light_on = FALSE wibbles = FALSE -/obj/effect/portal/jaunt_tunnel/teleport(atom/movable/M) +/obj/effect/portal/jaunt_tunnel/teleport(atom/movable/M, force = FALSE) . = ..() if(.) // KERPLUNK diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 312acb6672014..24e0f53a87ab7 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -229,21 +229,27 @@ for(var/datum/material/material as anything in mat_container.materials) var/amount = mat_container.materials[material] var/sheet_amount = amount / SHEET_MATERIAL_AMOUNT + var/obj/sheet_type = material.sheet_type data["materials"] += list(list( "name" = material.name, "id" = REF(material), "amount" = sheet_amount, "category" = "material", "value" = ore_values[material.type], + "icon" = sheet_type::icon, + "icon_state" = sheet_type::icon_state, )) for(var/research in stored_research.researched_designs) var/datum/design/alloy = SSresearch.techweb_design_by_id(research) + var/obj/alloy_type = alloy.build_path data["materials"] += list(list( "name" = alloy.name, "id" = alloy.id, "category" = "alloy", "amount" = can_smelt_alloy(alloy), + "icon" = alloy_type::icon, + "icon_state" = alloy_type::icon_state, )) data["disconnected"] = null @@ -274,29 +280,6 @@ ) return data -/obj/machinery/mineral/ore_redemption/ui_static_data(mob/user) - var/list/data = list() - - var/datum/component/material_container/mat_container = materials.mat_container - if (mat_container) - for(var/datum/material/material as anything in mat_container.materials) - var/obj/material_display = initial(material.sheet_type) - data["material_icons"] += list(list( - "id" = REF(material), - "product_icon" = icon2base64(getFlatIcon(image(icon = initial(material_display.icon), icon_state = initial(material_display.icon_state)), no_anim=TRUE)), - )) - - for(var/research in stored_research.researched_designs) - var/datum/design/alloy = SSresearch.techweb_design_by_id(research) - var/obj/alloy_display = initial(alloy.build_path) - data["material_icons"] += list(list( - "id" = alloy.id, - "product_icon" = icon2base64(getFlatIcon(image(icon = initial(alloy_display.icon), icon_state = initial(alloy_display.icon_state)), no_anim=TRUE)), - )) - - return data - - /obj/machinery/mineral/ore_redemption/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() if(.) diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index 363243a283388..7e572c2d92f63 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -177,6 +177,19 @@ paralyze_chance = 0 initial_size = 0.9 +/mob/living/basic/gorilla/hostile + name = "Feral Gorilla" + maxHealth = 180 + health = 180 + desc = "A gorilla created via \"advanced genetic science\". While not quite as strong as their wildborne brethren, this simian still packs a punch." + melee_damage_lower = 15 + melee_damage_upper = 18 + obj_damage = 25 + speed = 0.1 + paralyze_chance = 0 + initial_size = 0.9 + faction = list(FACTION_HOSTILE) + /mob/living/basic/gorilla/genetics/Initialize(mapload) . = ..() qdel(GetComponent(/datum/component/amputating_limbs)) diff --git a/code/modules/mob/living/carbon/alien/death.dm b/code/modules/mob/living/carbon/alien/death.dm index 85092244510a7..8671a66c98aec 100644 --- a/code/modules/mob/living/carbon/alien/death.dm +++ b/code/modules/mob/living/carbon/alien/death.dm @@ -7,5 +7,10 @@ /mob/living/carbon/alien/gib_animation() new /obj/effect/temp_visual/gib_animation(loc, "gibbed-a") -/mob/living/carbon/alien/spawn_dust() - new /obj/effect/decal/remains/xeno(loc) +/mob/living/carbon/alien/spawn_dust(just_ash) + if(just_ash) + return ..() + + var/obj/effect/decal/remains/xeno/bones = new(loc) + bones.pixel_z = -6 + bones.pixel_w = rand(-1, 1) diff --git a/code/modules/mob/living/carbon/alien/larva/death.dm b/code/modules/mob/living/carbon/alien/larva/death.dm index f33ee4efdf17d..3c4500518de89 100644 --- a/code/modules/mob/living/carbon/alien/larva/death.dm +++ b/code/modules/mob/living/carbon/alien/larva/death.dm @@ -15,5 +15,10 @@ /mob/living/carbon/alien/larva/gib_animation() new /obj/effect/temp_visual/gib_animation(loc, "gibbed-l") -/mob/living/carbon/alien/larva/spawn_dust() - new /obj/effect/decal/remains/xeno(loc) +/mob/living/carbon/alien/larva/spawn_dust(just_ash) + if(just_ash) + return ..() + + var/obj/effect/decal/remains/xeno/bones = new(loc) + bones.pixel_z = -6 + bones.pixel_w = rand(-1, 1) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 7e8fa7f1f8d2c..dad45038f137d 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -10,11 +10,17 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift) else new /obj/effect/gibspawner/human/bodypartless(drop_location(), src, get_static_viruses()) -/mob/living/carbon/human/spawn_dust(just_ash = FALSE) +/mob/living/carbon/human/spawn_dust(just_ash) if(just_ash) - new /obj/effect/decal/cleanable/ash(loc) - else - new /obj/effect/decal/remains/human(loc) + return ..() + + var/bone_type = /obj/effect/decal/remains/human + if(isplasmaman(src)) + bone_type = /obj/effect/decal/remains/plasma + + var/obj/effect/decal/remains/human/bones = new bone_type(loc) + bones.pixel_z = -6 + bones.pixel_w = rand(-1, 1) /mob/living/carbon/human/death(gibbed) if(stat == DEAD) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 5b0e64547a016..bd72ff464a958 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1192,7 +1192,7 @@ race = /datum/species/snail /mob/living/carbon/human/species/vampire - race = /datum/species/vampire + race = /datum/species/human/vampire /mob/living/carbon/human/species/zombie race = /datum/species/zombie diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index d0b052a888865..44b5d9590387a 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -4,7 +4,7 @@ ///maximum a vampire will drain, they will drain less if they hit their cap #define VAMP_DRAIN_AMOUNT 50 -/datum/species/vampire +/datum/species/human/vampire name = "Vampire" id = SPECIES_VAMPIRE examine_limb_id = SPECIES_HUMAN @@ -18,33 +18,30 @@ ) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID changesource_flags = MIRROR_BADMIN | MIRROR_PRIDE | WABBAJACK | ERT_SPAWN - exotic_bloodtype = "U" + exotic_bloodtype = "V" blood_deficiency_drain_rate = BLOOD_DEFICIENCY_MODIFIER // vampires already passively lose blood, so this just makes them lose it slightly more quickly when they have blood deficiency. mutantheart = /obj/item/organ/heart/vampire mutanttongue = /obj/item/organ/tongue/vampire - mutantstomach = null - mutantlungs = null - skinned_type = /obj/item/stack/sheet/animalhide/human ///some starter text sent to the vampire initially, because vampires have shit to do to stay alive var/info_text = "You are a Vampire. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability." -/datum/species/vampire/check_roundstart_eligible() +/datum/species/human/vampire/check_roundstart_eligible() if(check_holidays(HALLOWEEN)) return TRUE return ..() -/datum/species/vampire/on_species_gain(mob/living/carbon/human/new_vampire, datum/species/old_species) +/datum/species/human/vampire/on_species_gain(mob/living/carbon/human/new_vampire, datum/species/old_species) . = ..() to_chat(new_vampire, "[info_text]") new_vampire.skin_tone = "albino" new_vampire.update_body(0) RegisterSignal(new_vampire, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(damage_weakness)) -/datum/species/vampire/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) +/datum/species/human/vampire/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) . = ..() UnregisterSignal(C, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS) -/datum/species/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick, times_fired) +/datum/species/human/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick, times_fired) . = ..() if(istype(vampire.loc, /obj/structure/closet/crate/coffin)) var/need_mob_update = FALSE @@ -66,27 +63,27 @@ vampire.adjust_fire_stacks(3 * seconds_per_tick) vampire.ignite_mob() -/datum/species/vampire/proc/damage_weakness(datum/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item) +/datum/species/human/vampire/proc/damage_weakness(datum/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item) SIGNAL_HANDLER if(istype(attacking_item, /obj/item/nullrod/whip)) damage_mods += 2 -/datum/species/vampire/get_physical_attributes() +/datum/species/human/vampire/get_physical_attributes() return "Vampires are afflicted with the Thirst, needing to sate it by draining the blood out of another living creature. However, they do not need to breathe or eat normally. \ They will instantly turn into dust if they run out of blood or enter a holy area. However, coffins stabilize and heal them, and they can transform into bats!" -/datum/species/vampire/get_species_description() +/datum/species/human/vampire/get_species_description() return "A classy Vampire! They descend upon Space Station Thirteen Every year to spook the crew! \"Bleeg!!\"" -/datum/species/vampire/get_species_lore() +/datum/species/human/vampire/get_species_lore() return list( "Vampires are unholy beings blessed and cursed with The Thirst. \ The Thirst requires them to feast on blood to stay alive, and in return it gives them many bonuses. \ Because of this, Vampires have split into two clans, one that embraces their powers as a blessing and one that rejects it.", ) -/datum/species/vampire/create_pref_unique_perks() +/datum/species/human/vampire/create_pref_unique_perks() var/list/to_add = list() to_add += list( @@ -115,7 +112,7 @@ return to_add // Vampire blood is special, so it needs to be handled with its own entry. -/datum/species/vampire/create_pref_blood_perks() +/datum/species/human/vampire/create_pref_blood_perks() var/list/to_add = list() to_add += list(list( @@ -132,7 +129,7 @@ return to_add // There isn't a "Minor Undead" biotype, so we have to explain it in an override (see: dullahans) -/datum/species/vampire/create_pref_biotypes_perks() +/datum/species/human/vampire/create_pref_biotypes_perks() var/list/to_add = list() to_add += list(list( diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 8688e256022ba..6616736a61064 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -98,7 +98,7 @@ ghostize() QDEL_IN(src, DUST_ANIMATION_TIME) // since this is sometimes called in the middle of movement, allow half a second for movement to finish, ghosting to happen and animation to play. Looks much nicer and doesn't cause multiple runtimes. -/// Animates turning into dust +/// Animates turning into dust. /// Does not delete src afterwards, BUT it will become invisible (and grey), so ensure you handle that yourself /atom/movable/proc/dust_animation(atom/anim_loc = src.loc) if(isnull(anim_loc)) // the effect breaks if we have a null loc @@ -130,8 +130,19 @@ #undef DUST_ANIMATION_TIME +/** + * Spawns dust / ash or remains where the mob was + * + * just_ash: If TRUE, just ash will spawn where the mob was, as opposed to remains + */ /mob/living/proc/spawn_dust(just_ash = FALSE) - new /obj/effect/decal/cleanable/ash(loc) + var/ash_type = /obj/effect/decal/cleanable/ash + if(mob_size >= MOB_SIZE_LARGE) + ash_type = /obj/effect/decal/cleanable/ash/large + + var/obj/effect/decal/cleanable/ash/ash = new ash_type(loc) + ash.pixel_z = -5 + ash.pixel_w = rand(-1, 1) /* * Called when the mob dies. Can also be called manually to kill a mob. diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 360d975cb9ed8..3b5c012d591d4 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -140,22 +140,27 @@ /datum/emote/living/flap/run_emote(mob/user, params, type_override, intentional) . = ..() - if(ishuman(user)) - var/mob/living/carbon/human/human_user = user - var/open = FALSE - var/obj/item/organ/wings/functional/wings = human_user.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS) - - // open/close functional wings - if(istype(wings)) - if(wings.wings_open) - open = TRUE - wings.close_wings() - else - wings.open_wings() - addtimer(CALLBACK(wings, open ? TYPE_PROC_REF(/obj/item/organ/wings/functional, open_wings) : TYPE_PROC_REF(/obj/item/organ/wings/functional, close_wings)), wing_time) + if(!ishuman(user)) + return + var/mob/living/carbon/human/human_user = user + var/obj/item/organ/wings/wings = human_user.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS) - // play a flapping noise if the wing has this implemented - wings.make_flap_sound(human_user) + // play a flapping noise if the wing has this implemented + if(!istype(wings)) + return + wings.make_flap_sound(human_user) + + // open/close functional wings + var/obj/item/organ/wings/functional/wings_functional = wings + if(!istype(wings_functional)) + return + var/open = FALSE + if(wings_functional.wings_open) + open = TRUE + wings_functional.close_wings() + else + wings_functional.open_wings() + addtimer(CALLBACK(wings_functional, open ? TYPE_PROC_REF(/obj/item/organ/wings/functional, open_wings) : TYPE_PROC_REF(/obj/item/organ/wings/functional, close_wings)), wing_time) /datum/emote/living/flap/aflap key = "aflap" diff --git a/code/modules/mob/living/silicon/death.dm b/code/modules/mob/living/silicon/death.dm index 85e749d276541..67083168eb30e 100644 --- a/code/modules/mob/living/silicon/death.dm +++ b/code/modules/mob/living/silicon/death.dm @@ -1,8 +1,13 @@ /mob/living/silicon/spawn_gibs() new /obj/effect/gibspawner/robot(drop_location(), src) -/mob/living/silicon/spawn_dust() - new /obj/effect/decal/remains/robot(loc) +/mob/living/silicon/spawn_dust(just_ash) + if(just_ash) + return ..() + + var/obj/effect/decal/remains/robot/robones = new(loc) + robones.pixel_z = -6 + robones.pixel_w = rand(-1, 1) /mob/living/silicon/death(gibbed) diag_hud_set_status() diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index 91627b5099fe5..99c5686aa5325 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -7,9 +7,6 @@ QDEL_NULL(mmi) return ..() -/mob/living/silicon/robot/spawn_dust() - new /obj/effect/decal/remains/robot(loc) - /mob/living/silicon/robot/death(gibbed) if(stat == DEAD) return diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm index 390431300d541..565919c07ecd5 100644 --- a/code/modules/mod/modules/_module.dm +++ b/code/modules/mod/modules/_module.dm @@ -418,7 +418,7 @@ /obj/item/mod/module/anomaly_locked name = "MOD anomaly locked module" desc = "A form of a module, locked behind an anomalous core to function." - incompatible_modules = list(/obj/item/mod/module/anomaly_locked) + incompatible_modules = list() /// The core item the module runs off. var/obj/item/assembly/signaler/anomaly/core /// Accepted types of anomaly cores. diff --git a/code/modules/mod/modules/module_kinesis.dm b/code/modules/mod/modules/module_kinesis.dm index 3c9ae3310b755..733e5ab40d97b 100644 --- a/code/modules/mod/modules/module_kinesis.dm +++ b/code/modules/mod/modules/module_kinesis.dm @@ -17,7 +17,7 @@ accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/grav) required_slots = list(ITEM_SLOT_GLOVES) /// Range of the knesis grab. - var/grab_range = 5 + var/grab_range = 8 /// Time between us hitting objects with kinesis. var/hit_cooldown_time = 1 SECONDS /// Stat required for us to grab a mob. diff --git a/code/modules/mod/modules/modules_science.dm b/code/modules/mod/modules/modules_science.dm index 1d15abece56d0..8cb15d35370aa 100644 --- a/code/modules/mod/modules/modules_science.dm +++ b/code/modules/mod/modules/modules_science.dm @@ -55,9 +55,9 @@ desc = "A module that uses a gravitational core to make the user completely weightless." icon_state = "antigrav" module_type = MODULE_TOGGLE - complexity = 3 + complexity = 2 active_power_cost = DEFAULT_CHARGE_DRAIN * 0.7 - incompatible_modules = list(/obj/item/mod/module/anomaly_locked, /obj/item/mod/module/atrocinator) + incompatible_modules = list(/obj/item/mod/module/atrocinator, /obj/item/mod/module/anomaly_locked/antigrav) accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/grav) required_slots = list(ITEM_SLOT_BACK|ITEM_SLOT_BELT) @@ -88,21 +88,34 @@ icon_state = "teleporter" module_type = MODULE_ACTIVE complexity = 3 - use_energy_cost = DEFAULT_CHARGE_DRAIN * 5 - cooldown_time = 5 SECONDS + use_energy_cost = DEFAULT_CHARGE_DRAIN * 25 + cooldown_time = 4 SECONDS + incompatible_modules = list(/obj/item/mod/module/anomaly_locked/teleporter) accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/bluespace) required_slots = list(ITEM_SLOT_BACK|ITEM_SLOT_BELT) /// Time it takes to teleport - var/teleport_time = 3 SECONDS + var/teleport_time = 1 SECONDS + /// Maximum turf range + var/max_range = 9 /obj/item/mod/module/anomaly_locked/teleporter/on_select_use(atom/target) . = ..() if(!.) return var/turf/open/target_turf = get_turf(target) - if(!istype(target_turf) || target_turf.is_blocked_turf_ignore_climbable() || !(target_turf in view(mod.wearer))) + if(get_dist(target_turf, mod.wearer) > max_range) + balloon_alert(mod.wearer, "too far!") + return + if(!istype(target_turf)) balloon_alert(mod.wearer, "invalid target!") return + if(target_turf.is_blocked_turf_ignore_climbable() || !los_check(mod.wearer, target, pass_args = PASSTABLE|PASSGLASS|PASSGRILLE|PASSMOB|PASSMACHINE|PASSSTRUCTURE|PASSFLAPS|PASSWINDOW)) + balloon_alert(mod.wearer, "blocked destination!") + return + // check early so we don't go through the whole loops + if(!check_teleport_valid(mod.wearer, target_turf, channel = TELEPORT_CHANNEL_BLUESPACE, original_destination = target_turf)) + balloon_alert(mod.wearer, "something holds you back!") + return balloon_alert(mod.wearer, "teleporting...") var/matrix/pre_matrix = matrix() pre_matrix.Scale(4, 0.25) diff --git a/code/modules/modular_computers/file_system/programs/maintenance/camera.dm b/code/modules/modular_computers/file_system/programs/maintenance/camera.dm index f851dada495f3..e62aa35a6088c 100644 --- a/code/modules/modular_computers/file_system/programs/maintenance/camera.dm +++ b/code/modules/modular_computers/file_system/programs/maintenance/camera.dm @@ -11,12 +11,18 @@ circuit_comp_type = /obj/item/circuit_component/mod_program/camera /// Camera built-into the tablet. - var/obj/item/camera/internal_camera + var/obj/item/camera/app/internal_camera /// Latest picture taken by the app. var/datum/picture/internal_picture /// How many pictures were taken already, used for the camera's TGUI photo display var/picture_number = 1 +// Special type of camera for this exact usecase to prevent harddels +/obj/item/camera/app + name = "internal camera" + desc = "Specialized internal camera protected from the hellish depths of SSWardrobe. \ + Yell at coders if you somehow manage to see this" + /datum/computer_file/program/maintenance/camera/on_install() . = ..() internal_camera = new(computer) diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index 3657bb84db83a..a13483e82c5e2 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -725,7 +725,7 @@ plane = FLOOR_PLANE light_type = /obj/item/light/bulb fitting = "bulb" - nightshift_brightness = 3 + nightshift_brightness = 4 fire_brightness = 4.5 /obj/machinery/light/floor/get_light_offset() diff --git a/code/modules/projectiles/guns/special/medbeam.dm b/code/modules/projectiles/guns/special/medbeam.dm index 0ad5caf2fec82..95da571baf547 100644 --- a/code/modules/projectiles/guns/special/medbeam.dm +++ b/code/modules/projectiles/guns/special/medbeam.dm @@ -83,56 +83,26 @@ last_check = world.time - if(!los_check(loc, current_target)) + if(!los_check(loc, current_target, mid_check = CALLBACK(src, PROC_REF(mid_los_check)))) QDEL_NULL(current_beam)//this will give the target lost message return if(current_target) on_beam_tick(current_target) -/obj/item/gun/medbeam/proc/los_check(atom/movable/user, mob/target) - var/turf/user_turf = user.loc - if(mounted) - user_turf = get_turf(user) - else if(!istype(user_turf)) - return FALSE - var/obj/dummy = new(user_turf) - dummy.pass_flags |= PASSTABLE|PASSGLASS|PASSGRILLE //Grille/Glass so it can be used through common windows - var/turf/previous_step = user_turf - var/first_step = TRUE - for(var/turf/next_step as anything in (get_line(user_turf, target) - user_turf)) - if(first_step) - for(var/obj/blocker in user_turf) - if(!blocker.density || !(blocker.flags_1 & ON_BORDER_1)) - continue - if(blocker.CanPass(dummy, get_dir(user_turf, next_step))) - continue - return FALSE // Could not leave the first turf. - first_step = FALSE - if(mounted && next_step == user_turf) - - continue //Mechs are dense and thus fail the check - if(next_step.density) +/obj/item/gun/medbeam/proc/mid_los_check(atom/movable/user, mob/target, pass_args = PASSTABLE|PASSGLASS|PASSGRILLE, turf/next_step, obj/dummy) + for(var/obj/effect/ebeam/medical/B in next_step)// Don't cross the str-beams! + if(QDELETED(current_beam)) + break //We shouldn't be processing anymore. + if(QDELETED(B)) + continue + if(!B.owner) + stack_trace("beam without an owner! [B]") + continue + if(B.owner.origin != current_beam.origin) + explosion(B.loc, heavy_impact_range = 3, light_impact_range = 5, flash_range = 8, explosion_cause = src) qdel(dummy) return FALSE - for(var/atom/movable/movable as anything in next_step) - if(!movable.CanPass(dummy, get_dir(next_step, previous_step))) - qdel(dummy) - return FALSE - for(var/obj/effect/ebeam/medical/B in next_step)// Don't cross the str-beams! - if(QDELETED(current_beam)) - break //We shouldn't be processing anymore. - if(QDELETED(B)) - continue - if(!B.owner) - stack_trace("beam without an owner! [B]") - continue - if(B.owner.origin != current_beam.origin) - explosion(B.loc, heavy_impact_range = 3, light_impact_range = 5, flash_range = 8, explosion_cause = src) - qdel(dummy) - return FALSE - previous_step = next_step - qdel(dummy) return TRUE /obj/item/gun/medbeam/proc/on_beam_hit(mob/living/target) diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm index b8a2250722534..ebd392f536892 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm @@ -480,6 +480,7 @@ Basically, we fill the time between now and 2s from now with hands based off the overdose_threshold = 20 self_consuming = TRUE //No pesky liver shenanigans chemical_flags = REAGENT_DONOTSPLIT | REAGENT_DEAD_PROCESS + affected_organ_flags = NONE ///If we brought someone back from the dead var/back_from_the_dead = FALSE /// List of trait buffs to give to the affected mob, and remove as needed. diff --git a/code/modules/spells/spell_types/self/splattercasting_spell.dm b/code/modules/spells/spell_types/self/splattercasting_spell.dm index 184a2afab7ca2..e76f8e3c1b9bf 100644 --- a/code/modules/spells/spell_types/self/splattercasting_spell.dm +++ b/code/modules/spells/spell_types/self/splattercasting_spell.dm @@ -28,7 +28,7 @@ brings unimaginable momentary torment as your heart stops, and your skin grows cold. You are now \ merely a vessel for the arcane flow. Soon, all that is left is not pain, but hunger.")) - cast_on.set_species(/datum/species/vampire) + cast_on.set_species(/datum/species/human/vampire) cast_on.blood_volume = BLOOD_VOLUME_NORMAL ///for predictable blood total amounts when the spell is first cast. cast_on.AddComponent(/datum/component/splattercasting) diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vampire.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_human_vampire.png similarity index 100% rename from code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vampire.png rename to code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_human_vampire.png diff --git a/code/modules/uplink/uplink_items/device_tools.dm b/code/modules/uplink/uplink_items/device_tools.dm index 714c3133482c4..ef2ab6fd1fddc 100644 --- a/code/modules/uplink/uplink_items/device_tools.dm +++ b/code/modules/uplink/uplink_items/device_tools.dm @@ -242,9 +242,9 @@ active gravitational singularities or tesla balls towards it. This will not work when the engine is still \ in containment. Because of its size, it cannot be carried. Ordering this \ sends you a small beacon that will teleport the larger beacon to your location upon activation." - progression_minimum = 30 MINUTES + progression_minimum = 20 MINUTES item = /obj/item/sbeacondrop - cost = 10 + cost = 4 surplus = 0 // not while there isnt one on any station purchasable_from = ~UPLINK_ALL_SYNDIE_OPS diff --git a/code/modules/vehicles/mecha/mecha_movement.dm b/code/modules/vehicles/mecha/mecha_movement.dm index 9fdbf4cef8967..aaba86d7cb832 100644 --- a/code/modules/vehicles/mecha/mecha_movement.dm +++ b/code/modules/vehicles/mecha/mecha_movement.dm @@ -139,6 +139,8 @@ // if we're not strafing or if we are forced to rotate or if we are holding down the key if(dir != direction && (!strafe || forcerotate || keyheld)) setDir(direction) + if(!(mecha_flags & QUIET_TURNS)) + playsound(src, turnsound, 40, TRUE) if(keyheld || !pivot_step) //If we pivot step, we don't return here so we don't just come to a stop return TRUE @@ -146,10 +148,6 @@ //Otherwise just walk normally . = try_step_multiz(direction) - //dir and olddir are the current direction of the sprite and the old direction of the sprite respectively - if (dir != olddir && !(mecha_flags & QUIET_TURNS)) - playsound(src, turnsound, 40, TRUE) - if(phasing) use_energy(phasing_energy_drain) if(strafe) diff --git a/config/config.txt b/config/config.txt index 61cf30f74df0e..8f9acdca405b1 100644 --- a/config/config.txt +++ b/config/config.txt @@ -610,3 +610,9 @@ UPLOAD_LIMIT 524288 ## Restricts admin client uploads to the server, defined in bytes, default is 5MB UPLOAD_LIMIT_ADMIN 5242880 + +## Uncomment to allow admins with +DEBUG to start the byond-tracy profiler during the round. +#ALLOW_TRACY_START + +## Uncomment to allow admins with +DEBUG to queue the next round to run the byond-tracy profiler. +#ALLOW_TRACY_QUEUE diff --git a/html/changelogs/AutoChangeLog-pr-87701.yml b/html/changelogs/AutoChangeLog-pr-87701.yml new file mode 100644 index 0000000000000..1f05ead77f3f7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87701.yml @@ -0,0 +1,4 @@ +author: "carlarctg" +delete-after: True +changes: + - rscadd: "Adds the Perceptomatrix Helm, a hallucination anomaly core item" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87816.yml b/html/changelogs/AutoChangeLog-pr-87816.yml deleted file mode 100644 index cd829eb2934bd..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87816.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed scanner gates saying both bypass and detection lines when malfunctioning" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87862.yml b/html/changelogs/AutoChangeLog-pr-87862.yml deleted file mode 100644 index 68001ac6100d9..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87862.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "carlarctg" -delete-after: True -changes: - - spellcheck: "spellecheck: existence not existance" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87870.yml b/html/changelogs/AutoChangeLog-pr-87870.yml deleted file mode 100644 index c72aff1a0ed20..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87870.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "silo connection on some machines won't time out when changing FPS settings" - - code_imp: "improved attack chain code for silo connection" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87885.yml b/html/changelogs/AutoChangeLog-pr-87885.yml deleted file mode 100644 index d6582ff3aabad..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87885.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ben10Omintrix" -delete-after: True -changes: - - bugfix: "fixes seedling ai getting stuck when trying to refill water from emptied water tanks" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87887.yml b/html/changelogs/AutoChangeLog-pr-87887.yml deleted file mode 100644 index 5b0a6f175c032..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87887.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Absolucy" -delete-after: True -changes: - - bugfix: "Admin-deleting a mob now ghostizes it beforehand, preventing a runtime error." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87898.yml b/html/changelogs/AutoChangeLog-pr-87898.yml deleted file mode 100644 index aa4f5a81aa944..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-87898.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "xPokee" -delete-after: True -changes: - - bugfix: "fixed brains turning invisible after being washed" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87907.yml b/html/changelogs/AutoChangeLog-pr-87907.yml new file mode 100644 index 0000000000000..f193ce7beefb7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87907.yml @@ -0,0 +1,4 @@ +author: "zxaber" +delete-after: True +changes: + - bugfix: "Firelocks opened by a mech will correctly close when the mech moves out of range." \ No newline at end of file diff --git a/html/changelogs/archive/2024-11.yml b/html/changelogs/archive/2024-11.yml index b4f73b08b7b85..51197f3841a72 100644 --- a/html/changelogs/archive/2024-11.yml +++ b/html/changelogs/archive/2024-11.yml @@ -496,3 +496,69 @@ - bugfix: Fix using chairs in holodeck to create infinite metal xPokee, waterpig: - code_imp: cleaned up beserk.dm +2024-11-15: + Absolucy: + - refactor: The ORM, "ore container", and order console UIs (produce, mining, bitrunner + vendors) now load icons in a more efficient manner. + - bugfix: Admin-deleting a mob now ghostizes it beforehand, preventing a runtime + error. + Ben10Omintrix: + - bugfix: fixes seedling ai getting stuck when trying to refill water from emptied + water tanks + Dawnseer: + - bugfix: removes the gas mask check for if the gas mask mouth is covered. Now it + only checks for filters and other cigs + GremlinSeeker: + - bugfix: Syndicate Biodome fixes + Majkl-J: + - bugfix: Fixes SSWardrobe stealing a camera from the camera app when on a dummy, + causing a harddel + Melbert: + - image: Speeds up some frames of the dust animation slightly + - image: Dust/remains spawned after being dusted are now aligned towards the bottom + of the tile + - image: Bigger mobs now produce bigger piles of ash + - image: Plasmamen now dust into plasma bones + SmArtKar: + - bugfix: Many years later, projectiles finally can pass through portals - this + time without crashing the server. + - bugfix: Fixed tenacity effect printing its messages when it shouldn't be, and + not removing its' effects when it should've. + - bugfix: Fixed scanner gates saying both bypass and detection lines when malfunctioning + SyncIt21: + - bugfix: Fixed visual glitches when inserting items from an slot other than the + hands into evidence bags & other storages that have quick gather mode enabled + - bugfix: silo connection on some machines won't time out when changing FPS settings + - code_imp: improved attack chain code for silo connection + Time-Green: + - bugfix: Nooartrium heart damage can no longer be bypassed with non-organic hearts + carlarctg: + - bugfix: you now snip cuffs with right click to prevent accidental cuts + - spellcheck: 'spellecheck: existence not existance' + - balance: Significantly buffed the anomalock modules. + - balance: Anomalock modules can be used with eachother. + - balance: Antigravity module costs 2 complexity. + - balance: Teleporter module is thrice as fast at teleporting with a slightly reduced + cooldown, but has a much larger power cost. + - code_imp: Changed how teleporter tracks maximum range to be less painful to the + end user. + - refactor: Refactored LoS checks to be a proc on atom, los_check + - balance: Kinesis module's default range has been extended to 8. + - balance: Kinesis module can drag around people in critical condition or worse. + - bugfix: vampires are a human subtype & have stomachs/lungs + grungussuss: + - sound: sandstone blocks have the correct sound now + - qol: added feedback for cutting mulebot wires + larentoun: + - bugfix: Fixes a runtime when wingless creature flaps their wings + mc-oofert: + - bugfix: Added dehydrator to birdshot kitchen. Surgery theatre now has a surgery + tray and surplus prosthetics. An unwired hallway APC is now wired. 1st SM filter + is now set to Nitrogen. Chemistry closet in pharmacy now contains extra chemicals + to compensate for not having a chemical storage. Atmos air for distro mixer + now mixes correctly + timothymtorres: + - balance: Lower the telecrystal price of the singularity beacon from 10 to 4 and + reduce the timer to 20 minutes before it can be purchased. + xPokee: + - bugfix: fixed brains turning invisible after being washed diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 85d450e03bdd6..41bdf992bbf41 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/mob/clothing/head/helmet.dmi b/icons/mob/clothing/head/helmet.dmi index db48dda1fd61c..05fe660a33a29 100644 Binary files a/icons/mob/clothing/head/helmet.dmi and b/icons/mob/clothing/head/helmet.dmi differ diff --git a/icons/mob/dust_animation.dmi b/icons/mob/dust_animation.dmi index 459fc2aa3c4b3..10d8418a14453 100644 Binary files a/icons/mob/dust_animation.dmi and b/icons/mob/dust_animation.dmi differ diff --git a/icons/obj/clothing/head/helmet.dmi b/icons/obj/clothing/head/helmet.dmi index 621afe57ddce4..e213773717591 100644 Binary files a/icons/obj/clothing/head/helmet.dmi and b/icons/obj/clothing/head/helmet.dmi differ diff --git a/icons/obj/devices/new_assemblies.dmi b/icons/obj/devices/new_assemblies.dmi index 7bf96e5ba92e3..f80f89ce20a09 100644 Binary files a/icons/obj/devices/new_assemblies.dmi and b/icons/obj/devices/new_assemblies.dmi differ diff --git a/strings/tips.txt b/strings/tips.txt index 7d5f9f82ccc2e..2e80296af2258 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -55,6 +55,7 @@ As a Heretic, the Path of Cosmos allows you to take rightful ownership of the ve As a Janitor Cyborg, you are the bane of all slaughter demons and even Bubblegum himself. Cleaning up blood stains will severely gimp them. As a Janitor, if someone steals your janicart, you can instead use your space cleaner spray, grenades, water sprayer, exact bloody revenge or order another from Cargo. As a Janitor, mousetraps can be used to create bombs or booby-trap containers. +As a Janitor, you can command cleanbots by pointing at a tile and saying mop/clean. As a Medical Cyborg, you can fully perform surgery and even augment people. As a Medical Doctor, almost every type of wound can be treated at least temporarily with gauze. When in doubt, wrap it up! As a Medical Doctor, corpses placed inside a freezer or morgue tray will have their organs frozen preventing decay. If you don't have time to revive multiple dead bodies, transfer them to the morgue temporarily! diff --git a/tgstation.dme b/tgstation.dme index 8ea0d99629865..73c488c1c5acc 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -244,6 +244,7 @@ #include "code\__DEFINES\time.dm" #include "code\__DEFINES\tools.dm" #include "code\__DEFINES\toys.dm" +#include "code\__DEFINES\tracy.dm" #include "code\__DEFINES\trader.dm" #include "code\__DEFINES\transport.dm" #include "code\__DEFINES\tts.dm" @@ -3925,6 +3926,7 @@ #include "code\modules\clothing\head\mind_monkey_helmet.dm" #include "code\modules\clothing\head\moth.dm" #include "code\modules\clothing\head\papersack.dm" +#include "code\modules\clothing\head\perceptomatrix.dm" #include "code\modules\clothing\head\pirate.dm" #include "code\modules\clothing\head\religious.dm" #include "code\modules\clothing\head\soft_caps.dm" diff --git a/tgui/packages/tgui/interfaces/OreContainer.tsx b/tgui/packages/tgui/interfaces/OreContainer.tsx index 261523c6e9501..daae93a8edf36 100644 --- a/tgui/packages/tgui/interfaces/OreContainer.tsx +++ b/tgui/packages/tgui/interfaces/OreContainer.tsx @@ -2,23 +2,27 @@ import { createSearch, toTitleCase } from 'common/string'; import { useState } from 'react'; import { useBackend } from '../backend'; -import { Button, Flex, Image, Input, Section, Stack } from '../components'; +import { + Button, + DmIcon, + Flex, + Icon, + Input, + Section, + Stack, +} from '../components'; import { Window } from '../layouts'; type Ores = { id: string; name: string; amount: number; -}; - -type Ore_images = { - name: string; icon: string; + icon_state: string; }; type Data = { ores: Ores[]; - ore_images: Ore_images[]; }; export const OreContainer = (props) => { @@ -58,7 +62,13 @@ export const OreContainer = (props) => { - + } + /> @@ -87,30 +97,6 @@ export const OreContainer = (props) => { ); }; -const RetrieveIcon = (props) => { - const { data } = useBackend(); - const { ore_images = [] } = data; - const { ore } = props; - - let icon_display = ore_images.find((icon) => icon.name === ore.name); - - if (!icon_display) { - return null; - } - - return ( - - ); -}; - const Orename = (props) => { const { ore_name } = props; const return_name = ore_name.split(' '); diff --git a/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx b/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx index 3bb87d7dce240..b9088f32e0d4a 100644 --- a/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx +++ b/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx @@ -6,8 +6,8 @@ import { BlockQuote, Box, Button, + DmIcon, Icon, - Image, Input, LabeledList, Section, @@ -175,14 +175,7 @@ export const OreRedemptionMachine = (props) => { }; const MaterialRow = (props) => { - const { data } = useBackend(); - const { compact } = props; - const { material_icons } = data; - const { material, onRelease } = props; - - const display = material_icons.find( - (mat_icon) => mat_icon.id === material.id, - ); + const { compact, material, onRelease } = props; const sheet_amounts = Math.floor(material.amount); const print_amount = 5; @@ -192,14 +185,12 @@ const MaterialRow = (props) => { {!compact && ( - } /> )} diff --git a/tgui/packages/tgui/interfaces/ProduceConsole.tsx b/tgui/packages/tgui/interfaces/ProduceConsole.tsx index 686b194abea8c..b13fda8af077c 100644 --- a/tgui/packages/tgui/interfaces/ProduceConsole.tsx +++ b/tgui/packages/tgui/interfaces/ProduceConsole.tsx @@ -8,8 +8,8 @@ import { Button, Dimmer, Divider, + DmIcon, Icon, - Image, Input, NumberInput, Section, @@ -26,7 +26,8 @@ type OrderDatum = { cat: string; ref: string; cost: number; - product_icon: string; + icon: string; + icon_state: string; }; type Item = { @@ -127,13 +128,13 @@ const ShoppingTab = (props) => { />{' '} {!condensed && ( - } /> )}