diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm index 96dec4af720..0bfcc133f0c 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm @@ -25,8 +25,8 @@ /obj/item/clothing/shoes/galoshes{ pixel_y = -5 }, -/obj/item/flashlight/eyelight{ - pixel_y = 11 +/obj/item/flashlight{ + pixel_y = 8 }, /turf/open/floor/plating/icemoon, /area/ruin/plasma_facility/operations) diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 6f3ac43d0dc..80ebdb040f0 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -152,16 +152,6 @@ }, /turf/open/floor/grass/Airless, /area/station/hallway/primary/central/aft) -"ael" = ( -/obj/machinery/door/airlock/public/glass/incinerator/atmos_interior, -/obj/effect/mapping_helpers/airlock/locked, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, -/turf/open/floor/engine, -/area/station/maintenance/disposal/incinerator) "aem" = ( /obj/machinery/power/terminal, /obj/structure/cable, @@ -201,14 +191,6 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"aeH" = ( -/obj/machinery/atmospherics/components/trinary/filter/flipped/layer2{ - dir = 4 - }, -/obj/structure/extinguisher_cabinet/directional/north, -/obj/machinery/light/small/directional/north, -/turf/open/floor/plating, -/area/station/maintenance/disposal/incinerator) "aeX" = ( /obj/structure/window/spawner/directional/east, /obj/item/kirbyplants/random, @@ -531,12 +513,6 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/freezer, /area/station/service/kitchen/coldroom) -"amT" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/structure/chair/stool/bar/directional/south, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "anb" = ( /obj/effect/turf_decal/siding/thinplating_new/terracotta, /obj/effect/turf_decal/siding/red/corner{ @@ -2456,6 +2432,12 @@ }, /turf/open/floor/engine, /area/station/science/ordnance/burnchamber) +"aVV" = ( +/obj/machinery/atmospherics/pipe/layer_manifold/supply/visible{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/station/maintenance/department/engine/atmos) "aVX" = ( /obj/structure/cable, /obj/structure/chair, @@ -2661,6 +2643,13 @@ /obj/item/radio/intercom/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"baO" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/effect/spawner/random/entertainment/arcade{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "baP" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -3581,6 +3570,12 @@ /obj/item/airlock_painter/decal, /turf/open/floor/iron/smooth, /area/station/cargo/sorting) +"btT" = ( +/obj/machinery/camera/directional/east{ + c_tag = "Atmospherics Tank - Mix" + }, +/turf/open/floor/engine/vacuum, +/area/station/engineering/atmos) "btV" = ( /obj/effect/turf_decal/siding/wideplating, /obj/structure/railing/corner, @@ -4380,26 +4375,6 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood, /area/station/service/chapel) -"bJH" = ( -/obj/effect/turf_decal/tile/brown/opposingcorners, -/obj/machinery/atmospherics/pipe/smart/simple/cyan/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/airlock/engineering{ - name = "Engineering Office" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ - cycle_id = "atmos_airlock_1" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/iron, -/area/station/engineering/atmos/office) "bJK" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -4942,6 +4917,13 @@ }, /turf/open/space/basic, /area/space/nearstation) +"bWp" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "bWs" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -4949,11 +4931,6 @@ /obj/machinery/chem_heater/withbuffer, /turf/open/floor/iron, /area/station/science/xenobiology) -"bXb" = ( -/obj/effect/turf_decal/sand/plating, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/plating, -/area/station/maintenance/department/electrical) "bXi" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -5111,24 +5088,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"cag" = ( -/obj/effect/turf_decal/tile/brown/opposingcorners, -/obj/machinery/atmospherics/pipe/smart/simple/orange/hidden{ - dir = 4 - }, -/obj/machinery/door/airlock/engineering{ - name = "Engineering Office" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ - cycle_id = "atmos_airlock_1" - }, -/obj/structure/cable, -/obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/engineering/atmos/office) "cam" = ( /obj/machinery/flasher/directional/east{ id = "AI"; @@ -5429,6 +5388,10 @@ /obj/effect/spawner/structure/window/survival_pod, /turf/open/floor/plating, /area/station/ai_monitored/turret_protected/ai) +"cfD" = ( +/obj/item/pickaxe, +/turf/open/floor/plating, +/area/station/maintenance/department/electrical) "cfH" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -5708,16 +5671,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) -"ckR" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Plasma to Pure" - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/engineering/atmos) "ckV" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -6199,6 +6152,11 @@ /obj/machinery/light/cold/directional/north, /turf/open/floor/iron, /area/station/security/prison/rec) +"cva" = ( +/obj/structure/cable, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/plating, +/area/station/maintenance/disposal/incinerator) "cvc" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -6689,6 +6647,16 @@ }, /turf/open/floor/plating, /area/station/engineering/atmos/pumproom) +"cEm" = ( +/obj/machinery/atmospherics/components/binary/pump/on{ + name = "O2 to Airmix" + }, +/obj/machinery/light/no_nightlight/directional/north, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/engineering/atmos) "cEn" = ( /obj/structure/disposalpipe/segment, /obj/effect/decal/cleanable/dirt, @@ -7324,14 +7292,6 @@ }, /turf/open/floor/plating, /area/station/ai_monitored/turret_protected/aisat/maint) -"cQV" = ( -/obj/machinery/door/airlock/engineering/glass{ - name = "Engineering Storage" - }, -/turf/open/floor/iron/smooth_half{ - dir = 8 - }, -/area/station/engineering/main) "cRc" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -7542,6 +7502,12 @@ }, /turf/closed/wall, /area/station/service/library) +"cUB" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/structure/chair/stool/bar/directional/south, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "cUH" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -7744,6 +7710,15 @@ /obj/structure/sign/departments/telecomms/directional/south, /turf/open/floor/iron, /area/station/hallway/secondary/dock) +"cYp" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "cYt" = ( /obj/structure/cable, /turf/open/floor/plating, @@ -8370,6 +8345,13 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/textured_half, /area/station/commons/fitness/locker_room) +"diG" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/machinery/light/small/directional/east, +/obj/structure/chair/stool/bar/directional/south, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "diI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/neutral, @@ -8542,6 +8524,14 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/iron, /area/station/hallway/secondary/dock) +"dlM" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, +/obj/machinery/light/small/directional/west, +/obj/machinery/airlock_sensor/incinerator_atmos{ + pixel_y = -20 + }, +/turf/open/floor/engine, +/area/station/maintenance/disposal/incinerator) "dmk" = ( /obj/machinery/holopad, /obj/effect/landmark/start/depsec/medical, @@ -9215,10 +9205,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"dzH" = ( -/obj/machinery/portable_atmospherics/canister/plasma, -/turf/open/floor/engine/plasma, -/area/station/engineering/atmos) "dAn" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/plating, @@ -9639,6 +9625,10 @@ /obj/effect/spawner/random/structure/girder, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) +"dJl" = ( +/obj/machinery/air_sensor/mix_tank, +/turf/open/floor/engine/vacuum, +/area/station/engineering/atmos) "dJn" = ( /obj/machinery/light/small/directional/south{ dir = 4 @@ -10677,6 +10667,16 @@ /obj/structure/broken_flooring/singular/directional/east, /turf/open/floor/iron, /area/station/hallway/secondary/dock) +"eeu" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Atmospherics Maintenance" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, +/turf/open/floor/plating, +/area/station/maintenance/disposal/incinerator) "eeD" = ( /obj/structure/showcase/cyborg/old{ pixel_y = 20 @@ -10844,13 +10844,6 @@ /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) -"ehP" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/machinery/light/small/directional/east, -/obj/structure/chair/stool/bar/directional/south, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "ehT" = ( /obj/machinery/door/airlock{ id_tag = "commiss2"; @@ -11440,6 +11433,27 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/side, /area/station/hallway/primary/central/fore) +"est" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners, +/obj/machinery/atmospherics/pipe/smart/simple/cyan/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering{ + name = "Engineering Office" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "atmos_airlock_1" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, +/turf/open/floor/iron, +/area/station/engineering/atmos/office) "esv" = ( /obj/docking_port/stationary{ dwidth = 4; @@ -12412,11 +12426,6 @@ /obj/effect/turf_decal/stripes/asteroid/end, /turf/open/floor/circuit/green, /area/station/science/robotics/mechbay) -"eKd" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, -/obj/machinery/light/small/directional/west, -/turf/open/floor/engine, -/area/station/maintenance/disposal/incinerator) "eKf" = ( /obj/structure/table, /obj/item/storage/box/donkpockets/donkpocketpizza, @@ -12445,9 +12454,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"eKU" = ( -/turf/closed/wall/r_wall/rust, -/area/station/engineering/atmos/pumproom) "eKW" = ( /obj/machinery/door/airlock/maintenance{ name = "Bathroom" @@ -12599,6 +12605,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/port/aft) +"eOX" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/item/kirbyplants/random, +/obj/machinery/airalarm/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "eOY" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ dir = 4 @@ -12713,13 +12726,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"eRi" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "eRy" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -13375,6 +13381,17 @@ "feR" = ( /turf/open/floor/carpet, /area/station/service/library) +"feY" = ( +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber" + }, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter) "ffi" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/north, @@ -14363,13 +14380,6 @@ "fxi" = ( /turf/open/floor/iron/dark/small, /area/station/science/xenobiology) -"fxp" = ( -/obj/effect/spawner/structure/window/reinforced/plasma, -/obj/machinery/atmospherics/pipe/smart/simple/orange{ - dir = 1 - }, -/turf/open/floor/plating, -/area/station/engineering/supermatter/room) "fxF" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -14425,14 +14435,6 @@ /obj/machinery/power/apc/auto_name/directional/east, /turf/open/floor/plating, /area/station/service/chapel/funeral) -"fyC" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/machinery/light/small/directional/east, -/obj/structure/chair/stool/bar/directional/north, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "fyH" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -16670,6 +16672,13 @@ }, /turf/open/floor/iron/dark/corner, /area/station/science/xenobiology) +"gjn" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "gjE" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt/dust, @@ -16794,6 +16803,12 @@ "gmf" = ( /turf/open/floor/iron/white/small, /area/station/commons/toilet/restrooms) +"gmg" = ( +/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/station/maintenance/department/engine/atmos) "gmm" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -16935,15 +16950,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/security/execution/transfer) -"goY" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, -/area/station/maintenance/starboard/fore) "goZ" = ( /obj/structure/rack, /obj/item/clothing/head/costume/papersack/smiley, @@ -18153,6 +18159,10 @@ }, /turf/open/floor/iron/freezer, /area/station/command/corporate_suite) +"gJq" = ( +/obj/effect/spawner/random/structure/crate_loot, +/turf/open/floor/plating, +/area/station/maintenance/department/electrical) "gJu" = ( /obj/structure/closet, /obj/effect/mapping_helpers/broken_floor, @@ -18698,13 +18708,6 @@ /obj/structure/sign/departments/cargo/directional/west, /turf/open/floor/iron/dark, /area/station/hallway/primary/central/fore) -"gTa" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/camera/autoname/directional/east, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "gTb" = ( /turf/open/floor/iron/dark/side{ dir = 8 @@ -18845,12 +18848,6 @@ /obj/machinery/atmospherics/pipe/smart/simple/green/visible, /turf/open/floor/engine/o2, /area/station/engineering/atmos) -"gUQ" = ( -/obj/machinery/atmospherics/pipe/layer_manifold/supply/visible{ - dir = 4 - }, -/turf/closed/wall/r_wall, -/area/station/engineering/atmos/pumproom) "gUV" = ( /obj/structure/cable, /obj/structure/chair/stool/directional/south{ @@ -19669,12 +19666,6 @@ /obj/effect/mapping_helpers/airlock/access/all/security/general, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"hhr" = ( -/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall/r_wall, -/area/station/engineering/atmos/pumproom) "hhL" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -19864,6 +19855,10 @@ /obj/machinery/status_display/ai/directional/west, /turf/open/floor/iron/dark/herringbone, /area/station/ai_monitored/command/nuke_storage) +"hkX" = ( +/obj/machinery/button/ignition/incinerator/atmos, +/turf/closed/wall/r_wall, +/area/station/maintenance/disposal/incinerator) "hlC" = ( /obj/effect/spawner/structure/window, /obj/effect/turf_decal/bot{ @@ -20154,11 +20149,6 @@ dir = 8 }, /area/station/science/lobby) -"hqH" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/item/reagent_containers/cup/watering_can/wood, -/turf/open/floor/plating, -/area/station/maintenance/starboard/greater) "hqM" = ( /obj/structure/toiletbong{ dir = 1 @@ -20987,6 +20977,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"hEw" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/machinery/light/small/directional/east, +/obj/structure/chair/stool/bar/directional/north, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "hED" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -21364,6 +21362,21 @@ /obj/machinery/status_display/ai/directional/east, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"hMB" = ( +/obj/machinery/atmospherics/components/trinary/filter/flipped/layer2{ + dir = 4 + }, +/obj/machinery/light/small/directional/north, +/obj/machinery/button/door/incinerator_vent_atmos_aux{ + pixel_x = 8; + pixel_y = 24 + }, +/obj/machinery/button/door/incinerator_vent_atmos_main{ + pixel_x = 8; + pixel_y = 36 + }, +/turf/open/floor/plating, +/area/station/maintenance/disposal/incinerator) "hMK" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/item/kirbyplants/organic/applebush, @@ -21865,13 +21878,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark, /area/station/science/genetics) -"hWa" = ( -/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green, -/turf/open/floor/iron, -/area/station/engineering/atmos) "hWk" = ( /obj/machinery/vending/coffee, /obj/structure/extinguisher_cabinet/directional/south, @@ -22194,6 +22200,13 @@ /obj/effect/spawner/random/engineering/atmospherics_portable, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"ibF" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "ibI" = ( /obj/effect/turf_decal/siding/white/corner{ dir = 8 @@ -22926,6 +22939,11 @@ /obj/structure/chair/stool/directional/west, /turf/open/floor/iron, /area/station/security/prison/rec) +"iof" = ( +/obj/effect/spawner/structure/window/reinforced/plasma, +/obj/machinery/atmospherics/pipe/smart/simple/orange/visible, +/turf/open/floor/plating, +/area/station/engineering/supermatter/room) "ioo" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -23295,13 +23313,6 @@ "itb" = ( /turf/closed/wall/r_wall/rust, /area/station/ai_monitored/turret_protected/aisat/maint) -"itr" = ( -/obj/machinery/atmospherics/pipe/bridge_pipe/yellow/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green, -/turf/open/floor/iron, -/area/station/engineering/atmos) "itw" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -25617,13 +25628,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/greater) -"jbE" = ( -/obj/effect/spawner/structure/window/reinforced/plasma, -/obj/machinery/atmospherics/pipe/smart/simple/purple/visible{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/engineering/atmos) "jbV" = ( /obj/machinery/photocopier, /turf/open/floor/iron/dark, @@ -27087,6 +27091,15 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"jCB" = ( +/obj/machinery/door/airlock/engineering{ + name = "Engineering Office" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/engine_equipment, +/turf/open/floor/iron/smooth_half{ + dir = 8 + }, +/area/station/maintenance/department/engine/atmos) "jCH" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, @@ -27811,15 +27824,6 @@ /obj/structure/spider/stickyweb, /turf/open/floor/iron/small, /area/station/maintenance/department/engine/atmos) -"jMQ" = ( -/obj/machinery/atmospherics/components/binary/pump/off{ - name = "O2 To Pure" - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/engineering/atmos) "jMX" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -28232,6 +28236,13 @@ /obj/machinery/camera/autoname/directional/north, /turf/open/floor/iron, /area/station/cargo/storage) +"jTC" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/camera/autoname/directional/east, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "jTD" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/o2{ dir = 8 @@ -30250,6 +30261,9 @@ /obj/effect/turf_decal/trimline/neutral/line, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"kyS" = ( +/turf/closed/wall/r_wall/rust, +/area/station/maintenance/department/electrical) "kzs" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -30962,13 +30976,6 @@ /obj/structure/closet/firecloset, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"kNv" = ( -/obj/machinery/air_sensor/mix_tank, -/obj/machinery/camera/directional/east{ - c_tag = "Atmospherics Tank - Mix" - }, -/turf/open/floor/engine/vacuum, -/area/station/engineering/atmos) "kNx" = ( /turf/open/floor/engine/o2, /area/station/engineering/atmos) @@ -31500,6 +31507,9 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/plating, /area/station/hallway/secondary/dock) +"kXX" = ( +/turf/open/floor/engine/vacuum, +/area/station/engineering/atmos) "kYa" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -31881,14 +31891,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/textured_half, /area/station/security/brig) -"ldP" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/structure/chair/sofa/bench/right{ - dir = 4 - }, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "lee" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/purple/opposingcorners, @@ -32121,6 +32123,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/small, /area/station/maintenance/department/electrical) +"lgs" = ( +/obj/machinery/door/airlock/engineering/glass{ + name = "Engineering Storage" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/engine_equipment, +/turf/open/floor/iron/smooth_half{ + dir = 8 + }, +/area/station/engineering/main) "lgw" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -32323,6 +32334,15 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating/rust, /area/station/maintenance/department/engine/atmos) +"ljc" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "ljg" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 1 @@ -32462,6 +32482,16 @@ /obj/item/pen, /turf/open/floor/iron, /area/station/security/prison/rec) +"lkE" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "CO2 to Pure" + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/engineering/atmos) "lkI" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -33213,9 +33243,6 @@ /obj/machinery/camera/autoname/directional/west, /turf/open/floor/iron, /area/station/cargo/miningoffice) -"lwK" = ( -/turf/closed/wall/r_wall/rust, -/area/station/engineering/atmos/storage) "lwO" = ( /obj/machinery/door/airlock/highsecurity{ name = "Engine Room" @@ -33895,12 +33922,6 @@ /obj/machinery/light/cold/directional/north, /turf/open/floor/iron, /area/station/science/lower) -"lGO" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/sink/directional/west, -/turf/open/floor/iron, -/area/station/security/prison/garden) "lGT" = ( /obj/structure/chair/stool/directional/south, /obj/effect/decal/cleanable/dirt, @@ -35503,13 +35524,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/station/engineering/atmos) -"mgO" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/effect/spawner/random/entertainment/arcade{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "mgR" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ dir = 9 @@ -36634,13 +36648,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"mDb" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, -/area/station/maintenance/department/electrical) "mDf" = ( /obj/structure/chair/wood{ dir = 8 @@ -37270,10 +37277,6 @@ /obj/structure/broken_flooring/singular/directional/east, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"mMF" = ( -/obj/structure/sign/warning/pods/directional/north, -/turf/open/floor/plating, -/area/station/maintenance/department/electrical) "mMN" = ( /obj/structure/chair/office{ dir = 8 @@ -38513,6 +38516,25 @@ dir = 4 }, /area/station/science/xenobiology) +"nlP" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners, +/obj/machinery/atmospherics/pipe/smart/simple/orange/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering{ + name = "Engineering Office" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "atmos_airlock_1" + }, +/obj/structure/cable, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, +/turf/open/floor/iron, +/area/station/engineering/atmos/office) "nlQ" = ( /obj/machinery/holopad, /obj/effect/turf_decal/siding/thinplating{ @@ -39090,6 +39112,17 @@ }, /turf/open/floor/iron/smooth, /area/station/maintenance/solars/starboard/aft) +"nuV" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/structure/chair/sofa/bench/left{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "nuY" = ( /obj/structure/broken_flooring/pile/directional/east, /obj/structure/alien/weeds/node, @@ -39850,12 +39883,6 @@ /obj/machinery/light/cold/directional/south, /turf/open/floor/iron/dark, /area/station/medical/medbay/lobby) -"nIF" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/effect/spawner/random/entertainment/arcade, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "nIJ" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -39934,15 +39961,6 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"nKe" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/smart/simple/orange{ - dir = 1 - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter/room) "nKj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -40414,6 +40432,16 @@ /obj/machinery/camera/autoname/directional/south, /turf/open/floor/iron, /area/station/hallway/secondary/dock) +"nTx" = ( +/obj/machinery/portable_atmospherics/canister/air, +/obj/effect/turf_decal/bot{ + dir = 1 + }, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/dark, +/area/station/engineering/atmos/storage) "nTy" = ( /obj/machinery/transport/power_rectifier{ configured_transport_id = "bird_1" @@ -40885,15 +40913,6 @@ /obj/machinery/computer/records/security, /turf/open/floor/iron, /area/station/security/brig/entrance) -"ocZ" = ( -/obj/machinery/portable_atmospherics/canister/air, -/obj/effect/turf_decal/bot{ - dir = 1 - }, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/engineering/atmos/storage) "odh" = ( /obj/effect/landmark/atmospheric_sanity/ignore_area, /turf/open/floor/plating, @@ -40924,6 +40943,17 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/dark/small, /area/station/medical/morgue) +"odS" = ( +/obj/machinery/door/airlock/engineering/glass/critical{ + heat_proof = 1; + name = "Supermatter Chamber" + }, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/turf/open/floor/engine, +/area/station/engineering/supermatter) "odX" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -43190,12 +43220,6 @@ }, /turf/open/floor/iron, /area/station/security/execution/transfer) -"oTK" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/item/kirbyplants/random, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "oTM" = ( /obj/structure/table, /obj/effect/turf_decal/siding{ @@ -43643,6 +43667,14 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"pbU" = ( +/obj/machinery/door/airlock/engineering{ + name = "Engine Airlock" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, +/turf/open/floor/plating, +/area/station/engineering/supermatter/room) "pca" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/stripes/red/line{ @@ -44329,10 +44361,6 @@ /obj/structure/flora/bush/jungle/c/style_random, /turf/open/floor/grass, /area/station/service/chapel) -"pnO" = ( -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/disposal/incinerator) "pnQ" = ( /obj/effect/turf_decal/stripes/white/line{ dir = 6 @@ -46119,6 +46147,18 @@ /obj/machinery/camera/autoname/directional/west, /turf/open/floor/iron, /area/station/engineering/storage/tech) +"pTk" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/airlock{ + name = "Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/commons/fitness/recreation/entertainment) "pTq" = ( /obj/machinery/door/airlock/maintenance{ name = "Crematorium Maintenance" @@ -46139,6 +46179,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/smooth_large, /area/station/service/lawoffice) +"pTA" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/effect/spawner/random/entertainment/arcade, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "pTZ" = ( /obj/effect/turf_decal/siding/wideplating/dark{ dir = 8 @@ -46454,6 +46500,14 @@ /obj/structure/broken_flooring/pile/directional/east, /turf/open/floor/plating, /area/station/hallway/secondary/dock) +"pYi" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "pYr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -46931,16 +46985,6 @@ /obj/machinery/power/apc/auto_name/directional/north, /turf/open/floor/iron/white, /area/station/science/cytology) -"qht" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "CO2 to Pure" - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/engineering/atmos) "qhD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -47557,14 +47601,6 @@ }, /turf/open/floor/iron/dark/small, /area/station/maintenance/aft) -"qux" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, -/area/station/maintenance/starboard/fore) "quO" = ( /obj/structure/reagent_dispensers/wall/peppertank/directional/east, /obj/effect/turf_decal/tile/red/half/contrasted{ @@ -47970,6 +48006,10 @@ name = "Holodeck Projector Floor" }, /area/station/holodeck/rec_center) +"qBv" = ( +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/smooth_large, +/area/station/engineering/supermatter/room) "qBz" = ( /obj/effect/turf_decal/siding/wood, /obj/structure/mannequin/plastic, @@ -48755,6 +48795,15 @@ /obj/machinery/door/firedoor/heavy, /turf/open/floor/iron/dark/textured, /area/station/engineering/atmos/office) +"qPF" = ( +/obj/machinery/atmospherics/components/binary/pump/off{ + name = "O2 To Pure" + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/engineering/atmos) "qPJ" = ( /obj/machinery/status_display/ai/directional/north, /turf/open/floor/iron, @@ -48794,6 +48843,12 @@ "qQv" = ( /turf/open/floor/iron, /area/station/security/prison/rec) +"qQy" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/department/electrical) "qQB" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -49086,13 +49141,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"qUI" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "qUJ" = ( /obj/effect/turf_decal/bot{ dir = 1 @@ -50563,6 +50611,11 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/small, /area/station/ai_monitored/command/storage/eva) +"rty" = ( +/obj/machinery/portable_atmospherics/canister/plasma, +/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, +/turf/open/floor/engine/plasma, +/area/station/engineering/atmos) "rtI" = ( /turf/open/floor/iron/white/corner{ dir = 8 @@ -50645,13 +50698,6 @@ "ruD" = ( /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"ruR" = ( -/obj/machinery/door/airlock/engineering{ - name = "Engine Airlock" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plating, -/area/station/engineering/supermatter/room) "ruS" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -51556,11 +51602,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"rKa" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/structure/chair/stool/bar/directional/north, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "rKv" = ( /obj/structure/broken_flooring/singular/directional/east, /turf/open/floor/iron, @@ -52916,6 +52957,11 @@ }, /turf/open/floor/iron, /area/station/maintenance/port/fore) +"siN" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/structure/chair/stool/bar/directional/north, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "sjl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -53427,9 +53473,6 @@ /obj/structure/disposalpipe/segment, /turf/closed/wall, /area/station/maintenance/port/greater) -"srw" = ( -/turf/closed/wall/r_wall/rust, -/area/station/engineering/atmospherics_engine) "srx" = ( /obj/machinery/power/port_gen/pacman, /obj/effect/turf_decal/bot{ @@ -53549,13 +53592,6 @@ dir = 1 }, /area/station/maintenance/department/science/xenobiology) -"stG" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "stH" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/brown/half, @@ -53580,6 +53616,13 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"stW" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/smart/simple/orange/visible, +/turf/open/floor/engine, +/area/station/engineering/supermatter/room) "stX" = ( /obj/effect/landmark/start/chief_medical_officer, /turf/open/floor/wood/parquet, @@ -53603,6 +53646,14 @@ }, /turf/open/floor/carpet/purple, /area/station/commons/dorms) +"sue" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/structure/chair/sofa/bench/right{ + dir = 4 + }, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "sul" = ( /obj/effect/turf_decal/siding{ dir = 1 @@ -53638,6 +53689,12 @@ /obj/effect/mapping_helpers/airlock/access/any/service/maintenance, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"svj" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/dark, +/area/station/engineering/atmospherics_engine) "svo" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/dna_scannernew, @@ -54317,6 +54374,20 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/engine) +"sHB" = ( +/obj/machinery/door/airlock/public/glass/incinerator/atmos_interior, +/obj/effect/mapping_helpers/airlock/locked, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, +/obj/machinery/airlock_controller/incinerator_atmos{ + pixel_x = -40; + pixel_y = -8 + }, +/turf/open/floor/engine, +/area/station/maintenance/disposal/incinerator) "sHH" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/portable_atmospherics/canister/plasma, @@ -56170,6 +56241,12 @@ }, /turf/open/misc/sandy_dirt, /area/station/security/tram) +"tlJ" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/item/kirbyplants/random, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "tlX" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/blue/fourcorners, @@ -56711,18 +56788,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/server) -"tuI" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/airlock{ - name = "Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, -/area/station/commons/fitness/recreation/entertainment) "tuP" = ( /obj/machinery/light/small/directional/east, /obj/item/kirbyplants/random, @@ -59145,6 +59210,11 @@ dir = 1 }, /area/station/science/research) +"uiV" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/item/reagent_containers/cup/watering_can/wood, +/turf/open/floor/plating, +/area/station/maintenance/starboard/greater) "uiY" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -59941,6 +60011,11 @@ "uvA" = ( /turf/closed/wall/r_wall, /area/station/command/gateway) +"uvG" = ( +/obj/effect/turf_decal/tile/neutral/opposingcorners, +/obj/effect/spawner/random/entertainment/arcade, +/turf/open/floor/iron, +/area/station/commons/fitness/recreation/entertainment) "uwB" = ( /obj/effect/turf_decal/tile/dark_red/half/contrasted{ dir = 4 @@ -60075,11 +60150,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"uAD" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/effect/spawner/random/entertainment/arcade, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "uAK" = ( /obj/machinery/computer/security, /obj/effect/turf_decal/siding/red{ @@ -60088,19 +60158,6 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/wood/tile, /area/station/command/bridge) -"uAM" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/bot{ - dir = 1 - }, -/obj/structure/closet/firecloset, -/turf/open/floor/engine, -/area/station/engineering/supermatter/room) "uAY" = ( /turf/open/floor/plating, /area/station/maintenance/department/bridge) @@ -60811,6 +60868,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating/rust, /area/station/engineering/main) +"uLl" = ( +/obj/machinery/atmospherics/pipe/bridge_pipe/yellow/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible, +/turf/open/floor/iron, +/area/station/engineering/atmos) "uLD" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -61472,15 +61536,6 @@ /obj/effect/mapping_helpers/airlock/access/any/medical/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"uXe" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "uXs" = ( /obj/structure/window/spawner/directional/east, /obj/structure/window/spawner/directional/west, @@ -61717,10 +61772,6 @@ }, /turf/open/floor/iron/dark, /area/station/security/interrogation) -"vcm" = ( -/obj/item/pickaxe, -/turf/open/misc/asteroid, -/area/station/maintenance/department/electrical) "vcB" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -61997,6 +62048,12 @@ /obj/item/toy/crayon/purple, /turf/open/floor/iron/white, /area/station/science/research) +"vge" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/sink/directional/west, +/turf/open/floor/iron, +/area/station/security/prison/garden) "vgf" = ( /obj/machinery/portable_atmospherics/scrubber, /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -63898,15 +63955,6 @@ /obj/machinery/light/cold/directional/east, /turf/open/floor/engine, /area/station/science/xenobiology) -"vHU" = ( -/obj/machinery/door/airlock/engineering{ - name = "Engineering Office" - }, -/obj/effect/mapping_helpers/airlock/access/any/engineering/general, -/turf/open/floor/iron/smooth_half{ - dir = 8 - }, -/area/station/maintenance/department/engine/atmos) "vHV" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -65436,14 +65484,6 @@ "wfr" = ( /turf/closed/wall/r_wall, /area/station/medical/pharmacy) -"wfB" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt/dust, -/obj/effect/spawner/random/structure/steam_vent, -/turf/open/floor/plating, -/area/station/maintenance/department/electrical) "wfG" = ( /obj/structure/disposalpipe/segment, /obj/machinery/firealarm/directional/west, @@ -65753,6 +65793,13 @@ /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, /area/station/maintenance/aft) +"wmi" = ( +/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible, +/turf/open/floor/iron, +/area/station/engineering/atmos) "wmq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -66902,17 +66949,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) -"wDO" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/structure/chair/sofa/bench/left{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "wEf" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ @@ -67700,16 +67736,6 @@ }, /turf/open/floor/iron/smooth, /area/station/engineering/main) -"wPO" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - name = "O2 to Airmix" - }, -/obj/machinery/atmospherics/pipe/bridge_pipe/green{ - dir = 4 - }, -/obj/machinery/light/no_nightlight/directional/north, -/turf/open/floor/iron, -/area/station/engineering/atmos) "wPP" = ( /obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ dir = 1 @@ -68269,13 +68295,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood/tile, /area/station/science/lower) -"wYb" = ( -/obj/effect/turf_decal/tile/neutral/opposingcorners, -/obj/item/kirbyplants/random, -/obj/machinery/airalarm/directional/east, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/commons/fitness/recreation/entertainment) "wYd" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -69147,6 +69166,10 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron/white, /area/station/science/cytology) +"xkQ" = ( +/obj/effect/spawner/random/structure/girder, +/turf/open/floor/plating, +/area/station/maintenance/department/electrical) "xkU" = ( /obj/effect/turf_decal/siding/thinplating_new/terracotta{ dir = 9 @@ -69514,6 +69537,16 @@ dir = 1 }, /area/station/command/bridge) +"xqy" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "Plasma to Pure" + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/engineering/atmos) "xqC" = ( /turf/closed/wall, /area/station/maintenance/hallway/abandoned_command) @@ -70293,13 +70326,6 @@ /obj/effect/spawner/random/trash, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"xAx" = ( -/obj/machinery/door/airlock/engineering/glass/critical{ - heat_proof = 1; - name = "Supermatter Chamber" - }, -/turf/open/floor/engine, -/area/station/engineering/supermatter) "xAA" = ( /obj/effect/turf_decal/tile/green/half/contrasted{ dir = 1 @@ -72320,16 +72346,6 @@ "yeh" = ( /turf/closed/wall, /area/station/hallway/primary/starboard) -"yei" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Transit Tube Station" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, -/turf/open/floor/plating, -/area/station/maintenance/disposal/incinerator) "yel" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -79360,7 +79376,7 @@ ybp qBK jMp cor -wPO +cEm wLw udH gbh @@ -79601,7 +79617,7 @@ rDU hYC bLp wGx -qht +lkE nrn lCT trX @@ -79617,7 +79633,7 @@ kNx tyc dJn nrn -jMQ +qPF wmL civ gbh @@ -81403,7 +81419,7 @@ fAD jWm ybO kVB -dzH +rty rPg nrn trY @@ -81646,7 +81662,7 @@ wWm mPB pit wWm -pnO +cva pCn teV dix @@ -81657,7 +81673,7 @@ ykk hYC egC nlt -ckR +xqy nrn ktJ saq @@ -81899,7 +81915,7 @@ wBo sRf wBo hFO -wBo +hkX mPB wWm nlR @@ -82155,9 +82171,9 @@ wBo fgX uFS wBo -eKd +dlM wBo -aeH +hMB dOP pit dHx @@ -82413,7 +82429,7 @@ bTI jnI gya qBM -ael +sHB wcF eqr mUe @@ -83454,8 +83470,8 @@ oVm fjf sRW fjf -itr -hWa +uLl +wmi wFK ybO qOr @@ -83959,7 +83975,7 @@ pWm pRw pnl pxz -yei +eeu ybO ybO qKA @@ -83992,7 +84008,7 @@ kjW fcE ceN cDV -kUN +bNq ybs knv knv @@ -84218,8 +84234,8 @@ wzv wzv fjh dfd -ybO -jbE +pnl +ooo ukP ooo jZl @@ -84230,7 +84246,7 @@ wmq vMI pKW kiP -wmq +svj dYv jZl feu @@ -84240,7 +84256,7 @@ bGX jhj cGV tkU -ocZ +nTx pqr tkU kUN @@ -84249,7 +84265,7 @@ tKn eWr xcW prP -kUN +bNq ybs knv aJq @@ -84475,9 +84491,9 @@ wzv wzv fjh wzv -ybO +pnl dpH -kNv +dJl gAy jZl bKK @@ -84506,7 +84522,7 @@ hBi bzF gzM svd -kUN +bNq liX jqd lxP @@ -84732,10 +84748,10 @@ pWm pWm uEH dfd -ybO -ybO -ybO -ybO +pnl +kXX +kXX +kXX jZl bEG rCk @@ -84763,7 +84779,7 @@ isC bPd vDG rry -kUN +bNq olj cmf gBh @@ -84988,11 +85004,11 @@ wzv wzv wzv yil -yil -wfB -kNn -yil -kNn +wzv +pnl +kXX +btT +kXX jZl oqq tmK @@ -85020,7 +85036,7 @@ uqg cjS gqS kmL -eKU +ecq olj gBh gBh @@ -85241,16 +85257,16 @@ dDB aWx tdY qcF -wzv +kNn yil xnL yil -pWm -pWm -pWm -mMF -mDb -srw +qQy +pnl +pnl +pnl +pnl +kyS tXF qaU yew @@ -85277,7 +85293,7 @@ hMQ tNm nWa iua -kUN +bNq bJK dez gBh @@ -85498,14 +85514,14 @@ pWm pWm pWm pWm -pWm rjo pWm pWm pWm -bvt -bvt -bXb +qQy +qQy +qQy +qQy yil fTJ qpp @@ -85534,7 +85550,7 @@ kti iwR oQK dFG -kUN +bNq cvJ olj knv @@ -85753,18 +85769,18 @@ dDB dDB tYT aJq -aJq -pWm +gcs ako mmT vtJ acg pWm -bvt -bvt -vcm +gJq +wzv +wzv +wzv oii -jZl +pnl sZP wvZ mDS @@ -85791,7 +85807,7 @@ lkN rjw vSt kOH -kUN +bNq cvJ aIk knv @@ -86010,8 +86026,7 @@ dDB dDB tYT aJq -aJq -pWm +gcs arN wOz viE @@ -86019,9 +86034,10 @@ bOa pWm bvt bvt -bvt +xkQ +cfD oii -jZl +pnl gmv jrD jrD @@ -86048,7 +86064,7 @@ vuV xLS lfq cHt -kUN +bNq xxt liX knv @@ -86267,8 +86283,7 @@ dDB dDB tYT aJq -aJq -pWm +gcs pWm hDg qMG @@ -86277,35 +86292,36 @@ bvt bvt bvt bvt +bvt yil -jZl +pnl wFZ oLc jDi jDi jDi -jZl -srw -jZl -jZl +pnl +kyS +pnl +pnl jZl xck -cag +nlP xck -bJH +est xck cGV -cGV -cGV -lwK -cGV -kUN -hhr -kUN -gUQ -kUN -kUN -kUN +bNq +bNq +ecq +bNq +bNq +gmg +bNq +aVV +bNq +bNq +bNq knv tZE knv @@ -86526,22 +86542,22 @@ dDB tYT aJq bvt -bvt fiw oIf pWm bvt bvt bvt +bvt pWm oii -jZl +pnl jDi jDi jDi jDi jDi -jZl +pnl oCE oCE lYH @@ -86792,13 +86808,13 @@ bvt bvt pWm yil -jZl +pnl urP kLr wkj tuu kHd -jZl +pnl oCE pWm pWm @@ -86963,7 +86979,7 @@ eua izh xAG jWd -lGO +vge cZA hyX tBm @@ -87050,11 +87066,11 @@ bvt pWm qjp kNn -jZl -jZl -jZl -srw -jZl +pnl +pnl +pnl +kyS +pnl tOc oCE pWm @@ -88349,14 +88365,14 @@ oYv jJg bsG wqW -cQV +lgs tdb tdb tdb tdb qyr mLZ -vHU +jCB lER hRO knv @@ -88839,7 +88855,7 @@ ayK ayK ayK lQU -ruR +pbU lQU ayK lQU @@ -88847,7 +88863,7 @@ lQU lQU ayK lQU -ruR +pbU lQU ayK rDV @@ -89606,8 +89622,8 @@ uqe uLW blb aKm -fxp -nKe +iof +stW guh cBl fJe @@ -90393,7 +90409,7 @@ szg tpW pUM kMe -kMe +qBv fGf ayK izf @@ -91156,7 +91172,7 @@ dyI dyI ozQ ozQ -xAx +odS brA brA dyI @@ -91670,7 +91686,7 @@ cBd cBd dyI ozQ -xAx +feY brA dyI oer @@ -92701,7 +92717,7 @@ buI kjs xUK vni -uAM +nHH lHd nHH xTr @@ -112293,14 +112309,14 @@ fcW jVY cvk nFW -uAD -rKa +uvG +siN jpp -wDO -ldP +nuV +sue jpp -amT -mgO +cUB +baO pzd gMz rem @@ -112550,14 +112566,14 @@ xUy rEd aWb nFW -nIF -fyC -stG -qUI +pTA +hEw +bWp +gjn jpp -eRi -ehP -mgO +ibF +diG +baO pzd ycQ rem @@ -112809,10 +112825,10 @@ nFW nFW pzd pzd -oTK -uXe -gTa -wYb +tlJ +cYp +jTC +eOX pzd xQJ xQJ @@ -113067,7 +113083,7 @@ fsq iRl pzd pzd -tuI +pTk pzd pzd pzd @@ -113324,7 +113340,7 @@ fLg tHi tfc wOp -goY +ljc xQJ ejn vJx @@ -113581,7 +113597,7 @@ pot rUq lyq wOp -goY +ljc xQJ mbV vJx @@ -113838,7 +113854,7 @@ iqi cUY dnk wOp -qux +pYi xXT ihv rdw @@ -129055,7 +129071,7 @@ uxL lhl jxD ylD -hqH +uiV vzv brz cgM diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index a9af6ae5b9a..f39e285d0eb 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -7935,6 +7935,15 @@ /obj/structure/sink/kitchen/directional/south, /turf/open/floor/iron, /area/station/service/hydroponics) +"cmh" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/service/hydroponics/garden) "cmq" = ( /obj/machinery/door/airlock/external{ name = "External Access" @@ -9029,15 +9038,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"cBD" = ( -/obj/effect/turf_decal/siding/wood/corner{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/service/hydroponics/garden) "cBG" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -17599,6 +17599,14 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/white, /area/mine/living_quarters) +"fjX" = ( +/obj/structure/sink/directional/south, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/turf_decal/tile/green/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/security/prison/garden) "fkc" = ( /obj/machinery/power/terminal{ dir = 8 @@ -19597,6 +19605,12 @@ dir = 1 }, /area/station/security/prison) +"fQL" = ( +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/south, +/obj/item/radio/intercom/directional/west, +/turf/open/floor/iron, +/area/station/service/hydroponics/garden) "fQU" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -21885,21 +21899,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/plating, /area/station/hallway/secondary/exit/departure_lounge) -"gBV" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/red/filled/corner{ - dir = 8 - }, -/obj/machinery/holopad, -/obj/effect/landmark/start/depsec/medical, -/obj/machinery/computer/security/telescreen/med_sec/directional/east, -/turf/open/floor/iron/dark/smooth_large, -/area/station/security/checkpoint/medical) "gBX" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/hollow/reinforced/middle{ @@ -24787,10 +24786,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"hto" = ( -/obj/structure/girder, -/turf/closed/wall, -/area/station/maintenance/starboard/aft) "htp" = ( /obj/machinery/door/poddoor/preopen{ id = "xenobio2"; @@ -27127,6 +27122,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/aisat/atmos) +"ify" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/service/hydroponics/garden) "ifA" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/warning/cold_temp, @@ -29669,6 +29670,21 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) +"iTE" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/red/filled/corner{ + dir = 8 + }, +/obj/machinery/holopad, +/obj/effect/landmark/start/depsec/medical, +/obj/machinery/computer/security/telescreen/med_sec/directional/east, +/turf/open/floor/iron/dark/smooth_large, +/area/station/security/checkpoint/medical) "iTJ" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -43790,12 +43806,6 @@ /mob/living/carbon/human/species/monkey, /turf/open/floor/engine, /area/station/science/genetics) -"nhS" = ( -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/south, -/obj/item/radio/intercom/directional/west, -/turf/open/floor/iron, -/area/station/service/hydroponics/garden) "nhT" = ( /obj/machinery/door/airlock/external{ glass = 1; @@ -52419,12 +52429,6 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) -"pGy" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/service/hydroponics/garden) "pGJ" = ( /obj/structure/sign/poster/contraband/random/directional/north, /obj/effect/mapping_helpers/burnt_floor, @@ -54283,13 +54287,6 @@ }, /turf/open/floor/iron, /area/station/command/heads_quarters/qm) -"qiT" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/effect/turf_decal/tile/green/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/service/hydroponics/garden) "qjb" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ dir = 10 @@ -66884,6 +66881,13 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/medical/storage) +"tQp" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/effect/turf_decal/tile/green/anticorner/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/service/hydroponics/garden) "tQE" = ( /obj/effect/turf_decal/siding/brown/corner{ dir = 4 @@ -69459,6 +69463,17 @@ "uIg" = ( /turf/open/floor/engine/n2o, /area/station/engineering/atmos) +"uIi" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/machinery/camera/directional/east{ + c_tag = "Garden" + }, +/obj/item/kirbyplants/random, +/obj/machinery/status_display/ai/directional/east, +/turf/open/floor/iron/dark, +/area/station/service/hydroponics/garden) "uIj" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -73912,14 +73927,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/large, /area/station/command/heads_quarters/ce) -"wcz" = ( -/obj/structure/sink/directional/south, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/security/prison/garden) "wcD" = ( /obj/structure/chair/plastic{ dir = 4 @@ -77699,17 +77706,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet/blue, /area/station/hallway/secondary/entry) -"xhg" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/obj/machinery/camera/directional/east{ - c_tag = "Garden" - }, -/obj/item/kirbyplants/random, -/obj/machinery/status_display/ai/directional/east, -/turf/open/floor/iron/dark, -/area/station/service/hydroponics/garden) "xhk" = ( /turf/open/floor/iron/dark, /area/station/commons/storage/primary) @@ -169048,7 +169044,7 @@ bCp fYi tCL jNf -wcz +fjX hKI fWe ozX @@ -227938,7 +227934,7 @@ esv lCb ddZ eUA -nhS +fQL oCO oCO oCO @@ -228196,7 +228192,7 @@ eUi eBB tNd nor -qiT +tQp cgw mZu hjv @@ -228708,7 +228704,7 @@ lJO wDf sAR sAR -cBD +cmh kPy dQI pPT @@ -228965,8 +228961,8 @@ lJO mCT mut lGo -xhg -pGy +uIi +ify wCL tTc wtr @@ -251348,7 +251344,7 @@ pJC nKa dhk cDT -gBV +iTE cAI cMN uYm @@ -259618,7 +259614,7 @@ lXi vzD vzD vzD -hto +vzD jOj vzD daT diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 5e78718c948..823ada46192 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -1155,16 +1155,6 @@ /obj/machinery/door/window/left/directional/west, /turf/open/floor/grass, /area/station/service/hydroponics/garden) -"atk" = ( -/obj/machinery/airalarm/directional/east, -/obj/structure/table/reinforced, -/obj/item/storage/toolbox/mechanical, -/obj/item/clothing/head/utility/welding, -/obj/effect/turf_decal/siding/purple{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/science/robotics/mechbay) "atl" = ( /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron/freezer, @@ -5239,6 +5229,34 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"bSi" = ( +/obj/structure/table/reinforced, +/obj/effect/turf_decal/trimline/yellow/filled/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/yellow/filled/mid_joiner{ + dir = 4 + }, +/obj/item/hand_labeler{ + pixel_x = 3; + pixel_y = 5 + }, +/obj/item/storage/pill_bottle/epinephrine{ + pixel_x = -9; + pixel_y = 1 + }, +/obj/item/stack/sheet/mineral/plasma{ + pixel_y = 14; + pixel_x = 3 + }, +/obj/item/hand_labeler_refill{ + pixel_x = 10; + pixel_y = -2 + }, +/turf/open/floor/iron/white/smooth_edge{ + dir = 4 + }, +/area/station/medical/pharmacy) "bSr" = ( /obj/effect/turf_decal/siding/purple{ dir = 4 @@ -10265,22 +10283,6 @@ }, /turf/open/floor/carpet/orange, /area/station/service/theater) -"dGs" = ( -/obj/structure/table/reinforced, -/obj/item/storage/pill_bottle/epinephrine, -/obj/item/stack/sheet/mineral/plasma{ - pixel_y = 12 - }, -/obj/effect/turf_decal/trimline/yellow/filled/line{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/yellow/filled/mid_joiner{ - dir = 4 - }, -/turf/open/floor/iron/white/smooth_edge{ - dir = 4 - }, -/area/station/medical/pharmacy) "dGt" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -10747,6 +10749,20 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/storage) +"dPo" = ( +/obj/item/stack/sheet/glass, +/obj/item/clothing/glasses/welding, +/obj/item/disk/tech_disk{ + pixel_y = 6 + }, +/obj/item/reagent_containers/dropper, +/obj/structure/table, +/obj/machinery/requests_console/auto_name/directional/north, +/obj/effect/mapping_helpers/requests_console/supplies, +/obj/effect/mapping_helpers/requests_console/ore_update, +/obj/effect/mapping_helpers/requests_console/assistance, +/turf/open/floor/iron/white, +/area/station/science/lab) "dPq" = ( /obj/machinery/camera/autoname/directional/east, /turf/open/floor/grass, @@ -17273,10 +17289,6 @@ dir = 1 }, /area/station/science/research) -"ggl" = ( -/obj/machinery/camera/autoname/directional/west, -/turf/open/floor/grass, -/area/station/service/hydroponics/garden) "ggu" = ( /obj/machinery/door/airlock/public/glass{ name = "Library" @@ -34379,6 +34391,11 @@ /obj/machinery/computer/station_alert, /turf/open/floor/iron, /area/station/engineering/atmos/upper) +"miq" = ( +/obj/machinery/computer/security/telescreen/rd/directional/south, +/obj/machinery/keycard_auth/wall_mounted/directional/south, +/turf/open/floor/glass/reinforced/plasma, +/area/station/command/heads_quarters/rd) "mit" = ( /obj/structure/weightmachine/weightlifter, /obj/machinery/newscaster/directional/east, @@ -39202,6 +39219,19 @@ }, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) +"nUW" = ( +/obj/structure/table/reinforced, +/obj/item/stack/sheet/plasteel{ + amount = 15 + }, +/obj/item/assembly/prox_sensor{ + pixel_x = 5; + pixel_y = 7 + }, +/obj/structure/fireaxecabinet/mechremoval/directional/east, +/obj/item/stack/sheet/glass/fifty, +/turf/open/floor/iron/dark/textured, +/area/station/science/robotics/lab) "nVa" = ( /obj/structure/closet/secure_closet/brig/genpop, /obj/machinery/firealarm/directional/south, @@ -42471,20 +42501,6 @@ /obj/machinery/digital_clock/directional/south, /turf/open/floor/iron/white/textured_large, /area/station/medical/treatment_center) -"pfz" = ( -/obj/item/stack/sheet/glass, -/obj/item/clothing/glasses/welding, -/obj/item/disk/tech_disk{ - pixel_y = 6 - }, -/obj/item/reagent_containers/dropper, -/obj/structure/table, -/obj/machinery/requests_console/auto_name/directional/north, -/obj/effect/mapping_helpers/requests_console/supplies, -/obj/effect/mapping_helpers/requests_console/ore_update, -/obj/effect/mapping_helpers/requests_console/assistance, -/turf/open/floor/iron/white, -/area/station/science/lab) "pfV" = ( /obj/machinery/holopad, /turf/open/floor/iron, @@ -49567,12 +49583,6 @@ /obj/machinery/digital_clock/directional/south, /turf/open/floor/iron/white, /area/station/science/lab) -"rBL" = ( -/obj/machinery/computer/records/medical, -/obj/effect/turf_decal/tile/red/fourcorners, -/obj/machinery/computer/security/telescreen/med_sec/directional/north, -/turf/open/floor/iron/dark, -/area/station/security/checkpoint/medical) "rBT" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/transit_tube/station/dispenser/reverse{ @@ -49759,6 +49769,10 @@ /obj/machinery/firealarm/directional/north, /turf/open/floor/iron, /area/station/engineering/storage) +"rEm" = ( +/obj/machinery/camera/autoname/directional/west, +/turf/open/floor/grass, +/area/station/service/hydroponics/garden) "rEp" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/dark_blue/half/contrasted{ @@ -49937,6 +49951,16 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/cargo/sorting) +"rHk" = ( +/obj/machinery/airalarm/directional/east, +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/mechanical, +/obj/item/clothing/head/utility/welding, +/obj/effect/turf_decal/siding/purple{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/science/robotics/mechbay) "rHm" = ( /obj/structure/lattice/catwalk, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -53807,11 +53831,6 @@ }, /turf/open/floor/iron, /area/station/command/bridge) -"sXs" = ( -/obj/machinery/computer/security/telescreen/rd/directional/south, -/obj/machinery/keycard_auth/wall_mounted/directional/south, -/turf/open/floor/glass/reinforced/plasma, -/area/station/command/heads_quarters/rd) "sXG" = ( /obj/effect/turf_decal/tile/purple/opposingcorners, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -58832,6 +58851,12 @@ /obj/structure/cable, /turf/open/floor/plating/airless, /area/station/solars/port) +"uJq" = ( +/obj/machinery/computer/records/medical, +/obj/effect/turf_decal/tile/red/fourcorners, +/obj/machinery/computer/security/telescreen/med_sec/directional/north, +/turf/open/floor/iron/dark, +/area/station/security/checkpoint/medical) "uJt" = ( /obj/effect/mapping_helpers/engraving, /turf/closed/wall, @@ -66442,19 +66467,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet/purple, /area/station/service/library) -"xvO" = ( -/obj/structure/table/reinforced, -/obj/item/stack/sheet/plasteel{ - amount = 15 - }, -/obj/item/assembly/prox_sensor{ - pixel_x = 5; - pixel_y = 7 - }, -/obj/structure/fireaxecabinet/mechremoval/directional/east, -/obj/item/stack/sheet/glass/fifty, -/turf/open/floor/iron/dark/textured, -/area/station/science/robotics/lab) "xvU" = ( /obj/effect/landmark/event_spawn, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -82777,7 +82789,7 @@ mBj jHx iJF kFT -rBL +uJq sGt ltj fvo @@ -87401,7 +87413,7 @@ xlw qfB vyO hjW -dGs +bSi rdP qfB rgx @@ -88940,7 +88952,7 @@ tIH tIH tIH iuv -ggl +rEm tIH tIH kAg @@ -103815,7 +103827,7 @@ tdk hkc swi dHy -atk +rHk trL nMP xOU @@ -104319,7 +104331,7 @@ vfJ xbu gMK cPt -pfz +dPo wtu dfr mKF @@ -104340,7 +104352,7 @@ qnQ xcb wCO tld -xvO +nUW azv azv azv @@ -177836,7 +177848,7 @@ gmH rXS tOL fPv -sXs +miq iFN mZn oND diff --git a/_maps/safehouses/bathroom.dmm b/_maps/safehouses/bathroom.dmm index 76712d6193c..69ad0b25e95 100644 --- a/_maps/safehouses/bathroom.dmm +++ b/_maps/safehouses/bathroom.dmm @@ -27,7 +27,7 @@ dir = 4 }, /obj/machinery/light/small/blacklight/directional/east, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "v" = ( /obj/machinery/light/small/blacklight/directional/east, @@ -68,7 +68,7 @@ /obj/effect/turf_decal/loading_area{ dir = 4 }, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "M" = ( /obj/effect/decal/cleanable/dirt, diff --git a/_maps/safehouses/den.dmm b/_maps/safehouses/den.dmm index 15debc7e284..9b0b37f5351 100644 --- a/_maps/safehouses/den.dmm +++ b/_maps/safehouses/den.dmm @@ -18,7 +18,7 @@ /obj/effect/turf_decal/loading_area{ dir = 4 }, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "e" = ( /obj/structure/table/reinforced/plastitaniumglass, @@ -59,7 +59,7 @@ /obj/effect/turf_decal/loading_area{ dir = 4 }, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "z" = ( /obj/effect/turf_decal/trimline/yellow/corner{ diff --git a/_maps/safehouses/dig.dmm b/_maps/safehouses/dig.dmm index 73f0d247dfb..aa26f980d60 100644 --- a/_maps/safehouses/dig.dmm +++ b/_maps/safehouses/dig.dmm @@ -20,7 +20,7 @@ dir = 8 }, /obj/effect/landmark/bitrunning/cache_goal_turf, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "i" = ( /obj/effect/turf_decal/siding/yellow{ @@ -98,7 +98,7 @@ /obj/effect/turf_decal/loading_area, /obj/effect/turf_decal/box/corners, /obj/effect/landmark/bitrunning/cache_goal_turf, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "T" = ( /obj/effect/landmark/bitrunning/hololadder_spawn, diff --git a/_maps/safehouses/ice.dmm b/_maps/safehouses/ice.dmm index 96d689339ab..f9716de7103 100644 --- a/_maps/safehouses/ice.dmm +++ b/_maps/safehouses/ice.dmm @@ -60,7 +60,7 @@ /obj/effect/turf_decal/loading_area{ dir = 4 }, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "p" = ( /obj/structure/railing, @@ -69,7 +69,7 @@ /obj/effect/turf_decal/loading_area{ dir = 4 }, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "u" = ( /obj/effect/decal/cleanable/dirt/dust, diff --git a/_maps/safehouses/lavaland_boss.dmm b/_maps/safehouses/lavaland_boss.dmm index 7331a5b79d7..56141803990 100644 --- a/_maps/safehouses/lavaland_boss.dmm +++ b/_maps/safehouses/lavaland_boss.dmm @@ -63,7 +63,7 @@ /obj/machinery/light/directional/east, /obj/structure/railing, /obj/effect/landmark/bitrunning/cache_goal_turf, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "A" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ diff --git a/_maps/safehouses/mine.dmm b/_maps/safehouses/mine.dmm index 904c3c5378e..4bf99ab14f3 100644 --- a/_maps/safehouses/mine.dmm +++ b/_maps/safehouses/mine.dmm @@ -26,7 +26,7 @@ }, /obj/machinery/light/directional/east, /obj/effect/landmark/bitrunning/cache_goal_turf, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "B" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ @@ -52,7 +52,7 @@ }, /obj/structure/railing, /obj/effect/landmark/bitrunning/cache_goal_turf, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "H" = ( /obj/machinery/door/airlock/external/glass{ diff --git a/_maps/safehouses/shuttle.dmm b/_maps/safehouses/shuttle.dmm index 75fe975258c..19f0c4b73aa 100644 --- a/_maps/safehouses/shuttle.dmm +++ b/_maps/safehouses/shuttle.dmm @@ -16,7 +16,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/bitrunning/cache_goal_turf, /obj/effect/turf_decal/loading_area, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "i" = ( /obj/effect/turf_decal/stripes/line{ @@ -41,7 +41,7 @@ /obj/machinery/light/small/directional/south, /obj/effect/landmark/bitrunning/cache_goal_turf, /obj/effect/turf_decal/loading_area, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "m" = ( /obj/modular_map_connector, diff --git a/_maps/safehouses/shuttle_space.dmm b/_maps/safehouses/shuttle_space.dmm index 0029f5b0a6e..2f4071a8347 100644 --- a/_maps/safehouses/shuttle_space.dmm +++ b/_maps/safehouses/shuttle_space.dmm @@ -67,7 +67,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/bitrunning/cache_goal_turf, /obj/effect/turf_decal/loading_area, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "z" = ( /obj/effect/turf_decal/stripes/line{ @@ -98,7 +98,7 @@ /obj/machinery/light/small/directional/south, /obj/effect/landmark/bitrunning/cache_goal_turf, /obj/effect/turf_decal/loading_area, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "E" = ( /obj/effect/turf_decal/stripes/line{ diff --git a/_maps/safehouses/wood.dmm b/_maps/safehouses/wood.dmm index 05fbb97f915..5faa33faa41 100644 --- a/_maps/safehouses/wood.dmm +++ b/_maps/safehouses/wood.dmm @@ -19,7 +19,7 @@ /obj/effect/turf_decal/loading_area{ dir = 4 }, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "v" = ( /obj/machinery/light/small/directional/east, @@ -50,7 +50,7 @@ /obj/effect/turf_decal/loading_area{ dir = 4 }, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/safehouse) "T" = ( /obj/effect/landmark/bitrunning/hololadder_spawn, diff --git a/_maps/virtual_domains/clown_planet.dmm b/_maps/virtual_domains/clown_planet.dmm index 1973dacfb88..37e00bd45fc 100644 --- a/_maps/virtual_domains/clown_planet.dmm +++ b/_maps/virtual_domains/clown_planet.dmm @@ -759,7 +759,9 @@ /turf/open/indestructible/white, /area/lavaland/surface/outdoors/virtual_domain) "WT" = ( -/obj/machinery/door/airlock/bananium, +/obj/machinery/door/airlock/bananium{ + use_power = 0 + }, /turf/open/floor/carpet, /area/lavaland/surface/outdoors/virtual_domain) "WX" = ( diff --git a/_maps/virtual_domains/island_brawl.dmm b/_maps/virtual_domains/island_brawl.dmm index fa04316b9b6..c9010062f54 100644 --- a/_maps/virtual_domains/island_brawl.dmm +++ b/_maps/virtual_domains/island_brawl.dmm @@ -2540,7 +2540,7 @@ /area/virtual_domain) "GD" = ( /obj/effect/landmark/bitrunning/permanent_exit, -/turf/open/floor/bitrunning_transport, +/turf/open/indestructible/bitrunning_transport, /area/virtual_domain/protected_space/fullbright) "GI" = ( /turf/open/floor/iron/dark/textured_large, diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm index 97ec38c1c3c..4374288b07c 100644 --- a/code/__DEFINES/ai/ai_blackboard.dm +++ b/code/__DEFINES/ai/ai_blackboard.dm @@ -24,6 +24,8 @@ ///the list of interactions we can have with the owner #define BB_INTERACTIONS_WITH_OWNER "BB_interactions_with_owner" +///The trait checked by ai_behavior/find_potential_targets/prioritize_trait to return a target with a trait over the rest. +#define BB_TARGET_PRIORITY_TRAIT "target_priority_trait" /// Store a single or list of emotes at this key #define BB_EMOTE_KEY "BB_emotes" diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm index 76fd6c798d5..fb6952eb084 100644 --- a/code/__DEFINES/ai/monsters.dm +++ b/code/__DEFINES/ai/monsters.dm @@ -70,8 +70,12 @@ #define BB_LOBSTROSITY_TARGET_LIMB "BB_lobstrosity_target_limb" /// We increment this counter every time we try to move while dragging an arm and if we go too long we'll give up trying to get out of line of sight and just eat the fingers #define BB_LOBSTROSITY_FINGER_LUST "BB_lobstrosity_finger_lust" +/// Does this carp still target lying mobs even if they aren't stunned, and flee from sary fishermen? #define BB_LOBSTROSITY_NAIVE_HUNTER "BB_lobstrosity_naive_hunter" +/// Does this carp run from scary fishermen? +#define BB_CARPS_FEAR_FISHERMAN "BB_carp_fear_fisherman" + // eyeball keys ///the death glare ability #define BB_GLARE_ABILITY "BB_glare_ability" diff --git a/code/__DEFINES/basic_mobs.dm b/code/__DEFINES/basic_mobs.dm index ae74872cd73..e519fb25240 100644 --- a/code/__DEFINES/basic_mobs.dm +++ b/code/__DEFINES/basic_mobs.dm @@ -70,5 +70,3 @@ GLOBAL_VAR_INIT(gutlunch_count, 0) #define BB_RAPTOR_TROUGH_TARGET "raptor_trough_target" #define MAX_RAPTOR_POP 64 - - diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index de50b9187d6..aadf93fad74 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -106,6 +106,8 @@ DEFINE_BITFIELD(no_equip_flags, list( #define HIDESNOUT (1<<12) ///hides mutant/moth wings, does not apply to functional wings #define HIDEMUTWINGS (1<<13) +///hides belts and riggings +#define HIDEBELT (1<<14) //SKYRAT EDIT ADDITION: CUSTOM EAR TOGGLE FOR ANTHRO/ETC EAR SHOWING - /// Manually set this on items you want anthro ears to show on! diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 13d0f1c9063..f7700da8441 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -100,7 +100,7 @@ #define JOB_CHAPLAIN "Chaplain" #define JOB_PSYCHOLOGIST "Psychologist" #define JOB_BARBER "Barber" // SKYRAT EDIT ADDITION -#define JOB_BOUNCER "Service Guard" // SKYRAT EDIT ADDITION +#define JOB_BOUNCER "Bouncer" // SKYRAT EDIT ADDITION //ERTs #define JOB_ERT_DEATHSQUAD "Death Commando" #define JOB_ERT_COMMANDER "Emergency Response Team Commander" diff --git a/code/__DEFINES/mining.dm b/code/__DEFINES/mining.dm index 5b612b4b7bc..d0fa97062b1 100644 --- a/code/__DEFINES/mining.dm +++ b/code/__DEFINES/mining.dm @@ -9,6 +9,7 @@ #define MAX_BOULDERS_PER_VENT 10 /// Time multiplier #define INATE_BOULDER_SPEED_MULTIPLIER 3 + // Vent type /// Large vents, giving large boulders. #define LARGE_VENT_TYPE "large" @@ -17,6 +18,14 @@ /// Small vents, giving small boulders. #define SMALL_VENT_TYPE "small" +// Timers for the ore vents to perform wave defense. +/// Duration for wave defense for a small vent. +#define WAVE_DURATION_SMALL 60 SECONDS +/// Duration for wave defense for a medium vent. +#define WAVE_DURATION_MEDIUM 90 SECONDS +/// Duration for wave defense for a large vent. +#define WAVE_DURATION_LARGE 150 SECONDS + /// Proximity to a vent that a wall ore needs to be for 5 ore to be mined. #define VENT_PROX_VERY_HIGH 3 /// Proximity to a vent that a wall ore needs to be for 4 ore to be mined. diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 3a47fe1ca0a..294d32ddc3b 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -225,6 +225,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_REVEAL_FISH "reveal_fish" ///This trait gets you a list of fishes that can be caught when examining a fishing spot. #define TRAIT_EXAMINE_FISHING_SPOT "examine_fishing_spot" +///lobstrosities and carps will prioritize/flee from those that have this trait (given by the skill-locked hat) +#define TRAIT_SCARY_FISHERMAN "scary_fisherman" ///Trait given to turfs or objects that can be fished from #define TRAIT_FISHING_SPOT "fishing_spot" ///Trait given to mobs that can fish without a rod @@ -1125,6 +1127,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///Trait given to limb by /mob/living/basic/living_limb_flesh #define TRAIT_IGNORED_BY_LIVING_FLESH "livingflesh_ignored" +///Trait given to organs that have been inside a living being previously +#define TRAIT_USED_ORGAN "used_organ" + /// Trait given while using /datum/action/cooldown/mob_cooldown/wing_buffet #define TRAIT_WING_BUFFET "wing_buffet" /// Trait given while tired after using /datum/action/cooldown/mob_cooldown/wing_buffet diff --git a/code/__DEFINES/uplink.dm b/code/__DEFINES/uplink.dm index 67df6fc0e62..929b558dfec 100644 --- a/code/__DEFINES/uplink.dm +++ b/code/__DEFINES/uplink.dm @@ -36,9 +36,12 @@ /// Typepath used for uplink items which don't actually produce an item (essentially just a placeholder) /// Future todo: Make this not necessary / make uplink items support item-less items natively -#define ABSTRACT_UPLINK_ITEM /obj/effect/gibspawner/generic +#define ABSTRACT_UPLINK_ITEM /obj/item/loot_table_maker /// Lower threshold for which an uplink items's TC cost is considered "low" for spy bounties picking rewards #define SPY_LOWER_COST_THRESHOLD 5 /// Upper threshold for which an uplink items's TC cost is considered "high" for spy bounties picking rewards #define SPY_UPPER_COST_THRESHOLD 12 + +/// Minimal cost for an item to be eligible for a discount +#define TRAITOR_DISCOUNT_MIN_PRICE 4 diff --git a/code/__DEFINES/~skyrat_defines/DNA.dm b/code/__DEFINES/~skyrat_defines/DNA.dm index 5ea728ac724..d8c48d45066 100644 --- a/code/__DEFINES/~skyrat_defines/DNA.dm +++ b/code/__DEFINES/~skyrat_defines/DNA.dm @@ -69,14 +69,20 @@ //In inches #define PENIS_MIN_GIRTH PENIS_MIN_LENGTH -#define PENIS_MAX_GIRTH 15 +#define PENIS_MAX_GIRTH 20 +/// for non oversized mobs with a 'normal' body size +#define PENIS_MAX_GIRTH_NORMAL_SIZED 15 #define PENIS_DEFAULT_GIRTH 5 // a lil big but not by much #define PENIS_MIN_LENGTH 1 -#define PENIS_MAX_LENGTH 20 +#define PENIS_MAX_LENGTH 36 +/// for non oversized mobs with a 'normal' body size +#define PENIS_MAX_LENGTH_NORMAL_SIZED 20 #define PENIS_DEFAULT_LENGTH 6 //still a lil long but not insane #define TESTICLES_MIN_SIZE 0 -#define TESTICLES_MAX_SIZE 3 +#define TESTICLES_MAX_SIZE 6 +/// for non oversized mobs with a 'normal' body size +#define TESTICLES_MAX_NORMAL_SIZED 3 #define SHEATH_NONE "None" #define SHEATH_NORMAL "Sheath" diff --git a/code/__DEFINES/~skyrat_defines/keybindings.dm b/code/__DEFINES/~skyrat_defines/keybindings.dm index 5a205f4f0f8..76dc277fe59 100644 --- a/code/__DEFINES/~skyrat_defines/keybindings.dm +++ b/code/__DEFINES/~skyrat_defines/keybindings.dm @@ -1,5 +1,9 @@ #define COMSIG_KB_MOB_PIXEL_SHIFT_DOWN "keybinding_mob_pixel_shift_down" #define COMSIG_KB_MOB_PIXEL_SHIFT_UP "keybinding_mob_pixel_shift_up" +#define COMSIG_KB_MOB_ITEM_PIXEL_SHIFT_DOWN "keybinding_mob_item_pixelshift_down" +#define COMSIG_KB_MOB_ITEM_PIXEL_SHIFT_UP "keybinding_mob_item_pixelshift_up" +#define COMSIG_KB_MOB_PIXEL_TILT_DOWN "keybinding_mob_pixeltilt_down" +#define COMSIG_KB_MOB_PIXEL_TILT_UP "keybinding_mob_pixeltilt_up" #define COMSIG_KB_CLIENT_LOOC_DOWN "keybinding_client_looc_down" #define COMSIG_KB_CLIENT_WHISPER_DOWN "keybinding_client_whisper_down" #define COMSIG_KB_LIVING_COMBAT_INDICATOR "keybinding_living_combat_indicator" diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index aa953760bce..ce48e593980 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -214,16 +214,16 @@ if(istype(atom_to_find, type)) return atom_to_find - while(!istype(atom_to_find.loc, type)) + while(!istype(atom_to_find, type)) if(!atom_to_find.loc) return atom_to_find = atom_to_find.loc else if(isatom(type)) atom_to_find = target - if(atom_to_find.loc == type) + if(atom_to_find == type) return atom_to_find - while(atom_to_find.loc != type) + while(atom_to_find != type) if(!atom_to_find.loc) return atom_to_find = atom_to_find.loc diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 596e688a256..0aa6f91da99 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -121,7 +121,7 @@ if(isnull(user_input)) // User pressed cancel return if(no_trim) - return copytext(html_encode(user_input), 1, max_length) + return copytext_char(html_encode(user_input), 1, max_length) else return trim(html_encode(user_input), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) @@ -140,7 +140,7 @@ if(isnull(user_input)) // User pressed cancel return if(no_trim) - return copytext(html_encode(user_input), 1, max_length) + return copytext_char(html_encode(user_input), 1, max_length) else return trim(html_encode(user_input), max_length) @@ -368,7 +368,7 @@ */ /proc/truncate(text, max_length) if(length(text) > max_length) - return copytext(text, 1, max_length) + return copytext_char(text, 1, max_length) return text //Returns a string with reserved characters and spaces before the first word and after the last word removed. diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 5a3ea8d8de0..fd934e922bb 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -200,6 +200,7 @@ DEFINE_BITFIELD(flags_inv, list( "HIDEHEADGEAR" = HIDEHEADGEAR, "HIDEJUMPSUIT" = HIDEJUMPSUIT, "HIDEMASK" = HIDEMASK, + "HIDEBELT" = HIDEBELT, "HIDENECK" = HIDENECK, "HIDESHOES" = HIDESHOES, "HIDESNOUT" = HIDESNOUT, diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 8d97c8fe84f..17f9c742da1 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -61,6 +61,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT" = TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT, "TRAIT_ON_HIT_EFFECT" = TRAIT_ON_HIT_EFFECT, "TRAIT_RUNECHAT_HIDDEN" = TRAIT_RUNECHAT_HIDDEN, + "TRAIT_SCARY_FISHERMAN" = TRAIT_SCARY_FISHERMAN, "TRAIT_SECLUDED_LOCATION" = TRAIT_SECLUDED_LOCATION, "TRAIT_SNOWSTORM_IMMUNE" = TRAIT_SNOWSTORM_IMMUNE, "TRAIT_TELEKINESIS_CONTROLLED" = TRAIT_TELEKINESIS_CONTROLLED, @@ -218,7 +219,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ECHOLOCATION_RECEIVER" = TRAIT_ECHOLOCATION_RECEIVER, "TRAIT_ELDRITCH_PAINTING_EXAMINE" = TRAIT_ELDRITCH_PAINTING_EXAMINE, "TRAIT_ELITE_CHALLENGER" = TRAIT_ELITE_CHALLENGER, - "TRAIT_EMOTEMUTE " = TRAIT_EMOTEMUTE, "TRAIT_EMOTEMUTE" = TRAIT_EMOTEMUTE, "TRAIT_EMPATH" = TRAIT_EMPATH, "TRAIT_ENTRAILS_READER" = TRAIT_ENTRAILS_READER, @@ -617,6 +617,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( ), /obj/item/organ = list( "TRAIT_LIVING_HEART" = TRAIT_LIVING_HEART, + "TRAIT_USED_ORGAN" = TRAIT_USED_ORGAN, ), /obj/item/organ/internal/liver = list( "TRAIT_BALLMER_SCIENTIST" = TRAIT_BALLMER_SCIENTIST, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 8be2556d08e..3fd9993c018 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -18,6 +18,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_MOVE_VENTCRAWLING" = TRAIT_MOVE_VENTCRAWLING, "TRAIT_MOVE_UPSIDE_DOWN" = TRAIT_MOVE_UPSIDE_DOWN, "TRAIT_RUNECHAT_HIDDEN" = TRAIT_RUNECHAT_HIDDEN, + "TRAIT_SCARY_FISHERMAN" = TRAIT_SCARY_FISHERMAN, "TRAIT_SNOWSTORM_IMMUNE" = TRAIT_SNOWSTORM_IMMUNE, "TRAIT_VOIDSTORM_IMMUNE" = TRAIT_VOIDSTORM_IMMUNE, "TRAIT_WEATHER_IMMUNE" = TRAIT_WEATHER_IMMUNE, @@ -29,14 +30,21 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_AGENDER" = TRAIT_AGENDER, "TRAIT_AGEUSIA" = TRAIT_AGEUSIA, "TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE, + "TRAIT_ALLOW_HERETIC_CASTING" = TRAIT_ALLOW_HERETIC_CASTING, + "TRAIT_ALWAYS_NO_ACCESS" = TRAIT_ALWAYS_NO_ACCESS, + "TRAIT_ALWAYS_WANTED" = TRAIT_ALWAYS_WANTED, "TRAIT_ANOSMIA" = TRAIT_ANOSMIA, + "TRAIT_ANTENNAE" = TRAIT_ANTENNAE, "TRAIT_ANTIMAGIC" = TRAIT_ANTIMAGIC, + "TRAIT_ANTIMAGIC_NO_SELFBLOCK" = TRAIT_ANTIMAGIC_NO_SELFBLOCK, "TRAIT_ANXIOUS" = TRAIT_ANXIOUS, "TRAIT_BADDNA" = TRAIT_BADDNA, "TRAIT_BADTOUCH" = TRAIT_BADTOUCH, "TRAIT_BALD" = TRAIT_BALD, + "TRAIT_BALLOON_SUTRA" = TRAIT_BALLOON_SUTRA, "TRAIT_BATON_RESISTANCE" = TRAIT_BATON_RESISTANCE, "TRAIT_BEAST_EMPATHY" = TRAIT_BEAST_EMPATHY, + "TRAIT_BLOB_ALLY" = TRAIT_BLOB_ALLY, "TRAIT_BLOCK_SHUTTLE_MOVEMENT" = TRAIT_BLOCK_SHUTTLE_MOVEMENT, "TRAIT_BLOOD_CLANS" = TRAIT_BLOOD_CLANS, "TRAIT_BLOODSHOT_EYES" = TRAIT_BLOODSHOT_EYES, @@ -45,20 +53,27 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_BOOZE_SLIDER" = TRAIT_BOOZE_SLIDER, "TRAIT_BYPASS_MEASURES" = TRAIT_BYPASS_MEASURES, "TRAIT_CAN_HOLD_ITEMS" = TRAIT_CAN_HOLD_ITEMS, + "TRAIT_CAN_STRIP" = TRAIT_CAN_STRIP, + "TRAIT_CAN_USE_NUKE" = TRAIT_CAN_USE_NUKE, "TRAIT_CANNOT_BE_UNBUCKLED" = TRAIT_CANNOT_BE_UNBUCKLED, "TRAIT_CANNOT_OPEN_PRESENTS" = TRAIT_CANNOT_OPEN_PRESENTS, + "TRAIT_CATLIKE_GRACE" = TRAIT_CATLIKE_GRACE, "TRAIT_CHASM_DESTROYED" = TRAIT_CHASM_DESTROYED, "TRAIT_CHUNKYFINGERS_IGNORE_BATON" = TRAIT_CHUNKYFINGERS_IGNORE_BATON, "TRAIT_CHUNKYFINGERS" = TRAIT_CHUNKYFINGERS, + "TRAIT_CLEANBOT_WHISPERER" = TRAIT_CLEANBOT_WHISPERER, + "TRAIT_CLIFF_WALKER" = TRAIT_CLIFF_WALKER, "TRAIT_CLOWN_ENJOYER" = TRAIT_CLOWN_ENJOYER, "TRAIT_CLUMSY" = TRAIT_CLUMSY, "TRAIT_COMMISSIONED" = TRAIT_COMMISSIONED, + "TRAIT_CORPSELOCKED" = TRAIT_CORPSELOCKED, "TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION, "TRAIT_CULT_HALO" = TRAIT_CULT_HALO, "TRAIT_DEAF" = TRAIT_DEAF, "TRAIT_DEATHCOMA" = TRAIT_DEATHCOMA, "TRAIT_DEFIB_BLACKLISTED" = TRAIT_DEFIB_BLACKLISTED, "TRAIT_DEPRESSION" = TRAIT_DEPRESSION, + "TRAIT_DETECT_STORM" = TRAIT_DETECT_STORM, "TRAIT_DIAGNOSTIC_HUD" = TRAIT_DIAGNOSTIC_HUD, "TRAIT_BOT_PATH_HUD" = TRAIT_BOT_PATH_HUD, "TRAIT_DISCOORDINATED_TOOL_USER" = TRAIT_DISCOORDINATED_TOOL_USER, @@ -70,42 +85,59 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_DWARF" = TRAIT_DWARF, "TRAIT_EASILY_WOUNDED" = TRAIT_EASILY_WOUNDED, "TRAIT_EASYDISMEMBER" = TRAIT_EASYDISMEMBER, - "TRAIT_EMOTEMUTE " = TRAIT_EMOTEMUTE, + "TRAIT_EMOTEMUTE" = TRAIT_EMOTEMUTE, "TRAIT_EMPATH" = TRAIT_EMPATH, + "TRAIT_ENTRAILS_READER" = TRAIT_ENTRAILS_READER, + "TRAIT_EXAMINE_FISHING_SPOT" = TRAIT_EXAMINE_FISHING_SPOT, "TRAIT_EXAMINE_FITNESS" = TRAIT_EXAMINE_FITNESS, "TRAIT_EXPANDED_FOV" = TRAIT_EXPANDED_FOV, "TRAIT_EXPERT_FISHER" = TRAIT_EXPERT_FISHER, + "TRAIT_EXTROVERT" = TRAIT_EXTROVERT, "TRAIT_FAKEDEATH" = TRAIT_FAKEDEATH, + "TRAIT_FASTMED" = TRAIT_FASTMED, "TRAIT_FAST_CUFFING" = TRAIT_FAST_CUFFING, + "TRAIT_FAST_TYING" = TRAIT_FAST_TYING, "TRAIT_FAT" = TRAIT_FAT, "TRAIT_FEARLESS" = TRAIT_FEARLESS, "TRAIT_FENCE_CLIMBER" = TRAIT_FENCE_CLIMBER, "TRAIT_FIST_MINING" = TRAIT_FIST_MINING, "TRAIT_FIXED_HAIRCOLOR" = TRAIT_FIXED_HAIRCOLOR, "TRAIT_FIXED_MUTANT_COLORS" = TRAIT_FIXED_MUTANT_COLORS, + "TRAIT_FLESH_DESIRE" = TRAIT_FLESH_DESIRE, "TRAIT_FLOORED" = TRAIT_FLOORED, + "TRAIT_FORBID_MINING_SHUTTLE_CONSOLE_OUTSIDE_STATION" = TRAIT_FORBID_MINING_SHUTTLE_CONSOLE_OUTSIDE_STATION, "TRAIT_FORCED_STANDING" = TRAIT_FORCED_STANDING, "TRAIT_FREERUNNING" = TRAIT_FREERUNNING, + "TRAIT_FREE_FLOAT_MOVEMENT" = TRAIT_FREE_FLOAT_MOVEMENT, + "TRAIT_FREE_HYPERSPACE_MOVEMENT" = TRAIT_FREE_HYPERSPACE_MOVEMENT, + "TRAIT_FREE_HYPERSPACE_SOFTCORDON_MOVEMENT" = TRAIT_FREE_HYPERSPACE_SOFTCORDON_MOVEMENT, "TRAIT_FRIENDLY" = TRAIT_FRIENDLY, "TRAIT_GAMER" = TRAIT_GAMER, "TRAIT_GAMERGOD" = TRAIT_GAMERGOD, + "TRAIT_GARLIC_BREATH" = TRAIT_GARLIC_BREATH, "TRAIT_GENELESS" = TRAIT_GENELESS, "TRAIT_GIANT" = TRAIT_GIANT, "TRAIT_GOOD_HEARING" = TRAIT_GOOD_HEARING, "TRAIT_GRABWEAKNESS" = TRAIT_GRABWEAKNESS, "TRAIT_GREENTEXT_CURSED" = TRAIT_GREENTEXT_CURSED, "TRAIT_GUNFLIP" = TRAIT_GUNFLIP, + "TRAIT_GUN_NATURAL" = TRAIT_GUN_NATURAL, "TRAIT_HANDS_BLOCKED" = TRAIT_HANDS_BLOCKED, "TRAIT_HARDLY_WOUNDED" = TRAIT_HARDLY_WOUNDED, + "TRAIT_HATED_BY_DOGS" = TRAIT_HATED_BY_DOGS, + "TRAIT_HEAVY_DRINKER" = TRAIT_HEAVY_DRINKER, "TRAIT_HEAVY_SLEEPER" = TRAIT_HEAVY_SLEEPER, "TRAIT_HIDE_EXTERNAL_ORGANS" = TRAIT_HIDE_EXTERNAL_ORGANS, + "TRAIT_HIGH_VALUE_RANSOM" = TRAIT_HIGH_VALUE_RANSOM, "TRAIT_HOLY" = TRAIT_HOLY, "TRAIT_HUSK" = TRAIT_HUSK, + "TRAIT_ID_APPRAISER" = TRAIT_ID_APPRAISER, "TRAIT_IGNORE_ELEVATION" = TRAIT_IGNORE_ELEVATION, "TRAIT_IGNORESLOWDOWN" = TRAIT_IGNORESLOWDOWN, "TRAIT_ILLITERATE" = TRAIT_ILLITERATE, "TRAIT_IMMOBILIZED" = TRAIT_IMMOBILIZED, "TRAIT_INCAPACITATED" = TRAIT_INCAPACITATED, + "TRAIT_INTROVERT" = TRAIT_INTROVERT, "TRAIT_INVISIBLE_MAN" = TRAIT_INVISIBLE_MAN, "TRAIT_IWASBATONED" = TRAIT_IWASBATONED, "TRAIT_JOLLY" = TRAIT_JOLLY, @@ -113,23 +145,28 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_KNOCKEDOUT" = TRAIT_KNOCKEDOUT, "TRAIT_KNOW_ENGI_WIRES" = TRAIT_KNOW_ENGI_WIRES, "TRAIT_KNOW_ROBO_WIRES" = TRAIT_KNOW_ROBO_WIRES, + "TRAIT_LIGHTBULB_REMOVER" = TRAIT_LIGHTBULB_REMOVER, "TRAIT_LIGHT_DRINKER" = TRAIT_LIGHT_DRINKER, "TRAIT_LIGHT_STEP" = TRAIT_LIGHT_STEP, "TRAIT_LIGHTBULB_REMOVER" = TRAIT_LIGHTBULB_REMOVER, "TRAIT_LIMBATTACHMENT" = TRAIT_LIMBATTACHMENT, "TRAIT_LITERATE" = TRAIT_LITERATE, "TRAIT_LIVERLESS_METABOLISM" = TRAIT_LIVERLESS_METABOLISM, + "TRAIT_MADNESS_IMMUNE" = TRAIT_MADNESS_IMMUNE, "TRAIT_MAGICALLY_GIFTED" = TRAIT_MAGICALLY_GIFTED, + "TRAIT_MARTIAL_ARTS_IMMUNE" = TRAIT_MARTIAL_ARTS_IMMUNE, "TRAIT_MEDICAL_HUD" = TRAIT_MEDICAL_HUD, "TRAIT_MIME_FAN" = TRAIT_MIME_FAN, "TRAIT_MIMING" = TRAIT_MIMING, "TRAIT_MINDSHIELD" = TRAIT_MINDSHIELD, "TRAIT_MOB_HIDE_HAPPINESS" = TRAIT_MOB_HIDE_HAPPINESS, "TRAIT_MORBID" = TRAIT_MORBID, + "TRAIT_MULTIZ_SUIT_SENSORS" = TRAIT_MULTIZ_SUIT_SENSORS, "TRAIT_MUSICIAN" = TRAIT_MUSICIAN, "TRAIT_MUTANT_COLORS" = TRAIT_MUTANT_COLORS, "TRAIT_MUTE" = TRAIT_MUTE, "TRAIT_NAIVE" = TRAIT_NAIVE, + "TRAIT_NEGATES_GRAVITY" = TRAIT_NEGATES_GRAVITY, "TRAIT_NEVER_WOUNDED" = TRAIT_NEVER_WOUNDED, "TRAIT_NICE_SHOT" = TRAIT_NICE_SHOT, "TRAIT_NIGHT_VISION" = TRAIT_NIGHT_VISION, @@ -138,13 +175,18 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_NO_DNA_COPY" = TRAIT_NO_DNA_COPY, "TRAIT_NO_EXTINGUISH" = TRAIT_NO_EXTINGUISH, "TRAIT_NO_GLIDE" = TRAIT_NO_GLIDE, + "TRAIT_NO_GUN_AKIMBO" = TRAIT_NO_GUN_AKIMBO, + "TRAIT_NO_MINDSWAP" = TRAIT_NO_MINDSWAP, + "TRAIT_NO_MIRROR_REFLECTION" = TRAIT_NO_MIRROR_REFLECTION, "TRAIT_NO_PLASMA_TRANSFORM" = TRAIT_NO_PLASMA_TRANSFORM, "TRAIT_NO_SLIP_ALL" = TRAIT_NO_SLIP_ALL, "TRAIT_NO_SLIP_ICE" = TRAIT_NO_SLIP_ICE, "TRAIT_NO_SLIP_SLIDE" = TRAIT_NO_SLIP_SLIDE, "TRAIT_NO_SLIP_WATER" = TRAIT_NO_SLIP_WATER, "TRAIT_NO_SOUL" = TRAIT_NO_SOUL, + "TRAIT_NO_STAGGER" = TRAIT_NO_STAGGER, "TRAIT_NO_TRANSFORM" = TRAIT_NO_TRANSFORM, + "TRAIT_NO_TWOHANDING" = TRAIT_NO_TWOHANDING, "TRAIT_NO_UNDERWEAR" = TRAIT_NO_UNDERWEAR, "TRAIT_NO_ZOMBIFY" = TRAIT_NO_ZOMBIFY, "TRAIT_NOBLOOD" = TRAIT_NOBLOOD, @@ -153,7 +195,10 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_NOCRITOVERLAY" = TRAIT_NOCRITOVERLAY, "TRAIT_NODEATH" = TRAIT_NODEATH, "TRAIT_NODISMEMBER" = TRAIT_NODISMEMBER, + "TRAIT_NOFAT" = TRAIT_NOFAT, + "TRAIT_NOFEAR_HOLDUPS" = TRAIT_NOFEAR_HOLDUPS, "TRAIT_NOFIRE" = TRAIT_NOFIRE, + "TRAIT_NOFIRE_SPREAD" = TRAIT_NOFIRE_SPREAD, "TRAIT_NOFLASH" = TRAIT_NOFLASH, "TRAIT_NOGUNS" = TRAIT_NOGUNS, "TRAIT_TOSS_GUN_HARD" = TRAIT_TOSS_GUN_HARD, @@ -162,7 +207,9 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_NOLIMBDISABLE" = TRAIT_NOLIMBDISABLE, "TRAIT_NOMOBSWAP" = TRAIT_NOMOBSWAP, "TRAIT_NOSOFTCRIT" = TRAIT_NOSOFTCRIT, + "TRAIT_OFF_BALANCE_TACKLER" = TRAIT_OFF_BALANCE_TACKLER, "TRAIT_OIL_FRIED" = TRAIT_OIL_FRIED, + "TRAIT_OVERDOSEIMMUNE" = TRAIT_OVERDOSEIMMUNE, "TRAIT_OVERWATCH_IMMUNE" = TRAIT_OVERWATCH_IMMUNE, "TRAIT_PACIFISM" = TRAIT_PACIFISM, "TRAIT_HIPPOCRATIC_OATH" = TRAIT_HIPPOCRATIC_OATH, @@ -174,6 +221,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_PASSTABLE" = TRAIT_PASSTABLE, "TRAIT_PASSWINDOW" = TRAIT_PASSWINDOW, "TRAIT_PERFECT_ATTACKER" = TRAIT_PERFECT_ATTACKER, + "TRAIT_PERMANENTLY_MORTAL" = TRAIT_PERMANENTLY_MORTAL, "TRAIT_PHOTOGRAPHER" = TRAIT_PHOTOGRAPHER, "TRAIT_PIERCEIMMUNE" = TRAIT_PIERCEIMMUNE, "TRAIT_PLANT_SAFE" = TRAIT_PLANT_SAFE, @@ -184,16 +232,22 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_PROSOPAGNOSIA" = TRAIT_PROSOPAGNOSIA, "TRAIT_PULL_BLOCKED" = TRAIT_PULL_BLOCKED, "TRAIT_PUSHIMMUNE" = TRAIT_PUSHIMMUNE, + "TRAIT_QUICK_BUILD" = TRAIT_QUICK_BUILD, "TRAIT_QUICK_CARRY" = TRAIT_QUICK_CARRY, "TRAIT_QUICKER_CARRY" = TRAIT_QUICKER_CARRY, "TRAIT_RADIMMUNE" = TRAIT_RADIMMUNE, + "TRAIT_REMOTE_TASTING" = TRAIT_REMOTE_TASTING, "TRAIT_RESISTCOLD" = TRAIT_RESISTCOLD, "TRAIT_RESISTHEAT" = TRAIT_RESISTHEAT, "TRAIT_RESISTHEATHANDS" = TRAIT_RESISTHEATHANDS, "TRAIT_RESISTHIGHPRESSURE" = TRAIT_RESISTHIGHPRESSURE, "TRAIT_RESISTLOWPRESSURE" = TRAIT_RESISTLOWPRESSURE, "TRAIT_RESTRAINED" = TRAIT_RESTRAINED, + "TRAIT_REVEAL_FISH" = TRAIT_REVEAL_FISH, + "TRAIT_ROCK_STONER" = TRAIT_ROCK_STONER, + "TRAIT_ROD_SUPLEX" = TRAIT_ROD_SUPLEX, "TRAIT_ROUGHRIDER" = TRAIT_ROUGHRIDER, + "TRAIT_SABRAGE_PRO" = TRAIT_SABRAGE_PRO, "TRAIT_SECURITY_HUD" = TRAIT_SECURITY_HUD, "TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE, "TRAIT_SETTLER" = TRAIT_SETTLER, @@ -208,23 +262,28 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_SLOW_FLIP" = TRAIT_SLOW_FLIP, "TRAIT_SMOKER" = TRAIT_SMOKER, "TRAIT_SNOB" = TRAIT_SNOB, + "TRAIT_SOFTSPOKEN" = TRAIT_SOFTSPOKEN, "TRAIT_SOOTHED_THROAT" = TRAIT_SOOTHED_THROAT, "TRAIT_SPACEWALK" = TRAIT_SPACEWALK, "TRAIT_SPECIAL_TRAUMA_BOOST" = TRAIT_SPECIAL_TRAUMA_BOOST, "TRAIT_SPIRITUAL" = TRAIT_SPIRITUAL, "TRAIT_STABLEHEART" = TRAIT_STABLEHEART, "TRAIT_STABLELIVER" = TRAIT_STABLELIVER, + "TRAIT_STRENGTH" = TRAIT_STRENGTH, "TRAIT_STRONG_GRABBER" = TRAIT_STRONG_GRABBER, "TRAIT_STRONG_STOMACH" = TRAIT_STRONG_STOMACH, "TRAIT_STUBBY_BODY" = TRAIT_STUBBY_BODY, "TRAIT_STUNIMMUNE" = TRAIT_STUNIMMUNE, "TRAIT_STURDY_FRAME" = TRAIT_STURDY_FRAME, + "TRAIT_SUPERMATTER_SOOTHER" = TRAIT_SUPERMATTER_SOOTHER, "TRAIT_SURGEON" = TRAIT_SURGEON, "TRAIT_SURGICALLY_ANALYZED" = TRAIT_SURGICALLY_ANALYZED, "TRAIT_TAGGER" = TRAIT_TAGGER, "TRAIT_TENTACLE_IMMUNE" = TRAIT_TENTACLE_IMMUNE, "TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE, "TRAIT_THERMAL_VISION" = TRAIT_THERMAL_VISION, + "TRAIT_THROWINGARM" = TRAIT_THROWINGARM, + "TRAIT_TIME_STOP_IMMUNE" = TRAIT_TIME_STOP_IMMUNE, "TRAIT_TOXIMMUNE" = TRAIT_TOXIMMUNE, "TRAIT_TOXINLOVER" = TRAIT_TOXINLOVER, "TRAIT_TRAIT_MEDIBOTCOMINGTHROUGH" = TRAIT_MEDIBOTCOMINGTHROUGH, @@ -240,7 +299,10 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_UNSTABLE" = TRAIT_UNSTABLE, "TRAIT_USED_DNA_VAULT" = TRAIT_USED_DNA_VAULT, "TRAIT_USES_SKINTONES" = TRAIT_USES_SKINTONES, + "TRAIT_VENTCRAWLER_ALWAYS" = TRAIT_VENTCRAWLER_ALWAYS, + "TRAIT_VENTCRAWLER_NUDE" = TRAIT_VENTCRAWLER_NUDE, "TRAIT_VIRUSIMMUNE" = TRAIT_VIRUSIMMUNE, + "TRAIT_VIRUS_RESISTANCE" = TRAIT_VIRUS_RESISTANCE, "TRAIT_VORACIOUS" = TRAIT_VORACIOUS, "TRAIT_WOUND_LICKER" = TRAIT_WOUND_LICKER, "TRAIT_WEAK_SOUL" = TRAIT_WEAK_SOUL, diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 713f03bc75a..6ee994cf79c 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -319,14 +319,14 @@ GLOBAL_LIST_EMPTY(radial_menus) current_page = WRAP(current_page + 1,1,pages+1) update_screen_objects() -/datum/radial_menu/proc/show_to(mob/M) +/datum/radial_menu/proc/show_to(mob/M, offset_x = 0, offset_y = 0) if(current_user) hide() if(!M.client || !anchor) return current_user = M.client //Blank - menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing", layer = RADIAL_BACKGROUND_LAYER) + menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing", layer = RADIAL_BACKGROUND_LAYER, pixel_x = offset_x, pixel_y = offset_y) SET_PLANE_EXPLICIT(menu_holder, ABOVE_HUD_PLANE, M) menu_holder.appearance_flags |= KEEP_APART|RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM menu_holder.vis_contents += elements + close_button @@ -358,7 +358,7 @@ GLOBAL_LIST_EMPTY(radial_menus) Choices should be a list where list keys are movables or text used for element names and return value and list values are movables/icons/images used for element icons */ -/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE, no_repeat_close = FALSE, radial_slice_icon = "radial_slice", autopick_single_option = TRUE, entry_animation = TRUE, click_on_hover = FALSE) +/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE, no_repeat_close = FALSE, radial_slice_icon = "radial_slice", autopick_single_option = TRUE, entry_animation = TRUE, click_on_hover = FALSE, user_space = FALSE) if(!user || !anchor || !length(choices)) return @@ -381,11 +381,18 @@ GLOBAL_LIST_EMPTY(radial_menus) menu.radius = radius if(istype(custom_check)) menu.custom_check_callback = custom_check - menu.anchor = anchor + menu.anchor = user_space ? user : anchor menu.radial_slice_icon = radial_slice_icon menu.check_screen_border(user) //Do what's needed to make it look good near borders or on hud menu.set_choices(choices, tooltips, click_on_hover) - menu.show_to(user) + var/offset_x = 0 + var/offset_y = 0 + if (user_space) + var/turf/user_turf = get_turf(user) + var/turf/anchor_turf = get_turf(anchor) + offset_x = (anchor_turf.x - user_turf.x) * world.icon_size + anchor.pixel_x - user.pixel_x + offset_y = (anchor_turf.y - user_turf.y) * world.icon_size + anchor.pixel_y - user.pixel_y + menu.show_to(user, offset_x, offset_y) menu.wait(user, anchor, require_near) var/answer = menu.selected_choice qdel(menu) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 40b56abdc1b..c45d740f498 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -482,8 +482,26 @@ return TRUE +/atom/movable/screen/storage/cell + +/atom/movable/screen/storage/cell/mouse_drop_receive(atom/target, mob/living/user, params) + var/datum/storage/storage = master_ref?.resolve() + + if (isnull(storage) || !istype(user) || storage != user.active_storage) + return + + if (!user.can_perform_action(storage.parent, FORBID_TELEKINESIS_REACH)) + return + + if (target.loc != storage.real_location) + return + + /// Due to items in storage ignoring transparency for click hitboxes, this only can happen if we drag onto a free cell - aka after all current contents + storage.real_location.contents -= target + storage.real_location.contents += target + storage.refresh_views() + /atom/movable/screen/storage/corner - name = "storage" icon_state = "storage_corner_topleft" /atom/movable/screen/storage/corner/top_right diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index b4253951536..77bd066f547 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -37,6 +37,7 @@ GLOBAL_LIST_INIT_TYPED(quirk_blacklist, /list/datum/quirk, list( list(/datum/quirk/light_drinker, /datum/quirk/drunkhealing), list(/datum/quirk/oversized, /datum/quirk/freerunning), list(/datum/quirk/oversized, /datum/quirk/item_quirk/settler), + list(/datum/quirk/echolocation, /datum/quirk/item_quirk/blindness, /datum/quirk/item_quirk/nearsighted, /datum/quirk/item_quirk/deafness), //SKYRAT EDIT ADDITION END )) diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm index 4cf04039e85..7673551a653 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm @@ -152,3 +152,15 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/ /// Returns the desired final target from the filtered list of targets /datum/ai_behavior/find_potential_targets/proc/pick_final_target(datum/ai_controller/controller, list/filtered_targets) return pick(filtered_targets) + +/// Targets with the trait specified by the BB_TARGET_PRIORITY_TRAIT blackboard key will be prioritized over the rest. +/datum/ai_behavior/find_potential_targets/prioritize_trait + +/datum/ai_behavior/find_potential_targets/prioritize_trait/pick_final_target(datum/ai_controller/controller, list/filtered_targets) + var/priority_targets = list() + for(var/atom/target as anything in filtered_targets) + if(HAS_TRAIT(target, controller.blackboard[BB_TARGET_PRIORITY_TRAIT])) + priority_targets += target + if(length(priority_targets)) + return pick(priority_targets) + return ..() diff --git a/code/datums/ai/basic_mobs/basic_subtrees/find_targets_prioritize_traits.dm b/code/datums/ai/basic_mobs/basic_subtrees/find_targets_prioritize_traits.dm new file mode 100644 index 00000000000..6c83469960a --- /dev/null +++ b/code/datums/ai/basic_mobs/basic_subtrees/find_targets_prioritize_traits.dm @@ -0,0 +1,6 @@ +/// Find something with a specific trait to run from +/datum/ai_planning_subtree/find_target_prioritize_traits + +/datum/ai_planning_subtree/find_target_prioritize_traits/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + . = ..() + controller.queue_behavior(/datum/ai_behavior/find_potential_targets/prioritize_trait, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION, BB_TARGET_PRIORITY_TRAIT) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm index 4a2f5b476c7..3d593286484 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm @@ -12,6 +12,8 @@ var/atom/flee_from = controller.blackboard[target_key] if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING] || QDELETED(flee_from)) return + if(!should_flee(controller, flee_from)) + return var/flee_distance = controller.blackboard[BB_BASIC_MOB_FLEE_DISTANCE] || DEFAULT_BASIC_FLEE_DISTANCE if (get_dist(controller.pawn, flee_from) >= flee_distance) return @@ -19,8 +21,21 @@ controller.queue_behavior(flee_behaviour, target_key, hiding_place_key) return SUBTREE_RETURN_FINISH_PLANNING //we gotta get out of here. +/datum/ai_planning_subtree/flee_target/proc/should_flee(datum/ai_controller/controller, atom/flee_from) + if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING] || QDELETED(flee_from)) + return FALSE + return TRUE + /// Try to escape from your current target, without performing any other actions. /// Reads from some fleeing-specific targeting keys rather than the current mob target. /datum/ai_planning_subtree/flee_target/from_flee_key target_key = BB_BASIC_MOB_FLEE_TARGET hiding_place_key = BB_BASIC_MOB_FLEE_TARGET_HIDING_LOCATION + +/// A subtype that forces the mob to flee from targets with the scary fisherman trait anyway. +/datum/ai_planning_subtree/flee_target/from_fisherman + +/datum/ai_planning_subtree/flee_target/from_fisherman/should_flee(datum/ai_controller/controller, atom/flee_from) + if (!QDELETED(flee_from) && HAS_TRAIT(flee_from, TRAIT_SCARY_FISHERMAN)) + return TRUE + return ..() diff --git a/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm index 5b1f5ffbff9..f764568d4ba 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm @@ -22,3 +22,12 @@ return controller.queue_behavior(ranged_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions. + +/datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman + +/datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/atom/movable/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + if(QDELETED(target)) + return ..() + if(!HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN)) + return ..() diff --git a/code/datums/ai/basic_mobs/basic_subtrees/simple_find_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/simple_find_target.dm index 1c7d8de9120..42608730f98 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/simple_find_target.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/simple_find_target.dm @@ -12,4 +12,3 @@ if(watcher.stat != DEAD) return return ..() - diff --git a/code/datums/components/callouts.dm b/code/datums/components/callouts.dm index 24e7f081fbe..98d489cc915 100644 --- a/code/datums/components/callouts.dm +++ b/code/datums/components/callouts.dm @@ -111,7 +111,7 @@ for(var/datum/callout_option/callout_option as anything in callout_options) callout_items[callout_option] = image(icon = 'icons/hud/radial.dmi', icon_state = callout_option::icon_state) - var/datum/callout_option/selection = show_radial_menu(user, get_turf(clicked_atom), callout_items, entry_animation = FALSE, click_on_hover = TRUE) + var/datum/callout_option/selection = show_radial_menu(user, get_turf(clicked_atom), callout_items, entry_animation = FALSE, click_on_hover = TRUE, user_space = TRUE) if (!selection) return diff --git a/code/datums/components/crafting/entertainment.dm b/code/datums/components/crafting/entertainment.dm index 84b2ef163bb..f1aa865e0cb 100644 --- a/code/datums/components/crafting/entertainment.dm +++ b/code/datums/components/crafting/entertainment.dm @@ -250,11 +250,17 @@ ) category = CAT_EQUIPMENT -/datum/crafting_recipe/bonedice - name = "Bone Die" - result = /obj/item/dice/d6/bone - time = 5 SECONDS +/datum/crafting_recipe/violin + name = "Violin" + result = /obj/item/instrument/violin reqs = list( - /obj/item/stack/sheet/bone = 1, + /obj/item/stack/sheet/mineral/wood = 4, + /obj/item/stack/sheet/cloth = 2, + /obj/item/stack/sheet/iron = 1, ) - category = CAT_EQUIPMENT + tool_paths = list( + /obj/item/hatchet, + ) + time = 30 SECONDS + category = CAT_ENTERTAINMENT + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED diff --git a/code/datums/components/crafting/equipment.dm b/code/datums/components/crafting/equipment.dm index bd2b8b1d8b6..9bc0559c28a 100644 --- a/code/datums/components/crafting/equipment.dm +++ b/code/datums/components/crafting/equipment.dm @@ -23,6 +23,17 @@ time = 4 SECONDS category = CAT_EQUIPMENT +/datum/crafting_recipe/improvisedshield + name = "Moonflower Shield" + result = /obj/item/shield/buckler/moonflower + reqs = list( + /obj/item/seeds/sunflower/moonflower = 3, + /obj/item/grown/log/steel = 3, + ) + time = 4 SECONDS + category = CAT_EQUIPMENT + + /datum/crafting_recipe/radiogloves name = "Radio Gloves" result = /obj/item/clothing/gloves/radio @@ -260,3 +271,18 @@ ) category = CAT_EQUIPMENT tool_behaviors = list(TOOL_WELDER, TOOL_WIRECUTTER) + +// SKYRAT EDIT REMOVAL START +/* +/datum/crafting_recipe/arrow_quiver + name = "Archery Quiver" + result = /obj/item/storage/bag/quiver/lesser + time = 10 + reqs = list( + /obj/item/stack/sheet/leather = 4, + /obj/item/stack/sheet/cardboard = 4 + ) + category = CAT_EQUIPMENT + tool_behaviors = list(TOOL_WELDER, TOOL_WIRECUTTER) + +*/ // SKYRAT EDIT REMOVAL END diff --git a/code/datums/components/crafting/melee_weapon.dm b/code/datums/components/crafting/melee_weapon.dm index 594ff7aefd3..018d99d8703 100644 --- a/code/datums/components/crafting/melee_weapon.dm +++ b/code/datums/components/crafting/melee_weapon.dm @@ -191,3 +191,13 @@ ) time = 10 SECONDS category = CAT_WEAPON_MELEE + +/datum/crafting_recipe/bambostaff + name = "Bamboo Bo Staff" + result = /obj/item/bambostaff + reqs = list( + /obj/item/stack/sheet/mineral/bamboo = 4, + /obj/item/grown/log/steel = 2, + ) + time = 8 SECONDS + category = CAT_WEAPON_MELEE diff --git a/code/datums/components/crafting/ranged_weapon.dm b/code/datums/components/crafting/ranged_weapon.dm index 4b6ab64a22c..0e3c7b11916 100644 --- a/code/datums/components/crafting/ranged_weapon.dm +++ b/code/datums/components/crafting/ranged_weapon.dm @@ -375,6 +375,21 @@ category = CAT_WEAPON_RANGED crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED +/datum/crafting_recipe/shortbow + name = "Shortbow" + result = /obj/item/gun/ballistic/bow/shortbow + reqs = list( + /obj/item/stack/sheet/mineral/wood = 4, + /obj/item/stack/sheet/cloth = 2, + /obj/item/stack/sheet/iron = 1, + ) + tool_paths = list( + /obj/item/hatchet, + ) + time = 30 SECONDS + category = CAT_WEAPON_RANGED + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED + /datum/crafting_recipe/photoncannon name = "Photon Cannon" result = /obj/item/gun/energy/photon diff --git a/code/datums/components/crafting/tailoring.dm b/code/datums/components/crafting/tailoring.dm index 2bcec49aeb5..3c498f74416 100644 --- a/code/datums/components/crafting/tailoring.dm +++ b/code/datums/components/crafting/tailoring.dm @@ -6,6 +6,61 @@ time = 5 SECONDS category = CAT_CLOTHING +/datum/crafting_recipe/durathread_robe + name = "Durathread Robe" + result = /obj/item/clothing/suit/wizrobe/durathread + reqs = list( + /obj/item/stack/sheet/durathread = 3, + /obj/item/stack/sheet/leather = 6, + ) + time = 5 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_robe_fire + name = "Durathread Pyromancer Robe" + result = /obj/item/clothing/suit/wizrobe/durathread/fire + reqs = list(/obj/item/clothing/suit/wizrobe/durathread = 1, + /obj/item/grown/novaflower = 1, + /obj/item/seeds/chili = 3) + time = 2 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_robe_ice + name = "Durathread Ice-o-mancer Robe" + result = /obj/item/clothing/suit/wizrobe/durathread/ice + reqs = list(/obj/item/clothing/suit/wizrobe/durathread = 1, + /obj/item/seeds/chili/ice = 1, + /obj/item/food/grown/herbs = 3) + time = 2 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_robe_electric + name = "Durathread Electromancer Robe" + result = /obj/item/clothing/suit/wizrobe/durathread/electric + reqs = list(/obj/item/clothing/suit/wizrobe/durathread = 1, + /obj/item/food/grown/mushroom/jupitercup = 1, + /obj/item/food/grown/sunflower = 3) + time = 2 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_robe_earth + name = "Durathread Geomancer Robe" + result = /obj/item/clothing/suit/wizrobe/durathread/earth + reqs = list(/obj/item/clothing/suit/wizrobe/durathread = 1, + /obj/item/food/grown/cahnroot = 1, + /obj/item/food/grown/potato = 3) + time = 2 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/durathread_robe_necro + name = "Durathread Necromancer Robe" + result = /obj/item/clothing/suit/wizrobe/durathread/necro + reqs = list(/obj/item/clothing/suit/wizrobe/durathread = 1, + /obj/item/food/grown/cannabis/death = 2, + /obj/item/food/grown/mushroom/angel = 2) + time = 2 SECONDS + category = CAT_CLOTHING + /datum/crafting_recipe/durathread_helmet name = "Durathread Helmet" result = /obj/item/clothing/head/helmet/durathread @@ -14,6 +69,62 @@ time = 4 SECONDS category = CAT_CLOTHING +/datum/crafting_recipe/watermelon_armour + name = "Watermelon Armour" + result = /obj/item/clothing/suit/armor/durability/watermelon + reqs = list(/obj/item/clothing/head/helmet/durability/watermelon = 3, + /obj/item/stack/sheet/durathread = 1) + time = 4 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/watermelon_armour_fr + name = "Watermelon Armour" + result = /obj/item/clothing/suit/armor/durability/watermelon/fire_resist + reqs = list(/obj/item/clothing/head/helmet/durability/watermelon/fire_resist = 3, + /obj/item/stack/sheet/durathread = 1) + time = 4 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/holymelon_armour + name = "Holymelon Armour" + result = /obj/item/clothing/suit/armor/durability/holymelon + reqs = list(/obj/item/clothing/head/helmet/durability/holymelon = 3, + /obj/item/stack/sheet/durathread = 1) + time = 4 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/holymelonmelon_armour_fr + name = "Holymelon Armour" + result = /obj/item/clothing/suit/armor/durability/holymelon/fire_resist + reqs = list(/obj/item/clothing/head/helmet/durability/holymelon/fire_resist = 3, + /obj/item/stack/sheet/durathread = 1) + time = 4 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/barrelmelon_armour + name = "Barrelmelon Armour" + result = /obj/item/clothing/suit/armor/durability/barrelmelon + reqs = list(/obj/item/clothing/head/helmet/durability/barrelmelon = 3, + /obj/item/stack/sheet/durathread = 1) + time = 4 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/barrelmelon_armour_fr + name = "Barrelmelon Armour" + result = /obj/item/clothing/suit/armor/durability/barrelmelon/fire_resist + reqs = list(/obj/item/clothing/head/helmet/durability/barrelmelon/fire_resist = 3, + /obj/item/stack/sheet/durathread = 1) + time = 4 SECONDS + category = CAT_CLOTHING + +/datum/crafting_recipe/grass_sheath + name = "Grass Sabre Sheath" + result = /obj/item/storage/belt/grass_sabre + reqs = list(/obj/item/food/grown/grass = 4, + /obj/item/food/grown/grass/fairy = 2) + time = 4 SECONDS + category = CAT_CONTAINERS + /datum/crafting_recipe/fannypack name = "Fannypack" result = /obj/item/storage/belt/fannypack diff --git a/code/datums/components/crafting/weapon_ammo.dm b/code/datums/components/crafting/weapon_ammo.dm index f68ff58072c..9a3448bc803 100644 --- a/code/datums/components/crafting/weapon_ammo.dm +++ b/code/datums/components/crafting/weapon_ammo.dm @@ -111,3 +111,68 @@ ) category = CAT_WEAPON_AMMO crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/arrow + name = "Arrow" + result = /obj/item/ammo_casing/arrow + reqs = list( + /obj/item/stack/sheet/mineral/wood = 1, + /obj/item/stack/sheet/cloth = 1, + /obj/item/stack/sheet/iron = 1, + ) + tool_paths = list( + /obj/item/hatchet, + ) + time = 5 SECONDS + category = CAT_WEAPON_AMMO + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/sticky_arrow + name = "Sticky arrow" + result = /obj/item/ammo_casing/arrow/sticky + reqs = list( + /obj/item/ammo_casing/arrow = 1, + /obj/item/food/honeycomb = 3, + ) + time = 5 SECONDS + category = CAT_WEAPON_AMMO + crafting_flags = CRAFT_CHECK_DENSITY + +/datum/crafting_recipe/poison_arrow + name = "Poison arrow" + result = /obj/item/ammo_casing/arrow/poison + reqs = list( + /obj/item/ammo_casing/arrow = 1, + /obj/item/food/grown/berries/poison = 5, + ) + time = 5 SECONDS + category = CAT_WEAPON_AMMO + crafting_flags = CRAFT_CHECK_DENSITY + +/datum/crafting_recipe/plastic_arrow + name = "Plastic Arrow" + result = /obj/item/ammo_casing/arrow/plastic + reqs = list( + /obj/item/stack/sheet/plastic = 1, + ) + tool_paths = list( + /obj/item/hatchet, + ) + time = 5 SECONDS + category = CAT_WEAPON_AMMO + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED + + +/datum/crafting_recipe/holy_arrow + name = "Holy Arrow" + result = /obj/item/ammo_casing/arrow/holy + reqs = list( + /obj/item/ammo_casing/arrow = 1, + /datum/reagent/water/holywater = 10, + ) + tool_paths = list( + /obj/item/gun/ballistic/bow/divine, + ) + time = 5 SECONDS + category = CAT_WEAPON_AMMO + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED diff --git a/code/datums/components/echolocation.dm b/code/datums/components/echolocation.dm index 020c47ad875..f5181a98147 100644 --- a/code/datums/components/echolocation.dm +++ b/code/datums/components/echolocation.dm @@ -32,7 +32,7 @@ /// Cooldown for the echolocation. COOLDOWN_DECLARE(cooldown_last) -/datum/component/echolocation/Initialize(echo_range, cooldown_time, image_expiry_time, fade_in_time, fade_out_time, images_are_static, blocking_trait, echo_group, echo_icon = "echo", color_path) +/datum/component/echolocation/Initialize(echo_range, cooldown_time, image_expiry_time, fade_in_time, fade_out_time, images_are_static, blocking_trait, echo_group, echo_icon, color_path, use_echo = TRUE, show_own_outline = FALSE, personal_color = "#ffffff") // SKYRAT EDIT CHANGE - ORIGINAL: /datum/component/echolocation/Initialize(echo_range, cooldown_time, image_expiry_time, fade_in_time, fade_out_time, images_are_static, blocking_trait, echo_group, echo_icon = "echo", color_path) . = ..() var/mob/living/echolocator = parent if(!istype(echolocator)) @@ -55,12 +55,19 @@ src.images_are_static = images_are_static if(!isnull(blocking_trait)) src.blocking_trait = blocking_trait + // SKYRAT ADDITION START: echolocation + src.show_own_outline = show_own_outline + src.echo_color = personal_color + // SKYRAT EDIT ADDITION END if(ispath(color_path)) client_color = echolocator.add_client_colour(color_path) src.echo_group = echo_group || REF(src) echolocator.add_traits(list(TRAIT_ECHOLOCATION_RECEIVER, TRAIT_TRUE_NIGHT_VISION), echo_group) //so they see all the tiles they echolocated, even if they are in the dark echolocator.become_blind(ECHOLOCATION_TRAIT) - echolocator.overlay_fullscreen("echo", /atom/movable/screen/fullscreen/echo, echo_icon) + // SKYRAT EDIT ADDITION START + if (use_echo) // add constructor toggle to not use the eye overlay + echolocator.overlay_fullscreen("echo", /atom/movable/screen/fullscreen/echo, echo_icon) + // SKYRAT EDIT ADDITION END START_PROCESSING(SSfastprocess, src) /datum/component/echolocation/Destroy(force) @@ -85,7 +92,7 @@ echolocate() /datum/component/echolocation/proc/echolocate() - if(!COOLDOWN_FINISHED(src, cooldown_last)) + if(stall || !COOLDOWN_FINISHED(src, cooldown_last)) // SKYRAT EDIT CHANGE - ORIGINAL: if(!COOLDOWN_FINISHED(src, cooldown_last)) return COOLDOWN_START(src, cooldown_last, cooldown_time) var/mob/living/echolocator = parent @@ -121,11 +128,18 @@ if(images_are_static) final_image.pixel_x = input.pixel_x final_image.pixel_y = input.pixel_y - if(HAS_TRAIT_FROM(input, TRAIT_ECHOLOCATION_RECEIVER, echo_group)) //mark other echolocation with full white - final_image.color = white_matrix + // SKYRAT ADDITION START: echolocation (show outlines on self) + if(HAS_TRAIT_FROM(input, TRAIT_ECHOLOCATION_RECEIVER, echo_group)) //mark other echolocation with full white, except ourselves + var/datum/component/echolocation/located_component = input.GetComponent(/datum/component/echolocation) + var/mob/living/echolocator = parent + if(located_component) + final_image.color = located_component.echo_color + else if(input != echolocator) + final_image.color = white_matrix + // SKYRAT EDIT ADDITION END var/list/fade_ins = list(final_image) for(var/mob/living/echolocate_receiver as anything in receivers) - if(echolocate_receiver == input) + if(echolocate_receiver == input && !show_own_outline) // SKYRAT EDIT CHANGE - ORIGINAL: if(echolocate_receiver == input) continue if(receivers[echolocate_receiver][input]) var/previous_image = receivers[echolocate_receiver][input]["image"] diff --git a/code/datums/components/heart_eater.dm b/code/datums/components/heart_eater.dm index 5b73c40c954..507090b9452 100644 --- a/code/datums/components/heart_eater.dm +++ b/code/datums/components/heart_eater.dm @@ -68,6 +68,9 @@ var/obj/item/organ/internal/heart/previous_heart = last_heart_we_ate?.resolve() if(we_ate_heart == previous_heart) return + if (!HAS_TRAIT(we_ate_heart, TRAIT_USED_ORGAN)) + to_chat(eater, span_warning("This heart is utterly lifeless, you won't receive any boons from consuming it!")) + return bites_taken = 0 last_heart_we_ate = WEAKREF(we_ate_heart) diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index a5ff46964bf..d831ba2f0d9 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -227,9 +227,12 @@ for(var/datum/uplink_item/item as anything in uplink_handler.extra_purchasable) if(item.stock_key in stock_list) extra_purchasable_stock[REF(item)] = stock_list[item.stock_key] + var/atom/actual_item = item.item extra_purchasable += list(list( "id" = item.type, "name" = item.name, + "icon" = actual_item.icon, + "icon_state" = actual_item.icon_state, "cost" = item.cost, "desc" = item.desc, "category" = item.category ? initial(item.category.name) : null, @@ -288,6 +291,11 @@ return item = SStraitor.uplink_items_by_type[item_path] uplink_handler.purchase_item(ui.user, item, parent) + if("buy_raw_tc") + if (uplink_handler.telecrystals <= 0) + return + var/desired_amount = tgui_input_number(ui.user, "How many raw telecrystals to buy?", "Buy Raw TC", default = uplink_handler.telecrystals, max_value = uplink_handler.telecrystals) + uplink_handler.purchase_raw_tc(ui.user, desired_amount, parent) if("lock") if(!lockable) return TRUE diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm index c2154736cc0..7aa7f120e75 100644 --- a/code/datums/dog_fashion.dm +++ b/code/datums/dog_fashion.dm @@ -243,3 +243,18 @@ obj_icon_state = "eyepatch" emote_hear = list("sighs gruffly.", "groans.") emote_see = list("considers their own mortality.", "stares bleakly into the middle distance.", "ponders the horrors of warfare.") + +/datum/dog_fashion/head/watermelon + name = "Watermelon Warrior %REAL_NAME%" + desc = "5% safer than normal and ready to take on advantage!" + obj_icon_state = "watermelon" + +/datum/dog_fashion/head/holymelon + name = "Holymelon Paladin %REAL_NAME%" + desc = "Extraterrestial powers beware, %NAME% is here to smite you down!" + obj_icon_state = "holymelon" + +/datum/dog_fashion/head/barrelmelon + name = "Barrelmelon Berserk %REAL_NAME%" + desc = "Either the sturdiness of the helmet gave %REAL_NAME% a confidence boost, or its bit tight on their head..." + obj_icon_state = "barrelmelon" diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm index 5a00fd40d39..b10574c56e8 100644 --- a/code/datums/emotes.dm +++ b/code/datums/emotes.dm @@ -103,13 +103,12 @@ if(tmp_sound && should_play_sound(user, intentional) && TIMER_COOLDOWN_FINISHED(user, type)) TIMER_COOLDOWN_START(user, type, audio_cooldown) //SKYRAT EDIT CHANGE BEGIN - //playsound(user, tmp_sound, 50, vary) - SKYRAT EDIT - ORIGINAL + //playsound(source = user,soundin = tmp_sound,vol = 50, vary = vary, ignore_walls = sound_wall_ignore) - SKYRAT EDIT - ORIGINAL if(istype(src, /datum/emote/living/lewd)) play_lewd_sound(user, tmp_sound, sound_volume, vary, pref_to_check = /datum/preference/toggle/erp/sounds) else - playsound(user, tmp_sound, sound_volume, vary) + playsound(source = user, soundin = tmp_sound, vol = sound_volume, vary = vary, ignore_walls = sound_wall_ignore) //SKYRAT EDIT CHANGE END - playsound(source = user,soundin = tmp_sound,vol = 50, vary = vary, ignore_walls = sound_wall_ignore) var/is_important = emote_type & EMOTE_IMPORTANT var/is_visual = emote_type & EMOTE_VISIBLE diff --git a/code/datums/greyscale/json_configs/meter.json b/code/datums/greyscale/json_configs/meter.json index 73cfb739959..344500c2a9d 100644 --- a/code/datums/greyscale/json_configs/meter.json +++ b/code/datums/greyscale/json_configs/meter.json @@ -2,26 +2,26 @@ "meter": [ { "type": "icon_state", - "icon_state": "pressure_off", + "icon_state": "meter_base", "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", + "icon_state": "pressure_off", "blend_mode": "overlay" } ], "meter0": [ { "type": "icon_state", - "icon_state": "pressure0", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure0", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -32,14 +32,14 @@ "meter1_1": [ { "type": "icon_state", - "icon_state": "pressure1_1", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure1_1", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -50,14 +50,14 @@ "meter1_2": [ { "type": "icon_state", - "icon_state": "pressure1_2", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure1_2", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -68,14 +68,14 @@ "meter1_3": [ { "type": "icon_state", - "icon_state": "pressure1_3", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure1_3", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -86,14 +86,14 @@ "meter1_4": [ { "type": "icon_state", - "icon_state": "pressure1_4", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure1_4", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -104,14 +104,14 @@ "meter1_5": [ { "type": "icon_state", - "icon_state": "pressure1_5", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure1_5", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -122,14 +122,14 @@ "meter1_6": [ { "type": "icon_state", - "icon_state": "pressure1_6", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure1_6", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -140,14 +140,14 @@ "meter2_1": [ { "type": "icon_state", - "icon_state": "pressure2_1", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure2_1", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -158,14 +158,14 @@ "meter2_2": [ { "type": "icon_state", - "icon_state": "pressure2_2", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure2_2", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -176,14 +176,14 @@ "meter2_3": [ { "type": "icon_state", - "icon_state": "pressure2_3", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure2_3", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -194,14 +194,14 @@ "meter2_4": [ { "type": "icon_state", - "icon_state": "pressure2_4", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure2_4", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -212,14 +212,14 @@ "meter2_5": [ { "type": "icon_state", - "icon_state": "pressure2_5", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure2_5", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -230,14 +230,14 @@ "meter2_6": [ { "type": "icon_state", - "icon_state": "pressure2_6", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure2_6", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -248,14 +248,14 @@ "meter3_1": [ { "type": "icon_state", - "icon_state": "pressure3_1", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure3_1", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -266,14 +266,14 @@ "meter3_2": [ { "type": "icon_state", - "icon_state": "pressure3_2", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure3_2", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -284,14 +284,14 @@ "meter3_3": [ { "type": "icon_state", - "icon_state": "pressure3_3", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure3_3", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -302,14 +302,14 @@ "meter3_4": [ { "type": "icon_state", - "icon_state": "pressure3_4", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure3_4", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -320,14 +320,14 @@ "meter3_5": [ { "type": "icon_state", - "icon_state": "pressure3_5", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure3_5", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -338,14 +338,14 @@ "meter3_6": [ { "type": "icon_state", - "icon_state": "pressure3_6", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure3_6", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", @@ -356,14 +356,14 @@ "meter4": [ { "type": "icon_state", - "icon_state": "pressure4", - "blend_mode": "overlay", - "color_ids": [ 1 ] + "icon_state": "meter_base", + "blend_mode": "overlay" }, { "type": "icon_state", - "icon_state": "meter_base", - "blend_mode": "overlay" + "icon_state": "pressure4", + "blend_mode": "overlay", + "color_ids": [ 1 ] }, { "type": "icon_state", diff --git a/code/datums/pod_style.dm b/code/datums/pod_style.dm index 681e66ad082..853d7e05878 100644 --- a/code/datums/pod_style.dm +++ b/code/datums/pod_style.dm @@ -56,7 +56,7 @@ glow_color = "blue" id = "deathsquad" -/datum/pod_style/advanced +/datum/pod_style/cultist name = "bloody supply pod" ui_name = "Cultist" desc = "A Nanotrasen supply pod covered in scratch-marks, blood, and strange runes." diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index a01bb21a451..7cdb9d40615 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -449,11 +449,38 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) SEND_SIGNAL(parent, COMSIG_ATOM_STORED_ITEM, to_insert, user, force) SEND_SIGNAL(src, COMSIG_STORAGE_STORED_ITEM, to_insert, user, force) + RegisterSignal(to_insert, COMSIG_MOUSEDROPPED_ONTO, PROC_REF(mousedrop_receive)) to_insert.forceMove(real_location) item_insertion_feedback(user, to_insert, override) parent.update_appearance() return TRUE +/// Since items inside storages ignore transparency for QOL reasons, we're tracking when things are dropped onto them instead of our UI elements +/datum/storage/proc/mousedrop_receive(atom/dropped_onto, atom/movable/target, mob/user, params) + SIGNAL_HANDLER + + if (src != user.active_storage) + return + + if (!user.can_perform_action(parent, FORBID_TELEKINESIS_REACH)) + return + + if (target.loc != real_location) // what even + UnregisterSignal(target, COMSIG_MOUSEDROPPED_ONTO) + return + + if(numerical_stacking) + return + + var/drop_index = real_location.contents.Find(dropped_onto) + real_location.contents -= target + // Use an empty list if we're dropping onto the last item + var/list/to_move = real_location.contents.len >= drop_index ? real_location.contents.Copy(drop_index) : list() + real_location.contents -= to_move + real_location.contents += target + real_location.contents += to_move + refresh_views() + /** * Inserts every item in a given list, with a progress bar * @@ -544,6 +571,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) refresh_views() parent.update_appearance() + UnregisterSignal(thing, COMSIG_MOUSEDROPPED_ONTO) SEND_SIGNAL(parent, COMSIG_ATOM_REMOVED_ITEM, thing, remove_to_loc, silent) SEND_SIGNAL(src, COMSIG_STORAGE_REMOVED_ITEM, thing, remove_to_loc, silent) return TRUE @@ -719,7 +747,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) parent.add_fingerprint(user) return COMPONENT_CANCEL_MOUSEDROP_ONTO - else if(ismob(over_object)) + if(ismob(over_object)) if(over_object != user || !user.can_perform_action(parent, FORBID_TELEKINESIS_REACH | ALLOW_RESTING)) return @@ -727,13 +755,24 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) INVOKE_ASYNC(src, PROC_REF(open_storage), user) return COMPONENT_CANCEL_MOUSEDROP_ONTO - else if(!istype(over_object, /atom/movable/screen)) - if(!user.can_perform_action(over_object, FORBID_TELEKINESIS_REACH)) - return + if(istype(over_object, /atom/movable/screen)) + return - parent.add_fingerprint(user) - INVOKE_ASYNC(src, PROC_REF(dump_content_at), over_object, user) - return COMPONENT_CANCEL_MOUSEDROP_ONTO + if(!user.can_perform_action(over_object, FORBID_TELEKINESIS_REACH)) + return + + parent.add_fingerprint(user) + + var/atom/dump_loc = over_object.get_dumping_location() + if(isnull(dump_loc)) + return + + /// Don't dump *onto* objects in the same storage as ourselves + if (over_object.loc == parent.loc && !isnull(parent.loc.atom_storage) && isnull(over_object.atom_storage)) + return + + INVOKE_ASYNC(src, PROC_REF(dump_content_at), over_object, dump_loc, user) + return COMPONENT_CANCEL_MOUSEDROP_ONTO /** * Dumps all of our contents at a specific location. @@ -741,7 +780,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) * @param atom/dest_object where to dump to * @param mob/user the user who is dumping the contents */ -/datum/storage/proc/dump_content_at(atom/dest_object, mob/user) +/datum/storage/proc/dump_content_at(atom/dest_object, dump_loc, mob/user) if(locked) user.balloon_alert(user, "closed!") return @@ -764,10 +803,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) SEND_SIGNAL(src, COMSIG_STORAGE_DUMP_POST_TRANSFER, dest_object, user) return - var/atom/dump_loc = dest_object.get_dumping_location() - if(isnull(dump_loc)) - return - // Storage to loc transfer requires a do_after to_chat(user, span_notice("You start dumping out the contents of [parent] onto [dest_object]...")) if(!do_after(user, 2 SECONDS, target = dest_object)) diff --git a/code/datums/storage/storage_interface.dm b/code/datums/storage/storage_interface.dm index cd28b9eb3f7..c0cab0dd795 100644 --- a/code/datums/storage/storage_interface.dm +++ b/code/datums/storage/storage_interface.dm @@ -2,7 +2,7 @@ /datum/storage_interface /// UI elements for this theme var/atom/movable/screen/close/closer - var/atom/movable/screen/storage/cells + var/atom/movable/screen/storage/cell/cells var/atom/movable/screen/storage/corner/corner_top_left var/atom/movable/screen/storage/corner/top_right/corner_top_right var/atom/movable/screen/storage/corner/bottom_left/corner_bottom_left diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 40e06362d97..6395323efc7 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -186,6 +186,7 @@ /obj/machinery/LateInitialize() SHOULD_NOT_OVERRIDE(TRUE) post_machine_initialize() + CheckParts() /obj/machinery/Destroy(force) SSmachines.unregister_machine(src) diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 3fa7d25767f..887c04ebede 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -137,6 +137,7 @@ icon = 'icons/obj/wallmounts.dmi' icon_state = "migniter" result_path = /obj/machinery/sparker + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT) pixel_shift = 26 /obj/machinery/sparker diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 11994de5731..731b8f3a085 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -119,6 +119,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light_switch, 26) icon = 'icons/obj/machines/wallmounts.dmi' icon_state = "light-nopower" result_path = /obj/machinery/light_switch + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT) pixel_shift = 26 /obj/item/circuit_component/light_switch diff --git a/code/game/machinery/medipen_refiller.dm b/code/game/machinery/medipen_refiller.dm index 57c3fa2f8d4..bbe331db506 100644 --- a/code/game/machinery/medipen_refiller.dm +++ b/code/game/machinery/medipen_refiller.dm @@ -25,7 +25,6 @@ . = ..() AddComponent(/datum/component/plumbing/simple_demand) register_context() - CheckParts() /obj/machinery/medipen_refiller/add_context(atom/source, list/context, obj/item/held_item, mob/user) if(held_item) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 80289a201be..ef18dc6b068 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -36,9 +36,11 @@ Buildable meters icon_state_preview = "junction" pipe_type = /obj/machinery/atmospherics/pipe/heat_exchanging/junction /obj/item/pipe/directional/vent + name = "air vent fitting" icon_state_preview = "uvent" pipe_type = /obj/machinery/atmospherics/components/unary/vent_pump /obj/item/pipe/directional/scrubber + name = "air scrubber fitting" icon_state_preview = "scrubber" pipe_type = /obj/machinery/atmospherics/components/unary/vent_scrubber /obj/item/pipe/directional/connector @@ -78,6 +80,7 @@ Buildable meters RPD_type = PIPE_TRIN_M var/flipped = FALSE /obj/item/pipe/trinary/flippable/filter + name = "gas filter fitting" icon_state_preview = "filter" pipe_type = /obj/machinery/atmospherics/components/trinary/filter /obj/item/pipe/trinary/flippable/mixer diff --git a/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm b/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm index 6832b07d125..a9d2e0bcaa0 100644 --- a/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm +++ b/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm @@ -449,3 +449,23 @@ /obj/structure/table = list(/obj/structure/table/greyscale = 9, /obj/structure/table/abductor = 1), /obj/structure/toilet = list(/obj/structure/toilet/greyscale = 1), ) + +/datum/dimension_theme/bronze + name = "Bronze" + icon = 'icons/obj/weapons/spear.dmi' + icon_state = "ratvarian_spear" + material = /datum/material/bronze + replace_walls = /turf/closed/wall/mineral/bronze + replace_floors = list(/turf/open/floor/bronze = 1, /turf/open/floor/bronze/flat = 1, /turf/open/floor/bronze/filled = 1) + replace_objs = list( + /obj/structure/girder = list(/obj/structure/girder/bronze = 1), + /obj/structure/window/fulltile = list(/obj/structure/window/bronze/fulltile = 1), + /obj/structure/window = list(/obj/structure/window/bronze = 1), + /obj/structure/statue = list(/obj/structure/statue/bronze/marx = 1), // karl marx was a servant of ratvar + /obj/structure/table = list(/obj/structure/table/bronze = 1), + /obj/structure/toilet = list(/obj/structure/toilet/greyscale = 1), + /obj/structure/chair = list(/obj/structure/chair/bronze = 1), + /obj/item/reagent_containers/cup/glass/trophy = list(/obj/item/reagent_containers/cup/glass/trophy/bronze_cup = 1), + /obj/machinery/door/airlock = list(/obj/machinery/door/airlock/bronze = 1), + ) + sound = 'sound/magic/clockwork/fellowship_armory.ogg' diff --git a/code/game/objects/effects/particles/fire.dm b/code/game/objects/effects/particles/fire.dm index 9d90d0d29c2..99046858073 100644 --- a/code/game/objects/effects/particles/fire.dm +++ b/code/game/objects/effects/particles/fire.dm @@ -33,3 +33,21 @@ drift = generator(GEN_VECTOR, list(-0.1,0), list(0.1,0.025), UNIFORM_RAND) spin = generator(GEN_NUM, list(-15,15), NORMAL_RAND) scale = generator(GEN_VECTOR, list(0.5,0.5), list(2,2), NORMAL_RAND) + +/particles/embers/spark + count = 3 + spawning = 2 + gradient = list("#FBAF4D", "#FCE6B6", "#FFFFFF") + lifespan = 1.5 SECONDS + fade = 1 SECONDS + fadein = 0.1 SECONDS + grow = -0.1 + velocity = generator(GEN_CIRCLE, 3, 3, SQUARE_RAND) + position = generator(GEN_SPHERE, 0, 0, LINEAR_RAND) + scale = generator(GEN_VECTOR, list(0.5, 0.5), list(1,1), NORMAL_RAND) + drift = list(0) + +/particles/embers/spark/severe + count = 10 + spawning = 5 + gradient = list("#FCE6B6", "#FFFFFF") diff --git a/code/game/objects/effects/particles/smoke.dm b/code/game/objects/effects/particles/smoke.dm index 27249c65a68..776c90534a9 100644 --- a/code/game/objects/effects/particles/smoke.dm +++ b/code/game/objects/effects/particles/smoke.dm @@ -84,3 +84,16 @@ grow = 0.05 spin = 2 color = "#fcffff77" + +/particles/smoke/cyborg + count = 5 + spawning = 1 + lifespan = 1 SECONDS + fade = 1.8 SECONDS + position = list(0, 0, 0) + scale = list(0.5, 0.5) + grow = 0.1 + +/particles/smoke/cyborg/heavy_damage + lifespan = 0.8 SECONDS + fade = 0.8 SECONDS diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 9bc86d0c7f9..93c6b6bdc99 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -860,7 +860,7 @@ if(carbon_target.client) carbon_target.set_eye_blur_if_lower(6 SECONDS) carbon_target.adjust_temp_blindness(2 SECONDS) - if(carbon_target.get_eye_protection() <= 0) // no eye protection? ARGH IT BURNS. Warning: don't add a stun here. It's a roundstart item with some quirks. + if(carbon_target.get_eye_protection() <= 0 || carbon_target.is_eyes_covered()) // no eye protection? ARGH IT BURNS. Warning: don't add a stun here. It's a roundstart item with some quirks. added redundancy because gas masks don't give you eye protection carbon_target.adjust_jitter(1 SECONDS) carbon_target.adjust_eye_blur(0.5 SECONDS) flash_color(carbon_target, flash_color=paint_color, flash_time=40) diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 0abf30a6f24..b34540e441c 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -147,7 +147,6 @@ if(!cell || !cell_removable) return FALSE - cell.update_appearance() cell.forceMove(get_turf(src)) balloon_alert(user, "removed [cell]") cell = null diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index f6917ee3c48..96dae8c0fc5 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -963,14 +963,10 @@ var/dark_light_range = 2.5 ///Variable to preserve old lighting behavior in flashlights, to handle darkness. var/dark_light_power = -3 - var/on = FALSE /obj/item/flashlight/flashdark/update_brightness() . = ..() - if(on) - set_light(dark_light_range, dark_light_power) - else - set_light(0) + set_light(dark_light_range, dark_light_power) //type and subtypes spawned and used to give some eyes lights, /obj/item/flashlight/eyelight diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index ed3d8e4605b..3d61f2a1760 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -352,10 +352,10 @@ return - if(iscarbon(talking_movable)) - var/mob/living/carbon/talking_carbon = talking_movable - if(talking_carbon.client?.prefs.read_preference(/datum/preference/toggle/radio_noise)) - SEND_SOUND(talking_carbon, 'sound/misc/radio_talk.ogg') + if(isliving(talking_movable)) + var/mob/living/talking_living = talking_movable + if(talking_living.client?.prefs.read_preference(/datum/preference/toggle/radio_noise)) + SEND_SOUND(talking_living, 'sound/misc/radio_talk.ogg') // All radios make an attempt to use the subspace system first signal.send_to_receivers() @@ -428,15 +428,17 @@ SEND_SIGNAL(src, COMSIG_RADIO_RECEIVE_MESSAGE, data) flick_overlay_view(overlay_speaker_active, 5 SECONDS) - if(iscarbon(loc)) - var/mob/living/carbon/holder = loc - if(!holder.client?.prefs.read_preference(/datum/preference/toggle/radio_noise)) - return + if(!isliving(loc)) + return - var/list/spans = data["spans"] - SEND_SOUND(holder, 'sound/misc/radio_receive.ogg') - if(SPAN_COMMAND in spans) - SEND_SOUND(holder, 'sound/misc/radio_important.ogg') + var/mob/living/holder = loc + if(!holder.client?.prefs.read_preference(/datum/preference/toggle/radio_noise)) + return + + var/list/spans = data["spans"] + SEND_SOUND(holder, 'sound/misc/radio_receive.ogg') + if(SPAN_COMMAND in spans) + SEND_SOUND(holder, 'sound/misc/radio_important.ogg') /obj/item/radio/ui_state(mob/user) return GLOB.inventory_state diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index 01ff7eb5f08..f32b2ee30ec 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -167,12 +167,6 @@ icon_state = "de6" microwave_riggable = FALSE // You can't melt wood in the microwave -/obj/item/dice/d6/bone - name = "bone die" - desc = "A die carved from a creature's bone. Dried blood marks the indented pits." - icon_state = "db6" - microwave_riggable = FALSE // You can't melt bone in the microwave - /obj/item/dice/d6/space name = "space cube" desc = "A die with six sides. 6 TIMES 255 TIMES 255 TILE TOTAL EXISTENCE, SQUARE YOUR MIND OF EDUCATED STUPID: 2 DOES NOT EXIST." diff --git a/code/game/objects/items/food/misc.dm b/code/game/objects/items/food/misc.dm index 8ef85c8ea21..4e8b8cbf220 100644 --- a/code/game/objects/items/food/misc.dm +++ b/code/game/objects/items/food/misc.dm @@ -16,6 +16,87 @@ juice_typepath = /datum/reagent/consumable/watermelonjuice w_class = WEIGHT_CLASS_SMALL +/obj/item/food/watermelonmush + name = "watermelon mush" + desc = "A plop of watery goodness." + icon = 'icons/obj/service/hydroponics/harvest.dmi' + icon_state = "watermelonpulp" + food_reagents = list( + /datum/reagent/water = 2, + /datum/reagent/consumable/nutriment/vitamin = 0.1, + /datum/reagent/consumable/nutriment = 0.5, + ) + tastes = list("watermelon" = 1) + foodtypes = FRUIT + food_flags = FOOD_FINGER_FOOD + juice_typepath = /datum/reagent/consumable/watermelonjuice + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/holymelonslice + name = "holymelon slice" + desc = "A slice of holy goodness." + icon = 'icons/obj/service/hydroponics/harvest.dmi' + icon_state = "holymelonslice" + food_reagents = list( + /datum/reagent/water/holywater = 0.5, + /datum/reagent/consumable/nutriment/vitamin = 0.2, + /datum/reagent/consumable/nutriment = 1, + ) + tastes = list("holymelon" = 1) + foodtypes = FRUIT + food_flags = FOOD_FINGER_FOOD + juice_typepath = /datum/reagent/water/holywater + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/holymelonmush + name = "holymelon mush" + desc = "A plop of holy goodness." + icon = 'icons/obj/service/hydroponics/harvest.dmi' + icon_state = "holymelonpulp" + food_reagents = list( + /datum/reagent/water/holywater = 1, + /datum/reagent/consumable/nutriment/vitamin = 0.1, + /datum/reagent/consumable/nutriment = 0.5, + ) + tastes = list("holymelon" = 1) + foodtypes = FRUIT + food_flags = FOOD_FINGER_FOOD + juice_typepath = /datum/reagent/water/holywater + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/barrelmelonslice + name = "barrelmelon slice" + desc = "A slice of beery goodness." + icon = 'icons/obj/service/hydroponics/harvest.dmi' + icon_state = "barrelmelonslice" + food_reagents = list( + /datum/reagent/consumable/ethanol/beer = 1, + /datum/reagent/consumable/nutriment/vitamin = 0.2, + /datum/reagent/consumable/nutriment = 1, + ) + tastes = list("beer" = 1) + foodtypes = FRUIT + food_flags = FOOD_FINGER_FOOD + juice_typepath = /datum/reagent/consumable/ethanol/beer + w_class = WEIGHT_CLASS_SMALL + +/obj/item/food/barrelmelonmush + name = "barrelmelon mush" + desc = "A plop of beery goodness." + icon = 'icons/obj/service/hydroponics/harvest.dmi' + icon_state = "barrelmelonpulp" + food_reagents = list( + /datum/reagent/consumable/ethanol/beer = 2, + /datum/reagent/consumable/nutriment/vitamin = 0.1, + /datum/reagent/consumable/nutriment = 0.5, + ) + tastes = list("beer" = 1) + foodtypes = FRUIT + food_flags = FOOD_FINGER_FOOD + juice_typepath = /datum/reagent/consumable/ethanol/beer + w_class = WEIGHT_CLASS_SMALL + + /obj/item/food/appleslice name = "apple slice" desc = "The perfect after-school snack." diff --git a/code/game/objects/items/granters/crafting/fletching.dm b/code/game/objects/items/granters/crafting/fletching.dm new file mode 100644 index 00000000000..91ce20c43dd --- /dev/null +++ b/code/game/objects/items/granters/crafting/fletching.dm @@ -0,0 +1,22 @@ + +/obj/item/book/granter/crafting_recipe/fletching + name = "Whittle Me This: Fletching for the Modern Spacer" + desc = "A how-to guide to crafting and maintaining wooden bows, fletching arrows, and... making violins?" + crafting_recipe_types = list( + /datum/crafting_recipe/arrow, + /datum/crafting_recipe/plastic_arrow, + /datum/crafting_recipe/shortbow, + /datum/crafting_recipe/holy_arrow, + ///datum/crafting_recipe/arrow_quiver, // SKYRAT EDIT REMOVAL: public-knowledge quiver + /datum/crafting_recipe/violin, + ) + icon_state = "book4" + uses = INFINITY + remarks = list( + "Okay, so the quality of the wood has some impact.", + "I feel like the violin chapter is in here as a joke, surely...", + "The author seems oddly proud about how many years they've been hunting in 'these parts'...", + "i really wish they'd stop with all the marriage euphemisms...", + "I need membership? Membership with what?", + "Okay, I think I get the point already...", + ) diff --git a/code/game/objects/items/grenades/_grenade.dm b/code/game/objects/items/grenades/_grenade.dm index 6c84b5cf46e..bb9d275fb00 100644 --- a/code/game/objects/items/grenades/_grenade.dm +++ b/code/game/objects/items/grenades/_grenade.dm @@ -17,6 +17,8 @@ obj_flags = CONDUCTS_ELECTRICITY slot_flags = ITEM_SLOT_BELT max_integrity = 40 + pickup_sound = 'sound/items/grenade_pick_up.ogg' + drop_sound = 'sound/items/grenade_drop.ogg' /// Bitfields which prevent the grenade from detonating if set. Includes ([GRENADE_DUD]|[GRENADE_USED]) var/dud_flags = NONE ///Is this grenade currently armed? diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index c5a68260aba..dfcd6031d87 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -48,6 +48,8 @@ breakouttime = 1 MINUTES armor_type = /datum/armor/restraints_handcuffs custom_price = PAYCHECK_COMMAND * 0.35 + pickup_sound = 'sound/items/handcuffs_pick_up.ogg' + drop_sound = 'sound/items/handcuffs_drop.ogg' ///How long it takes to handcuff someone var/handcuff_time = 4 SECONDS @@ -55,6 +57,8 @@ var/handcuff_time_mod = 1 ///Sound that plays when starting to put handcuffs on someone var/cuffsound = 'sound/weapons/handcuffs.ogg' + ///Sound that plays when restrain is successful + var/cuffsuccesssound = 'sound/items/handcuff_finish.ogg' ///If set, handcuffs will be destroyed on application and leave behind whatever this is set to. var/trashtype = null /// How strong the cuffs are. Weak cuffs can be broken with wirecutters or boxcutters. @@ -120,6 +124,7 @@ return apply_cuffs(victim, user, dispense = iscyborg(user)) + playsound(loc, cuffsuccesssound, 30, TRUE, -2) victim.visible_message( span_notice("[user] handcuffs [victim]."), diff --git a/code/game/objects/items/knives.dm b/code/game/objects/items/knives.dm index 1a16b08eb86..848058a6a27 100644 --- a/code/game/objects/items/knives.dm +++ b/code/game/objects/items/knives.dm @@ -166,6 +166,19 @@ force = 15 throwforce = 15 +/obj/item/knife/combat/root + name = "cahn'root dagger" + icon = 'icons/obj/weapons/stabby.dmi' + icon_state = "rootdagger" + worn_icon_state = "root_dagger" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + inhand_icon_state = "rootshiv" + embed_type = /datum/embed_data/combat_knife/weak + desc = "A root dagger, deceptively sharp. Perfect to hide and stab someone with, or make a couple and throw them at enemies." + force = 15 + throwforce = 15 + /obj/item/knife/combat/bone name = "bone dagger" inhand_icon_state = "bone_dagger" @@ -177,7 +190,6 @@ desc = "A sharpened bone. The bare minimum in survival." embed_type = /datum/embed_data/combat_knife/weak obj_flags = parent_type::obj_flags & ~CONDUCTS_ELECTRICITY - slot_flags = NONE force = 15 throwforce = 15 custom_materials = null @@ -189,7 +201,9 @@ name = "cyborg knife" icon = 'icons/obj/items_cyborg.dmi' icon_state = "knife_cyborg" + worn_icon_state = "knife_cyborg" //error sprite - this shouldn't have been dropped desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable." + slot_flags = NONE //you can't put this in your mouth /obj/item/knife/shiv name = "glass shiv" @@ -279,3 +293,18 @@ /obj/item/knife/shiv/carrot/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] forcefully drives \the [src] into [user.p_their()] eye! It looks like [user.p_theyre()] trying to commit suicide!")) return BRUTELOSS + +/obj/item/knife/shiv/parsnip + name = "parsnip shiv" + icon_state = "parsnipshiv" + inhand_icon_state = "parsnipshiv" + desc = "Truly putting 'snip' in the 'parsnip', and it's not sub-par either!" + custom_materials = null + +/obj/item/knife/shiv/root + name = "cahn'root shiv" + icon_state = "rootshiv" + inhand_icon_state = "rootshiv" + desc = "A root sharpened into a shiv. A root source of someone's stab wounds soon, most likely." + custom_materials = null + diff --git a/code/game/objects/items/melee/baton.dm b/code/game/objects/items/melee/baton.dm index 27909b5317e..6bef1b35f3b 100644 --- a/code/game/objects/items/melee/baton.dm +++ b/code/game/objects/items/melee/baton.dm @@ -318,6 +318,8 @@ bare_wound_bonus = 5 clumsy_knockdown_time = 15 SECONDS active = FALSE + pickup_sound = 'sound/items/stun_baton_pick_up.ogg' + drop_sound = 'sound/items/stun_baton_drop.ogg' /// The sound effecte played when our baton is extended. var/on_sound = 'sound/weapons/batonextend.ogg' @@ -436,6 +438,8 @@ light_on = FALSE light_color = LIGHT_COLOR_ORANGE light_power = 0.5 + pickup_sound = 'sound/items/stun_baton_pick_up.ogg' + drop_sound = 'sound/items/stun_baton_drop.ogg' var/throw_stun_chance = 35 @@ -504,7 +508,6 @@ /obj/item/melee/baton/security/Exited(atom/movable/mov_content) . = ..() if(mov_content == cell) - cell.update_appearance() cell = null active = FALSE update_appearance() diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 0f38cf2d5de..684141b2257 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -164,6 +164,47 @@ user.death(FALSE) REMOVE_TRAIT(src, TRAIT_NODROP, SABRE_SUICIDE_TRAIT) + +/obj/item/melee/parsnip_sabre + name = "parsnip sabre" + desc = "An elegant weapon, if weird weapon. Suprisingly sharp for being made from a parsnip." + icon = 'icons/obj/weapons/sword.dmi' + icon_state = "parsnip_sabre" + inhand_icon_state = "parsnip_sabre" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + force = 15 + throwforce = 10 + demolition_mod = 0.3 + w_class = WEIGHT_CLASS_BULKY + block_chance = 40 + armour_penetration = 40 + sharpness = SHARP_EDGED + attack_verb_continuous = list("slashes", "cuts") + attack_verb_simple = list("slash", "cut") + block_sound = 'sound/weapons/parry.ogg' + hitsound = 'sound/weapons/rapierhit.ogg' + custom_materials = null + wound_bonus = 5 + bare_wound_bonus = 15 + +/obj/item/melee/sabre/Initialize(mapload) + . = ..() + AddComponent(/datum/component/jousting) + +/obj/item/melee/parsnip_sabre/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE) + if(attack_type == PROJECTILE_ATTACK || attack_type == LEAP_ATTACK) + final_block_chance = 0 //Don't bring a sword to a gunfight, and also you aren't going to really block someone full body tackling you with a sword + return ..() + +/obj/item/melee/parsnip_sabre/on_exit_storage(datum/storage/container) + . = ..() + playsound(container.parent, 'sound/items/unsheath.ogg', 25, TRUE) + +/obj/item/melee/parsnip_sabre/on_enter_storage(datum/storage/container) + . = ..() + playsound(container.parent, 'sound/items/sheath.ogg', 25, TRUE) + /obj/item/melee/beesword name = "The Stinger" desc = "Taken from a giant bee and folded over one thousand times in pure honey. Can sting through anything." diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 1553f0e9c8f..c980fe0dbb3 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -99,6 +99,15 @@ max_integrity = 55 w_class = WEIGHT_CLASS_NORMAL +/obj/item/shield/buckler/moonflower + name = "moonflower buckler" + desc = "A buckler made from a steel-cap reinforced moonflower." + icon_state = "moonflower_buckler" + inhand_icon_state = "moonflower_buckler" + block_chance = 40 + max_integrity = 40 + w_class = WEIGHT_CLASS_NORMAL + /obj/item/shield/kite name = "kite shield" desc = "Protect your internal organs with this almond shaped shield." @@ -140,6 +149,8 @@ shield_break_sound = 'sound/effects/glassbr3.ogg' shield_break_leftover = /obj/item/shard armor_type = /datum/armor/item_shield/riot + pickup_sound = 'sound/items/plastic_shield_pick_up.ogg' + drop_sound = 'sound/items/plastic_shield_drop.ogg' /obj/item/shield/riot/Initialize(mapload) . = ..() diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 6314c16c844..69dbe87cd5c 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -41,6 +41,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ merge_type = /obj/item/stack/rods pickup_sound = 'sound/items/iron_rod_pick_up.ogg' drop_sound = 'sound/items/metal_drop.ogg' + sound_vary = TRUE /datum/embed_data/rods embed_chance = 50 diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index de4d7506be3..399aca8558d 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -398,6 +398,9 @@ /obj/item/restraints/legcuffs/bola, /obj/item/stock_parts/power_store/cell/microfusion, //SKYRAT EDIT ADDITION )) + atom_storage.open_sound = 'sound/items/holster.ogg' + atom_storage.open_sound_vary = TRUE + atom_storage.rustle_sound = FALSE /obj/item/storage/belt/security/full/PopulateContents() new /obj/item/reagent_containers/spray/pepper(src) @@ -883,6 +886,50 @@ new /obj/item/melee/sabre(src) update_appearance() +/obj/item/storage/belt/grass_sabre + name = "sabre sheath" + desc = "An simple grass sheath designed to hold a sabre of... some sorts. Actual metal one might be too sharp, though..." + icon_state = "grass_sheath" + inhand_icon_state = "grass_sheath" + worn_icon_state = "grass_sheath" + w_class = WEIGHT_CLASS_BULKY + interaction_flags_click = parent_type::interaction_flags_click | NEED_DEXTERITY | NEED_HANDS + +/obj/item/storage/belt/grass_sabre/Initialize(mapload) + . = ..() + AddElement(/datum/element/update_icon_updates_onmob) + + atom_storage.max_slots = 1 + atom_storage.rustle_sound = FALSE + atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY + atom_storage.set_holdable(/obj/item/melee/sabre) + atom_storage.click_alt_open = FALSE + +/obj/item/storage/belt/grass_sabre/examine(mob/user) + . = ..() + if(length(contents)) + . += span_notice("Alt-click it to quickly draw the blade.") + +/obj/item/storage/belt/grass_sabre/click_alt(mob/user) + if(length(contents)) + var/obj/item/I = contents[1] + user.visible_message(span_notice("[user] takes [I] out of [src]."), span_notice("You take [I] out of [src].")) + user.put_in_hands(I) + update_appearance() + else + balloon_alert(user, "it's empty!") + return CLICK_ACTION_SUCCESS + +/obj/item/storage/belt/grass_sabre/update_icon_state() + icon_state = initial(inhand_icon_state) + inhand_icon_state = initial(inhand_icon_state) + worn_icon_state = initial(worn_icon_state) + if(contents.len) + icon_state += "-sabre" + inhand_icon_state += "-sabre" + worn_icon_state += "-sabre" + return ..() + /obj/item/storage/belt/plant name = "botanical belt" desc = "A sturdy leather belt used to hold most hydroponics supplies." diff --git a/code/game/objects/items/storage/boxes/job_boxes.dm b/code/game/objects/items/storage/boxes/job_boxes.dm index 7f6b1398c5f..2620cb58dc8 100644 --- a/code/game/objects/items/storage/boxes/job_boxes.dm +++ b/code/game/objects/items/storage/boxes/job_boxes.dm @@ -43,7 +43,7 @@ if(HAS_TRAIT(SSstation, STATION_TRAIT_RADIOACTIVE_NEBULA)) new /obj/item/storage/pill_bottle/potassiodide(src) - if(LAZYLEN(SSmapping.multiz_levels)) + if(length(SSmapping.levels_by_trait(ZTRAIT_STATION)) > 1) new /obj/item/climbing_hook/emergency(src) new /obj/item/oxygen_candle(src) //SKYRAT EDIT ADDITION diff --git a/code/game/objects/items/storage/holsters.dm b/code/game/objects/items/storage/holsters.dm index afb7b0f750b..f8dee3afdc7 100644 --- a/code/game/objects/items/storage/holsters.dm +++ b/code/game/objects/items/storage/holsters.dm @@ -33,6 +33,8 @@ /obj/item/gun/energy/laser/captain, /obj/item/gun/energy/e_gun/hos, )) + atom_storage.open_sound = 'sound/items/holster.ogg' + atom_storage.open_sound_vary = TRUE /obj/item/storage/belt/holster/energy name = "energy shoulder holsters" diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index c6b0d52cdc1..20e3846adef 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -191,7 +191,7 @@ desc = "A hydraulic prying tool, simple but powerful." icon = 'icons/obj/items_cyborg.dmi' icon_state = "toolkit_engiborg_crowbar" - worn_icon_state = "crowbar" + worn_icon_state = "toolkit_engiborg_crowbar" //error sprite - this shouldn't have been dropped usesound = 'sound/items/jaws_pry.ogg' force = 10 toolspeed = 0.5 diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index fbe11fe933d..cd8247af3df 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -505,6 +505,36 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 user.visible_message(span_suicide("[user] is strangling [user.p_them()]self with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!")) return OXYLOSS +/obj/item/bambostaff + name = "Bamboo Staff" + desc = "A long bamboo-made staff with steel-capped ends. It is rumoured that initiates of Spider Clan train with such before getting to learn how to use a katana." + force = 10 + block_chance = 45 + block_sound = 'sound/weapons/genhit.ogg' + slot_flags = ITEM_SLOT_BACK + w_class = WEIGHT_CLASS_BULKY + hitsound = SFX_SWING_HIT + attack_verb_continuous = list("smashes", "slams", "whacks", "thwacks") + attack_verb_simple = list("smash", "slam", "whack", "thwack") + icon = 'icons/obj/weapons/staff.dmi' + icon_state = "bambostaff0" + inhand_icon_state = "bambostaff0" + worn_icon_state = "bambostaff0" + lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' + +/obj/item/nullrod/bostaff/Initialize(mapload) + . = ..() + AddComponent(/datum/component/two_handed, \ + force_unwielded = 10, \ + force_wielded = 14, \ + icon_wielded = "[base_icon_state]1", \ + ) + +/obj/item/nullrod/bostaff/update_icon_state() + icon_state = "[base_icon_state]0" + return ..() + /obj/item/cane name = "cane" desc = "A cane used by a true gentleman. Or a clown." diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index ce1b48985bb..f12479c66a4 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -12,7 +12,7 @@ /// Icon to use as a 32x32 preview in crafting menus and such var/icon_preview var/icon_state_preview - /// The vertical pixel offset applied when the object is anchored on a tile with table + /// The vertical pixel_z offset applied when the object is anchored on a tile with table /// Ignored when set to 0 - to avoid shifting directional wall-mounted objects above tables var/anchored_tabletop_offset = 0 @@ -278,7 +278,14 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) return FALSE return TRUE -/// Adjusts the vertical pixel offset when the object is anchored on a tile with table +/// Adjusts the vertical pixel_z offset when the object is anchored on a tile with table /obj/proc/check_on_table() - if(anchored_tabletop_offset != 0 && !istype(src, /obj/structure/table) && locate(/obj/structure/table) in loc) - pixel_y = anchored ? anchored_tabletop_offset : initial(pixel_y) + if(anchored_tabletop_offset == 0) + return + if(istype(src, /obj/structure/table)) + return + + if(anchored && locate(/obj/structure/table) in loc) + pixel_z = anchored_tabletop_offset + else + pixel_z = initial(pixel_z) diff --git a/code/game/objects/structures/lavaland/ore_vent.dm b/code/game/objects/structures/lavaland/ore_vent.dm index 024276198ab..f9214b989b9 100644 --- a/code/game/objects/structures/lavaland/ore_vent.dm +++ b/code/game/objects/structures/lavaland/ore_vent.dm @@ -39,6 +39,7 @@ MEDIUM_VENT_TYPE = 5, SMALL_VENT_TYPE = 7, ) + var/wave_timer = WAVE_DURATION_SMALL /// What string do we use to warn the player about the excavation event? var/excavation_warning = "Are you ready to excavate this ore vent?" @@ -219,6 +220,9 @@ node.arrive(src) RegisterSignal(node, COMSIG_QDELETING, PROC_REF(handle_wave_conclusion)) RegisterSignal(node, COMSIG_MOVABLE_MOVED, PROC_REF(handle_wave_conclusion)) + addtimer(CALLBACK(node, TYPE_PROC_REF(/atom, update_appearance)), wave_timer * 0.25) + addtimer(CALLBACK(node, TYPE_PROC_REF(/atom, update_appearance)), wave_timer * 0.5) + addtimer(CALLBACK(node, TYPE_PROC_REF(/atom, update_appearance)), wave_timer * 0.75) particles = new /particles/smoke/ash() for(var/i in 1 to 5) // Clears the surroundings of the ore vent before starting wave defense. for(var/turf/closed/mineral/rock in oview(i)) @@ -247,11 +251,6 @@ spawn_distance = 4, \ spawn_distance_exclude = 3, \ ) - var/wave_timer = 60 SECONDS - if(boulder_size == BOULDER_SIZE_MEDIUM) - wave_timer = 90 SECONDS - else if(boulder_size == BOULDER_SIZE_LARGE) - wave_timer = 150 SECONDS COOLDOWN_START(src, wave_cooldown, wave_timer) addtimer(CALLBACK(src, PROC_REF(handle_wave_conclusion)), wave_timer) icon_state = icon_state_tapped @@ -290,6 +289,7 @@ icon_state = icon_state_tapped update_appearance(UPDATE_ICON_STATE) qdel(GetComponent(/datum/component/gps)) + UnregisterSignal(node, COMSIG_QDELETING) else visible_message(span_danger("\the [src] creaks and groans as the mining attempt fails, and the vent closes back up.")) icon_state = initial(icon_state) @@ -474,18 +474,22 @@ switch(string_boulder_size) if(LARGE_VENT_TYPE) boulder_size = BOULDER_SIZE_LARGE + wave_timer = WAVE_DURATION_LARGE if(mapload) GLOB.ore_vent_sizes["large"] += 1 if(MEDIUM_VENT_TYPE) boulder_size = BOULDER_SIZE_MEDIUM + wave_timer = WAVE_DURATION_MEDIUM if(mapload) GLOB.ore_vent_sizes["medium"] += 1 if(SMALL_VENT_TYPE) boulder_size = BOULDER_SIZE_SMALL + wave_timer = WAVE_DURATION_SMALL if(mapload) GLOB.ore_vent_sizes["small"] += 1 else boulder_size = BOULDER_SIZE_SMALL //Might as well set a default value + wave_timer = WAVE_DURATION_SMALL name = initial(name) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 881603e11d8..e2cc6a55202 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -356,6 +356,7 @@ if((shove_flags & SHOVE_KNOCKDOWN_BLOCKED) || !(shove_flags & SHOVE_BLOCKED)) return target.Knockdown(SHOVE_KNOCKDOWN_TABLE) + target.apply_status_effect(/datum/status_effect/next_shove_stuns) target.visible_message(span_danger("[shover.name] shoves [target.name] onto \the [src]!"), span_userdanger("You're shoved onto \the [src] by [shover.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, shover) to_chat(shover, span_danger("You shove [target.name] onto \the [src]!")) diff --git a/code/modules/admin/verbs/server.dm b/code/modules/admin/verbs/server.dm index e3a66dcd1b3..f0817f06a36 100644 --- a/code/modules/admin/verbs/server.dm +++ b/code/modules/admin/verbs/server.dm @@ -16,10 +16,15 @@ ADMIN_VERB(toggle_hub, R_SERVER, "Toggle Hub", "Toggles the server's visilibilit SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Hub Visibility", "[GLOB.hub_visibility ? "Enabled" : "Disabled"]")) // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! +#define REGULAR_RESTART "Regular Restart" +#define REGULAR_RESTART_DELAYED "Regular Restart (with delay)" +#define HARD_RESTART "Hard Restart (No Delay/Feedback Reason)" +#define HARDEST_RESTART "Hardest Restart (No actions, just reboot)" +#define TGS_RESTART "Server Restart (Kill and restart DD)" ADMIN_VERB(restart, R_SERVER, "Reboot World", "Restarts the world immediately.", ADMIN_CATEGORY_SERVER) - var/list/options = list("Regular Restart", "Regular Restart (with delay)", "Hard Restart (No Delay/Feeback Reason)", "Hardest Restart (No actions, just reboot)") + var/list/options = list(REGULAR_RESTART, REGULAR_RESTART_DELAYED, HARD_RESTART, HARDEST_RESTART) if(world.TgsAvailable()) - options += "Server Restart (Kill and restart DD)"; + options += TGS_RESTART; if(SSticker.admin_delay_notice) if(alert(user, "Are you sure? An admin has already delayed the round end for the following reason: [SSticker.admin_delay_notice]", "Confirmation", "Yes", "No") != "Yes") @@ -32,12 +37,12 @@ ADMIN_VERB(restart, R_SERVER, "Reboot World", "Restarts the world immediately.", BLACKBOX_LOG_ADMIN_VERB("Reboot World") var/init_by = "Initiated by [user.holder.fakekey ? "Admin" : user.key]." switch(result) - if("Regular Restart") + if(REGULAR_RESTART) if(!user.is_localhost()) if(alert(user, "Are you sure you want to restart the server?","This server is live", "Restart", "Cancel") != "Restart") return FALSE SSticker.Reboot(init_by, "admin reboot - by [user.key] [user.holder.fakekey ? "(stealth)" : ""]", 10) - if("Regular Restart (with delay)") + if(REGULAR_RESTART_DELAYED) var/delay = input("What delay should the restart have (in seconds)?", "Restart Delay", 5) as num|null if(!delay) return FALSE @@ -45,16 +50,22 @@ ADMIN_VERB(restart, R_SERVER, "Reboot World", "Restarts the world immediately.", if(alert(user,"Are you sure you want to restart the server?","This server is live", "Restart", "Cancel") != "Restart") return FALSE SSticker.Reboot(init_by, "admin reboot - by [user.key] [user.holder.fakekey ? "(stealth)" : ""]", delay * 10) - if("Hard Restart (No Delay, No Feeback Reason)") + if(HARD_RESTART) to_chat(world, "World reboot - [init_by]") world.Reboot() - if("Hardest Restart (No actions, just reboot)") + if(HARDEST_RESTART) to_chat(world, "Hard world reboot - [init_by]") world.Reboot(fast_track = TRUE) - if("Server Restart (Kill and restart DD)") + if(TGS_RESTART) to_chat(world, "Server restart - [init_by]") world.TgsEndProcess() +#undef REGULAR_RESTART +#undef REGULAR_RESTART_DELAYED +#undef HARD_RESTART +#undef HARDEST_RESTART +#undef TGS_RESTART + ADMIN_VERB(end_round, R_SERVER, "End Round", "Forcibly ends the round and allows the server to restart normally.", ADMIN_CATEGORY_SERVER) var/confirm = tgui_alert(user, "End the round and restart the game world?", "End Round", list("Yes", "Cancel")) if(confirm != "Yes") diff --git a/code/modules/antagonists/heretic/knowledge/ash_lore.dm b/code/modules/antagonists/heretic/knowledge/ash_lore.dm index 496b90b3f12..315bb14b664 100644 --- a/code/modules/antagonists/heretic/knowledge/ash_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/ash_lore.dm @@ -1,7 +1,5 @@ /** * # The path of Ash. - * Spell names are in this language: OLD NORDIC - * Both are related: Nordic Mythology-Yggdrassil-Ash Tree Genus-Ash * * Goes as follows: * @@ -233,7 +231,7 @@ text = "[generate_heretic_text()] Fear the blaze, for the Ashlord, [user.real_name] has ascended! The flames shall consume all! [generate_heretic_text()]", title = "[generate_heretic_text()]", sound = 'sound/ambience/antag/heretic/ascend_ash.ogg', - color_override = "white", + color_override = "pink", ) var/datum/action/cooldown/spell/fire_sworn/circle_spell = new(user.mind) diff --git a/code/modules/antagonists/heretic/knowledge/blade_lore.dm b/code/modules/antagonists/heretic/knowledge/blade_lore.dm index 357e789416d..de79151739f 100644 --- a/code/modules/antagonists/heretic/knowledge/blade_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/blade_lore.dm @@ -1,7 +1,5 @@ /** * # The path of Blades. Stab stab. - * Spell names are in this language: ARAMAIC - * Both are related: Aramaic-Damascus-Blade * * Goes as follows: * diff --git a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm index 8a94aada74a..a3e75761320 100644 --- a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm @@ -1,7 +1,5 @@ /** * # The path of Cosmos. - * Spell names are in this language: SUMERIAN - * Both are related: Sumerian-Original-Primordial-Cosmic * * Goes as follows: * @@ -285,7 +283,7 @@ text = "[generate_heretic_text()] A Star Gazer has arrived into the station, [user.real_name] has ascended! This station is the domain of the Cosmos! [generate_heretic_text()]", title = "[generate_heretic_text()]", sound = 'sound/ambience/antag/heretic/ascend_cosmic.ogg', - color_override = "purple", + color_override = "pink", ) var/mob/living/basic/heretic_summon/star_gazer/star_gazer_mob = new /mob/living/basic/heretic_summon/star_gazer(loc) star_gazer_mob.maxHealth = INFINITY diff --git a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm index 9e963ae9ea7..6dde1a3038d 100644 --- a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm @@ -5,8 +5,6 @@ /** * # The path of Flesh. - * Spell names are in this language: LATIN - * Both are related: Latin-Rome-Hedonism-Flesh * * Goes as follows: * @@ -332,7 +330,7 @@ text = "[generate_heretic_text()] Ever coiling vortex. Reality unfolded. ARMS OUTREACHED, THE LORD OF THE NIGHT, [user.real_name] has ascended! Fear the ever twisting hand! [generate_heretic_text()]", title = "[generate_heretic_text()]", sound = 'sound/ambience/antag/heretic/ascend_flesh.ogg', - color_override = "red", + color_override = "pink", ) var/datum/action/cooldown/spell/shapeshift/shed_human_form/worm_spell = new(user.mind) diff --git a/code/modules/antagonists/heretic/knowledge/lock_lore.dm b/code/modules/antagonists/heretic/knowledge/lock_lore.dm index b238d6dd3c7..17e73cb162c 100644 --- a/code/modules/antagonists/heretic/knowledge/lock_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/lock_lore.dm @@ -1,7 +1,5 @@ /** * # The path of Lock. - * Spell names are in this language: EGYPTIAN - * Both are related: Egyptian-Mysteries-Secrets-Lock * * Goes as follows: * @@ -243,7 +241,7 @@ text = "Delta-class dimensional anomaly detec[generate_heretic_text()] Reality rended, torn. Gates open, doors open, [user.real_name] has ascended! Fear the tide! [generate_heretic_text()]", title = "[generate_heretic_text()]", sound = 'sound/ambience/antag/heretic/ascend_knock.ogg', - color_override = "yellow", + color_override = "pink", ) // buffs diff --git a/code/modules/antagonists/heretic/knowledge/moon_lore.dm b/code/modules/antagonists/heretic/knowledge/moon_lore.dm index 5ba55b64058..917944d30fe 100644 --- a/code/modules/antagonists/heretic/knowledge/moon_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/moon_lore.dm @@ -1,7 +1,5 @@ /** * # The path of Moon. - * Spell names are in this language: ANCIENT HEBREW - * Both are related: Ancient Hebrew-Moon Mysticism-Moon * * Goes as follows: * @@ -211,7 +209,7 @@ The truth shall finally devour the lie! [generate_heretic_text()]", title = "[generate_heretic_text()]", sound = 'sound/ambience/antag/heretic/ascend_moon.ogg', - color_override = "blue", + color_override = "pink", ) ADD_TRAIT(user, TRAIT_MADNESS_IMMUNE, REF(src)) diff --git a/code/modules/antagonists/heretic/knowledge/rust_lore.dm b/code/modules/antagonists/heretic/knowledge/rust_lore.dm index fe0d03ec18f..3a081c8d295 100644 --- a/code/modules/antagonists/heretic/knowledge/rust_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/rust_lore.dm @@ -1,6 +1,5 @@ /** * # The path of Rust. - * Spell names are in this language: OLD SLAVIC * * Goes as follows: * @@ -257,7 +256,7 @@ text = "[generate_heretic_text()] Fear the decay, for the Rustbringer, [user.real_name] has ascended! None shall escape the corrosion! [generate_heretic_text()]", title = "[generate_heretic_text()]", sound = 'sound/ambience/antag/heretic/ascend_rust.ogg', - color_override = "brown", + color_override = "pink", ) trigger(loc) RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) diff --git a/code/modules/antagonists/heretic/knowledge/starting_lore.dm b/code/modules/antagonists/heretic/knowledge/starting_lore.dm index 7cb3b82a39a..4e5e2910e0e 100644 --- a/code/modules/antagonists/heretic/knowledge/starting_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/starting_lore.dm @@ -1,5 +1,4 @@ // Heretic starting knowledge. -// Default heretic language is Ancient Greek, because, uh, they're like ancient and shit. /// Global list of all heretic knowledge that have route = PATH_START. List of PATHS. GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge()) diff --git a/code/modules/antagonists/heretic/knowledge/void_lore.dm b/code/modules/antagonists/heretic/knowledge/void_lore.dm index 0fd4f925fa8..51f0146fca3 100644 --- a/code/modules/antagonists/heretic/knowledge/void_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/void_lore.dm @@ -1,7 +1,5 @@ /** * # The path of VOID. - * Spell names are in this language: PALI - * Both are related: Pali-Buddhism-Nothingness-Void * * Goes as follows: * @@ -221,7 +219,7 @@ text = "[generate_heretic_text()] The nobleman of void [user.real_name] has arrived, stepping along the Waltz that ends worlds! [generate_heretic_text()]", title = "[generate_heretic_text()]", sound = 'sound/ambience/antag/heretic/ascend_void.ogg', - color_override = "blue", + color_override = "pink", ) ADD_TRAIT(user, TRAIT_RESISTLOWPRESSURE, MAGIC_TRAIT) diff --git a/code/modules/antagonists/heretic/magic/aggressive_spread.dm b/code/modules/antagonists/heretic/magic/aggressive_spread.dm index 0c14550f0b2..dfb4a948474 100644 --- a/code/modules/antagonists/heretic/magic/aggressive_spread.dm +++ b/code/modules/antagonists/heretic/magic/aggressive_spread.dm @@ -10,8 +10,8 @@ school = SCHOOL_FORBIDDEN cooldown_time = 30 SECONDS - invocation = "Agresiv'noe rasprostra-neniye!" - invocation_type = INVOCATION_SHOUT + invocation = "A'GRSV SPR'D" + invocation_type = INVOCATION_WHISPER spell_requirements = NONE aoe_radius = 2 diff --git a/code/modules/antagonists/heretic/magic/apetravulnera.dm b/code/modules/antagonists/heretic/magic/apetravulnera.dm index eedef71f4b6..e80d0891184 100644 --- a/code/modules/antagonists/heretic/magic/apetravulnera.dm +++ b/code/modules/antagonists/heretic/magic/apetravulnera.dm @@ -10,8 +10,8 @@ school = SCHOOL_FORBIDDEN cooldown_time = 45 SECONDS - invocation = "Shea' shen-eh!" - invocation_type = INVOCATION_SHOUT + invocation = "AP'TRA VULN'RA!" + invocation_type = INVOCATION_WHISPER spell_requirements = NONE cast_range = 4 diff --git a/code/modules/antagonists/heretic/magic/ash_ascension.dm b/code/modules/antagonists/heretic/magic/ash_ascension.dm index 70422a7c48a..8b564198a61 100644 --- a/code/modules/antagonists/heretic/magic/ash_ascension.dm +++ b/code/modules/antagonists/heretic/magic/ash_ascension.dm @@ -10,7 +10,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 70 SECONDS - invocation = "EID'R-ELDR!!!" + invocation = "FL'MS" invocation_type = INVOCATION_WHISPER spell_requirements = NONE @@ -72,8 +72,8 @@ school = SCHOOL_FORBIDDEN cooldown_time = 30 SECONDS - invocation = "ILLA-LASARA'FOSS!!!" - invocation_type = INVOCATION_SHOUT + invocation = "C'SC'DE" + invocation_type = INVOCATION_WHISPER spell_requirements = NONE /// The radius the flames will go around the caster. @@ -112,7 +112,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 300 - invocation = "Eld'sky!" + invocation = "F'RE" invocation_type = INVOCATION_WHISPER spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/ash_jaunt.dm b/code/modules/antagonists/heretic/magic/ash_jaunt.dm index 4f8c59d6351..41242063a90 100644 --- a/code/modules/antagonists/heretic/magic/ash_jaunt.dm +++ b/code/modules/antagonists/heretic/magic/ash_jaunt.dm @@ -10,7 +10,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 15 SECONDS - invocation = "Askgraar' goetur!" + invocation = "ASH'N P'SSG'" invocation_type = INVOCATION_WHISPER spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/blood_cleave.dm b/code/modules/antagonists/heretic/magic/blood_cleave.dm index b3370a3ccc6..d5317f23e34 100644 --- a/code/modules/antagonists/heretic/magic/blood_cleave.dm +++ b/code/modules/antagonists/heretic/magic/blood_cleave.dm @@ -10,7 +10,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 45 SECONDS - invocation = "Fer're!" + invocation = "CL'VE!" invocation_type = INVOCATION_WHISPER spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/blood_siphon.dm b/code/modules/antagonists/heretic/magic/blood_siphon.dm index 6280353a072..1e3d6258826 100644 --- a/code/modules/antagonists/heretic/magic/blood_siphon.dm +++ b/code/modules/antagonists/heretic/magic/blood_siphon.dm @@ -11,7 +11,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 15 SECONDS - invocation = "Sanguis suctio!" + invocation = "FL'MS O'ET'RN'ITY." invocation_type = INVOCATION_WHISPER spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/burglar_finesse.dm b/code/modules/antagonists/heretic/magic/burglar_finesse.dm index c5264119bb4..a90acb8495f 100644 --- a/code/modules/antagonists/heretic/magic/burglar_finesse.dm +++ b/code/modules/antagonists/heretic/magic/burglar_finesse.dm @@ -9,7 +9,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 40 SECONDS - invocation = "Khenem" + invocation = "Y'O'K!" invocation_type = INVOCATION_WHISPER spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/cosmic_expansion.dm b/code/modules/antagonists/heretic/magic/cosmic_expansion.dm index 6869dc0df51..3fb197d392c 100644 --- a/code/modules/antagonists/heretic/magic/cosmic_expansion.dm +++ b/code/modules/antagonists/heretic/magic/cosmic_expansion.dm @@ -11,7 +11,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 45 SECONDS - invocation = "An'gar baltil!" + invocation = "C'SM'S 'XP'ND" invocation_type = INVOCATION_SHOUT spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/cosmic_runes.dm b/code/modules/antagonists/heretic/magic/cosmic_runes.dm index e07aa4fbe8b..207b60ae939 100644 --- a/code/modules/antagonists/heretic/magic/cosmic_runes.dm +++ b/code/modules/antagonists/heretic/magic/cosmic_runes.dm @@ -11,7 +11,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 15 SECONDS - invocation = "Is'zara-runen" + invocation = "ST'R R'N'" invocation_type = INVOCATION_WHISPER spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/eldritch_blind.dm b/code/modules/antagonists/heretic/magic/eldritch_blind.dm index 413ff4fe678..8df20503821 100644 --- a/code/modules/antagonists/heretic/magic/eldritch_blind.dm +++ b/code/modules/antagonists/heretic/magic/eldritch_blind.dm @@ -5,7 +5,7 @@ overlay_icon_state = "bg_heretic_border" school = SCHOOL_FORBIDDEN - invocation = "Caecus" + invocation = "E'E'S" spell_requirements = NONE cast_range = 10 diff --git a/code/modules/antagonists/heretic/magic/eldritch_emplosion.dm b/code/modules/antagonists/heretic/magic/eldritch_emplosion.dm index 4028f80f84c..c68ed07c81f 100644 --- a/code/modules/antagonists/heretic/magic/eldritch_emplosion.dm +++ b/code/modules/antagonists/heretic/magic/eldritch_emplosion.dm @@ -8,7 +8,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 30 SECONDS - invocation = "Pulsus Energiae" + invocation = "E'P" invocation_type = INVOCATION_WHISPER spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm b/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm index bde032a3b39..e598f1f9215 100644 --- a/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm +++ b/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm @@ -7,7 +7,7 @@ overlay_icon_state = "bg_heretic_border" school = SCHOOL_FORBIDDEN - invocation = "Forma" + invocation = "SH'PE" invocation_type = INVOCATION_WHISPER spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/fire_blast.dm b/code/modules/antagonists/heretic/magic/fire_blast.dm index 8c6d632be9f..4c17ca5ffc0 100644 --- a/code/modules/antagonists/heretic/magic/fire_blast.dm +++ b/code/modules/antagonists/heretic/magic/fire_blast.dm @@ -12,7 +12,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 45 SECONDS - invocation = "Eld'fjall!" + invocation = "V'LC'N!" invocation_type = INVOCATION_SHOUT spell_requirements = NONE channel_time = 5 SECONDS diff --git a/code/modules/antagonists/heretic/magic/flesh_ascension.dm b/code/modules/antagonists/heretic/magic/flesh_ascension.dm index add0704a8d6..a2d792080e0 100644 --- a/code/modules/antagonists/heretic/magic/flesh_ascension.dm +++ b/code/modules/antagonists/heretic/magic/flesh_ascension.dm @@ -9,7 +9,7 @@ school = SCHOOL_FORBIDDEN - invocation = "REALITAS EXSERPAT!!" + invocation = "REALITY UNCOIL!" invocation_type = INVOCATION_SHOUT spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/flesh_surgery.dm b/code/modules/antagonists/heretic/magic/flesh_surgery.dm index a486b986cd8..ff474f06319 100644 --- a/code/modules/antagonists/heretic/magic/flesh_surgery.dm +++ b/code/modules/antagonists/heretic/magic/flesh_surgery.dm @@ -11,8 +11,8 @@ school = SCHOOL_FORBIDDEN cooldown_time = 20 SECONDS - invocation = "Carnis chirurgia" - invocation_type = INVOCATION_WHISPER + invocation = "CL'M M'N!" // "CLAIM MINE", but also almost "KALI MA" + invocation_type = INVOCATION_SHOUT spell_requirements = NONE hand_path = /obj/item/melee/touch_attack/flesh_surgery diff --git a/code/modules/antagonists/heretic/magic/furious_steel.dm b/code/modules/antagonists/heretic/magic/furious_steel.dm index 36c7c07608b..0ab882a9289 100644 --- a/code/modules/antagonists/heretic/magic/furious_steel.dm +++ b/code/modules/antagonists/heretic/magic/furious_steel.dm @@ -11,7 +11,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 60 SECONDS - invocation = "Ham'sana-qasep!" + invocation = "F'LSH'NG S'LV'R!" invocation_type = INVOCATION_SHOUT spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/manse_link.dm b/code/modules/antagonists/heretic/magic/manse_link.dm index e077c6db2b4..06fd4dd9863 100644 --- a/code/modules/antagonists/heretic/magic/manse_link.dm +++ b/code/modules/antagonists/heretic/magic/manse_link.dm @@ -11,7 +11,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 20 SECONDS - invocation = "Diaperaste' to-myalo!" + invocation = "PI'RC' TH' M'ND." invocation_type = INVOCATION_SHOUT spell_requirements = NONE antimagic_flags = MAGIC_RESISTANCE|MAGIC_RESISTANCE_MIND diff --git a/code/modules/antagonists/heretic/magic/mansus_grasp.dm b/code/modules/antagonists/heretic/magic/mansus_grasp.dm index 803bdd3d218..43dde25374f 100644 --- a/code/modules/antagonists/heretic/magic/mansus_grasp.dm +++ b/code/modules/antagonists/heretic/magic/mansus_grasp.dm @@ -10,7 +10,7 @@ school = SCHOOL_EVOCATION cooldown_time = 10 SECONDS - invocation = "Ad verum per aspera!" + invocation = "R'CH T'H TR'TH!" invocation_type = INVOCATION_SHOUT // Mimes can cast it. Chaplains can cast it. Anyone can cast it, so long as they have a hand. spell_requirements = SPELL_CASTABLE_WITHOUT_INVOCATION diff --git a/code/modules/antagonists/heretic/magic/mind_gate.dm b/code/modules/antagonists/heretic/magic/mind_gate.dm index aa6b8ef20af..c5a6e74452a 100644 --- a/code/modules/antagonists/heretic/magic/mind_gate.dm +++ b/code/modules/antagonists/heretic/magic/mind_gate.dm @@ -11,7 +11,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 20 SECONDS - invocation = "Sha'ar ha-da'at" + invocation = "Op' 'oY 'Mi'd" invocation_type = INVOCATION_WHISPER spell_requirements = NONE cast_range = 6 diff --git a/code/modules/antagonists/heretic/magic/moon_parade.dm b/code/modules/antagonists/heretic/magic/moon_parade.dm index 4919500e351..3b7f1d007cd 100644 --- a/code/modules/antagonists/heretic/magic/moon_parade.dm +++ b/code/modules/antagonists/heretic/magic/moon_parade.dm @@ -11,7 +11,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 30 SECONDS - invocation = "Tsiyun' levani!" + invocation = "L'N'R P'RAD" invocation_type = INVOCATION_SHOUT spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/moon_ringleader.dm b/code/modules/antagonists/heretic/magic/moon_ringleader.dm index e62c34bb990..3c0b1d2aedb 100644 --- a/code/modules/antagonists/heretic/magic/moon_ringleader.dm +++ b/code/modules/antagonists/heretic/magic/moon_ringleader.dm @@ -12,7 +12,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 1 MINUTES - invocation = "Manahel-qomem!" + invocation = "R''S 'E" invocation_type = INVOCATION_SHOUT spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/moon_smile.dm b/code/modules/antagonists/heretic/magic/moon_smile.dm index 236fd257e38..35f2d77e3e6 100644 --- a/code/modules/antagonists/heretic/magic/moon_smile.dm +++ b/code/modules/antagonists/heretic/magic/moon_smile.dm @@ -12,7 +12,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 20 SECONDS - invocation = "Hiyuk-levana!" + invocation = "Mo'N S'M'LE" invocation_type = INVOCATION_SHOUT spell_requirements = NONE cast_range = 6 diff --git a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm index 8a9b60644b6..4e37f5db17f 100644 --- a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm +++ b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm @@ -11,7 +11,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 1 MINUTES - invocation = "Dyrth-a Vaktry'ggjandi" + invocation = "GL'RY T' TH' N'GHT'W'TCH'ER" invocation_type = INVOCATION_WHISPER spell_requirements = SPELL_REQUIRES_HUMAN diff --git a/code/modules/antagonists/heretic/magic/realignment.dm b/code/modules/antagonists/heretic/magic/realignment.dm index dbce0fe0940..d3ddc03fbbe 100644 --- a/code/modules/antagonists/heretic/magic/realignment.dm +++ b/code/modules/antagonists/heretic/magic/realignment.dm @@ -14,8 +14,8 @@ cooldown_reduction_per_rank = -6 SECONDS // we're not a wizard spell but we use the levelling mechanic spell_max_level = 10 // we can get up to / over a minute duration cd time - invocation = "Rasut" - invocation_type = INVOCATION_WHISPER + invocation = "R'S'T." + invocation_type = INVOCATION_SHOUT spell_requirements = NONE /datum/action/cooldown/spell/realignment/is_valid_target(atom/cast_on) diff --git a/code/modules/antagonists/heretic/magic/rust_wave.dm b/code/modules/antagonists/heretic/magic/rust_wave.dm index 7ecb3fd0ffb..0282a32b2b6 100644 --- a/code/modules/antagonists/heretic/magic/rust_wave.dm +++ b/code/modules/antagonists/heretic/magic/rust_wave.dm @@ -13,8 +13,8 @@ school = SCHOOL_FORBIDDEN cooldown_time = 30 SECONDS - invocation = "Entro'pichniy-plim!" - invocation_type = INVOCATION_SHOUT + invocation = "'NTR'P'C PL'M'" + invocation_type = INVOCATION_WHISPER spell_requirements = NONE cone_levels = 5 @@ -78,8 +78,8 @@ school = SCHOOL_FORBIDDEN cooldown_time = 35 SECONDS - invocation = "Diffunde' verbum!" - invocation_type = INVOCATION_SHOUT + invocation = "SPR'D TH' WO'D" + invocation_type = INVOCATION_WHISPER spell_requirements = NONE projectile_type = /obj/projectile/magic/aoe/rust_wave diff --git a/code/modules/antagonists/heretic/magic/star_blast.dm b/code/modules/antagonists/heretic/magic/star_blast.dm index 294608a03b9..3eb62b7ada8 100644 --- a/code/modules/antagonists/heretic/magic/star_blast.dm +++ b/code/modules/antagonists/heretic/magic/star_blast.dm @@ -10,7 +10,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 20 SECONDS - invocation = "Pi-rig is'zara!" + invocation = "R'T'T' ST'R!" invocation_type = INVOCATION_SHOUT spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/star_touch.dm b/code/modules/antagonists/heretic/magic/star_touch.dm index dff56df4e3f..89c5d02e7d4 100644 --- a/code/modules/antagonists/heretic/magic/star_touch.dm +++ b/code/modules/antagonists/heretic/magic/star_touch.dm @@ -13,7 +13,7 @@ sound = 'sound/items/welder.ogg' school = SCHOOL_FORBIDDEN cooldown_time = 15 SECONDS - invocation = "An'gar sig!" + invocation = "ST'R 'N'RG'!" invocation_type = INVOCATION_SHOUT spell_requirements = NONE antimagic_flags = MAGIC_RESISTANCE diff --git a/code/modules/antagonists/heretic/magic/void_cold_cone.dm b/code/modules/antagonists/heretic/magic/void_cold_cone.dm index 40dc9612a50..92c45dc10b0 100644 --- a/code/modules/antagonists/heretic/magic/void_cold_cone.dm +++ b/code/modules/antagonists/heretic/magic/void_cold_cone.dm @@ -11,7 +11,7 @@ school = SCHOOL_FORBIDDEN cooldown_time = 30 SECONDS - invocation = "Sunya'kop!" + invocation = "FR'ZE!" invocation_type = INVOCATION_SHOUT spell_requirements = NONE diff --git a/code/modules/antagonists/heretic/magic/void_phase.dm b/code/modules/antagonists/heretic/magic/void_phase.dm index f3f0864224c..350ca0f29c1 100644 --- a/code/modules/antagonists/heretic/magic/void_phase.dm +++ b/code/modules/antagonists/heretic/magic/void_phase.dm @@ -12,8 +12,8 @@ school = SCHOOL_FORBIDDEN cooldown_time = 30 SECONDS - invocation = "Sunya'sthiti!" - invocation_type = INVOCATION_SHOUT + invocation = "RE'L'TY PH'S'E." + invocation_type = INVOCATION_WHISPER spell_requirements = NONE cast_range = 9 diff --git a/code/modules/antagonists/heretic/magic/void_pull.dm b/code/modules/antagonists/heretic/magic/void_pull.dm index dc4673b0714..2021bf8a04e 100644 --- a/code/modules/antagonists/heretic/magic/void_pull.dm +++ b/code/modules/antagonists/heretic/magic/void_pull.dm @@ -11,8 +11,8 @@ school = SCHOOL_FORBIDDEN cooldown_time = 40 SECONDS - invocation = "Sunya'apamkti!" - invocation_type = INVOCATION_SHOUT + invocation = "BR'NG F'RTH TH'M T' M'." + invocation_type = INVOCATION_WHISPER spell_requirements = NONE aoe_radius = 7 diff --git a/code/modules/antagonists/heretic/magic/wave_of_desperation.dm b/code/modules/antagonists/heretic/magic/wave_of_desperation.dm index b9502f08967..3b78b56ddc0 100644 --- a/code/modules/antagonists/heretic/magic/wave_of_desperation.dm +++ b/code/modules/antagonists/heretic/magic/wave_of_desperation.dm @@ -11,8 +11,8 @@ school = SCHOOL_FORBIDDEN cooldown_time = 5 MINUTES - invocation = "Kher' Sekh-em waaef'k!" - invocation_type = INVOCATION_SHOUT + invocation = "F'K 'FF." + invocation_type = INVOCATION_WHISPER spell_requirements = NONE aoe_radius = 3 diff --git a/code/modules/antagonists/spy/spy.dm b/code/modules/antagonists/spy/spy.dm index 8bcc113f089..2468eb27cad 100644 --- a/code/modules/antagonists/spy/spy.dm +++ b/code/modules/antagonists/spy/spy.dm @@ -8,6 +8,8 @@ hijack_speed = 1 ui_name = "AntagInfoSpy" preview_outfit = /datum/outfit/spy + can_assign_self_objectives = TRUE + default_custom_objective = "Rob the station blind." /// Whether an uplink has been created (successfully or at all) var/uplink_created = FALSE /// String displayed in the antag panel pointing the spy to where their uplink is. diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 733e22461c7..bbdfa77ecea 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -47,7 +47,8 @@ /// The uplink handler that this traitor belongs to. var/datum/uplink_handler/uplink_handler - var/uplink_sale_count = 3 + var/uplink_sales_min = 4 + var/uplink_sales_max = 6 ///the final objective the traitor has to accomplish, be it escaping, hijacking, or just martyrdom. var/datum/objective/ending_objective @@ -98,14 +99,14 @@ var/list/uplink_items = list() for(var/datum/uplink_item/item as anything in SStraitor.uplink_items) - if(item.item && !item.cant_discount && (item.purchasable_from & uplink_handler.uplink_flag) && item.cost > 1) + if(item.item && !item.cant_discount && (item.purchasable_from & uplink_handler.uplink_flag) && item.cost >= TRAITOR_DISCOUNT_MIN_PRICE) if(!length(item.restricted_roles) && !length(item.restricted_species)) uplink_items += item continue if((uplink_handler.assigned_role in item.restricted_roles) || (uplink_handler.assigned_species in item.restricted_species)) uplink_items += item continue - uplink_handler.extra_purchasable += create_uplink_sales(uplink_sale_count, /datum/uplink_category/discounts, 1, uplink_items) + uplink_handler.extra_purchasable += create_uplink_sales(rand(uplink_sales_min, uplink_sales_max), /datum/uplink_category/discounts, 1, uplink_items) if(give_objectives) forge_traitor_objectives() diff --git a/code/modules/antagonists/traitor/uplink_handler.dm b/code/modules/antagonists/traitor/uplink_handler.dm index f78ddb02478..2d27f3c4a0e 100644 --- a/code/modules/antagonists/traitor/uplink_handler.dm +++ b/code/modules/antagonists/traitor/uplink_handler.dm @@ -126,6 +126,21 @@ on_update() return TRUE +/datum/uplink_handler/proc/purchase_raw_tc(mob/user, amount, atom/movable/source) + if(shop_locked) + return FALSE + if(telecrystals < amount) + return FALSE + + telecrystals -= amount + var/tcs = new /obj/item/stack/telecrystal(get_turf(user), amount) + user.put_in_hands(tcs) + + log_uplink("[key_name(user)] purchased [amount] raw telecrystals from [source]'s uplink") + on_update() + return TRUE + + /// Generates objectives for this uplink handler /datum/uplink_handler/proc/generate_objectives() var/potential_objectives_left = maximum_potential_objectives - (length(potential_objectives) + length(active_objectives)) diff --git a/code/modules/asset_cache/assets/uplink.dm b/code/modules/asset_cache/assets/uplink.dm index e85ee1b35b5..35a907a234d 100644 --- a/code/modules/asset_cache/assets/uplink.dm +++ b/code/modules/asset_cache/assets/uplink.dm @@ -18,10 +18,13 @@ for(var/datum/uplink_item/item_path as anything in subtypesof(/datum/uplink_item)) var/datum/uplink_item/item = new item_path() + var/atom/actual_item = item.item if(item.item) { items += list(list( "id" = item_path, "name" = item.name, + "icon" = actual_item.icon, + "icon_state" = actual_item.icon_state, "cost" = item.cost, "desc" = item.desc, "category" = item.category ? initial(item.category.name) : null, diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 25217de538c..da6c75d699d 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -6,7 +6,7 @@ desc = "Very useful for filtering gasses." can_unwrench = TRUE - construction_type = /obj/item/pipe/trinary/flippable + construction_type = /obj/item/pipe/trinary/flippable/filter pipe_state = "filter" ///Rate of transfer of the gases to the outputs diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index 02f0d203544..8a165830cec 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -5,7 +5,7 @@ name = "air vent" desc = "Has a valve and pump attached to it." - + construction_type = /obj/item/pipe/directional/vent use_power = IDLE_POWER_USE idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.15 can_unwrench = TRUE diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 560c9d71743..4da90396052 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -3,6 +3,7 @@ name = "air scrubber" desc = "Has a valve and pump attached to it." + construction_type = /obj/item/pipe/directional/scrubber use_power = IDLE_POWER_USE idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.1 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.15 diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm index 9729c087145..210eb9b0d9e 100644 --- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm +++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm @@ -51,6 +51,10 @@ AddElement(/datum/element/elevation, pixel_shift = 8) register_context() +/obj/machinery/portable_atmospherics/on_construction(mob/user) + . = ..() + set_anchored(FALSE) + /obj/machinery/portable_atmospherics/on_deconstruction(disassembled) if(nob_crystal_inserted) new /obj/item/hypernoblium_crystal(src) diff --git a/code/modules/bitrunning/components/avatar_connection.dm b/code/modules/bitrunning/components/avatar_connection.dm index 4274893e998..6254427af39 100644 --- a/code/modules/bitrunning/components/avatar_connection.dm +++ b/code/modules/bitrunning/components/avatar_connection.dm @@ -20,7 +20,7 @@ help_text, ) - if(!isliving(parent) || !isliving(old_body) || !server.is_operational || !pod.is_operational) + if(!isliving(parent) || !isliving(old_body) || !old_mind || !server.is_operational || !pod.is_operational) return COMPONENT_INCOMPATIBLE var/mob/living/avatar = parent @@ -66,6 +66,9 @@ if(alias && avatar.real_name != alias) avatar.fully_replace_character_name(avatar.real_name, alias) + for(var/skill_type in old_mind.known_skills) + avatar.mind.set_experience(skill_type, old_mind.get_skill_exp(skill_type), silent = TRUE) + avatar.playsound_local(avatar, 'sound/magic/blink.ogg', 25, TRUE) avatar.set_static_vision(2 SECONDS) avatar.set_temp_blindness(1 SECONDS) // I'm in @@ -281,6 +284,10 @@ if(isnull(old_mind) || isnull(old_body)) return + for(var/skill_type in avatar.mind.known_skills) + old_mind.set_experience(skill_type, avatar.mind.get_skill_exp(skill_type), silent = TRUE) + avatar.mind.set_experience(skill_type, 0, silent = TRUE) + ghost.mind = old_mind if(old_body.stat != DEAD) old_mind.transfer_to(old_body, force_key_move = TRUE) diff --git a/code/modules/bitrunning/turfs.dm b/code/modules/bitrunning/turfs.dm index 93dce1789c4..6ceb31b0e31 100644 --- a/code/modules/bitrunning/turfs.dm +++ b/code/modules/bitrunning/turfs.dm @@ -1,4 +1,4 @@ -/turf/open/floor/bitrunning_transport +/turf/open/indestructible/bitrunning_transport name = "circuit floor" icon = 'icons/turf/floors.dmi' desc = "Looks complex. You can see the circuits running through the floor." diff --git a/code/modules/capture_the_flag/medieval_sim/medisim_classes.dm b/code/modules/capture_the_flag/medieval_sim/medisim_classes.dm index 3c4a55748c4..09ed5b40b1f 100644 --- a/code/modules/capture_the_flag/medieval_sim/medisim_classes.dm +++ b/code/modules/capture_the_flag/medieval_sim/medisim_classes.dm @@ -26,7 +26,7 @@ name = "Redfield Castle Archer" icon_state = "medisim_archer" - belt = /obj/item/storage/bag/quiver + belt = /obj/item/storage/bag/quiver/full suit = /obj/item/clothing/suit/armor/vest/cuirass l_hand = /obj/item/gun/ballistic/bow diff --git a/code/modules/cargo/packs/imports.dm b/code/modules/cargo/packs/imports.dm index a7853ad55ab..0ae09f0dc6e 100644 --- a/code/modules/cargo/packs/imports.dm +++ b/code/modules/cargo/packs/imports.dm @@ -313,11 +313,12 @@ risky espionage hallway operations. Enjoy our product!" contraband = TRUE cost = CARGO_CRATE_VALUE * 6 - contains = list(/obj/item/clothing/under/syndicate/floortilecamo = 3, - /obj/item/clothing/mask/floortilebalaclava = 3, - /obj/item/clothing/gloves/combat/floortile = 3, - /obj/item/clothing/shoes/jackboots/floortile = 3, - /obj/item/storage/backpack/floortile = 3 + contains = list( + /obj/item/clothing/under/syndicate/floortilecamo = 3, + /obj/item/clothing/mask/floortilebalaclava = 3, + /obj/item/clothing/gloves/combat/floortile = 3, + /obj/item/clothing/shoes/jackboots/floortile = 3, + /obj/item/storage/backpack/floortile = 3 ) crate_name = "floortile camouflauge crate" crate_type = /obj/structure/closet/crate/secure/weapon diff --git a/code/modules/cargo/packs/service.dm b/code/modules/cargo/packs/service.dm index 434450b4302..20323b52960 100644 --- a/code/modules/cargo/packs/service.dm +++ b/code/modules/cargo/packs/service.dm @@ -303,3 +303,17 @@ contains = list(/obj/item/wallframe/barsign/all_access) crate_name = "bar sign crate" discountable = SUPPLY_PACK_RARE_DISCOUNTABLE + +/datum/supply_pack/service/bowmaking + name = "Fletching and Bow-Making Starter Kit" + desc = "A fairly outdated copy of 'Whittle Me This: Fletching for the Modern Spacer', along with some useful materials. \ + For those looking to get into bow-making, or give their LARPing a little more edge, you can't go wrong. Also has \ + instructions for making violins." + cost = CARGO_CRATE_VALUE * 1.5 + contains = list( + /obj/item/book/granter/crafting_recipe/fletching = 1, + /obj/item/stack/sheet/mineral/wood = 10, + /obj/item/stack/sheet/cloth = 10, + ) + crate_name = "bowmaking starter kit crate" + crate_type = /obj/structure/closet/crate/wooden diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm index be71e79319f..f5915eaed37 100644 --- a/code/modules/cargo/supplypod.dm +++ b/code/modules/cargo/supplypod.dm @@ -426,18 +426,22 @@ insert(turf_underneath, holder) /obj/structure/closet/supplypod/insert(atom/to_insert, atom/movable/holder) - if(insertion_allowed(to_insert)) - if(isturf(to_insert)) - var/turf/turf_to_insert = to_insert - turfs_in_cargo += turf_to_insert.type - turf_to_insert.ScrapeAway() - else - var/atom/movable/movable_to_insert = to_insert - movable_to_insert.forceMove(holder) - return TRUE - else + if(!insertion_allowed(to_insert)) return FALSE + if(isturf(to_insert)) + var/turf/turf_to_insert = to_insert + turfs_in_cargo += turf_to_insert.type + turf_to_insert.ScrapeAway() + return TRUE + + var/atom/movable/movable_to_insert = to_insert + if (ismob(movable_to_insert)) + var/mob/mob_to_insert = movable_to_insert + if (!isnull(mob_to_insert.buckled)) + mob_to_insert.buckled.unbuckle_mob(mob_to_insert, force = TRUE) + movable_to_insert.forceMove(holder) + /obj/structure/closet/supplypod/insertion_allowed(atom/to_insert) if(to_insert.invisibility == INVISIBILITY_ABSTRACT) return FALSE diff --git a/code/modules/client/preferences/clothing.dm b/code/modules/client/preferences/clothing.dm index b54149db299..e57d87bf2c8 100644 --- a/code/modules/client/preferences/clothing.dm +++ b/code/modules/client/preferences/clothing.dm @@ -155,7 +155,7 @@ return /datum/sprite_accessory/undershirt/sports_bra::name return ..() -*/ // NOVA EDIT REMOVAL END +*/ // SKYRAT EDIT REMOVAL END /datum/preference/choiced/undershirt/icon_for(value) var/static/icon/body diff --git a/code/modules/clothing/head/hat.dm b/code/modules/clothing/head/hat.dm index d9258b8c7dd..7b7329088c8 100644 --- a/code/modules/clothing/head/hat.dm +++ b/code/modules/clothing/head/hat.dm @@ -210,6 +210,14 @@ name = "rice hat" desc = "Welcome to the rice fields, motherfucker." icon_state = "rice_hat" + base_icon_state = "rice_hat" + var/reversed = FALSE + +/obj/item/clothing/head/costume/rice_hat/click_alt(mob/user) + reversed = !reversed + worn_icon_state = "[base_icon_state][reversed ? "_kim" : ""]" + to_chat(user, span_notice("You [reversed ? "lower" : "raise"] the hat.")) + update_appearance() /obj/item/clothing/head/costume/lizard name = "lizardskin cloche hat" diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 68921334510..76c230ca504 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -568,3 +568,106 @@ fire = 50 acid = 50 wound = 30 + +/obj/item/clothing/head/helmet/durability/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE) + take_damage(1, BRUTE, 0, 0) + +/obj/item/clothing/head/helmet/durability/watermelon + name = "Watermelon Helmet" + desc = "A helmet cut out from a watermelon. Might take a few hits, but don't expect it whitstand much." + icon_state = "watermelon" + inhand_icon_state = "watermelon" + flags_inv = HIDEEARS + dog_fashion = /datum/dog_fashion/head/watermelon + armor_type = /datum/armor/helmet_watermelon + max_integrity = 15 + +/obj/item/clothing/head/helmet/durability/watermelon/fire_resist + resistance_flags = FIRE_PROOF + armor_type = /datum/armor/helmet_watermelon_fr + +/datum/armor/helmet_watermelon + melee = 15 + bullet = 10 + energy = 10 + bomb = 10 + fire = 0 + acid = 25 + wound = 5 + +/datum/armor/helmet_watermelon_fr + melee = 15 + bullet = 10 + energy = 10 + bomb = 10 + fire = 15 + acid = 30 + wound = 5 + +/obj/item/clothing/head/helmet/durability/holymelon + name = "Holymelon Helmet" + desc = "A helmet from a hollowed out holymelon. Might take a few hits, but don't expect it whitstand much." + icon_state = "holymelon" + inhand_icon_state = "holymelon" + flags_inv = HIDEEARS + dog_fashion = /datum/dog_fashion/head/holymelon + armor_type = /datum/armor/helmet_watermelon + max_integrity = 15 + var/decayed = FALSE + +/obj/item/clothing/head/helmet/durability/holymelon/fire_resist + resistance_flags = FIRE_PROOF + armor_type = /datum/armor/helmet_watermelon_fr + +/obj/item/clothing/head/helmet/durability/holymelon/Initialize(mapload) + . = ..() + if(decayed) + decay() + return + + AddComponent( + /datum/component/anti_magic, \ + antimagic_flags = MAGIC_RESISTANCE_HOLY, \ + inventory_flags = ITEM_SLOT_OCLOTHING, \ + charges = 1, \ + drain_antimagic = CALLBACK(src, PROC_REF(drain_antimagic)), \ + expiration = CALLBACK(src, PROC_REF(decay)) \ + ) + +/obj/item/clothing/head/helmet/durability/holymelon/proc/drain_antimagic(mob/user) + to_chat(user, span_warning("[src] looses a bit of its shimmer and glossiness...")) + +/obj/item/clothing/head/helmet/durability/holymelon/proc/decay() + take_damage(8, BRUTE, 0, 0) + +/obj/item/clothing/head/helmet/durability/barrelmelon + name = "Barrelmelon Helmet" + desc = "A helmet from hollowed out barrelmelon. As sturdy as if made from actual wood, though its rigid structure makes it break up quicker." + icon_state = "barrelmelon" + inhand_icon_state = "barrelmelon" + flags_inv = HIDEEARS + dog_fashion = /datum/dog_fashion/head/barrelmelon + armor_type = /datum/armor/helmet_barrelmelon + max_integrity = 10 + +/obj/item/clothing/head/helmet/durability/barrelmelon/fire_resist + resistance_flags = FIRE_PROOF + armor_type = /datum/armor/helmet_barrelmelon_fr + +/datum/armor/helmet_barrelmelon + melee = 25 + bullet = 20 + energy = 15 + bomb = 10 + fire = 0 + acid = 35 + wound = 10 + +/datum/armor/helmet_barrelmelon_fr + melee = 25 + bullet = 20 + energy = 15 + bomb = 10 + fire = 20 + acid = 40 + wound = 10 diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index 3003e9a76ee..cb0f9033960 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -169,6 +169,7 @@ clothing_flags = SNUG_FIT resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE dog_fashion = null + clothing_traits = list(TRAIT_SCARY_FISHERMAN) //Fish, carps, lobstrosities and frogs fear me. /obj/item/clothing/head/soft/fishing_hat/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 63a0dd515c3..380cd0cf3fb 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -118,33 +118,45 @@ . = ..() if(!up) . += visor_icon + if(smile) + var/mutable_appearance/smiley = mutable_appearance(icon, smile_state) + smiley.color = smile_color + . += smiley -/obj/item/clothing/head/helmet/space/plasmaman/attackby(obj/item/hitting_item, mob/living/user) - . = ..() - if(istype(hitting_item, /obj/item/toy/crayon)) - if(smile == FALSE) - var/obj/item/toy/crayon/CR = hitting_item - to_chat(user, span_notice("You start drawing a smiley face on the helmet's visor..")) - if(do_after(user, 2.5 SECONDS, target = src)) - smile = TRUE - smile_color = CR.paint_color - to_chat(user, "You draw a smiley on the helmet visor.") - update_appearance() - else - to_chat(user, span_warning("Seems like someone already drew something on this helmet's visor!")) - return - if(istype(hitting_item, /obj/item/clothing/head)) - var/obj/item/clothing/hitting_clothing = hitting_item - if(hitting_clothing.clothing_flags & STACKABLE_HELMET_EXEMPT) - to_chat(user, span_notice("You cannot place [hitting_clothing.name] on helmet!")) - return - if(attached_hat) - to_chat(user, span_notice("There's already something placed on helmet!")) - return - attached_hat = hitting_clothing - to_chat(user, span_notice("You placed [hitting_clothing.name] on helmet!")) - hitting_clothing.forceMove(src) +/obj/item/clothing/head/helmet/space/plasmaman/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/toy/crayon)) + if(smile) + to_chat(user, span_warning("Seems like someone already drew something on [src]'s visor!")) + return ITEM_INTERACT_BLOCKING + + var/obj/item/toy/crayon/crayon = tool + to_chat(user, span_notice("You start drawing a smiley face on [src]'s visor...")) + if(!do_after(user, 2.5 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + + smile = TRUE + smile_color = crayon.paint_color + to_chat(user, "You draw a smiley on [src] visor.") update_appearance() + return ITEM_INTERACT_SUCCESS + + if(!istype(tool, /obj/item/clothing/head)) + return NONE + + var/obj/item/clothing/hitting_clothing = tool + if(hitting_clothing.clothing_flags & STACKABLE_HELMET_EXEMPT) + to_chat(user, span_notice("You cannot place [hitting_clothing.name] on [src]!")) + return ITEM_INTERACT_BLOCKING + + if(attached_hat) + to_chat(user, span_notice("There's already something placed on [src]!")) + return ITEM_INTERACT_BLOCKING + + attached_hat = hitting_clothing + to_chat(user, span_notice("You placed [hitting_clothing.name] on [src]!")) + hitting_clothing.forceMove(src) + update_appearance() + return ITEM_INTERACT_SUCCESS ///By the by, helmets have the update_icon_updates_onmob element, so we don't have to call mob.update_worn_head() /obj/item/clothing/head/helmet/space/plasmaman/worn_overlays(mutable_appearance/standing, isinhands) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 9c34574840d..0d33f0e5f51 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -738,3 +738,113 @@ fire = 50 acid = 50 wound = 30 + +/obj/item/clothing/suit/armor/durability/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE) + take_damage(1, BRUTE, 0, 0) + +/obj/item/clothing/suit/armor/durability/watermelon + name = "watermelon" + desc = "An armour, made from watermelons. Propably won't take too many hits, but at least it looks serious... As serious as worn watermelon can be." + icon_state = "watermelon" + inhand_icon_state = null + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + armor_type = /datum/armor/watermelon + strip_delay = 60 + equip_delay_other = 40 + clothing_traits = list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED) + max_integrity = 15 + +/obj/item/clothing/suit/armor/durability/watermelon/fire_resist + resistance_flags = FIRE_PROOF + armor_type = /datum/armor/watermelon_fr + +/datum/armor/watermelon + melee = 15 + bullet = 10 + energy = 10 + bomb = 10 + fire = 0 + acid = 25 + wound = 5 + +/datum/armor/watermelon_fr + melee = 15 + bullet = 10 + energy = 10 + bomb = 10 + fire = 15 + acid = 30 + wound = 5 + +/obj/item/clothing/suit/armor/durability/holymelon + name = "holymelon" + desc = "An armour, made from holymelons. Inspires you to go on some sort of a crusade... Perhaps spreading spinach to children?" + icon_state = "holymelon" + inhand_icon_state = null + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + armor_type = /datum/armor/watermelon + strip_delay = 60 + equip_delay_other = 40 + clothing_traits = list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED) + max_integrity = 15 + var/decayed = FALSE + +/obj/item/clothing/suit/armor/durability/holymelon/fire_resist + resistance_flags = FIRE_PROOF + armor_type = /datum/armor/watermelon_fr + +/obj/item/clothing/suit/armor/durability/holymelon/Initialize(mapload) + . = ..() + if(decayed) + decay() + return + + AddComponent( + /datum/component/anti_magic, \ + antimagic_flags = MAGIC_RESISTANCE_HOLY, \ + inventory_flags = ITEM_SLOT_OCLOTHING, \ + charges = 1, \ + drain_antimagic = CALLBACK(src, PROC_REF(drain_antimagic)), \ + expiration = CALLBACK(src, PROC_REF(decay)) \ + ) + +/obj/item/clothing/suit/armor/durability/holymelon/proc/drain_antimagic(mob/user) + to_chat(user, span_warning("[src] looses a bit of its shimmer and glossiness...")) + +/obj/item/clothing/suit/armor/durability/holymelon/proc/decay() + take_damage(8, BRUTE, 0, 0) + + +/obj/item/clothing/suit/armor/durability/barrelmelon + name = "barrelmelon" + desc = "An armour, made from barrelmelons. Reeks of ale, inspiring to courageous deeds. Or, perhaps, a bar brawl." + icon_state = "barrelmelon" + inhand_icon_state = null + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + armor_type = /datum/armor/barrelmelon + strip_delay = 60 + equip_delay_other = 40 + clothing_traits = list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED) + max_integrity = 10 + +/obj/item/clothing/suit/armor/durability/barrelmelon/fire_resist + resistance_flags = FIRE_PROOF + armor_type = /datum/armor/barrelmelon_fr + +/datum/armor/barrelmelon + melee = 25 + bullet = 20 + energy = 15 + bomb = 10 + fire = 0 + acid = 35 + wound = 10 + +/datum/armor/barrelmelon_fr + melee = 25 + bullet = 20 + energy = 15 + bomb = 10 + fire = 20 + acid = 40 + wound = 10 diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index eb1ccb3c510..38bb028fa1e 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -49,6 +49,17 @@ resistance_flags = FLAMMABLE dog_fashion = /datum/dog_fashion/head/blue_wizard +/obj/item/clothing/head/wizard/chanterelle + name = "chanterelle hat" + desc = "An oversized chanterelle with hollow out space to fit a head in. Kinda looks like wizard's hat." + icon_state = "chanterelle" + inhand_icon_state = "chanterellehat" + armor_type = /datum/armor/none + resistance_flags = FLAMMABLE + +/obj/item/clothing/head/wizard/chanterelle/fr + resistance_flags = FIRE_PROOF + /obj/item/clothing/head/wizard/marisa name = "witch hat" desc = "Strange-looking hat-wear. Makes you want to cast fireballs." @@ -205,6 +216,48 @@ actions_types = list(/datum/action/item_action/stickmen) +/obj/item/clothing/suit/wizrobe/durathread + name = "durathread robe" + desc = "A rather dull durathread robe; not quite as protective as a proper piece of armour, but much stylish." + icon_state = "durathread-fake" + inhand_icon_state = null + armor_type = /datum/armor/robe_durathread + +/datum/armor/robe_durathread + melee = 15 + bullet = 5 + laser = 25 + energy = 30 + bomb = 10 + fire = 30 + acid = 40 + +/obj/item/clothing/suit/wizrobe/durathread/fire + name = "pyromancer robe" + desc = "A rather dull durathread robe; not quite as protective as an woven armour, but much stylish." + icon_state = "durathread-fire" + +/obj/item/clothing/suit/wizrobe/durathread/ice + name = "pyromancer robe" + desc = "A rather dull durathread robe; not quite as protective as an woven armour, but much stylish." + icon_state = "durathread-ice" + +/obj/item/clothing/suit/wizrobe/durathread/electric + name = "electromancer robe" + desc = "Doesn't actually conduit or isolate from electricity. Though it does have some durability on account of being made from durathread." + icon_state = "durathread-electric" + +/obj/item/clothing/suit/wizrobe/durathread/earth + name = "geomancer robe" + desc = "A rather dull durathread robe; not quite as protective as an woven armour, but much stylish." + icon_state = "durathread-earth" + +/obj/item/clothing/suit/wizrobe/durathread/necro + name = "necromancer robe" + desc = "A rather dull durathread robe; not quite as protective as an woven armour, but much stylish." + icon_state = "durathread-necro" + + /obj/item/clothing/suit/wizrobe/paper/ui_action_click(mob/user, action) stickmen() diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index feaa93424f9..4a0419f98f5 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -57,6 +57,11 @@ GLOBAL_LIST_INIT(specific_fish_icons, zebra_typecacheof(list( var/explosive_malus = FALSE /// If explosive_malus is true, this will be used to keep track of the turfs where an explosion happened for when we'll spawn the loot. var/list/exploded_turfs + /// Mindless mobs that can fish will never pull up items on this list + var/static/list/profound_fisher_blacklist = typecacheof(list( + /mob/living/basic/mining/lobstrosity, + /obj/structure/closet/crate/necropolis/tendril, + )) /datum/fish_source/New() if(!PERFORM_ALL_TESTS(focus_only/fish_sources_tables)) @@ -276,6 +281,9 @@ GLOBAL_LIST(fishing_property_cache) var/list/fish_list_properties = collect_fish_properties() + + if(HAS_TRAIT(fisherman, TRAIT_PROFOUND_FISHER) && !fisherman.client) + final_table -= profound_fisher_blacklist for(var/result in final_table) final_table[result] *= rod.hook?.get_hook_bonus_multiplicative(result) final_table[result] += rod.hook?.get_hook_bonus_additive(result)//Decide on order here so it can be multiplicative diff --git a/code/modules/food_and_drinks/machinery/smartfridge.dm b/code/modules/food_and_drinks/machinery/smartfridge.dm index 3519c55fc39..0768876014c 100644 --- a/code/modules/food_and_drinks/machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/machinery/smartfridge.dm @@ -32,6 +32,8 @@ var/welded_down = FALSE /// The sound of item retrieval var/vend_sound = 'sound/machines/machine_vend.ogg' + /// Whether the UI should be set to list view by default + var/default_list_view = FALSE /obj/machinery/smartfridge/Initialize(mapload) . = ..() @@ -369,7 +371,7 @@ var/atom/movable/atom = item if (!QDELETED(atom)) - var/key = "[atom.type]" + var/key = "[atom.type]-[atom.name]" if (listofitems[key]) listofitems[key]["amount"]++ else @@ -383,6 +385,7 @@ .["contents"] = sort_list(listofitems) .["name"] = name .["isdryer"] = FALSE + .["default_list_view"] = default_list_view /obj/machinery/smartfridge/Exited(atom/movable/gone, direction) // Update the UIs in case something inside is removed . = ..() @@ -400,6 +403,7 @@ if("Release") var/amount = text2num(params["amount"]) var/desired = 1 + var/dispensed_amount = 0 if(isAI(living_mob)) to_chat(living_mob, span_warning("[src] does not respect your authority!")) @@ -413,18 +417,18 @@ for(var/obj/item/dispensed_item in src) if(desired <= 0) break - if(istype(dispensed_item, text2path(params["path"]))) + if(params["path"] == "[dispensed_item.type]-[dispensed_item.name]") if(dispensed_item in component_parts) CRASH("Attempted removal of [dispensed_item] component_part from smartfridge via smartfridge interface.") //dispense the item if(!living_mob.put_in_hands(dispensed_item)) dispensed_item.forceMove(drop_location()) adjust_item_drop_location(dispensed_item) - if(vend_sound) - playsound(src, vend_sound, 50, TRUE, extrarange = -3) use_energy(active_power_usage) + dispensed_amount++ desired-- - + if(dispensed_amount && vend_sound) + playsound(src, vend_sound, 50, TRUE, extrarange = -3) if (visible_contents) update_appearance() return @@ -727,6 +731,7 @@ desc = "A refrigerated storage unit for medicine storage." base_build_path = /obj/machinery/smartfridge/chemistry contents_overlay_icon = "chem" + default_list_view = TRUE /obj/machinery/smartfridge/chemistry/accept_check(obj/item/weapon) // not an item or reagent container @@ -778,6 +783,7 @@ desc = "A refrigerated storage unit for volatile sample storage." base_build_path = /obj/machinery/smartfridge/chemistry/virology contents_overlay_icon = "viro" + default_list_view = TRUE /obj/machinery/smartfridge/chemistry/virology/preloaded initial_contents = list( diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index 9476ee33539..3aca50ae1be 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -27,6 +27,7 @@ name = "watermelon" desc = "It's full of watery goodness." icon_state = "watermelon" + inhand_icon_state = "watermelon" bite_consumption_mod = 2 w_class = WEIGHT_CLASS_NORMAL foodtypes = FRUIT @@ -39,6 +40,38 @@ /obj/item/food/grown/watermelon/make_dryable() return //No drying +/obj/item/food/grown/watermelon/attackby(obj/item/I, mob/user, params) + if(!istype(I, /obj/item/kitchen/spoon)) + return ..() + + var/melon_pulp_count = 1 + if(seed) + melon_pulp_count += round(seed.potency / 25) + + user.balloon_alert(user, "scooped out [melon_pulp_count] pulp(s)") + for(var/i in 1 to melon_pulp_count) + new /obj/item/food/watermelonmush(user.loc) + + /// The piece of armour melon turns into; either chetsplate or helmet + var/obj/item/clothing/melon_armour + /// Chance for the armour to be a chestplate instead of the helmet + var/melon_chestplate_chance = (max(0, seed.potency - 50) / 50) + if (prob(melon_chestplate_chance)) + if(seed.resistance_flags & FIRE_PROOF) + melon_armour = new /obj/item/clothing/suit/armor/durability/watermelon/fire_resist + else + melon_armour = new /obj/item/clothing/suit/armor/durability/watermelon + to_chat(user, span_notice("You hollow the melon into a helmet with [I].")) + else + if(seed.resistance_flags & FIRE_PROOF) + melon_armour = new /obj/item/clothing/head/helmet/durability/watermelon/fire_resist + else + melon_armour = new /obj/item/clothing/head/helmet/durability/watermelon + to_chat(user, span_notice("You hollow the melon into a chestplate with [I].")) + remove_item_from_storage(user) + qdel(src) + user.put_in_hands(melon_armour) + // Holymelon /obj/item/seeds/watermelon/holy name = "holymelon seed pack" @@ -66,6 +99,9 @@ wine_power = 70 //Water to wine, baby. wine_flavor = "divinity" +/obj/item/food/grown/holymelon/make_processable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/holymelonslice, 5, 20, screentip_verb = "Slice") + /obj/item/food/grown/holymelon/make_dryable() return //No drying @@ -73,6 +109,39 @@ . = ..() AddComponent(/datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_holyness))) + +/obj/item/food/grown/holymelon/attackby(obj/item/I, mob/user, params) + if(!istype(I, /obj/item/kitchen/spoon)) + return ..() + + var/holymelon_pulp_count = 1 + if(seed) + holymelon_pulp_count += round(seed.potency / 25) + + user.balloon_alert(user, "scooped out [holymelon_pulp_count] pulp(s)") + for(var/i in 1 to holymelon_pulp_count) + new /obj/item/food/holymelonmush(user.loc) + + /// The piece of armour holymelon turns into; either chetsplate or helmet + var/obj/item/clothing/holymelon_armour + /// Chance for the armour to be a chestplate instead of the helmet + var/holymelon_chestplate_chance = (max(0, seed.potency - 50) / 50) + if (prob(holymelon_chestplate_chance)) + if(seed.resistance_flags & FIRE_PROOF) + holymelon_armour = new /obj/item/clothing/suit/armor/durability/holymelon/fire_resist + else + holymelon_armour = new /obj/item/clothing/suit/armor/durability/holymelon + to_chat(user, span_notice("You hollow the holymelon into a helmet with [I].")) + else + if(seed.resistance_flags & FIRE_PROOF) + holymelon_armour = new /obj/item/clothing/head/helmet/durability/holymelon/fire_resist + else + holymelon_armour = new /obj/item/clothing/head/helmet/durability/holymelon + to_chat(user, span_notice("You hollow the holymelon into a chestplate with [I].")) + remove_item_from_storage(user) + qdel(src) + user.put_in_hands(holymelon_armour) + /* * Callback to be used with the edible component. * Checks whether or not the person eating the holymelon @@ -108,4 +177,41 @@ name = "barrelmelon" desc = "The nutriments within this melon have been compressed and fermented into rich alcohol." icon_state = "barrelmelon" + inhand_icon_state = "barrelmelon" distill_reagent = /datum/reagent/medicine/antihol //You can call it a integer overflow. + +/obj/item/food/grown/barrelmelon/make_processable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/barrelmelonslice, 5, 20, screentip_verb = "Chop") + +/obj/item/food/grown/barrelmelon/attackby(obj/item/I, mob/user, params) + if(!istype(I, /obj/item/kitchen/spoon)) + return ..() + + var/barrelmelon_pulp_count = 1 + if(seed) + barrelmelon_pulp_count += round(seed.potency / 25) + + user.balloon_alert(user, "scooped out [barrelmelon_pulp_count] pulp(s)") + for(var/i in 1 to barrelmelon_pulp_count) + new /obj/item/food/barrelmelonmush(user.loc) + + /// The piece of armour barrelmelon turns into; either chetsplate or helmet + var/obj/item/clothing/barrelmelon_armour + /// Chance for the armour to be a chestplate instead of the helmet + var/barrelmelon_chestplate_chance = (max(0, seed.potency - 50) / 50) + if (prob(barrelmelon_chestplate_chance)) + if(seed.resistance_flags & FIRE_PROOF) + barrelmelon_armour = new /obj/item/clothing/suit/armor/durability/barrelmelon/fire_resist + else + barrelmelon_armour = new /obj/item/clothing/suit/armor/durability/barrelmelon + to_chat(user, span_notice("You hollow the barrelmelon into a helmet with [I].")) + else + if(seed.resistance_flags & FIRE_PROOF) + barrelmelon_armour = new /obj/item/clothing/head/helmet/durability/barrelmelon/fire_resist + else + barrelmelon_armour = new /obj/item/clothing/head/helmet/durability/barrelmelon + to_chat(user, span_notice("You hollow the barrelmelon into a chestplate with [I].")) + + remove_item_from_storage(user) + qdel(src) + user.put_in_hands(barrelmelon_armour) diff --git a/code/modules/hydroponics/grown/mushrooms.dm b/code/modules/hydroponics/grown/mushrooms.dm index ac2b44547e6..9d1d802916b 100644 --- a/code/modules/hydroponics/grown/mushrooms.dm +++ b/code/modules/hydroponics/grown/mushrooms.dm @@ -197,6 +197,20 @@ desc = "Cantharellus Cibarius: These jolly yellow little shrooms sure look tasty!" icon_state = "chanterelle" +/obj/item/food/grown/mushroom/chanterelle/attackby(obj/item/I, mob/user, params) + if(!istype(I, /obj/item/kitchen/spoon)) + return ..() + if(seed.potency < 95) + return ..() + + to_chat(user, span_notice("You hollow up the chanterelle with [I].")) + remove_item_from_storage(user) + qdel(src) + if(seed.resistance_flags & FIRE_PROOF) + user.put_in_hands(new /obj/item/clothing/head/wizard/chanterelle/fr()) + else + user.put_in_hands(new /obj/item/clothing/head/wizard/chanterelle()) + //Jupiter Cup /obj/item/seeds/chanter/jupitercup name = "jupiter cup mycelium pack" diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm index 983771d8aaa..4393d76a5fa 100644 --- a/code/modules/hydroponics/grown/root.dm +++ b/code/modules/hydroponics/grown/root.dm @@ -12,7 +12,7 @@ instability = 15 growthstages = 3 growing_icon = 'icons/obj/service/hydroponics/growing_vegetables.dmi' - mutatelist = list(/obj/item/seeds/carrot/parsnip) + mutatelist = list(/obj/item/seeds/carrot/parsnip, /obj/item/seeds/carrot/cahnroot) reagents_add = list(/datum/reagent/medicine/oculine = 0.1, /datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.05) /obj/item/food/grown/carrot @@ -26,21 +26,23 @@ wine_power = 30 /obj/item/food/grown/carrot/attackby(obj/item/I, mob/user, params) - if(I.get_sharpness()) - var/carrot_blade - var/carrot_sword_chance = (max(0, seed.potency - 50) / 50) - if (prob(carrot_sword_chance)) - carrot_blade = new /obj/item/claymore/carrot - to_chat(user, span_notice("You sharpen the carrot into a sword with [I].")) - else - carrot_blade = new /obj/item/knife/shiv/carrot - to_chat(user, span_notice("You sharpen the carrot into a shiv with [I].")) - remove_item_from_storage(user) - qdel(src) - user.put_in_hands(carrot_blade) - else + if(!I.get_sharpness()) return ..() + /// The blade carrot will turn into once sharpened + var/obj/item/carrot_blade + /// Chance for it to become a sword rather than a shiv + var/carrot_sword_chance = (max(0, seed.potency - 50) / 50) + if (prob(carrot_sword_chance)) + carrot_blade = new /obj/item/claymore/carrot + to_chat(user, span_notice("You sharpen the carrot into a sword with [I].")) + else + carrot_blade = new /obj/item/knife/shiv/carrot + to_chat(user, span_notice("You sharpen the carrot into a shiv with [I].")) + remove_item_from_storage(user) + qdel(src) + user.put_in_hands(carrot_blade) + // Parsnip /obj/item/seeds/carrot/parsnip name = "parsnip seed pack" @@ -62,8 +64,6 @@ juice_typepath = /datum/reagent/consumable/parsnipjuice wine_power = 35 -<<<<<<< HEAD -======= /obj/item/food/grown/parsnip/attackby(obj/item/I, mob/user, params) if(!I.get_sharpness()) return ..() @@ -127,7 +127,6 @@ remove_item_from_storage(user) qdel(src) user.put_in_hands(root_blade) ->>>>>>> f5c010368599 (Renamed "Pack of *** seeds" to "*** seed pack" (#85370)) // White-Beet /obj/item/seeds/whitebeet diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 101239d8d31..3b151042042 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -617,6 +617,11 @@ /obj/item/grown/get_plant_seed() return seed + + + + + /obj/item/seeds/proc/perform_reagent_pollination(obj/item/seeds/donor) var/list/datum/plant_gene/reagent/valid_reagents = list() for(var/datum/plant_gene/reagent/donor_reagent in donor.genes) @@ -638,5 +643,11 @@ if(length(valid_reagents)) // pick a valid reagent that our receptor seed don't have and add the gene to it var/datum/plant_gene/reagent/selected_reagent = pick(valid_reagents) - genes += selected_reagent + + genes += selected_reagent.Copy() reagents_from_genes() + + + + + diff --git a/code/modules/jobs/job_types/assistant/gimmick_assistants.dm b/code/modules/jobs/job_types/assistant/gimmick_assistants.dm index 17bd554f39b..16c0e037844 100644 --- a/code/modules/jobs/job_types/assistant/gimmick_assistants.dm +++ b/code/modules/jobs/job_types/assistant/gimmick_assistants.dm @@ -167,6 +167,7 @@ belt = /obj/item/storage/belt/utility/full head = /obj/item/clothing/head/utility/hardhat uniform = /obj/item/clothing/under/color/yellow + l_pocket = /obj/item/modular_computer/pda/assistant outfit_weight = 6 diff --git a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm index df658d71ddd..7cc067ed0a2 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm @@ -564,7 +564,7 @@ /obj/item/nullrod/bostaff name = "monk's staff" desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts, it is now used to harass the clown." - force = 15 + force = 14 block_chance = 40 block_sound = 'sound/weapons/genhit.ogg' slot_flags = ITEM_SLOT_BACK @@ -578,7 +578,20 @@ worn_icon_state = "bostaff0" lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' - menu_description = "A staff which provides a medium-low chance of blocking incoming melee attacks and deals a little less damage. Can be worn on the back." + menu_description = "A staff which provides a medium-low chance of blocking incoming melee attacks and deals less damage, unless dual-wielded. Can be worn on the back." + +/obj/item/nullrod/bostaff/Initialize(mapload) + . = ..() + AddComponent(/datum/component/two_handed, \ + force_unwielded = 14, \ + force_wielded = 18, \ + icon_wielded = "[base_icon_state]1", \ + ) + +/obj/item/nullrod/bostaff/update_icon_state() + icon_state = "[base_icon_state]0" + return ..() + // Arrhythmic Knife - Lets your walk without rhythm by varying your walk speed. Can't be put away. diff --git a/code/modules/loadout/categories/pocket.dm b/code/modules/loadout/categories/pocket.dm index 8206192bb81..2689c2b726e 100644 --- a/code/modules/loadout/categories/pocket.dm +++ b/code/modules/loadout/categories/pocket.dm @@ -106,10 +106,6 @@ name = "Plush (Moth)" item_path = /obj/item/toy/plush/moth -/datum/loadout_item/pocket_items/plush/narsie - name = "Plush (Nar'sie)" - item_path = /obj/item/toy/plush/narplush - /datum/loadout_item/pocket_items/plush/nukie name = "Plush (Nukie)" item_path = /obj/item/toy/plush/nukeplushie @@ -122,10 +118,6 @@ name = "Plush (Plasmaman)" item_path = /obj/item/toy/plush/plasmamanplushie -/datum/loadout_item/pocket_items/plush/ratvar - name = "Plush (Ratvar)" - item_path = /obj/item/toy/plush/ratplush - /datum/loadout_item/pocket_items/plush/rouny name = "Plush (Rouny)" item_path = /obj/item/toy/plush/rouny diff --git a/code/modules/lootpanel/contents.dm b/code/modules/lootpanel/contents.dm index 44f4acd47f2..2fcd4201d8a 100644 --- a/code/modules/lootpanel/contents.dm +++ b/code/modules/lootpanel/contents.dm @@ -21,6 +21,8 @@ if(!istype(thing)) stack_trace("Non-atom in the contents of [source_turf]!") continue + if(QDELETED(thing)) + continue if(thing.mouse_opacity == MOUSE_OPACITY_TRANSPARENT) continue if(thing.IsObscured()) diff --git a/code/modules/lootpanel/search_object.dm b/code/modules/lootpanel/search_object.dm index 149be76e710..2cb0bdf85db 100644 --- a/code/modules/lootpanel/search_object.dm +++ b/code/modules/lootpanel/search_object.dm @@ -62,6 +62,7 @@ /datum/search_object/Destroy(force) item = null + icon = null return ..() @@ -75,6 +76,9 @@ /datum/search_object/proc/on_item_moved(atom/source) SIGNAL_HANDLER + if(QDELETED(src)) + return + qdel(src) @@ -82,4 +86,4 @@ /datum/search_object/proc/on_turf_change(turf/source, path, list/new_baseturfs, flags, list/post_change_callbacks) SIGNAL_HANDLER - post_change_callbacks += CALLBACK(src, GLOBAL_PROC_REF(qdel), src) + post_change_callbacks += CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src) diff --git a/code/modules/mob/living/basic/bots/_bots.dm b/code/modules/mob/living/basic/bots/_bots.dm index 9f2b915944b..04b3a7864d2 100644 --- a/code/modules/mob/living/basic/bots/_bots.dm +++ b/code/modules/mob/living/basic/bots/_bots.dm @@ -517,7 +517,6 @@ GLOBAL_LIST_INIT(command_strings, list( if(istype(item_to_drop, /obj/item/stock_parts/power_store/cell)) var/obj/item/stock_parts/power_store/cell/dropped_cell = item_to_drop dropped_cell.charge = 0 - dropped_cell.update_appearance() return if(istype(item_to_drop, /obj/item/storage)) diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm index 031ec3d4525..7dcbc4ae325 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm @@ -41,8 +41,6 @@ /mob/living/basic/mining/lobstrosity/Initialize(mapload) . = ..() - var/static/list/food_types = list(/obj/item/fish/lavaloop) - ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(food_types)) AddComponent(/datum/component/profound_fisher) AddElement(/datum/element/mob_grabber) AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm index 75b64d05120..32ec66a62cc 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm @@ -14,6 +14,7 @@ BB_LOBSTROSITY_FINGER_LUST = 0, BB_LOBSTROSITY_NAIVE_HUNTER = FALSE, BB_BASIC_MOB_FLEE_DISTANCE = 8, + BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN, BB_OWNER_SELF_HARM_RESPONSES = SHRIMP_HARM_RESPONSES, ) ai_traits = PAUSE_DURING_DO_AFTER @@ -24,7 +25,7 @@ /datum/ai_planning_subtree/random_speech/insect, /datum/ai_planning_subtree/hoard_fingers, /datum/ai_planning_subtree/pet_planning, - /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/find_target_prioritize_traits, /datum/ai_planning_subtree/targeted_mob_ability/lobster, /datum/ai_planning_subtree/flee_target/lobster, /datum/ai_planning_subtree/attack_obstacle_in_path, @@ -33,6 +34,14 @@ /datum/ai_planning_subtree/find_and_hunt_target/lobster_fishing, /datum/ai_planning_subtree/find_fingers, ) + +/datum/ai_controller/basic_controller/lobstrosity/TryPossessPawn(atom/new_pawn) + . = ..() + if(. & AI_CONTROLLER_INCOMPATIBLE) + return + var/static/list/food_types = typecacheof(list(/obj/item/fish/lavaloop)) + set_blackboard_key(BB_BASIC_FOODS, food_types) + ///Ensure that juveline lobstrosities witll charge at things they can reach. /datum/ai_controller/basic_controller/lobstrosity/juvenile blackboard = list( @@ -43,13 +52,14 @@ BB_LOBSTROSITY_FINGER_LUST = 0, BB_LOBSTROSITY_NAIVE_HUNTER = TRUE, BB_BASIC_MOB_FLEE_DISTANCE = 4, + BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN, BB_OWNER_SELF_HARM_RESPONSES = SHRIMP_HARM_RESPONSES, ) planning_subtrees = list( /datum/ai_planning_subtree/random_speech/insect, /datum/ai_planning_subtree/hoard_fingers, /datum/ai_planning_subtree/pet_planning, - /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/find_target_prioritize_traits, /datum/ai_planning_subtree/targeted_mob_ability/lobster, /datum/ai_planning_subtree/flee_target/lobster, /datum/ai_planning_subtree/attack_obstacle_in_path, @@ -100,14 +110,17 @@ melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/lobster /datum/ai_planning_subtree/basic_melee_attack_subtree/lobster/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) - if(!isliving(controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET])) + var/atom/movable/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + if(!isliving(target)) return ..() if (!controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) return if (!isnull(controller.blackboard[BB_LOBSTROSITY_TARGET_LIMB])) return + if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN)) + return //juvenile lobstrosities fear me. var/mob/living/living_pawn = controller.pawn - if (DOING_INTERACTION_WITH_TARGET(living_pawn, controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET])) + if (DOING_INTERACTION_WITH_TARGET(living_pawn, target)) return return ..() @@ -118,9 +131,14 @@ if (isnull(target) || !istype(target)) return ..() var/is_vulnerable = FALSE - if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && target.body_position == LYING_DOWN) - is_vulnerable = TRUE - else + if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER]) + if(HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN)) + //Trigger lobstrosity PTSD. Don't clear the target so we can run away. + controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, FALSE) + return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED + if(target.body_position == LYING_DOWN) + is_vulnerable = TRUE + if(!is_vulnerable) for (var/trait in controller.blackboard[BB_LOBSTROSITY_EXPLOIT_TRAITS]) if (!HAS_TRAIT(target, trait)) continue @@ -137,9 +155,12 @@ flee_behaviour = /datum/ai_behavior/run_away_from_target/lobster /datum/ai_planning_subtree/flee_target/lobster/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/atom/movable/target = controller.blackboard[target_key] + if(!QDELETED(target) && controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN)) + return ..() var/datum/action/cooldown/using_action = controller.blackboard[BB_TARGETED_ACTION] if (using_action?.IsAvailable()) - return + return FALSE return ..() /datum/ai_behavior/run_away_from_target/lobster @@ -147,19 +168,23 @@ /datum/ai_behavior/run_away_from_target/lobster/perform(seconds_per_tick, datum/ai_controller/controller, target_key, hiding_location_key) var/atom/target = controller.blackboard[target_key] - if(isnull(target)) + if(QDELETED(target)) return ..() - if(isliving(target)) - var/mob/living/living_target = target - if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && living_target.body_position == LYING_DOWN) + var/is_naive = controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] + var/is_scary = HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN) + + if(!is_naive || !is_scary) //the lobstrosity isn't naive/young and the target isn't a scary fisherman. + if(isliving(target)) + var/mob/living/living_target = target + if(is_naive && living_target.body_position == LYING_DOWN) + controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE) + return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED + for (var/trait in controller.blackboard[BB_LOBSTROSITY_EXPLOIT_TRAITS]) + if (!HAS_TRAIT(target, trait)) + continue controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE) return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED - for (var/trait in controller.blackboard[BB_LOBSTROSITY_EXPLOIT_TRAITS]) - if (!HAS_TRAIT(target, trait)) - continue - controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE) - return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED var/mob/living/us = controller.pawn if (us.pulling == target) @@ -174,7 +199,9 @@ /datum/ai_planning_subtree/targeted_mob_ability/lobster/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) var/atom/target = controller.blackboard[target_key] if(QDELETED(target) || in_range(controller.pawn, target)) - return FALSE + return + if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN)) + return return ..() diff --git a/code/modules/mob/living/basic/lavaland/node_drone/node_drone.dm b/code/modules/mob/living/basic/lavaland/node_drone/node_drone.dm index b149c6d0972..87687c56999 100644 --- a/code/modules/mob/living/basic/lavaland/node_drone/node_drone.dm +++ b/code/modules/mob/living/basic/lavaland/node_drone/node_drone.dm @@ -74,6 +74,31 @@ if(flying_state == FLY_IN_STATE || flying_state == FLY_OUT_STATE) icon_state = "mining_node_flying" +/mob/living/basic/node_drone/update_overlays() + . = ..() + if(attached_vent) + var/time_remaining = COOLDOWN_TIMELEFT(attached_vent, wave_cooldown) + var/wave_timers + switch(attached_vent?.boulder_size) + if(BOULDER_SIZE_SMALL) + wave_timers = WAVE_DURATION_SMALL + if(BOULDER_SIZE_MEDIUM) + wave_timers = WAVE_DURATION_MEDIUM + if(BOULDER_SIZE_LARGE) + wave_timers = WAVE_DURATION_LARGE + var/remaining_fraction = (time_remaining / wave_timers) + if(remaining_fraction <= 0.3) + . += "node_progress_4" + return + if(remaining_fraction <= 0.55) + . += "node_progress_3" + return + if(remaining_fraction <= 0.80) + . += "node_progress_2" + return + . += "node_progress_1" + return + /mob/living/basic/node_drone/proc/arrive(obj/structure/ore_vent/parent_vent) attached_vent = parent_vent maxHealth = 300 + ((attached_vent.boulder_size/BOULDER_SIZE_SMALL) * 100) diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm index 71017bd2207..810c4560386 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm @@ -55,6 +55,12 @@ /// This subtype only exists because if you queue multiple of the same action with different arguments it deletes their stored arguments /datum/ai_behavior/find_potential_targets/nearest/magicarp +/datum/ai_behavior/find_potential_targets/nearest/magicarp/pick_final_target(datum/ai_controller/controller, list/enemies_list) + for(var/atom/atom as anything in enemies_list) + if(HAS_TRAIT(atom, TRAIT_SCARY_FISHERMAN)) + enemies_list -= atom + return ..() + /// Then use it on that target /datum/ai_planning_subtree/targeted_mob_ability/magicarp ability_key = BB_MAGICARP_SPELL diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm index 84b96ae3ce4..da672832a0a 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm @@ -31,6 +31,9 @@ finish_planning = TRUE /datum/ai_planning_subtree/make_carp_rift/panic_teleport/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/atom/movable/fleeing_from = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + if(!QDELETED(fleeing_from) && controller.blackboard[BB_CARPS_FEAR_FISHERMAN] && HAS_TRAIT(fleeing_from, TRAIT_SCARY_FISHERMAN)) + return ..() if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) return return ..() @@ -42,6 +45,14 @@ /datum/ai_planning_subtree/make_carp_rift/aggressive_teleport rift_behaviour = /datum/ai_behavior/make_carp_rift/towards/aggressive +/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/atom/movable/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + if(QDELETED(target) || !controller.blackboard[BB_CARPS_FEAR_FISHERMAN] || !HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN)) + return ..() + if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) + return + return ..() + /** * # Make carp rift * Make a carp rift somewhere @@ -174,7 +185,7 @@ /datum/ai_planning_subtree/shortcut_to_target_through_carp_rift/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] - if (QDELETED(target)) + if (QDELETED(target) || (controller.blackboard[BB_CARPS_FEAR_FISHERMAN] && HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN))) return var/distance_to_target = get_dist(controller.pawn, target) diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm index 0befb20987c..4491ef11491 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm @@ -12,24 +12,48 @@ BB_BASIC_MOB_STOP_FLEEING = TRUE, BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/allow_items, BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, + BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN, + BB_CARPS_FEAR_FISHERMAN = TRUE, ) ai_movement = /datum/ai_movement/basic_avoidance idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/pet_planning, + /datum/ai_planning_subtree/simple_find_nearest_target_to_flee, + /datum/ai_planning_subtree/find_target_prioritize_traits, + /datum/ai_planning_subtree/make_carp_rift/panic_teleport, + /datum/ai_planning_subtree/flee_target/from_fisherman, + /datum/ai_planning_subtree/find_food, + /datum/ai_planning_subtree/attack_obstacle_in_path/carp, + /datum/ai_planning_subtree/shortcut_to_target_through_carp_rift, + /datum/ai_planning_subtree/make_carp_rift/aggressive_teleport, + /datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman, + /datum/ai_planning_subtree/carp_migration, + ) + +///Megacarps. The only difference is that they don't flee from scary fishermen and prioritize them. +/datum/ai_controller/basic_controller/carp/mega + blackboard = list( + BB_BASIC_MOB_STOP_FLEEING = TRUE, + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/allow_items, + BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, + BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN, + BB_CARPS_FEAR_FISHERMAN = FALSE, + ) planning_subtrees = list( /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/simple_find_nearest_target_to_flee, /datum/ai_planning_subtree/make_carp_rift/panic_teleport, /datum/ai_planning_subtree/flee_target, /datum/ai_planning_subtree/find_food, - /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/find_target_prioritize_traits, /datum/ai_planning_subtree/attack_obstacle_in_path/carp, /datum/ai_planning_subtree/shortcut_to_target_through_carp_rift, /datum/ai_planning_subtree/make_carp_rift/aggressive_teleport, /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/carp_migration, ) - /** * Carp which bites back, but doesn't look for targets. * 'Not hunting targets' includes food (and can rings), because they have been well trained. @@ -39,18 +63,20 @@ BB_BASIC_MOB_STOP_FLEEING = TRUE, BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, + BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN, + BB_CARPS_FEAR_FISHERMAN = TRUE, ) ai_traits = STOP_MOVING_WHEN_PULLED planning_subtrees = list( /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee, /datum/ai_planning_subtree/make_carp_rift/panic_teleport, - /datum/ai_planning_subtree/flee_target, + /datum/ai_planning_subtree/flee_target/from_fisherman, /datum/ai_planning_subtree/target_retaliate, /datum/ai_planning_subtree/attack_obstacle_in_path/carp, /datum/ai_planning_subtree/shortcut_to_target_through_carp_rift, /datum/ai_planning_subtree/make_carp_rift/aggressive_teleport, - /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman, ) /** @@ -61,12 +87,12 @@ planning_subtrees = list( /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/simple_find_nearest_target_to_flee, + /datum/ai_planning_subtree/find_target_prioritize_traits, /datum/ai_planning_subtree/make_carp_rift/panic_teleport, - /datum/ai_planning_subtree/flee_target, + /datum/ai_planning_subtree/flee_target/from_fisherman, /datum/ai_planning_subtree/find_food, /datum/ai_planning_subtree/find_nearest_magicarp_spell_target, /datum/ai_planning_subtree/targeted_mob_ability/magicarp, - /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path/carp, /datum/ai_planning_subtree/shortcut_to_target_through_carp_rift, /datum/ai_planning_subtree/make_carp_rift/aggressive_teleport, @@ -83,17 +109,19 @@ BB_BASIC_MOB_STOP_FLEEING = TRUE, BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, + BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN, + BB_CARPS_FEAR_FISHERMAN = TRUE, ) ai_traits = STOP_MOVING_WHEN_PULLED planning_subtrees = list( /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/simple_find_nearest_target_to_flee, /datum/ai_planning_subtree/make_carp_rift/panic_teleport, - /datum/ai_planning_subtree/flee_target, + /datum/ai_planning_subtree/flee_target/from_fisherman, /datum/ai_planning_subtree/find_food, /datum/ai_planning_subtree/attack_obstacle_in_path/carp, /datum/ai_planning_subtree/shortcut_to_target_through_carp_rift, /datum/ai_planning_subtree/make_carp_rift/aggressive_teleport, - /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman, /datum/ai_planning_subtree/carp_migration, ) diff --git a/code/modules/mob/living/basic/space_fauna/carp/megacarp.dm b/code/modules/mob/living/basic/space_fauna/carp/megacarp.dm index deadeaaa540..d82120a37e0 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/megacarp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/megacarp.dm @@ -24,6 +24,7 @@ ridable_data = /datum/component/riding/creature/megacarp greyscale_config = /datum/greyscale_config/carp_mega butcher_results = list(/obj/item/food/fishmeat/carp = 2, /obj/item/stack/sheet/animalhide/carp = 3) + ai_controller = /datum/ai_controller/basic_controller/carp/mega /mob/living/basic/carp/mega/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/basic/vermin/frog.dm b/code/modules/mob/living/basic/vermin/frog.dm index 90a1cc3efaa..cce415b960f 100644 --- a/code/modules/mob/living/basic/vermin/frog.dm +++ b/code/modules/mob/living/basic/vermin/frog.dm @@ -109,6 +109,7 @@ /datum/ai_controller/basic_controller/frog blackboard = list( + BB_BASIC_MOB_STOP_FLEEING = TRUE, //We only flee from scary fishermen. BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_OWNER_SELF_HARM_RESPONSES = list( @@ -122,7 +123,8 @@ planning_subtrees = list( /datum/ai_planning_subtree/target_retaliate, /datum/ai_planning_subtree/random_speech/frog, - /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman, + /datum/ai_planning_subtree/flee_target/from_fisherman, /datum/ai_planning_subtree/go_for_swim, ) @@ -131,11 +133,18 @@ /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/random_speech/frog, /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman, + /datum/ai_planning_subtree/flee_target/from_fisherman, ) /datum/ai_controller/basic_controller/frog/suicide_frog + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, + BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN, //No fear, only hatred. It has nothing to lose + ) + planning_subtrees = list( - /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/find_target_prioritize_traits, /datum/ai_planning_subtree/basic_melee_attack_subtree, ) diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index 3717cfcb89a..630171ba2c1 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -33,7 +33,6 @@ In all, this is a lot like the monkey code. /N to_chat(user, span_danger("You bite [src]!")) adjustBruteLoss(1) log_combat(user, src, "attacked") - updatehealth() else to_chat(user, span_warning("[name] is too injured for that.")) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index ab777d3ed9c..879ac86afc5 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -1260,10 +1260,9 @@ GLOBAL_LIST_EMPTY(features_by_species) //SKYRAT EDIT END // Get the insulation value based on the area's temp var/thermal_protection = humi.get_insulation_protection(area_temp) - var/original_bodytemp = humi.bodytemperature // Changes to the skin temperature based on the area - var/area_skin_diff = area_temp - original_bodytemp + var/area_skin_diff = area_temp - humi.bodytemperature if(!humi.on_fire || area_skin_diff > 0) // change rate of 0.05 as area temp has large impact on the surface var/area_skin_change = get_temp_change_amount(area_skin_diff, 0.05 * seconds_per_tick) @@ -1283,7 +1282,7 @@ GLOBAL_LIST_EMPTY(features_by_species) // Core to skin temp transfer, when not on fire if(!humi.on_fire) // Get the changes to the skin from the core temp - var/core_skin_diff = humi.coretemperature - original_bodytemp + var/core_skin_diff = humi.coretemperature - humi.bodytemperature // change rate of 0.045 to reflect temp back to the skin at the slight higher rate then core to skin var/core_skin_change = (1 + thermal_protection) * get_temp_change_amount(core_skin_diff, 0.045 * seconds_per_tick) diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index e59a6328aa7..5b43bf980c4 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -11,6 +11,8 @@ obscured |= ITEM_SLOT_NECK if(hidden_slots & HIDEMASK) obscured |= ITEM_SLOT_MASK + if(hidden_slots & HIDEBELT) + obscured |= ITEM_SLOT_BELT if(hidden_slots & HIDEEYES) obscured |= ITEM_SLOT_EYES if(hidden_slots & HIDEEARS) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 66deda41155..a502ab1df2e 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -174,13 +174,8 @@ if(now_pushing) return TRUE - var/they_can_move = TRUE - var/their_combat_mode = FALSE - if(isliving(M)) var/mob/living/L = M - their_combat_mode = L.combat_mode - they_can_move = L.mobility_flags & MOBILITY_MOVE //Also spread diseases for(var/thing in diseases) var/datum/disease/D = thing @@ -226,22 +221,7 @@ return TRUE if(!M.buckled && !M.has_buckled_mobs()) - var/mob_swap = FALSE - var/too_strong = (M.move_resist > move_force) //can't swap with immovable objects unless they help us - if(!they_can_move) //we have to physically move them - if(!too_strong) - mob_swap = TRUE - else - //You can swap with the person you are dragging on grab intent, and restrained people in most cases - if(M.pulledby == src && !too_strong) - mob_swap = TRUE - else if( - !(HAS_TRAIT(M, TRAIT_NOMOBSWAP) || HAS_TRAIT(src, TRAIT_NOMOBSWAP)) &&\ - ((HAS_TRAIT(M, TRAIT_RESTRAINED) && !too_strong) || !their_combat_mode) &&\ - (HAS_TRAIT(src, TRAIT_RESTRAINED) || !combat_mode) - ) - mob_swap = TRUE - if(mob_swap) + if(can_mobswap_with(M)) //switch our position with M if(loc && !loc.Adjacent(M.loc)) return TRUE @@ -294,6 +274,46 @@ if(prob(I.block_chance*2)) return +/mob/living/proc/can_mobswap_with(mob/other) + if (HAS_TRAIT(other, TRAIT_NOMOBSWAP) || HAS_TRAIT(src, TRAIT_NOMOBSWAP)) + return FALSE + + var/they_can_move = TRUE + var/their_combat_mode = FALSE + + if(isliving(other)) + var/mob/living/other_living = other + their_combat_mode = other_living.combat_mode + they_can_move = other_living.mobility_flags & MOBILITY_MOVE + + var/too_strong = other.move_resist > move_force + + // They cannot move, see if we can push through them + if (!they_can_move) + return !too_strong + + // We are pulling them and can move through + if (other.pulledby == src && !too_strong) + return TRUE + + // If we're in combat mode and not restrained we don't try to pass through people + if (combat_mode && !HAS_TRAIT(src, TRAIT_RESTRAINED)) + return FALSE + + // Nor can we pass through non-restrained people in combat mode (or if they're restrained but still too strong for us) + if (their_combat_mode && (!HAS_TRAIT(other, TRAIT_RESTRAINED) || too_strong)) + return FALSE + + if (isnull(other.client) || isnull(client)) + return TRUE + + // If both of us are trying to move in the same direction, let the fastest one through first + if (client.intended_direction == other.client.intended_direction) + return cached_multiplicative_slowdown < other.cached_multiplicative_slowdown + + // Else, sure, let us pass + return TRUE + /mob/living/get_photo_description(obj/item/camera/camera) var/list/holding = list() var/len = length(held_items) diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm index 7dea684e569..0c5eb6ec164 100644 --- a/code/modules/mob/living/silicon/ai/ai_defense.dm +++ b/code/modules/mob/living/silicon/ai/ai_defense.dm @@ -14,7 +14,6 @@ /mob/living/silicon/ai/blob_act(obj/structure/blob/B) if (stat != DEAD) adjustBruteLoss(60) - updatehealth() return TRUE return FALSE diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index 3a8cec66efd..5c4384302b8 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -21,18 +21,30 @@ else logevent("FATAL -- SYSTEM HALT") modularInterface.shutdown_computer() + eye_flash_timer = addtimer(CALLBACK(src, PROC_REF(flash_headlamp)), 2 SECONDS, TIMER_STOPPABLE | TIMER_LOOP) . = ..() locked = FALSE //unlock cover if(!QDELETED(builtInCamera) && builtInCamera.camera_enabled) builtInCamera.toggle_cam(src,0) + toggle_headlamp(TRUE) //So borg lights are disabled when killed. - drop_all_held_items() // particularly to ensure sight modes are cleared - update_icons() - unbuckle_all_mobs(TRUE) - SSblackbox.ReportDeath(src) + +/mob/living/silicon/robot/proc/flash_headlamp() + if(eye_lights) + eye_lights = null + regenerate_icons() + return + + eye_lights = new() + eye_lights.icon_state = "[model.special_light_key ? "[model.special_light_key]":"[model.cyborg_base_icon]"]_e_r" + eye_lights.color = COLOR_WHITE + SET_PLANE_EXPLICIT(eye_lights, ABOVE_GAME_PLANE, src) + eye_lights.icon = icon + regenerate_icons() + add_overlay(eye_lights) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 71c7aa9fc89..dcfea298f20 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -591,6 +591,7 @@ /mob/living/silicon/robot/updatehealth() ..() + update_damage_particles() if(!model.breakable_modules) return @@ -688,6 +689,9 @@ builtInCamera.toggle_cam(src, 0) if(full_heal_flags & HEAL_ADMIN) locked = TRUE + if(eye_flash_timer) + deltimer(eye_flash_timer) + eye_flash_timer = null src.set_stat(CONSCIOUS) notify_ai(AI_NOTIFICATION_NEW_BORG) toggle_headlamp(FALSE, TRUE) //This will reenable borg headlamps if doomsday is currently going on still. diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 0e4e79f84ce..16da8d89783 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -186,6 +186,52 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real return ..() +#define LOW_DAMAGE_UPPER_BOUND 1/3 +#define MODERATE_DAMAGE_UPPER_BOUND 2/3 + +/mob/living/silicon/robot/proc/update_damage_particles() + var/brute_percent = bruteloss / maxHealth + var/burn_percent = fireloss / maxHealth + + if (brute_percent > MODERATE_DAMAGE_UPPER_BOUND) + if(!smoke_particles) + smoke_particles = new(src, /particles/smoke/cyborg/heavy_damage, PARTICLE_ATTACH_MOB) + else if(!istype(smoke_particles.particles, /particles/smoke/cyborg/heavy_damage)) //TODO: needs to be darker + QDEL_NULL(smoke_particles) + smoke_particles = new(src, /particles/smoke/cyborg/heavy_damage, PARTICLE_ATTACH_MOB) + + else if (brute_percent > LOW_DAMAGE_UPPER_BOUND) + if(!smoke_particles) + smoke_particles = new(src, /particles/smoke/cyborg, PARTICLE_ATTACH_MOB) + else if(!istype(smoke_particles.particles, /particles/smoke/cyborg)) + QDEL_NULL(smoke_particles) + smoke_particles = new(src, /particles/smoke/cyborg, PARTICLE_ATTACH_MOB) + + else + if(smoke_particles) + QDEL_NULL(smoke_particles) + + if (burn_percent > MODERATE_DAMAGE_UPPER_BOUND) + if(!spark_particles) + spark_particles = new(src, /particles/embers/spark/severe, PARTICLE_ATTACH_MOB) + else if(!istype(spark_particles.particles, /particles/embers/spark/severe)) //TODO: needs to be more dramatic + QDEL_NULL(spark_particles) + spark_particles = new(src, /particles/embers/spark/severe, PARTICLE_ATTACH_MOB) + + else if (burn_percent > LOW_DAMAGE_UPPER_BOUND) + if(!spark_particles) + spark_particles = new(src, /particles/embers/spark, PARTICLE_ATTACH_MOB) + else if(!istype(spark_particles.particles, /particles/embers/spark)) + QDEL_NULL(spark_particles) + spark_particles = new(src, /particles/embers/spark, PARTICLE_ATTACH_MOB) + + else + if(spark_particles) + QDEL_NULL(spark_particles) + +#undef LOW_DAMAGE_UPPER_BOUND +#undef MODERATE_DAMAGE_UPPER_BOUND + /mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/adult/user, list/modifiers) if (LAZYACCESS(modifiers, RIGHT_CLICK)) if(body_position == STANDING_UP) @@ -214,7 +260,6 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real if(!wiresexposed && !issilicon(user)) if(!cell) return - cell.update_appearance() cell.add_fingerprint(user) to_chat(user, span_notice("You remove \the [cell].")) user.put_in_active_hand(cell) @@ -402,7 +447,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real if(stat != DEAD) adjustBruteLoss(30) else - investigate_log("has been gibbed a blob.", INVESTIGATE_DEATHS) + investigate_log("has been gibbed by a blob.", INVESTIGATE_DEATHS) gib(DROP_ALL_REMAINS) return TRUE diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm index 6f8abfc7254..f41f4bd8ffc 100644 --- a/code/modules/mob/living/silicon/robot/robot_defines.dm +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -57,6 +57,8 @@ // Overlay for borg eye lights var/mutable_appearance/eye_lights + ///Holds a reference to the timer taking care of blinking lights on dead cyborgs + var/eye_flash_timer = null // Overlay for borg hat var/mutable_appearance/hat_overlay @@ -115,6 +117,10 @@ var/low_power_mode = FALSE ///So they can initialize sparks whenever/N var/datum/effect_system/spark_spread/spark_system + ///Smoke particle holder for brute damage + var/obj/effect/abstract/particle_holder/smoke_particles = null + ///Spark particle holder for burn damage + var/obj/effect/abstract/particle_holder/spark_particles = null ///Jetpack-like effect. var/ionpulse = FALSE diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index bccde4f862f..b7e6bd6a8ed 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -18,7 +18,6 @@ flash_act(affect_silicon = 1) log_combat(user, src, "attacked") adjustBruteLoss(damage) - updatehealth() else playsound(loc, 'sound/weapons/slashmiss.ogg', 25, TRUE, -1) visible_message(span_danger("[user]'s swipe misses [src]!"), \ diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 2fea2871c03..baaf1b39b3c 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -27,7 +27,6 @@ playsound(loc, attacked_sound, 25, TRUE, -1) apply_damage(harm_intent_damage) log_combat(user, src, "attacked") - updatehealth() return TRUE /mob/living/simple_animal/get_shoving_message(mob/living/shover, obj/item/weapon, shove_flags) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index c483d371e1a..e2bb112e156 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -556,7 +556,6 @@ if(istype(item_to_drop, /obj/item/stock_parts/power_store/cell)) var/obj/item/stock_parts/power_store/cell/dropped_cell = item_to_drop dropped_cell.charge = 0 - dropped_cell.update_appearance() else if(istype(item_to_drop, /obj/item/storage)) var/obj/item/storage/storage_to_drop = item_to_drop diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 6b9b4aa77fa..f3194e88b18 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -754,7 +754,6 @@ new /obj/item/stack/cable_coil/cut(Tsec) if(cell) cell.forceMove(Tsec) - cell.update_appearance() cell = null new /obj/effect/decal/cleanable/oil(loc) diff --git a/code/modules/mob/mob_update_icons.dm b/code/modules/mob/mob_update_icons.dm index a355a385d9f..b14da72e830 100644 --- a/code/modules/mob/mob_update_icons.dm +++ b/code/modules/mob/mob_update_icons.dm @@ -54,6 +54,8 @@ update_worn_shoes(update_obscured = FALSE) if(obscured_flags & HIDEMASK) update_worn_mask(update_obscured = FALSE) + if(obscured_flags & HIDEBELT) + update_worn_belt(update_obscured = FALSE) if(obscured_flags & HIDEEARS) update_worn_ears(update_obscured = FALSE) if(obscured_flags & HIDEEYES) diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index f62992a9557..96efa91f1b4 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -548,7 +548,7 @@ radial_anchor = get_turf(user.loc) //they're phased out via some module, anchor the radial on the turf so it may still display if (!isnull(anchor_override)) radial_anchor = anchor_override - var/pick = show_radial_menu(user, radial_anchor, items, custom_check = FALSE, require_near = isnull(anchor_override), tooltips = TRUE) + var/pick = show_radial_menu(user, radial_anchor, items, custom_check = FALSE, require_near = isnull(anchor_override), tooltips = TRUE, user_space = !isnull(anchor_override)) if(!pick) return var/module_reference = display_names[pick] diff --git a/code/modules/mod/mod_core.dm b/code/modules/mod/mod_core.dm index 0c13efa1b95..5f93427f532 100644 --- a/code/modules/mod/mod_core.dm +++ b/code/modules/mod/mod_core.dm @@ -173,7 +173,6 @@ /obj/item/mod/core/standard/proc/uninstall_cell() if(!cell) return - cell.update_appearance() cell = null mod.update_charge_alert() diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 1d78e24f99c..7c29e1f3730 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -479,21 +479,21 @@ ), /obj/item/clothing/suit/mod = list( UNSEALED_CLOTHING = THICKMATERIAL, - SEALED_CLOTHING = STOPSPRESSUREDAMAGE, - SEALED_INVISIBILITY = HIDEJUMPSUIT, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT|HIDEBELT, UNSEALED_MESSAGE = CHESTPLATE_UNSEAL_MESSAGE, SEALED_MESSAGE = CHESTPLATE_SEAL_MESSAGE, ), /obj/item/clothing/gloves/mod = list( UNSEALED_CLOTHING = THICKMATERIAL, - SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, CAN_OVERSLOT = TRUE, UNSEALED_MESSAGE = GAUNTLET_UNSEAL_MESSAGE, SEALED_MESSAGE = GAUNTLET_SEAL_MESSAGE, ), /obj/item/clothing/shoes/mod = list( UNSEALED_CLOTHING = THICKMATERIAL, - SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, CAN_OVERSLOT = TRUE, UNSEALED_MESSAGE = BOOT_UNSEAL_MESSAGE, SEALED_MESSAGE = BOOT_SEAL_MESSAGE, @@ -502,7 +502,7 @@ "asteroid" = list( /obj/item/clothing/head/mod = list( UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL, - SEALED_CLOTHING = STOPSPRESSUREDAMAGE|HEADINTERNALS, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE|HEADINTERNALS, UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT, SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE, SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF, @@ -511,21 +511,21 @@ ), /obj/item/clothing/suit/mod = list( UNSEALED_CLOTHING = THICKMATERIAL, - SEALED_CLOTHING = STOPSPRESSUREDAMAGE, - SEALED_INVISIBILITY = HIDEJUMPSUIT, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT|HIDEBELT, UNSEALED_MESSAGE = CHESTPLATE_UNSEAL_MESSAGE, SEALED_MESSAGE = CHESTPLATE_SEAL_MESSAGE, ), /obj/item/clothing/gloves/mod = list( UNSEALED_CLOTHING = THICKMATERIAL, - SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, CAN_OVERSLOT = TRUE, UNSEALED_MESSAGE = GAUNTLET_UNSEAL_MESSAGE, SEALED_MESSAGE = GAUNTLET_SEAL_MESSAGE, ), /obj/item/clothing/shoes/mod = list( UNSEALED_CLOTHING = THICKMATERIAL, - SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, CAN_OVERSLOT = TRUE, UNSEALED_MESSAGE = BOOT_UNSEAL_MESSAGE, SEALED_MESSAGE = BOOT_SEAL_MESSAGE, diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index 5125b70a9a7..db9d150f343 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -123,7 +123,7 @@ theme = /datum/mod_theme/mining applied_core = /obj/item/mod/core/plasma applied_modules = list( - /obj/item/mod/module/storage, + /obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/gps, /obj/item/mod/module/orebag, /obj/item/mod/module/clamp, diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index e14fc483c0b..8db88e16ba3 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -286,7 +286,6 @@ icon_state = "apparatus" complexity = 1 incompatible_modules = list(/obj/item/mod/module/mouthhole) - overlay_state_inactive = "module_apparatus" required_slots = list(ITEM_SLOT_HEAD|ITEM_SLOT_MASK) /// Former flags of the helmet. var/former_helmet_flags = NONE @@ -712,6 +711,7 @@ attached_hat = hat var/obj/item/clothing/helmet = mod.get_part_from_slot(ITEM_SLOT_HEAD) if(istype(helmet)) + helmet.attach_clothing_traits(attached_hat.clothing_traits) former_flags = helmet.flags_cover former_visor_flags = helmet.visor_flags_cover helmet.flags_cover |= attached_hat.flags_cover @@ -734,11 +734,12 @@ balloon_alert(user, "hat removed") else balloon_alert_to_viewers("the hat falls to the floor!") - attached_hat = null var/obj/item/clothing/helmet = mod.get_part_from_slot(ITEM_SLOT_HEAD) if(istype(helmet)) + helmet.detach_clothing_traits(attached_hat) helmet.flags_cover = former_flags helmet.visor_flags_cover = former_visor_flags + attached_hat = null mod.wearer.update_clothing(mod.slot_flags) /obj/item/mod/module/hat_stabilizer/syndicate diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm index 871906fe4b8..7a487a009b2 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -308,7 +308,6 @@ /obj/machinery/power/apc/Exited(atom/movable/gone, direction) . = ..() if(gone == cell) - cell.update_appearance() cell = null charging = APC_NOT_CHARGING update_appearance() diff --git a/code/modules/power/apc/apc_tool_act.dm b/code/modules/power/apc/apc_tool_act.dm index 2072ab14561..8e4d51a703d 100644 --- a/code/modules/power/apc/apc_tool_act.dm +++ b/code/modules/power/apc/apc_tool_act.dm @@ -320,7 +320,6 @@ balloon_alert(user, "cell removed") var/turf/user_turf = get_turf(user) cell.forceMove(user_turf) - cell.update_appearance() cell = null charging = APC_NOT_CHARGING update_appearance() diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index a0c6a76f644..23fc78cc253 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -78,6 +78,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) /obj/machinery/gravity_generator/part/Destroy() atom_break() if(main_part) + main_part.generator_parts -= src UnregisterSignal(main_part, COMSIG_ATOM_UPDATED_ICON) main_part = null return ..() diff --git a/code/modules/power/lighting/light_construct.dm b/code/modules/power/lighting/light_construct.dm index ec09fdc2692..902ca9fb0eb 100644 --- a/code/modules/power/lighting/light_construct.dm +++ b/code/modules/power/lighting/light_construct.dm @@ -63,7 +63,6 @@ return user.visible_message(span_notice("[user] removes [cell] from [src]!"), span_notice("You remove [cell].")) user.put_in_hands(cell) - cell.update_appearance() cell = null add_fingerprint(user) diff --git a/code/modules/power/power_store.dm b/code/modules/power/power_store.dm index 03e75d052ad..d1118b929ed 100644 --- a/code/modules/power/power_store.dm +++ b/code/modules/power/power_store.dm @@ -57,6 +57,13 @@ ) AddElement(/datum/element/connect_loc, loc_connections) + +/obj/item/stock_parts/power_store/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) + . = ..() + if(!isturf(old_loc)) + update_appearance() + + /** * Signal proc for [COMSIG_ITEM_MAGICALLY_CHARGED] * diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index e4063d45200..c3a6af04dc6 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -5,6 +5,8 @@ name = "projectile gun" icon_state = "debug" w_class = WEIGHT_CLASS_NORMAL + pickup_sound = 'sound/items/gun_pick_up.ogg' + drop_sound = 'sound/items/gun_drop.ogg' ///sound when inserting magazine var/load_sound = 'sound/weapons/gun/general/magazine_insert_full.ogg' diff --git a/code/modules/projectiles/guns/ballistic/bows/_bow.dm b/code/modules/projectiles/guns/ballistic/bows/_bow.dm index 15c89ddb855..358e87929e2 100644 --- a/code/modules/projectiles/guns/ballistic/bows/_bow.dm +++ b/code/modules/projectiles/guns/ballistic/bows/_bow.dm @@ -27,7 +27,18 @@ /obj/item/gun/ballistic/bow/update_icon_state() . = ..() - icon_state = chambered ? "[base_icon_state]_[drawn ? "drawn" : "nocked"]" : "[base_icon_state]" + icon_state = "[base_icon_state][drawn ? "_drawn" : ""]" + +/obj/item/gun/ballistic/bow/update_overlays() + . = ..() + if(chambered) + // . += "[chambered.base_icon_state][drawn ? "_drawn" : ""]" SKYRAT EDIT REMOVAL + // SKYRAT EDIT START + var/icon_state = icon_exists(/obj/item/gun/ballistic/bow::icon, chambered.base_icon_state) ? chambered.base_icon_state : "arrow" + if(drawn) + icon_state += "_drawn" + . += icon(/obj/item/gun/ballistic/bow::icon, icon_state) + // SKYRAT EDIT END /obj/item/gun/ballistic/bow/click_alt(mob/user) if(isnull(chambered)) @@ -72,6 +83,11 @@ return FALSE return ..() //fires, removing the arrow +/obj/item/gun/ballistic/bow/postfire_empty_checks(last_shot_succeeded) + if(!chambered && !get_ammo()) + drawn = FALSE + update_appearance() + /obj/item/gun/ballistic/bow/equipped(mob/user, slot, initial) . = ..() if(slot != ITEM_SLOT_HANDS && chambered) diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm index 4ed74bc9793..4f5a01b1ebd 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm @@ -45,6 +45,60 @@ jostle_pain_mult = 3 rip_time = 1 SECONDS +/// sticky arrows +/obj/item/ammo_casing/arrow/sticky + name = "sticky arrow" + desc = "A sticky arrow. Not sharp-ended, but ripping it off yourself once hit would be rather difficult and painful." + icon_state = "sticky_arrow" + inhand_icon_state = "sticky_arrow" + base_icon_state = "sticky_arrow" + projectile_type = /obj/projectile/bullet/arrow/sticky + +///sticky arrow projectile +/obj/projectile/bullet/arrow/sticky + name = "sticky arrow" + desc = "Quite the sticky situation..." + icon_state = "sticky_arrow_projectile" + damage = 30 + speed = 0.75 + range = 20 + embed_type = /datum/embed_data/arrow/sticky + +/datum/embed_data/arrow/sticky + embed_chance = 99 + fall_chance = 0 + jostle_chance = 1 + ignore_throwspeed_threshold = TRUE + pain_stam_pct = 0.7 + pain_mult = 3 + jostle_pain_mult = 3 + rip_time = 8 SECONDS + +/// poison arrows +/obj/item/ammo_casing/arrow/poison + name = "poisonous arrow" + desc = "A poisonous arrow." + icon_state = "poison_arrow" + inhand_icon_state = "poison_arrow" + base_icon_state = "poison_arrow" + projectile_type = /obj/projectile/bullet/arrow/poison + +/// poison arrow projctile +/obj/projectile/bullet/arrow/poison + name = "poisonous arrow" + desc = "Better to not get hit with this!" + icon_state = "poison_arrow_projectile" + damage = 40 + embed_type = /datum/embed_data/arrow + +/obj/projectile/bullet/arrow/poison/on_hit(atom/target, blocked, pierce_hit) + . = ..() + if(!ishuman(target)) + return + + target.reagents?.add_reagent(/datum/reagent/toxin/cyanide, 8) + target.reagents?.add_reagent(/datum/reagent/toxin/staminatoxin, 1) + /// holy arrows /obj/item/ammo_casing/arrow/holy name = "holy arrow" @@ -59,22 +113,34 @@ name = "holy arrow" desc = "Here it comes, cultist scum!" icon_state = "holy_arrow_projectile" - damage = 20 //still a lot but this is roundstart gear so far less - -/datum/embed_data/holy_arrow - embed_chance = 50 - fall_chance = 2 - jostle_chance = 0 - ignore_throwspeed_threshold = TRUE - pain_stam_pct = 0.5 - pain_mult = 3 - rip_time = 1 SECONDS /obj/projectile/bullet/arrow/holy/Initialize(mapload) . = ..() //50 damage to revenants AddElement(/datum/element/bane, target_type = /mob/living/basic/revenant, damage_multiplier = 0, added_damage = 30) +/// plastic arrows +// completely dogshit quality and they break when they hit something. +/obj/item/ammo_casing/arrow/plastic + name = "plastic arrow" + desc = "The earliest mining teams within the Spinward Sector were the somewhat stout ancestors of the modern settlers. These teams \ + found themselves often unable to access the quality materials they were digging up for equipment maintenance, all being sent off-site. \ + Left with few options, and in need of a way to protect themselves in the hostile work enviroments of the Spinward, they turned \ + to the one material they had in abundance." + icon_state = "plastic_arrow" + base_icon_state = "plastic_arrow" + projectile_type = /obj/projectile/bullet/arrow/plastic + reusable = FALSE //cheap shit + +/// plastic arrow projectile +/obj/projectile/bullet/arrow/plastic + name = "plastic arrow" + desc = "If this is about to kill you, you should feel genuine shame." + damage = 5 + stamina = 50 + weak_against_armour = TRUE + icon_state = "plastic_arrow_projectile" + /// special pyre sect arrow /// in the future, this needs a special sprite, but bows don't support non-hardcoded arrow sprites /obj/item/ammo_casing/arrow/holy/blazing @@ -100,5 +166,5 @@ human_target.adjust_fire_stacks(2) human_target.ignite_mob() return - to_chat(human_target, span_danger("[src] reacts with the flames on y-")) + to_chat(human_target, span_danger("[src] reacts with the flames enveloping you! Oh shit!")) explosion(src, light_impact_range = 1, flame_range = 2) //ow diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm b/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm index 07d7cc93ce1..2492f0d4276 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm @@ -8,6 +8,7 @@ worn_icon_state = "harpoon_quiver" /// type of arrow the quivel should hold var/arrow_path = /obj/item/ammo_casing/arrow + var/max_slots = 40 /obj/item/storage/bag/quiver/Initialize(mapload) . = ..() @@ -17,7 +18,10 @@ atom_storage.max_total_storage = 100 atom_storage.set_holdable(/obj/item/ammo_casing/arrow) -/obj/item/storage/bag/quiver/PopulateContents() +/obj/item/storage/bag/quiver/lesser + max_slots = 10 + +/obj/item/storage/bag/quiver/full/PopulateContents() . = ..() for(var/i in 1 to 10) new arrow_path(src) @@ -29,3 +33,8 @@ inhand_icon_state = "holyquiver" worn_icon_state = "holyquiver" arrow_path = /obj/item/ammo_casing/arrow/holy + +/obj/item/storage/bag/quiver/holy/PopulateContents() + . = ..() + for(var/i in 1 to 10) + new arrow_path(src) diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_types.dm b/code/modules/projectiles/guns/ballistic/bows/bow_types.dm index b9ac1af0cca..cc6bfbb6477 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_types.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_types.dm @@ -4,6 +4,12 @@ name = "longbow" desc = "While pretty finely crafted, surely you can find something better to use in the current year." +/// Shortbow, made via the crafting recipe +/obj/item/gun/ballistic/bow/shortbow + name = "shortbow" + desc = "A simple homemade shortbow. Great for LARPing. Or poking out someones eye." + projectile_damage_multiplier = 0.36 + ///chaplain's divine archer bow /obj/item/gun/ballistic/bow/divine name = "divine bow" @@ -15,6 +21,7 @@ slot_flags = ITEM_SLOT_BACK obj_flags = UNIQUE_RENAME accepted_magazine_type = /obj/item/ammo_box/magazine/internal/bow/holy + //projectile_damage_multiplier = 0.4 // SKYRAT EDIT REMOVAL /obj/item/ammo_box/magazine/internal/bow/holy name = "divine bowstring" diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 6eb9849c7e1..e3b7cc44d59 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -3,6 +3,8 @@ name = "energy gun" desc = "A basic energy-based gun." icon = 'icons/obj/weapons/guns/energy.dmi' + pickup_sound = 'sound/items/gun_pick_up.ogg' + drop_sound = 'sound/items/gun_drop.ogg' /// What type of power cell this uses var/obj/item/stock_parts/power_store/cell diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 93748a33043..51adc8d68a5 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -255,11 +255,6 @@ /obj/machinery/chem_master/attack_ai_secondary(mob/user, list/modifiers) return attack_hand_secondary(user, modifiers) -/obj/machinery/chem_master/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/spritesheet/chemmaster) - ) - /obj/machinery/chem_master/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) @@ -281,9 +276,10 @@ //add containers to this category for(var/obj/item/reagent_containers/container as anything in printable_containers[category]) category_list["containers"] += list(list( - "icon" = sanitize_css_class_name("[container]"), "ref" = REF(container), "name" = initial(container.name), + "icon" = initial(container.icon), + "icon_state" = initial(container.icon_state), "volume" = initial(container.volume), )) diff --git a/code/modules/reagents/reagent_containers/misc.dm b/code/modules/reagents/reagent_containers/misc.dm index d2dc2adfb5f..8b13ab4a54b 100644 --- a/code/modules/reagents/reagent_containers/misc.dm +++ b/code/modules/reagents/reagent_containers/misc.dm @@ -91,7 +91,6 @@ /obj/item/reagent_containers/cup/maunamug/attack_hand(mob/living/user, list/modifiers) if(cell && open) - cell.update_appearance() user.put_in_hands(cell) cell = null to_chat(user, span_notice("You remove the power cell from [src].")) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index c207a6e25cb..62c9dfbb05c 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -229,6 +229,8 @@ stream_range = 4 amount_per_transfer_from_this = 5 list_reagents = list(/datum/reagent/consumable/condensedcapsaicin = 50) + pickup_sound = 'sound/items/pepper_spray_pick_up.ogg' + drop_sound = 'sound/items/pepper_spray_drop.ogg' /obj/item/reagent_containers/spray/pepper/empty //for protolathe printing list_reagents = null diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 9b26ca860d8..23ad6fd213d 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -90,8 +90,7 @@ var/list/boostlist = host.boosted_nodes[id] for(var/booster in boostlist) if(actual_costs[booster]) - var/delta = max(0, actual_costs[booster] - 250) - actual_costs[booster] -= min(boostlist[booster], delta) + actual_costs[booster] = max(actual_costs[booster] - boostlist[booster], 0) return actual_costs diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index be805ae9da8..6ec7fca37e3 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -715,13 +715,10 @@ if(!dumb_mob.compare_sentience_type(sentience_type)) // Will also return false if not a basic or simple mob, which are the only two we want anyway balloon_alert(user, "invalid creature!") return - if(isnull(potion_reason)) - balloon_alert(user, "no reason for offering set!") - return balloon_alert(user, "offering...") being_used = TRUE var/mob/chosen_one = SSpolling.poll_ghosts_for_target( - question = "[span_danger(user.name)] is offering [span_notice(dumb_mob.name)] an intelligence potion! Reason: [span_boldnotice(potion_reason)]", + question = "[span_danger(user.name)] is offering [span_notice(dumb_mob.name)] an intelligence potion![potion_reason ? " Reason: [span_boldnotice(potion_reason)]" : ""]", check_jobban = ROLE_SENTIENCE, poll_time = 20 SECONDS, checked_target = dumb_mob, diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_arms.dm b/code/modules/surgery/organs/internal/cyberimp/augments_arms.dm index e4ab654cb5e..4a7dcab80f2 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_arms.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_arms.dm @@ -2,7 +2,7 @@ name = "arm-mounted implant" desc = "You shouldn't see this! Adminhelp and report this as an issue on github!" zone = BODY_ZONE_R_ARM - icon_state = "implant-toolkit" + icon_state = "toolkit_generic" w_class = WEIGHT_CLASS_SMALL actions_types = list(/datum/action/item_action/organ_action/toggle) ///A ref for the arm we're taking up. Mostly for the unregister signal upon removal @@ -264,6 +264,7 @@ /obj/item/organ/internal/cyberimp/arm/toolset name = "integrated toolset implant" desc = "A stripped-down version of the engineering cyborg toolset, designed to be installed on subject's arm. Contain advanced versions of every tool." + icon_state = "toolkit_engineering" actions_types = list(/datum/action/item_action/organ_action/toggle/toolkit) items_to_create = list( /obj/item/screwdriver/cyborg, @@ -349,6 +350,7 @@ /obj/item/organ/internal/cyberimp/arm/surgery name = "surgical toolset implant" desc = "A set of surgical tools hidden behind a concealed panel on the user's arm." + icon_state = "toolkit_surgical" actions_types = list(/datum/action/item_action/organ_action/toggle/toolkit) items_to_create = list( /obj/item/retractor/augment, diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm b/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm index 046c84200d1..060499936d5 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm @@ -1,15 +1,12 @@ /obj/item/organ/internal/cyberimp/chest name = "cybernetic torso implant" desc = "Implants for the organs in your torso." - icon_state = "chest_implant" - implant_overlay = "chest_implant_overlay" zone = BODY_ZONE_CHEST /obj/item/organ/internal/cyberimp/chest/nutriment - name = "Nutriment pump implant" + name = "nutriment pump implant" desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are starving." - icon_state = "chest_implant" - implant_color = "#00AA00" + icon_state = "nutriment_implant" var/hunger_threshold = NUTRITION_LEVEL_STARVING var/synthesizing = 0 var/poison_amount = 5 @@ -37,18 +34,16 @@ /obj/item/organ/internal/cyberimp/chest/nutriment/plus - name = "Nutriment pump implant PLUS" + name = "nutriment pump implant PLUS" desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." - icon_state = "chest_implant" - implant_color = "#006607" + icon_state = "adv_nutriment_implant" hunger_threshold = NUTRITION_LEVEL_HUNGRY poison_amount = 10 /obj/item/organ/internal/cyberimp/chest/reviver - name = "Reviver implant" + name = "reviver implant" desc = "This implant will attempt to revive and heal you if you lose consciousness. For the faint of heart!" - icon_state = "chest_implant" - implant_color = "#AD0000" + icon_state = "reviver_implant" slot = ORGAN_SLOT_HEART_AID var/revive_cost = 0 var/reviving = FALSE @@ -164,7 +159,6 @@ slot = ORGAN_SLOT_THRUSTERS icon_state = "imp_jetpack" base_icon_state = "imp_jetpack" - implant_overlay = null implant_color = null actions_types = list(/datum/action/item_action/organ_action/toggle) w_class = WEIGHT_CLASS_NORMAL @@ -265,7 +259,7 @@ name = "\improper Herculean gravitronic spinal implant" desc = "This gravitronic spinal interface is able to improve the athletics of a user, allowing them greater physical ability. \ Contains a slot which can be upgraded with a gravity anomaly core, improving its performance." - implant_color = "#15704c" + icon_state = "herculean_implant" slot = ORGAN_SLOT_SPINE /// How much faster does the spinal implant improve our lifting speed, workout ability, reducing falling damage and improving climbing and standing speed var/athletics_boost_multiplier = 0.8 @@ -315,5 +309,7 @@ name = "\improper Atlas gravitonic spinal implant" desc = "This gravitronic spinal interface is able to improve the athletics of a user, allowing them greater physical ability. \ This one has been improved through the installation of a gravity anomaly core, allowing for personal gravity manipulation." + icon_state = "herculean_implant_core" + update_appearance() qdel(tool) return ITEM_INTERACT_SUCCESS diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm b/code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm index 401e951a853..d4c4b57d75f 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm @@ -2,7 +2,6 @@ name = "cybernetic eye implant" desc = "Implants for your eyes." icon_state = "eye_implant" - implant_overlay = "eye_implant_overlay" slot = ORGAN_SLOT_EYES zone = BODY_ZONE_PRECISE_EYES w_class = WEIGHT_CLASS_TINY @@ -41,21 +40,25 @@ toggled_on = FALSE /obj/item/organ/internal/cyberimp/eyes/hud/medical - name = "Medical HUD implant" + name = "medical HUD implant" desc = "These cybernetic eye implants will display a medical HUD over everything you see." + icon_state = "eye_implant_medical" HUD_traits = list(TRAIT_MEDICAL_HUD) /obj/item/organ/internal/cyberimp/eyes/hud/security - name = "Security HUD implant" + name = "security HUD implant" desc = "These cybernetic eye implants will display a security HUD over everything you see." + icon_state = "eye_implant_security" HUD_traits = list(TRAIT_SECURITY_HUD) /obj/item/organ/internal/cyberimp/eyes/hud/diagnostic - name = "Diagnostic HUD implant" + name = "diagnostic HUD implant" desc = "These cybernetic eye implants will display a diagnostic HUD over everything you see." + icon_state = "eye_implant_diagnostic" HUD_traits = list(TRAIT_DIAGNOSTIC_HUD, TRAIT_BOT_PATH_HUD) /obj/item/organ/internal/cyberimp/eyes/hud/security/syndicate - name = "Contraband Security HUD Implant" + name = "contraband security HUD implant" desc = "A Cybersun Industries brand Security HUD Implant. These illicit cybernetic eye implants will display a security HUD over everything you see." + icon_state = "eye_implant_syndicate" organ_flags = ORGAN_ROBOTIC | ORGAN_HIDDEN diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm index f36c6cfe838..f71e29631b3 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm @@ -22,8 +22,6 @@ /obj/item/organ/internal/cyberimp/brain name = "cybernetic brain implant" desc = "Injectors of extra sub-routines for the brain." - icon_state = "brain_implant" - implant_overlay = "brain_implant_overlay" zone = BODY_ZONE_HEAD w_class = WEIGHT_CLASS_TINY @@ -39,9 +37,9 @@ /obj/item/organ/internal/cyberimp/brain/anti_drop name = "anti-drop implant" desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." + icon_state = "brain_implant_antidrop" var/active = FALSE var/list/stored_items = list() - implant_color = "#DE7E00" slot = ORGAN_SLOT_BRAIN_ANTIDROP actions_types = list(/datum/action/item_action/organ_action/toggle) @@ -99,9 +97,9 @@ stored_items -= source /obj/item/organ/internal/cyberimp/brain/anti_stun - name = "CNS Rebooter implant" + name = "CNS rebooter implant" desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." - implant_color = COLOR_YELLOW + icon_state = "brain_implant_rebooter" slot = ORGAN_SLOT_BRAIN_ANTISTUN var/static/list/signalCache = list( diff --git a/code/modules/surgery/organs/organ_movement.dm b/code/modules/surgery/organs/organ_movement.dm index 2889cbe0708..ff9f753ce18 100644 --- a/code/modules/surgery/organs/organ_movement.dm +++ b/code/modules/surgery/organs/organ_movement.dm @@ -161,6 +161,7 @@ UnregisterSignal(organ_owner, COMSIG_ATOM_EXAMINE) SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, organ_owner) SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src, special) + ADD_TRAIT(src, TRAIT_USED_ORGAN, ORGAN_TRAIT) var/list/diseases = organ_owner.get_static_viruses() if(!LAZYLEN(diseases)) diff --git a/code/modules/surgery/revival.dm b/code/modules/surgery/revival.dm index 899e1f8b615..71a68c77c28 100644 --- a/code/modules/surgery/revival.dm +++ b/code/modules/surgery/revival.dm @@ -92,8 +92,7 @@ span_notice("[user] send a powerful shock to [target]'s brain with [tool]..."), ) target.grab_ghost() - target.adjustOxyLoss(-50, 0) - target.updatehealth() + target.adjustOxyLoss(-50) if(iscarbon(target)) var/mob/living/carbon/carbon_target = target carbon_target.set_heartattack(FALSE) diff --git a/code/modules/tgui_input/text.dm b/code/modules/tgui_input/text.dm index 4b3e59a6028..806696dcf4f 100644 --- a/code/modules/tgui_input/text.dm +++ b/code/modules/tgui_input/text.dm @@ -140,9 +140,9 @@ switch(action) if("submit") if(max_length) - if(length(params["entry"]) > max_length) + if(length_char(params["entry"]) > max_length) CRASH("[usr] typed a text string longer than the max length") - if(encode && (length(html_encode(params["entry"])) > max_length)) + if(encode && (length_char(html_encode(params["entry"])) > max_length)) to_chat(usr, span_notice("Your message was clipped due to special character usage.")) set_entry(params["entry"]) closed = TRUE diff --git a/code/modules/transport/elevator/elev_music_zone.dm b/code/modules/transport/elevator/elev_music_zone.dm index 8379e742cae..f5b3de8a67c 100644 --- a/code/modules/transport/elevator/elev_music_zone.dm +++ b/code/modules/transport/elevator/elev_music_zone.dm @@ -83,6 +83,8 @@ GLOBAL_LIST_EMPTY(elevator_music) /datum/proximity_monitor/advanced/elevator_music_area/field_turf_uncrossed(mob/exited, turf/old_location, turf/new_location) if (!(exited in tracked_mobs)) return + if ((new_location in field_turfs) || (new_location in edge_turfs)) + return qdel(tracked_mobs[exited]) tracked_mobs -= exited UnregisterSignal(exited, COMSIG_QDELETING) diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index bf963587ae1..7e501217eb6 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -2,9 +2,17 @@ /// Selects a set number of unique items from the uplink, and deducts a percentage discount from them /proc/create_uplink_sales(num, datum/uplink_category/category, limited_stock, list/sale_items) var/list/sales = list() - var/list/sale_items_copy = sale_items.Copy() + var/list/per_category = list() + + for (var/datum/uplink_item/possible_sale as anything in sale_items) + if (!(possible_sale.category in per_category)) + per_category[possible_sale.category] = list() + per_category[possible_sale.category] += possible_sale + for (var/i in 1 to num) - var/datum/uplink_item/taken_item = pick_n_take(sale_items_copy) + var/datum/uplink_category/item_category = pick(per_category) + var/datum/uplink_item/taken_item = pick(per_category[item_category]) + per_category -= item_category var/datum/uplink_item/uplink_item = new taken_item.type() var/discount = uplink_item.get_discount() var/static/list/disclaimer = list( diff --git a/code/modules/uplink/uplink_items/bundle.dm b/code/modules/uplink/uplink_items/bundle.dm index dae6166d49c..b6cdc2fd3d6 100644 --- a/code/modules/uplink/uplink_items/bundle.dm +++ b/code/modules/uplink/uplink_items/bundle.dm @@ -40,18 +40,7 @@ // Don't add telecrystals to the purchase_log since // it's just used to buy more items (including itself!) purchase_log_vis = FALSE - -/datum/uplink_item/bundles_tc/telecrystal/five - name = "5 Raw Telecrystals" - desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/five - cost = 5 - -/datum/uplink_item/bundles_tc/telecrystal/twenty - name = "20 Raw Telecrystals" - desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/twenty - cost = 20 + purchasable_from = NONE /datum/uplink_item/bundles_tc/bundle_a name = "Syndi-kit Tactical" diff --git a/code/modules/uplink/uplink_items/suits.dm b/code/modules/uplink/uplink_items/suits.dm index d940d4eb067..b66cce4eaec 100644 --- a/code/modules/uplink/uplink_items/suits.dm +++ b/code/modules/uplink/uplink_items/suits.dm @@ -79,3 +79,4 @@ purchasable_from = ~UPLINK_ALL_SYNDIE_OPS progression_minimum = 90 MINUTES cost = 16 + cant_discount = TRUE diff --git a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm index cd36624a34c..054abba77e8 100644 --- a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm @@ -122,7 +122,6 @@ if(isnull(victim)) //get gibbed stoopid return ..() victim.adjustOxyLoss(round(clamp_damage/2)) - victim.updatehealth() victim.visible_message(span_danger("[chassis] squeezes [victim]!"), \ span_userdanger("[chassis] squeezes you!"),\ span_hear("You hear something crack.")) diff --git a/code/modules/vehicles/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm index c2d37ee6e83..b4c29220254 100644 --- a/code/modules/vehicles/mecha/mech_fabricator.dm +++ b/code/modules/vehicles/mecha/mech_fabricator.dm @@ -149,8 +149,9 @@ /obj/machinery/mecha_part_fabricator/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) return FALSE - if(user.job != JOB_ROBOTICIST) - to_chat(user, span_warning("You clicking and typing but don’t understand what to do with it")) + if(!HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + to_chat(user, span_warning("You're unsure about [emag_card ? "where to swipe [emag_card] over" : "how to override"] [src] for any effect. Maybe if you had more knowledge of robotics...")) + return FALSE obj_flags |= EMAGGED for(var/found_illegal_mech_nods in SSresearch.techweb_nodes) @@ -179,6 +180,9 @@ if(design.build_type & MECHFAB) cached_designs |= design + for(var/datum/design/illegal_disign in illegal_local_designs) + cached_designs |= illegal_disign + var/design_delta = cached_designs.len - previous_design_count if(design_delta > 0) diff --git a/code/modules/vehicles/mecha/mech_melee_attack.dm b/code/modules/vehicles/mecha/mech_melee_attack.dm index 6fe64c879fa..f37d092b83f 100644 --- a/code/modules/vehicles/mecha/mech_melee_attack.dm +++ b/code/modules/vehicles/mecha/mech_melee_attack.dm @@ -72,6 +72,22 @@ return return ..() +/obj/vehicle/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/living/user) + if(!user.combat_mode) + return FALSE + + mecha_attacker.do_attack_animation(src) + switch(mecha_attacker.damtype) + if(BRUTE) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + if(BURN) + playsound(src, 'sound/items/welder.ogg', 50, TRUE) + else + return + mecha_attacker.visible_message(span_danger("[mecha_attacker] hits [src]!"), span_danger("You hit [src]!"), null, COMBAT_MESSAGE_RANGE) + ..() + return take_damage(mecha_attacker.force, mecha_attacker.damtype, "melee", FALSE, get_dir(src, mecha_attacker)) + /mob/living/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/living/user) if(istype(user) && !user.combat_mode) step_away(src, mecha_attacker) diff --git a/code/modules/vehicles/mecha/mecha_ai_interaction.dm b/code/modules/vehicles/mecha/mecha_ai_interaction.dm index 3a681cac97d..cec3d867e2b 100644 --- a/code/modules/vehicles/mecha/mecha_ai_interaction.dm +++ b/code/modules/vehicles/mecha/mecha_ai_interaction.dm @@ -12,7 +12,7 @@ to_chat(user, "[span_userdanger("ASSUME DIRECT CONTROL?")]
") return examine(user) - if(length(return_drivers()) > 0) + if(length(return_occupants()) >= max_occupants) to_chat(user, span_warning("This exosuit has a pilot and cannot be controlled.")) return var/can_control_mech = FALSE @@ -103,6 +103,7 @@ AI.controlled_equipment = src AI.remote_control = src AI.ShutOffDoomsdayDevice() + add_occupant(AI) to_chat(AI, AI.can_dominate_mechs ? span_greenannounce("Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!") :\ span_notice("You have been uploaded to a mech's onboard computer.")) to_chat(AI, "Use Middle-Mouse or the action button in your HUD to toggle equipment safety. Clicks with safety enabled will pass AI commands.") diff --git a/code/modules/vehicles/motorized_wheelchair.dm b/code/modules/vehicles/motorized_wheelchair.dm index cecf6b815e2..6a38f65e3bf 100644 --- a/code/modules/vehicles/motorized_wheelchair.dm +++ b/code/modules/vehicles/motorized_wheelchair.dm @@ -100,7 +100,6 @@ /obj/vehicle/ridden/wheelchair/motorized/attack_hand(mob/living/user, list/modifiers) if(!power_cell || !panel_open) return ..() - power_cell.update_appearance() to_chat(user, span_notice("You remove [power_cell] from [src].")) user.put_in_hands(power_cell) power_cell = null diff --git a/code/modules/vending/subtype.dm b/code/modules/vending/subtype.dm index 9b4f212224e..3a1a04ff6e7 100644 --- a/code/modules/vending/subtype.dm +++ b/code/modules/vending/subtype.dm @@ -10,6 +10,7 @@ circuit = null product_slogans = "Spawn \" too annoying? Too lazy to open game panel? This one's for you!;Subtype vendor, for all your debugging woes!" default_price = 0 + onstation = FALSE /// Spawns coders by default var/type_to_vend = /obj/item/food/grown/citrus diff --git a/html/changelogs/AutoChangeLog-pr-29110.yml b/html/changelogs/AutoChangeLog-pr-29110.yml deleted file mode 100644 index 8d57cf8f205..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29110.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - refactor: "moves the create_all_lighting_objects proc to the lighting subsystem" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29112.yml b/html/changelogs/AutoChangeLog-pr-29112.yml deleted file mode 100644 index cab85b5ef8b..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29112.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "The heretic's ritual of knowledge no longer requires binoculars" - - rscadd: "Clipboards are craftable using a wood plank, an iron rod and wirecutters" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29113.yml b/html/changelogs/AutoChangeLog-pr-29113.yml deleted file mode 100644 index c8313085a79..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29113.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - bugfix: "smuggler satchels will no longer spawn in space" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29114.yml b/html/changelogs/AutoChangeLog-pr-29114.yml deleted file mode 100644 index 25831022f19..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29114.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - sound: "leather, skins and cardboard have their own sound now" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29115.yml b/html/changelogs/AutoChangeLog-pr-29115.yml deleted file mode 100644 index 22d2ca323b6..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29115.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss and Kayozz" -delete-after: True -changes: - - sound: "more maintenance ambience has been added" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29116.yml b/html/changelogs/AutoChangeLog-pr-29116.yml deleted file mode 100644 index ad8ae5c273f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29116.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - sound: "added sniff sounds" - - sound: "added sigh sounds" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29117.yml b/html/changelogs/AutoChangeLog-pr-29117.yml deleted file mode 100644 index 51eb984c506..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29117.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Projectile dampener, recycler and ninja stealth MOD modules now work properly" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29118.yml b/html/changelogs/AutoChangeLog-pr-29118.yml deleted file mode 100644 index 7038d116e5b..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29118.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Mechs can no longer equip infinite amount of weapons" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29119.yml b/html/changelogs/AutoChangeLog-pr-29119.yml deleted file mode 100644 index 52585ed54f7..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29119.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "You can no longer tear peoples arms off with non-killer clamps" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29120.yml b/html/changelogs/AutoChangeLog-pr-29120.yml deleted file mode 100644 index 4c388113580..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29120.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - balance: "TTV bombs can be implanted into people's chest once again" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29121.yml b/html/changelogs/AutoChangeLog-pr-29121.yml deleted file mode 100644 index f0db9cc3718..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29121.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Mining MODsuits now can store everything that explorer suits can" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29122.yml b/html/changelogs/AutoChangeLog-pr-29122.yml deleted file mode 100644 index 372039c943c..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29122.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Fixed mapload circuit floors not drawing power and deconstructing circuit floors not reducing power load" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29123.yml b/html/changelogs/AutoChangeLog-pr-29123.yml deleted file mode 100644 index 25948dbb9a9..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29123.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Bisar" -delete-after: True -changes: - - bugfix: "All mining mobs now properly listen to the signals sent by attackers and will respond appropriately." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29124.yml b/html/changelogs/AutoChangeLog-pr-29124.yml deleted file mode 100644 index 750316df6f2..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29124.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - qol: "Aquariums start unanchored and don't autoconnect to plumbing. Their reproduction prevention is also disabled by default." - - balance: "Made it a tad easier to control the bait during the minigame. Buffed the fishing skill. No fishing duds at all when using ANY bait." - - balance: "Chasm Chrabs take less time to grow into Lobstrosities but need food a bit more frequently." - - balance: "\"Profound fisher\" mobs will have less RNG-dependant time fishing." - - bugfix: "You can now ACTUALLY interact with other things while fishing if the fishing rod isn't in your active hand." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29125.yml b/html/changelogs/AutoChangeLog-pr-29125.yml deleted file mode 100644 index 540d9230578..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29125.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - config: "Added a config for specific gateway delays so locations like the beach and the museum don't have to take 30 minutes to become available like the rest." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29126.yml b/html/changelogs/AutoChangeLog-pr-29126.yml deleted file mode 100644 index a0c46e89b8c..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29126.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - balance: "The nukeops surplus smg, the pp-95, has been reworked into the Abielle Smart-SMG. It performs nearly identically to the pp-95, however it's projectiles get a slight homing ability towards whatever you click on." - - sound: "New firing sounds for the surplus smg, credit to the m41 sound effects from tgmc" - - image: "New sprites for the surplus smg, made by me" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29127.yml b/html/changelogs/AutoChangeLog-pr-29127.yml deleted file mode 100644 index 42bf8d4f58a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29127.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - rscadd: "Soul-bound (originally called magic) traumas can now be cured by performing a blessed lobotomy featuring holy water" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29129.yml b/html/changelogs/AutoChangeLog-pr-29129.yml deleted file mode 100644 index 86ae64b166b..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29129.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "Stat Panel now scales like a chat, depends on the font size. Defaults from the chat font size, but you can separate it." - - refactor: "Refactored Stat Panel styles and Byond skin theme applying. Stat Panel now looks more like a TGUI" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29130.yml b/html/changelogs/AutoChangeLog-pr-29130.yml deleted file mode 100644 index 4daf9a024cc..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29130.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "plants no longer select reagent genes they already have while cross pollinating" - - code_imp: "improves reagent cross pollination code\n:cl:" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29132.yml b/html/changelogs/AutoChangeLog-pr-29132.yml deleted file mode 100644 index b505756ce67..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29132.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Fixes getting permanently hot or cold if wearing thermal insulation as a lizard" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29134.yml b/html/changelogs/AutoChangeLog-pr-29134.yml deleted file mode 100644 index 637316c1777..00000000000 --- a/html/changelogs/AutoChangeLog-pr-29134.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - image: "Big balls are now much rounder, to more easily slide down into a cannon." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29188.yml b/html/changelogs/AutoChangeLog-pr-29188.yml new file mode 100644 index 00000000000..0f0f3f7fece --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29188.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Rice hat no longer disappears upon being toggled and can be raised back up. Toggling sprites is now done by alt-clicking" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29213.yml b/html/changelogs/AutoChangeLog-pr-29213.yml new file mode 100644 index 00000000000..e534777fb44 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29213.yml @@ -0,0 +1,4 @@ +author: "HometownFunky" +delete-after: True +changes: + - image: "added shading to valeborg sprites and updated the colors for the vale jani/medical models." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29214.yml b/html/changelogs/AutoChangeLog-pr-29214.yml new file mode 100644 index 00000000000..63dce6443c2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29214.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Fixed handyman assistants spawning without a PDA" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29215.yml b/html/changelogs/AutoChangeLog-pr-29215.yml new file mode 100644 index 00000000000..91227bce656 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29215.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "juvenile lobstrosities will now look for food" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29217.yml b/html/changelogs/AutoChangeLog-pr-29217.yml new file mode 100644 index 00000000000..6397648a6a4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29217.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Elevator music no longer restarts when you take a step" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29218.yml b/html/changelogs/AutoChangeLog-pr-29218.yml new file mode 100644 index 00000000000..fdaca89d371 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29218.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - rscdel: "Remove narsie and ratvar plushies from loadout" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29220.yml b/html/changelogs/AutoChangeLog-pr-29220.yml new file mode 100644 index 00000000000..64d9e85e67d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29220.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - code_imp: "Removed multiple cases of unnecessary updatehealth" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29222.yml b/html/changelogs/AutoChangeLog-pr-29222.yml new file mode 100644 index 00000000000..aabb51ad52d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29222.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "Plasmamen helmets now display their smiles + can be painted with spraycans" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29223.yml b/html/changelogs/AutoChangeLog-pr-29223.yml new file mode 100644 index 00000000000..e2396d394b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29223.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - admin: "fix hard restart option" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29224.yml b/html/changelogs/AutoChangeLog-pr-29224.yml new file mode 100644 index 00000000000..4f3e7895da6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29224.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - image: "Ash Blade has received a new sprite." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29225.yml b/html/changelogs/AutoChangeLog-pr-29225.yml new file mode 100644 index 00000000000..ed6cf7587ca --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29225.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - image: "Resprited teleporter beacons" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-29226.yml b/html/changelogs/AutoChangeLog-pr-29226.yml new file mode 100644 index 00000000000..2a846bd19db --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-29226.yml @@ -0,0 +1,4 @@ +author: "Odairu" +delete-after: True +changes: + - rscadd: "adds pixel shifting items, and pixel tilting mobs" \ No newline at end of file diff --git a/html/changelogs/archive/2024-08.yml b/html/changelogs/archive/2024-08.yml new file mode 100644 index 00000000000..04551b0504d --- /dev/null +++ b/html/changelogs/archive/2024-08.yml @@ -0,0 +1,211 @@ +2024-08-01: + Bisar: + - bugfix: All mining mobs now properly listen to the signals sent by attackers and + will respond appropriately. + LT3: + - rscadd: Soul-bound (originally called magic) traumas can now be cured by performing + a blessed lobotomy featuring holy water + Rhials: + - rscadd: Spies can now pick their own custom objectives, if they so choose. + SkyratBot: + - bugfix: fixes a way of duplicating iron with wallmounted sparklers and light switches + - bugfix: Bank cards speak once more + - bugfix: Fixed mapload circuit floors not drawing power and deconstructing circuit + floors not reducing power load + - refactor: moves the create_all_lighting_objects proc to the lighting subsystem + - bugfix: spray can face spraying will no longer work on light-sensitives with eyewear + and people wearing eye covering masks + - bugfix: The clown planet domain is now completable + - bugfix: The charge indicators on power cells now work properly. + - code_imp: Removed some now redundant power cell appearance updates + - balance: Mining MODsuits are now considered thick clothing and gained expanded + storage. + - image: Mining MODsuits got a slight glowup and hide belts now + - rscadd: Carps, frogs and young lobstrosities now fear people wearing fishing hats! + Adults and megacarp favour the 'fight' part of the fear reflex however. + - bugfix: The hat stabilizer module now inherits the clothing traits of the attached + hat. + - qol: Aquariums start unanchored and don't autoconnect to plumbing. Their reproduction + prevention is also disabled by default. + - balance: Made it a tad easier to control the bait during the minigame. Buffed + the fishing skill. No fishing duds at all when using ANY bait. + - balance: Chasm Chrabs take less time to grow into Lobstrosities but need food + a bit more frequently. + - balance: '"Profound fisher" mobs will have less RNG-dependant time fishing.' + - bugfix: You can now ACTUALLY interact with other things while fishing if the fishing + rod isn't in your active hand. + - config: Added a config for specific gateway delays so locations like the beach + and the museum don't have to take 30 minutes to become available like the rest. + - rscadd: Stat Panel now scales like a chat, depends on the font size. Defaults + from the chat font size, but you can separate it. + - refactor: Refactored Stat Panel styles and Byond skin theme applying. Stat Panel + now looks more like a TGUI + - bugfix: plants no longer select reagent genes they already have while cross pollinating + - code_imp: 'improves reagent cross pollination code + + :cl:' + - image: Big balls are now much rounder, to more easily slide down into a cannon. + - bugfix: Heart eater wizard perk no longer works activates on organs that haven't + been used before + - balance: TTV bombs can be implanted into people's chest once again + - rscdel: Revert "Heretic spell invocations now use one dead language per path" + - bugfix: Removed a rogue wall grinder on icebox + - bugfix: Fixes getting permanently hot or cold if wearing thermal insulation as + a lizard + - bugfix: You no longer render on top of tall enough objects that get vertically + offset when anchored to a table when standing on the tile directly to the north + of them. Examples are soda and booze dispensers. + - bugfix: Removing the vertical offset some objects get when anchored to a table + can be done by unanchoring it at any point, rather than only on a table. + - bugfix: 'fix a bug where botany reagents would dissapear from existing plants + + :cl:' + - qol: smart fridge UI now groups items by type+name instead of just type + - qol: smart fridge UI now shows item names next to the images + - qol: smart fridge UI has a list view option (default for chem and viro versions) + - bugfix: fixed smart fridge stacking sounds when dispensing multiple items + - bugfix: Mechs can no longer equip infinite amount of weapons + - bugfix: Mining MODsuits now can store everything that explorer suits can + - qol: You can now reorder items inside storages by dragging them + - bugfix: Portable atmos machine circuit boards list correct components + - bugfix: Portable atmos machine circuit boards accept unwrenched fittings + - bugfix: Portable atmos machines are movable on construction + - bugfix: Projectile dampener, recycler and ninja stealth MOD modules now work properly + - balance: The nukeops surplus smg, the pp-95, has been reworked into the Abielle + Smart-SMG. It performs nearly identically to the pp-95, however it's projectiles + get a slight homing ability towards whatever you click on. + - sound: New firing sounds for the surplus smg, credit to the m41 sound effects + from tgmc + - image: New sprites for the surplus smg, made by me + - bugfix: You can no longer tear peoples arms off with non-killer clamps + - balance: Discounts now pick 4-6 items each from a unique category + - balance: Items that cost below 4 TC cannot get discounted anymore + - balance: Elite syndicate MODs for traitors can no longer get discounted + - rscadd: The heretic's ritual of knowledge no longer requires binoculars + - rscadd: Clipboards are craftable using a wood plank, an iron rod and wirecutters + - bugfix: Fixes SS13.wait not working when called multiple times before it finishes + waiting. + grungussuss: + - bugfix: the abandoned plasma research facility on icemoon no longer has an item + that shouldn't exist + - sound: added sniff sounds + - sound: added sigh sounds + - bugfix: smuggler satchels will no longer spawn in space + - sound: leather, skins and cardboard have their own sound now + grungussuss and Kayozz: + - sound: more maintenance ambience has been added +2024-08-02: + SkyratBot: + - bugfix: Flashdarks now broduce darkness upon toggling + StrangeWeirdKitten: + - bugfix: Emote sounds will no longer play twice + yooriss, Erol509, Majkl-J: + - rscadd: The Echolocation quirk is now available with several levels of customization, + granting 5 tiles of pulsing view distance and significantly enhanced hearing + at the downside of being blind when deafened and twice as vulnerable to ear + damage. + - code_imp: Moves quirks to a standalone folder +2024-08-05: + Bisar: + - qol: Machines check their parts during initialization now; this will usually apply + in cases such as a machine in a prefab having been varedited to be upgraded. + - code_imp: All machines check their parts during initialization. + LT3: + - bugfix: Bouncer now shows up as part of the service department + - bugfix: Synths have their own version of Blessed Lobotomy + Majkl-J: + - bugfix: Fixed harpy wing subtypes incorrectly fetching their icons + ReturnToZender (code): + - bugfix: Runechat now properly has its saturation capped at 90%. + Rhials: + - qol: Sentience potions can now be used without a provided summon reason. + SkyratBot: + - admin: Adds some missing traits to the mob trait list in VV + - bugfix: Silicons and simplemobs can also hear radio chatter now + - bugfix: Emergency climbing hooks now shouldn't spawn on non multi-z stations. + - bugfix: rod sounds will now vary in pitch + - qol: NODE drones summoned to tap a vent within ore vents now display a green status + light to show how much longer they need the vent defended for. + - qol: Skills are passed down to bitrunning avatars and then back to the original + body. + - bugfix: Fixed NT Frontier discounts not applying + - bugfix: Justice design no longer disappears + - bugfix: Mechs can attack other mechs in melee + - bugfix: birdshot engineering feedback has been applied + - image: All implants have received a fresh coat of paint + - bugfix: Putting people you're fireman carrying into contractor pods no longer + sends both of you to zelda's shadow realm + - bugfix: Shoving someone onto a table now causes them to become vulnerable to being + stunned. + - rscadd: Fletching starter kit! Make your own bow, shoot your friends in an unfortunate + workplace accident. Replace all those holy arrows you lost. + - bugfix: Bows now properly undraw once they have fired an arrow. + - code_imp: Bows now utilize overlays in order to display loaded arrows. Unique + overlays per arrow. + - qol: You no longer goofily swap with others trying to move in the same direction + as you if you're not faster than them + - code_imp: Moved mobswap check logic into a separate proc and made it more readable + - bugfix: Lizards no longer die from cold on icebox despite wearing insulation + - image: Made chem master container icons not blurry + - bugfix: Stop clientless lobstrosities from fishing other lobstrosities, which + in turn can fish other lobstrosities and so on. + - balance: Stop clientless lobstrosities from fishing the lavaland fishing spot + chest. + - qol: new uplink UI + - qol: made it possible to buy a custom amount of TC, instead of bundles with fixed + amounts + - rscadd: All the melons are now sliceable, and have inhands, instead of just watermelon + and holymelon respectively. + - rscadd: You can now hollow out melons of all kinds with a spoon to make helmets + or chestplates, based on the potency! If you are unlucky, you can tie up three + helmets into a chestplate with durathread using the crafting menu. + - rscadd: You can now make a bo staff out of bamboo and steelcap logs. + - rscadd: You can now make a moonflower buckler out of moonflowers and steelcap + logs. + - rscadd: You can also hollow out chantarelle to make mock-up wizard hat. + - rscadd: Parsnips, as mutation of carrots, become equaly able to be sharpaned, + turning into shivs, or with potency and luck, sabres. + - rscadd: You can now craft a durathread robe, and customize it into different variants + using specific plants in crafting menu. + - rscadd: Carrots gain a new possible mutation; cahn'root, brewable into root beer + and sharpanable into shivs or daggers! + - rscadd: Rice hat, made from bamboo, now has an alternative style, allowing you + to wear it in reverse and be much cooler. + - rscadd: Two new arrow variants appear in the crafting menu; sticky and poisonous + ones! If you want to make arrows at all though, remember to order bow-maker's + crate at cargo. + - bugfix: Fixed advanced pods showing up as cultist pods + - admin: Subtype vendor no longer requries an ID + - bugfix: wawastation pharmacy now has a hand labeller + - rscadd: RD can emag mech fabricator(like roboticist). + - qol: Callouts and MODsuit quick module pickers now track user + - bugfix: Existing gas flow meters have been recalled and replaced due to a faulty + screen connection, and once again convey pressure and temperature + - rscadd: Adds a bronze dimensional theme + - bugfix: AI mech control beacons and malf AI dominate mech work again. + Tattle: + - qol: dead cyborgs now blink yellow lights + - qol: damaged cyborgs have smoke particles when they've taken brute damage, and + sparks for burn + Varoxus: + - rscadd: increased maximum penis and testicle size. + jupyterkat: + - bugfix: fixed vibrators turning invisible on use + - bugfix: fixed toys not applying mood events on certain traits + - bugfix: fixed grammar on toys + - bugfix: toys now show that they are customizable and how to do it when available + - bugfix: 'toys interactions panel is no longer hidden under a scroll, and is now + a separate component + + :cl:' + xXPawnStarrXx: + - bugfix: fixed bounty pads accepting synthetic organs, which are basically cybernetic + tier 1's. +2024-08-06: + NullDagaf: + - code_imp: simple_farms now respect your skill level + - refactor: refactored simple_farm code + SkyratBot: + - bugfix: Bitrunning crate capture zones can no longer be destroyed + - image: added and updated belt/suit/mask storage sprites for several knives missing + them diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi index 8f0b121cb7f..1b92bfabd7b 100644 Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ diff --git a/icons/mob/clothing/belt.dmi b/icons/mob/clothing/belt.dmi index a2d318adfb7..724a29de21b 100644 Binary files a/icons/mob/clothing/belt.dmi and b/icons/mob/clothing/belt.dmi differ diff --git a/icons/mob/clothing/belt_mirror.dmi b/icons/mob/clothing/belt_mirror.dmi index 9594f622773..0507a030194 100644 Binary files a/icons/mob/clothing/belt_mirror.dmi and b/icons/mob/clothing/belt_mirror.dmi differ diff --git a/icons/mob/clothing/head/costume.dmi b/icons/mob/clothing/head/costume.dmi index 1de2281271f..09c11ca0acb 100644 Binary files a/icons/mob/clothing/head/costume.dmi and b/icons/mob/clothing/head/costume.dmi differ diff --git a/icons/mob/clothing/head/helmet.dmi b/icons/mob/clothing/head/helmet.dmi index 116f0256a62..579f4c53f0f 100644 Binary files a/icons/mob/clothing/head/helmet.dmi and b/icons/mob/clothing/head/helmet.dmi differ diff --git a/icons/mob/clothing/head/wizard.dmi b/icons/mob/clothing/head/wizard.dmi index 785ed63ca5b..cafde2136f7 100644 Binary files a/icons/mob/clothing/head/wizard.dmi and b/icons/mob/clothing/head/wizard.dmi differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index 5f577c7e255..ac40c153dd7 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/clothing/modsuit/mod_clothing.dmi b/icons/mob/clothing/modsuit/mod_clothing.dmi index 3a567eac4e7..cb2a472c32e 100644 Binary files a/icons/mob/clothing/modsuit/mod_clothing.dmi and b/icons/mob/clothing/modsuit/mod_clothing.dmi differ diff --git a/icons/mob/clothing/modsuit/mod_modules.dmi b/icons/mob/clothing/modsuit/mod_modules.dmi index 3c41dac86b2..4f2dc9740d1 100644 Binary files a/icons/mob/clothing/modsuit/mod_modules.dmi and b/icons/mob/clothing/modsuit/mod_modules.dmi differ diff --git a/icons/mob/clothing/suits/armor.dmi b/icons/mob/clothing/suits/armor.dmi index eb7a525e4b7..ea80204c2cd 100644 Binary files a/icons/mob/clothing/suits/armor.dmi and b/icons/mob/clothing/suits/armor.dmi differ diff --git a/icons/mob/clothing/suits/wizard.dmi b/icons/mob/clothing/suits/wizard.dmi index 454bc1f3cf1..9e8c8224130 100644 Binary files a/icons/mob/clothing/suits/wizard.dmi and b/icons/mob/clothing/suits/wizard.dmi differ diff --git a/icons/mob/inhands/64x64_lefthand.dmi b/icons/mob/inhands/64x64_lefthand.dmi index d15a47206f9..14f35aa9ef0 100644 Binary files a/icons/mob/inhands/64x64_lefthand.dmi and b/icons/mob/inhands/64x64_lefthand.dmi differ diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi index 88ad954734b..102417e36f5 100644 Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ diff --git a/icons/mob/inhands/clothing/hats_lefthand.dmi b/icons/mob/inhands/clothing/hats_lefthand.dmi index 4fa05fa6cd6..6ad1f8886c9 100644 Binary files a/icons/mob/inhands/clothing/hats_lefthand.dmi and b/icons/mob/inhands/clothing/hats_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing/hats_righthand.dmi b/icons/mob/inhands/clothing/hats_righthand.dmi index dfb0b71ef4b..3aba15568ef 100644 Binary files a/icons/mob/inhands/clothing/hats_righthand.dmi and b/icons/mob/inhands/clothing/hats_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/belt_lefthand.dmi b/icons/mob/inhands/equipment/belt_lefthand.dmi index 9f306a2777d..d5c4f7c4424 100644 Binary files a/icons/mob/inhands/equipment/belt_lefthand.dmi and b/icons/mob/inhands/equipment/belt_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/belt_righthand.dmi b/icons/mob/inhands/equipment/belt_righthand.dmi index 7b519f7cf69..0e0c7b817ee 100644 Binary files a/icons/mob/inhands/equipment/belt_righthand.dmi and b/icons/mob/inhands/equipment/belt_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/shields_lefthand.dmi b/icons/mob/inhands/equipment/shields_lefthand.dmi index 1aa27021b9e..a19d5f46245 100644 Binary files a/icons/mob/inhands/equipment/shields_lefthand.dmi and b/icons/mob/inhands/equipment/shields_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/shields_righthand.dmi b/icons/mob/inhands/equipment/shields_righthand.dmi index 4227ba00792..b4d080345c5 100644 Binary files a/icons/mob/inhands/equipment/shields_righthand.dmi and b/icons/mob/inhands/equipment/shields_righthand.dmi differ diff --git a/icons/mob/inhands/items/food_lefthand.dmi b/icons/mob/inhands/items/food_lefthand.dmi index 8e2b19c4dd4..5dabacf53db 100644 Binary files a/icons/mob/inhands/items/food_lefthand.dmi and b/icons/mob/inhands/items/food_lefthand.dmi differ diff --git a/icons/mob/inhands/items/food_righthand.dmi b/icons/mob/inhands/items/food_righthand.dmi index 12063ad38a8..7cd6569508c 100644 Binary files a/icons/mob/inhands/items/food_righthand.dmi and b/icons/mob/inhands/items/food_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 86bd5020f4f..86396dcaa8c 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index a6de8b97464..2cbe944aecc 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/staves_lefthand.dmi b/icons/mob/inhands/weapons/staves_lefthand.dmi index 5e4eb552f2a..917b46ae893 100644 Binary files a/icons/mob/inhands/weapons/staves_lefthand.dmi and b/icons/mob/inhands/weapons/staves_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/staves_righthand.dmi b/icons/mob/inhands/weapons/staves_righthand.dmi index 9de32d8cd95..da1765fe800 100644 Binary files a/icons/mob/inhands/weapons/staves_righthand.dmi and b/icons/mob/inhands/weapons/staves_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi index b9552c754c0..82c98f057c0 100644 Binary files a/icons/mob/inhands/weapons/swords_lefthand.dmi and b/icons/mob/inhands/weapons/swords_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi index f132e997658..3f6e471e83e 100644 Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ diff --git a/icons/mob/silicon/robots.dmi b/icons/mob/silicon/robots.dmi index 5c79a0f95e3..c2780ce26ab 100644 Binary files a/icons/mob/silicon/robots.dmi and b/icons/mob/silicon/robots.dmi differ diff --git a/icons/mob/simple/corgi_head.dmi b/icons/mob/simple/corgi_head.dmi index 2e14a3ed0bb..c07f1227a3d 100644 Binary files a/icons/mob/simple/corgi_head.dmi and b/icons/mob/simple/corgi_head.dmi differ diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index 5ccdf2c186f..14ed534744f 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/clothing/head/helmet.dmi b/icons/obj/clothing/head/helmet.dmi index fe52d505e43..cc54b2bf929 100644 Binary files a/icons/obj/clothing/head/helmet.dmi and b/icons/obj/clothing/head/helmet.dmi differ diff --git a/icons/obj/clothing/head/wizard.dmi b/icons/obj/clothing/head/wizard.dmi index 29595f02fc2..82ea73b68ba 100644 Binary files a/icons/obj/clothing/head/wizard.dmi and b/icons/obj/clothing/head/wizard.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_clothing.dmi b/icons/obj/clothing/modsuit/mod_clothing.dmi index 85dd8244970..6ab49417aa5 100644 Binary files a/icons/obj/clothing/modsuit/mod_clothing.dmi and b/icons/obj/clothing/modsuit/mod_clothing.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi index 52a4f2cfdd5..1ea1b91d39c 100644 Binary files a/icons/obj/clothing/modsuit/mod_modules.dmi and b/icons/obj/clothing/modsuit/mod_modules.dmi differ diff --git a/icons/obj/clothing/suits/armor.dmi b/icons/obj/clothing/suits/armor.dmi index 0484cf060d0..b1763f5453f 100644 Binary files a/icons/obj/clothing/suits/armor.dmi and b/icons/obj/clothing/suits/armor.dmi differ diff --git a/icons/obj/clothing/suits/wizard.dmi b/icons/obj/clothing/suits/wizard.dmi index fcfa748d3b3..94fc99b01b4 100644 Binary files a/icons/obj/clothing/suits/wizard.dmi and b/icons/obj/clothing/suits/wizard.dmi differ diff --git a/icons/obj/devices/tracker.dmi b/icons/obj/devices/tracker.dmi index 39be63ef4de..16190482573 100644 Binary files a/icons/obj/devices/tracker.dmi and b/icons/obj/devices/tracker.dmi differ diff --git a/icons/obj/medical/organs/organs.dmi b/icons/obj/medical/organs/organs.dmi index fd1f5af2dde..a9366894d7b 100644 Binary files a/icons/obj/medical/organs/organs.dmi and b/icons/obj/medical/organs/organs.dmi differ diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi index 1f6393a8c51..991762dba3d 100644 Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ diff --git a/icons/obj/pipes_n_cables/meter.dmi b/icons/obj/pipes_n_cables/meter.dmi index 0535fda8010..fa0d5e3bf4d 100644 Binary files a/icons/obj/pipes_n_cables/meter.dmi and b/icons/obj/pipes_n_cables/meter.dmi differ diff --git a/icons/obj/service/hydroponics/growing_vegetables.dmi b/icons/obj/service/hydroponics/growing_vegetables.dmi index 30f02e862e0..37ddd825a82 100644 Binary files a/icons/obj/service/hydroponics/growing_vegetables.dmi and b/icons/obj/service/hydroponics/growing_vegetables.dmi differ diff --git a/icons/obj/service/hydroponics/harvest.dmi b/icons/obj/service/hydroponics/harvest.dmi index b15a34105de..dd3cd5865de 100644 Binary files a/icons/obj/service/hydroponics/harvest.dmi and b/icons/obj/service/hydroponics/harvest.dmi differ diff --git a/icons/obj/service/hydroponics/seeds.dmi b/icons/obj/service/hydroponics/seeds.dmi index 4de1a757e1f..c18c361b0ec 100644 Binary files a/icons/obj/service/hydroponics/seeds.dmi and b/icons/obj/service/hydroponics/seeds.dmi differ diff --git a/icons/obj/toys/dice.dmi b/icons/obj/toys/dice.dmi index d41e503242d..26cf08af5b9 100644 Binary files a/icons/obj/toys/dice.dmi and b/icons/obj/toys/dice.dmi differ diff --git a/icons/obj/weapons/bows/arrows.dmi b/icons/obj/weapons/bows/arrows.dmi index 4453d4ca5f2..a6d7678e2f0 100644 Binary files a/icons/obj/weapons/bows/arrows.dmi and b/icons/obj/weapons/bows/arrows.dmi differ diff --git a/icons/obj/weapons/bows/bows.dmi b/icons/obj/weapons/bows/bows.dmi index 81b2fc48220..5e2dda9cef6 100644 Binary files a/icons/obj/weapons/bows/bows.dmi and b/icons/obj/weapons/bows/bows.dmi differ diff --git a/icons/obj/weapons/khopesh.dmi b/icons/obj/weapons/khopesh.dmi index 3c4ba40b34a..6f4a040f6a4 100644 Binary files a/icons/obj/weapons/khopesh.dmi and b/icons/obj/weapons/khopesh.dmi differ diff --git a/icons/obj/weapons/shields.dmi b/icons/obj/weapons/shields.dmi index 99e9b06aa40..eec85e9bea1 100644 Binary files a/icons/obj/weapons/shields.dmi and b/icons/obj/weapons/shields.dmi differ diff --git a/icons/obj/weapons/stabby.dmi b/icons/obj/weapons/stabby.dmi index 24d4e0aef31..be125b5f31d 100644 Binary files a/icons/obj/weapons/stabby.dmi and b/icons/obj/weapons/stabby.dmi differ diff --git a/icons/obj/weapons/staff.dmi b/icons/obj/weapons/staff.dmi index 2d1460cf7e9..45c20ae17e5 100644 Binary files a/icons/obj/weapons/staff.dmi and b/icons/obj/weapons/staff.dmi differ diff --git a/icons/obj/weapons/sword.dmi b/icons/obj/weapons/sword.dmi index d9a443cfc26..9464c7b4745 100644 Binary files a/icons/obj/weapons/sword.dmi and b/icons/obj/weapons/sword.dmi differ diff --git a/lua/timer.lua b/lua/timer.lua index 8619bbb54a2..e88fdd80607 100644 --- a/lua/timer.lua +++ b/lua/timer.lua @@ -61,9 +61,15 @@ __Timer_timer_process = function(seconds_per_tick) end function Timer.wait(time) +<<<<<<< HEAD local next_yield_index = __next_yield_index __add_internal_timer(function() SSlua:call_proc("queue_resume", state.state, next_yield_index) +======= + local yieldIndex = _exec.next_yield_index + __add_internal_timer(function() + SSlua:queue_resume(state.state, yieldIndex) +>>>>>>> 6577c58b948b (Fixes lua function SS13.wait. (#85427)) end, time * 10, false) coroutine.yield() end diff --git a/modular_skyrat/master_files/code/modules/cargo/bounties/medical.dm b/modular_skyrat/master_files/code/modules/cargo/bounties/medical.dm index e1b032bbc33..4ef9b0d1620 100644 --- a/modular_skyrat/master_files/code/modules/cargo/bounties/medical.dm +++ b/modular_skyrat/master_files/code/modules/cargo/bounties/medical.dm @@ -1,2 +1,28 @@ /datum/bounty/item/medical/tongue - description = "A recent attack by Mime extremists has left staff at Station 23 speechless. Ship some spare tongues. We'll accept cybernetic variants if need be." \ No newline at end of file + description = "A recent attack by Mime extremists has left staff at Station 23 speechless. Ship some spare tongues. We'll accept cybernetic variants if need be." + wanted_types = list(/obj/item/organ/internal/tongue/synth = FALSE,) + +/datum/bounty/item/medical/heart + wanted_types = list( + /obj/item/organ/internal/heart/synth = FALSE, + ) + +/datum/bounty/item/medical/lung + wanted_types = list( + /obj/item/organ/internal/lungs/synth = FALSE, + ) + +/datum/bounty/item/medical/ears + wanted_types = list( + /obj/item/organ/internal/ears/synth = FALSE, + ) + +/datum/bounty/item/medical/liver + wanted_types = list( + /obj/item/organ/internal/liver/synth = FALSE, + ) + +/datum/bounty/item/medical/eye + wanted_types = list( + /obj/item/organ/internal/eyes/synth = FALSE, + ) diff --git a/modular_skyrat/master_files/code/modules/client/preferences/genitals.dm b/modular_skyrat/master_files/code/modules/client/preferences/genitals.dm index 9f7926b9795..8c89617fa16 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences/genitals.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences/genitals.dm @@ -199,9 +199,24 @@ var/part_enabled = is_factual_sprite_accessory(relevant_mutant_bodypart, preferences.read_preference(/datum/preference/choiced/genital/penis)) return erp_allowed && part_enabled && (passed_initial_check || allowed) -/datum/preference/numeric/penis_length/apply_to_human(mob/living/carbon/human/target, value) +/// The difference between the absolute max length and the length for normal sized mobs +#define PENIS_LENGTH_ABOVE_NORMAL PENIS_MAX_LENGTH - PENIS_MAX_LENGTH_NORMAL_SIZED + +/datum/preference/numeric/penis_length/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + // Adjust allowed size based on character size + var/body_size = preferences?.read_preference(/datum/preference/numeric/body_size) || BODY_SIZE_NORMAL + var/has_oversized_quirk = preferences?.all_quirks.Find(/datum/quirk/oversized::name) + // Clamp this for normal sized characters. Max allowed size is proportional to the mob's body_size, rounded up. + if(!has_oversized_quirk) + var/adjusted_size = PENIS_MAX_LENGTH_NORMAL_SIZED + if(body_size > 1) + adjusted_size = ceil(round(PENIS_MAX_LENGTH_NORMAL_SIZED, step) + ((((body_size - round(1, step)) * round(2, step))) * round(PENIS_LENGTH_ABOVE_NORMAL, step))) // floating point inaccuracy fun + if(value > adjusted_size) + value = adjusted_size target.dna.features["penis_size"] = value +#undef PENIS_LENGTH_ABOVE_NORMAL + /datum/preference/numeric/penis_length/create_default_value() // if you change from this to PENIS_MAX_LENGTH the game should laugh at you return round(max(PENIS_MIN_LENGTH, PENIS_DEFAULT_LENGTH)) @@ -220,9 +235,24 @@ var/part_enabled = is_factual_sprite_accessory(relevant_mutant_bodypart, preferences.read_preference(/datum/preference/choiced/genital/penis)) return erp_allowed && part_enabled && (passed_initial_check || allowed) -/datum/preference/numeric/penis_girth/apply_to_human(mob/living/carbon/human/target, value) +/// The difference between the absolute max girth and the girth for normal sized mobs +#define PENIS_GIRTH_ABOVE_NORMAL PENIS_MAX_GIRTH - PENIS_MAX_GIRTH_NORMAL_SIZED + +/datum/preference/numeric/penis_girth/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences) + // Adjust allowed size based on character size + var/body_size = preferences?.read_preference(/datum/preference/numeric/body_size) || BODY_SIZE_NORMAL + var/has_oversized_quirk = preferences?.all_quirks.Find(/datum/quirk/oversized::name) + // Clamp this for normal sized characters. Max allowed size is proportional to the mob's body_size, rounded up. + if(!has_oversized_quirk) + var/adjusted_size = PENIS_MAX_GIRTH_NORMAL_SIZED + if(body_size > 1) + adjusted_size = ceil(round(PENIS_MAX_GIRTH_NORMAL_SIZED, step) + ((((body_size - round(1, step)) * round(2, step))) * round(PENIS_GIRTH_ABOVE_NORMAL, step))) // floating point inaccuracy fun + if(value > adjusted_size) + value = adjusted_size target.dna.features["penis_girth"] = value +#undef PENIS_GIRTH_ABOVE_NORMAL + /datum/preference/numeric/penis_girth/create_default_value() return round(max(PENIS_MIN_GIRTH, PENIS_DEFAULT_GIRTH)) @@ -323,7 +353,7 @@ savefile_key = "balls_size" relevant_mutant_bodypart = ORGAN_SLOT_TESTICLES minimum = 0 - maximum = 3 + maximum = 6 /datum/preference/numeric/balls_size/is_accessible(datum/preferences/preferences) var/passed_initial_check = ..(preferences) diff --git a/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic/bows/_bow.dm b/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic/bows/_bow.dm index 2161b681105..802e7820d4a 100644 --- a/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic/bows/_bow.dm +++ b/modular_skyrat/master_files/code/modules/projectiles/guns/ballistic/bows/_bow.dm @@ -6,3 +6,12 @@ . = ..() if(chambered) playsound(src, 'modular_skyrat/modules/tribal_extended/sound/sound_weapons_bowdraw.ogg', 75, 0) + +/obj/item/gun/ballistic/bow/click_alt(mob/user) + . = ..() + SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD) + +/obj/item/gun/ballistic/bow/drop_arrow() + . = ..() + SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD) + diff --git a/modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/taur_testicles_onmob.dmi b/modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/taur_testicles_onmob.dmi index 3018b88aeee..eadcbcdd58c 100644 Binary files a/modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/taur_testicles_onmob.dmi and b/modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/taur_testicles_onmob.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/testicles_onmob.dmi b/modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/testicles_onmob.dmi index 885c1b903c9..17ccc9df8b2 100644 Binary files a/modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/testicles_onmob.dmi and b/modular_skyrat/master_files/icons/mob/sprite_accessory/genitals/testicles_onmob.dmi differ diff --git a/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm b/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm index 7707f15cc09..49e4751e498 100644 --- a/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm +++ b/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm @@ -221,7 +221,7 @@ "Culinary Artist", "Sous-Chef", "Junior Chef", - "Tavern Chef",, + "Tavern Chef", "Confectionist", "Pastry Chef", ) diff --git a/modular_skyrat/modules/ashwalkers/code/buildings/ash_farming.dm b/modular_skyrat/modules/ashwalkers/code/buildings/ash_farming.dm index ddd3f209358..bc838bef5ec 100644 --- a/modular_skyrat/modules/ashwalkers/code/buildings/ash_farming.dm +++ b/modular_skyrat/modules/ashwalkers/code/buildings/ash_farming.dm @@ -82,6 +82,11 @@ var/atom/attached_atom ///the seed that is held within var/obj/item/seeds/planted_seed + /// The amount of worms we're storing + var/stored_worms = 0 + /// the farm level we're at + var/farm_level = SKILL_LEVEL_NONE + ///the max amount harvested from the plants var/max_harvest = 3 ///the cooldown amount between each harvest @@ -114,12 +119,10 @@ /obj/structure/simple_farm/examine(mob/user) . = ..() . += span_notice("
[src] will be ready for harvest in [DisplayTimeText(COOLDOWN_TIMELEFT(src, harvest_timer))]") - if(max_harvest < 6) - . += span_notice("
You can use sinew or worm fertilizer to lower the time between each harvest!") - if(harvest_cooldown > 30 SECONDS) - . += span_notice("You can use goliath hides or worm fertilizer to increase the amount dropped per harvest!") - if(bonus_potency < 50) - . += span_notice("You can use worm fertilizer to increase the potency of dropped crops!") + if(farm_level < SKILL_LEVEL_LEGENDARY) + . += span_notice("
You can use worm fertilizer to increase the level of the farm.") + if(stored_worms < 5) + . += span_notice("
You can use worms to increase the performance of the farm.") /obj/structure/simple_farm/process(seconds_per_tick) update_appearance() @@ -164,129 +167,87 @@ Destroy() return - //if its sinew, lower the cooldown - else if(istype(attacking_item, /obj/item/stack/sheet/sinew)) - var/obj/item/stack/sheet/sinew/use_item = attacking_item - - if(!use_item.use(1)) - return - - decrease_cooldown(user) - user.mind.adjust_experience(/datum/skill/primitive, 5) - return - - //if its goliath hide, increase the amount dropped - else if(istype(attacking_item, /obj/item/stack/sheet/animalhide/goliath_hide)) - var/obj/item/stack/sheet/animalhide/goliath_hide/use_item = attacking_item - - if(!use_item.use(1)) - return - - increase_yield(user) - user.mind.adjust_experience(/datum/skill/primitive, 5) - return - - else if(istype(attacking_item, /obj/item/stack/worm_fertilizer)) - - var/obj/item/stack/attacking_stack = attacking_item - - if(!allow_yield_increase() && !allow_decrease_cooldown()) - balloon_alert(user, "plant is already fully upgraded") - return - - if(!attacking_stack.use(1)) - balloon_alert(user, "unable to use [attacking_item]") - return - - if(!decrease_cooldown(user, silent = TRUE) && !increase_yield(user, silent = TRUE) && !increase_potency(user, silent = TRUE)) - balloon_alert(user, "plant is already fully upgraded") - - else - balloon_alert(user, "plant was upgraded") - user.mind.adjust_experience(/datum/skill/primitive, 5) - - return - + //if its a bag, harvest else if(istype(attacking_item, /obj/item/storage/bag/plants)) if(!COOLDOWN_FINISHED(src, harvest_timer)) return COOLDOWN_START(src, harvest_timer, harvest_cooldown) create_harvest(attacking_item, user) - user.mind.adjust_experience(/datum/skill/primitive, 5) + user.mind.adjust_experience(/datum/skill/primitive, 15) update_appearance() return + //if its fertilizer, boost our level + else if(istype(attacking_item, /obj/item/stack/worm_fertilizer)) + user.mind.adjust_experience(/datum/skill/primitive, 5) + if(farm_level >= SKILL_LEVEL_LEGENDARY) + balloon_alert(user, "farm already max level!") + return + + var/obj/item/stack/worm_fertilizer/fertilizer = attacking_item + if(!fertilizer.use(1)) + return + + balloon_alert(user, "increased farm level") + farm_level++ + return + + //if its worms, increase our worms + else if(istype(attacking_item, /obj/item/food/bait/worm)) + user.mind.adjust_experience(/datum/skill/primitive, 5) + if(stored_worms >= 5) + balloon_alert(user, "plant already full on worms!") + return + + balloon_alert(user, "applied worm") + qdel(attacking_item) + stored_worms++ + return + return ..() -/** - * a proc that will check if we can increase the yield-- without increasing it - */ -/obj/structure/simple_farm/proc/allow_yield_increase() - if(max_harvest >= 6) - return FALSE +/obj/structure/simple_farm/proc/increase_level(new_level) + while(new_level > farm_level) + farm_level++ + switch(farm_level) + if(SKILL_LEVEL_NOVICE) + //you figure out the weird red color these apples have doesnt make them inedible + max_harvest += 1 + bonus_potency += 10 - return TRUE + if(SKILL_LEVEL_APPRENTICE) + //hey these plants are the most ripe at this time in the season + max_harvest += 1 -/** - * a proc that will increase the amount of items the crop could produce (at a maximum of 6, from base of 3) - */ -/obj/structure/simple_farm/proc/increase_yield(mob/user, var/silent = FALSE) - if(!allow_yield_increase()) - if(!silent) - balloon_alert(user, "plant is at maximum yield") + if(SKILL_LEVEL_JOURNEYMAN) + //HEY, LADDERS EXIST, GO GET THOSE TREETOP FRUITS + harvest_cooldown -= 10 SECONDS + bonus_potency += 10 - return FALSE + if(SKILL_LEVEL_EXPERT) + //oh so THATS why im getting mold on produce + max_harvest += 1 - max_harvest++ + if(SKILL_LEVEL_MASTER) + //you realize you can let some frogs eat pests for you + harvest_cooldown -= 10 SECONDS + bonus_potency += 10 - if(!silent) - balloon_alert_to_viewers("plant will have increased yield") + if(SKILL_LEVEL_LEGENDARY) + //the PLANTS know who's their TENDER + var/static/list/color_matrix_were_rich = list( + 1.5, 1, 0, 0, + 1.5, 1, 0, 0, + 0, 0, 0.5, 0, + 0, 0, 0, 1, + 0, 0, 0, 0 + ) + add_atom_colour(color_matrix_were_rich, FIXED_COLOUR_PRIORITY) + bonus_potency += 20 + harvest_cooldown -= 15 SECONDS + balloon_alert_to_viewers("[src] gains a golden glow!") - return TRUE - -/** - * a proc that will check if we can decrease the time-- without increasing it - */ -/obj/structure/simple_farm/proc/allow_decrease_cooldown() - if(harvest_cooldown <= 30 SECONDS) - return FALSE - - return TRUE - -/** - * a proc that will decrease the amount of time it takes to be ready for harvest (at a maximum of 30 seconds, from a base of 1 minute) - */ -/obj/structure/simple_farm/proc/decrease_cooldown(mob/user, var/silent = FALSE) - if(!allow_decrease_cooldown()) - if(!silent) - balloon_alert(user, "already at maximum growth speed!") - - return FALSE - - harvest_cooldown -= 10 SECONDS - - if(!silent) - balloon_alert_to_viewers("plant will grow faster") - - return TRUE - -/** - * a proc that will increase the potency the crop grows at - */ -/obj/structure/simple_farm/proc/increase_potency(mob/user, var/silent = FALSE) - if(bonus_potency >= 50) - if(!silent) - balloon_alert(user, "plant is at maximum potency") - - return FALSE - - bonus_potency += 10 - - if(!silent) - balloon_alert_to_viewers("plant will have increased potency") - - return TRUE /** * used during the component so that it can move when its attached atom moves @@ -309,7 +270,16 @@ if(!planted_seed) return - for(var/i in 1 to rand(1, max_harvest)) + var/lower_cap = rand(1, max_harvest) + for(var/i in 0 to stored_worms) + if(prob(15)) + continue + lower_cap = max(1, lower_cap - 1) + + if(farm_level >= SKILL_LEVEL_LEGENDARY) + lower_cap = 1 + + for(var/i in lower_cap to max_harvest) var/obj/item/seeds/seed if(prob(15) && length(planted_seed.mutatelist)) var/type = pick(planted_seed.mutatelist) @@ -318,7 +288,16 @@ else seed = new planted_seed.type(null) + //we're ASHIE GAMING, we do not concern ourselves with such puny concepts as purity + seed.endurance = 100 + seed.lifespan = 100 + seed.instability = 0 + //also that + seed.yield = 5 + max_harvest + seed.potency = 50 + bonus_potency + if(stored_worms) + seed.potency += stored_worms * 4 var/harvest_type = seed.product || seed.type var/harvest = new harvest_type(get_turf(src), seed) diff --git a/modular_skyrat/modules/borgs/icons/widerobot_eng.dmi b/modular_skyrat/modules/borgs/icons/widerobot_eng.dmi index 6b1e971faa9..1d673d14b0b 100644 Binary files a/modular_skyrat/modules/borgs/icons/widerobot_eng.dmi and b/modular_skyrat/modules/borgs/icons/widerobot_eng.dmi differ diff --git a/modular_skyrat/modules/borgs/icons/widerobot_jani.dmi b/modular_skyrat/modules/borgs/icons/widerobot_jani.dmi index f0c7f0bb252..ea97b8f973e 100644 Binary files a/modular_skyrat/modules/borgs/icons/widerobot_jani.dmi and b/modular_skyrat/modules/borgs/icons/widerobot_jani.dmi differ diff --git a/modular_skyrat/modules/borgs/icons/widerobot_med.dmi b/modular_skyrat/modules/borgs/icons/widerobot_med.dmi index ea893a92894..d0f8aa9ce3b 100644 Binary files a/modular_skyrat/modules/borgs/icons/widerobot_med.dmi and b/modular_skyrat/modules/borgs/icons/widerobot_med.dmi differ diff --git a/modular_skyrat/modules/borgs/icons/widerobot_mine.dmi b/modular_skyrat/modules/borgs/icons/widerobot_mine.dmi index b72fb56d41c..b8e7a5c5ed5 100644 Binary files a/modular_skyrat/modules/borgs/icons/widerobot_mine.dmi and b/modular_skyrat/modules/borgs/icons/widerobot_mine.dmi differ diff --git a/modular_skyrat/modules/borgs/icons/widerobot_pk.dmi b/modular_skyrat/modules/borgs/icons/widerobot_pk.dmi index fad43b6d1e6..ae69a3fa7a0 100644 Binary files a/modular_skyrat/modules/borgs/icons/widerobot_pk.dmi and b/modular_skyrat/modules/borgs/icons/widerobot_pk.dmi differ diff --git a/modular_skyrat/modules/borgs/icons/widerobot_sec.dmi b/modular_skyrat/modules/borgs/icons/widerobot_sec.dmi index 44e5f13d190..5959fa59105 100644 Binary files a/modular_skyrat/modules/borgs/icons/widerobot_sec.dmi and b/modular_skyrat/modules/borgs/icons/widerobot_sec.dmi differ diff --git a/modular_skyrat/modules/borgs/icons/widerobot_serv.dmi b/modular_skyrat/modules/borgs/icons/widerobot_serv.dmi index f212892b9a9..6ab5d2a2f9b 100644 Binary files a/modular_skyrat/modules/borgs/icons/widerobot_serv.dmi and b/modular_skyrat/modules/borgs/icons/widerobot_serv.dmi differ diff --git a/modular_skyrat/modules/borgs/icons/widerobots_cargo.dmi b/modular_skyrat/modules/borgs/icons/widerobots_cargo.dmi index cd1e46bea44..d4e8298eba3 100644 Binary files a/modular_skyrat/modules/borgs/icons/widerobots_cargo.dmi and b/modular_skyrat/modules/borgs/icons/widerobots_cargo.dmi differ diff --git a/modular_skyrat/modules/cargo/code/packs.dm b/modular_skyrat/modules/cargo/code/packs.dm index 423ffec0c2d..9f1236ab7b5 100644 --- a/modular_skyrat/modules/cargo/code/packs.dm +++ b/modular_skyrat/modules/cargo/code/packs.dm @@ -698,8 +698,8 @@ /obj/item/clothing/suit/armor/vest/cuirass/larp, /obj/item/gun/ballistic/bow/longbow, /obj/item/gun/ballistic/bow/longbow, - /obj/item/storage/bag/quiver, - /obj/item/storage/bag/quiver, + /obj/item/storage/bag/quiver/full, + /obj/item/storage/bag/quiver/full, /obj/item/clothing/head/helmet/knight/red, /obj/item/clothing/head/helmet/knight/blue, /obj/item/food/bread/plain, diff --git a/modular_skyrat/modules/chat_colors/code/chat_color.dm b/modular_skyrat/modules/chat_colors/code/chat_color.dm index 8d17d3b46c9..a103a0456bb 100644 --- a/modular_skyrat/modules/chat_colors/code/chat_color.dm +++ b/modular_skyrat/modules/chat_colors/code/chat_color.dm @@ -78,7 +78,7 @@ var/luminance = hsl_color[NCM_COLOR_LUMINANCE] // Cap the saturation at 90% - saturation = min(saturation, CM_COLOR_SAT_MAX) + saturation = min(saturation, NCM_COLOR_SAT_MAX) // Now clamp the luminance according to the hue var/processed_luminance diff --git a/modular_skyrat/modules/customization/_globalvars/lists.dm b/modular_skyrat/modules/customization/_globalvars/lists.dm index b684abf4e1c..ae6b2478c32 100644 --- a/modular_skyrat/modules/customization/_globalvars/lists.dm +++ b/modular_skyrat/modules/customization/_globalvars/lists.dm @@ -45,7 +45,10 @@ GLOBAL_LIST_INIT(balls_size_translation, list( "0" = "Small", "1" = "Average", "2" = "Big", - "3" = "Enormous" + "3" = "Very Big", + "4" = "Enormous", + "5" = "Immense", + "6" = "Gargantuan" )) GLOBAL_LIST_INIT(marking_zone_to_bitflag, list( @@ -74,7 +77,10 @@ GLOBAL_LIST_INIT(preference_balls_sizes, list( "Small", "Average", "Big", + "Very Big", "Enormous", + "Immense", + "Gargantuan" )) GLOBAL_LIST_INIT(robotic_styles_list, list( diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/wings.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/wings.dm index 53deb332370..ce776e72110 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/wings.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/wings.dm @@ -200,6 +200,7 @@ /datum/sprite_accessory/wings/mammal/harpy/bat name = "Harpy (Bat)" icon_state = "harpybat" + color_src = USE_MATRIXED_COLORS /datum/sprite_accessory/wings/mammal/top/harpy/alt name = "Harpy (Top - Alt)" @@ -212,6 +213,7 @@ /datum/sprite_accessory/wings/mammal/top/harpy/bat name = "Harpy (Top - Bat)" icon_state = "harpybat_top" + color_src = USE_MATRIXED_COLORS /datum/sprite_accessory/wings/mammal/pterodactyl name = "Pterodactyl" diff --git a/modular_skyrat/modules/customization/modules/surgery/organs/genitals.dm b/modular_skyrat/modules/customization/modules/surgery/organs/genitals.dm index 1c9131e5698..68e72da16c2 100644 --- a/modular_skyrat/modules/customization/modules/surgery/organs/genitals.dm +++ b/modular_skyrat/modules/customization/modules/surgery/organs/genitals.dm @@ -259,7 +259,7 @@ layers = EXTERNAL_ADJACENT | EXTERNAL_BEHIND /obj/item/organ/external/genital/testicles/update_genital_icon_state() - var/measured_size = clamp(genital_size, 1, 3) + var/measured_size = clamp(genital_size, 1, 6) var/passed_string = "testicles_[genital_type]_[measured_size]" if(uses_skintones) passed_string += "_s" @@ -283,7 +283,7 @@ /obj/item/organ/external/genital/testicles/get_sprite_size_string() var/measured_size = FLOOR(genital_size,1) - measured_size = clamp(measured_size, 0, 3) + measured_size = clamp(measured_size, 0, 6) var/passed_string = "[genital_type]_[measured_size]" if(uses_skintones) passed_string += "_s" diff --git a/modular_skyrat/modules/goofsec/code/department_guards.dm b/modular_skyrat/modules/goofsec/code/department_guards.dm index c5818361ad9..c8b84a773c6 100644 --- a/modular_skyrat/modules/goofsec/code/department_guards.dm +++ b/modular_skyrat/modules/goofsec/code/department_guards.dm @@ -145,7 +145,7 @@ icon = 'modular_skyrat/master_files/icons/mob/landmarks.dmi' /obj/effect/landmark/start/bouncer - name = "Service Guard" + name = "Bouncer" icon_state = "Bouncer" icon = 'modular_skyrat/master_files/icons/mob/landmarks.dmi' diff --git a/modular_skyrat/modules/implants/code/augments_internal.dm b/modular_skyrat/modules/implants/code/augments_internal.dm index 1523ee7cbc0..ea4158bfc23 100644 --- a/modular_skyrat/modules/implants/code/augments_internal.dm +++ b/modular_skyrat/modules/implants/code/augments_internal.dm @@ -1,35 +1,36 @@ /obj/item/organ/internal/cyberimp/brain/anti_sleep name = "CNS jumpstarter" desc = "This implant will automatically attempt to jolt you awake when it detects you have fallen unconscious outside of REM sleeping cycles. Has a short cooldown. Conflicts with the CNS Rebooter, making them incompatible with eachother." + icon_state = "brain_implant_rebooter" implant_color = "#0356fc" slot = ORGAN_SLOT_BRAIN_ANTISTUN //One or the other, not both. - var/cooldown = FALSE + var/cooldown -/obj/item/organ/internal/cyberimp/brain/anti_sleep/on_life(mob/living/carbon/human/H) - H = owner - if(H.stat == UNCONSCIOUS && cooldown==FALSE) - H.AdjustUnconscious(-100, FALSE) - H.AdjustSleeping(-100, FALSE) - to_chat(owner, span_notice("You feel a rush of energy course through your body!")) - cooldown = TRUE - addtimer(CALLBACK(src, PROC_REF(sleepytimerend)), 5 SECONDS) - else +/obj/item/organ/internal/cyberimp/brain/anti_sleep/on_life(seconds_per_tick, times_fired) + if(timeleft(cooldown)) return -/obj/item/organ/internal/cyberimp/brain/anti_sleep/proc/sleepytimerend() - cooldown = FALSE - to_chat(owner, span_notice("You hear a small beep in your head as your CNS Jumpstarter finishes recharging.")) + var/mob/living/carbon/human/human_owner = owner + if(human_owner.stat != UNCONSCIOUS) + return -/obj/item/organ/internal/cyberimp/brain/anti_sleep/emp_act(severity, mob/living/carbon/human/H) + human_owner.AdjustUnconscious(-50 * seconds_per_tick, FALSE) + human_owner.AdjustSleeping(-50 * seconds_per_tick, FALSE) + to_chat(owner, span_notice("You feel a rush of energy course through your body!")) + cooldown = addtimer(CALLBACK(src, PROC_REF(sleepytimerend)), 5 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE | TIMER_DELETE_ME) + +/obj/item/organ/internal/cyberimp/brain/anti_sleep/proc/sleepytimerend() + to_chat(owner, span_notice("You hear a small beep in your head as your CNS Jumpstarter finishes recharging.")) + cooldown = null + +/obj/item/organ/internal/cyberimp/brain/anti_sleep/emp_act(severity) . = ..() - H = owner + var/mob/living/carbon/human/human_owner = owner if((organ_flags & ORGAN_FAILING) || . & EMP_PROTECT_SELF) return organ_flags |= ORGAN_FAILING - H.AdjustUnconscious(200) - cooldown = TRUE - addtimer(CALLBACK(src, PROC_REF(reboot)), 90 / severity) + human_owner.AdjustUnconscious(200) + cooldown = addtimer(CALLBACK(src, PROC_REF(reboot)), (9 SECONDS / severity), TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE | TIMER_DELETE_ME) /obj/item/organ/internal/cyberimp/brain/anti_sleep/proc/reboot() organ_flags &= ~ORGAN_FAILING - cooldown = FALSE diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/attachable_vibrator.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/attachable_vibrator.dm index 1db92a08430..bcff9841d2a 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/attachable_vibrator.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/attachable_vibrator.dm @@ -2,6 +2,11 @@ * VIBRATING EGG */ +#define EGGVIB_OFF "off" +#define EGGVIB_LOW "low" +#define EGGVIB_MEDIUM "medium" +#define EGGVIB_HIGH "high" + /obj/item/clothing/sextoy/eggvib name = "vibrating egg" desc = "A simple, vibrating sex toy." @@ -20,9 +25,7 @@ /// Bool of if the color's been changed or not before var/color_changed = FALSE /// The current mode of the toy, affects sprite - var/vibration_mode = "off" - /// Assoc list of modes, used to transfer between them - var/list/modes = list("low" = "medium", "medium" = "high", "high" = "off", "off" = "low") + var/vibration_mode = EGGVIB_OFF /// A looping sound called on process() var/datum/looping_sound/lewd/vibrator/low/soundloop1 /// A looping sound called on process() @@ -39,6 +42,13 @@ "pink" = image(icon = src.icon, icon_state = "[initial(base_icon_state)]_pink_low[(istype(src, /obj/item/clothing/sextoy/eggvib/signalvib)) ? "_on" : ""]"), "teal" = image(icon = src.icon, icon_state = "[initial(base_icon_state)]_teal_low[(istype(src, /obj/item/clothing/sextoy/eggvib/signalvib)) ? "_on" : ""]")) +/obj/item/clothing/sextoy/eggvib/examine(mob/user) + . = ..() + if(!color_changed) + . += span_notice("Alt-click to change it's colors.") + else + . += span_notice("Alt-click to toggle vibration modes.") + /obj/item/clothing/sextoy/eggvib/click_alt(mob/user) if(!color_changed) var/choice = show_radial_menu(user, src, vib_designs, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE) @@ -50,13 +60,13 @@ else toggle_mode() switch(vibration_mode) - if("low") + if(EGGVIB_LOW) to_chat(user, span_notice("You set the vibration mode to low. Bzzz...")) - if("medium") + if(EGGVIB_MEDIUM) to_chat(user, span_notice("You set the vibration mode to medium. Bzzzz!")) - if("high") + if(EGGVIB_HIGH) to_chat(user, span_notice("You set the vibration mode to high. Careful with that thing.")) - if("off") + if(EGGVIB_OFF) to_chat(user, span_notice("You turn off the vibrating egg. Fun time's over.")) update_icon() update_icon_state() @@ -87,26 +97,27 @@ /// Toggles between vibration modes seuentially /obj/item/clothing/sextoy/eggvib/proc/toggle_mode() - vibration_mode = modes[vibration_mode] - soundloop1.stop() - soundloop2.stop() - soundloop3.stop() switch(vibration_mode) - if("low") + if(EGGVIB_OFF) + vibration_mode = EGGVIB_LOW toy_on = TRUE play_lewd_sound(loc, 'sound/weapons/magin.ogg', 20, TRUE) soundloop1.start() - if("medium") - toy_on = TRUE + if(EGGVIB_LOW) + vibration_mode = EGGVIB_MEDIUM play_lewd_sound(loc, 'sound/weapons/magin.ogg', 20, TRUE) + soundloop1.stop() soundloop2.start() - if("high") - toy_on = TRUE + if(EGGVIB_MEDIUM) + vibration_mode = EGGVIB_HIGH play_lewd_sound(loc, 'sound/weapons/magin.ogg', 20, TRUE) + soundloop2.stop() soundloop3.start() - if("off") + if(EGGVIB_HIGH) + vibration_mode = EGGVIB_OFF toy_on = FALSE play_lewd_sound(loc, 'sound/weapons/magout.ogg', 20, TRUE) + soundloop3.stop() /obj/item/clothing/sextoy/eggvib/lewd_equipped(mob/living/carbon/human/user, slot, initial) . = ..() @@ -125,15 +136,16 @@ var/mob/living/carbon/human/target = loc if(!istype(target)) return - if(vibration_mode == "low") - target.adjust_arousal(0.5 * seconds_per_tick) - target.adjust_pleasure(0.5 * seconds_per_tick) - if(vibration_mode == "medium") - target.adjust_arousal(0.6 * seconds_per_tick) - target.adjust_pleasure(0.6 * seconds_per_tick) - if(vibration_mode == "high") - target.adjust_arousal(0.7 * seconds_per_tick) - target.adjust_pleasure(0.7 * seconds_per_tick) + switch(vibration_mode) + if(EGGVIB_LOW) + target.adjust_arousal(0.5 * seconds_per_tick) + target.adjust_pleasure(0.5 * seconds_per_tick) + if(EGGVIB_MEDIUM) + target.adjust_arousal(0.6 * seconds_per_tick) + target.adjust_pleasure(0.6 * seconds_per_tick) + if(EGGVIB_HIGH) + target.adjust_arousal(0.7 * seconds_per_tick) + target.adjust_pleasure(0.7 * seconds_per_tick) /* * SIGNALLER CONTROLLED EGG @@ -145,8 +157,7 @@ icon_state = "signalvib_pink_low_off" base_icon_state = "signalvib" inhand_icon_state = "signalvib_pink" - modes = list("low" = "medium", "medium" = "high", "high" = "low") - vibration_mode = "low" + vibration_mode = EGGVIB_LOW /// If TRUE, the code and frequency will be random on initialize() var/random = TRUE /// If TRUE, the set code and frequency will be appended to the toy's name @@ -175,7 +186,7 @@ /obj/item/clothing/sextoy/eggvib/signalvib/update_icon_state() . = ..() - icon_state = "[base_icon_state]_[current_color]_[vibration_mode == "off" ? "low_off" : (toy_on ? "[vibration_mode]_on" : "[vibration_mode]_off")]" + icon_state = "[base_icon_state]_[current_color]_[vibration_mode == EGGVIB_OFF ? "low_off" : (toy_on ? "[vibration_mode]_on" : "[vibration_mode]_off")]" inhand_icon_state = "[base_icon_state]_[current_color]" /obj/item/clothing/sextoy/eggvib/signalvib/proc/set_frequency(new_frequency) @@ -205,13 +216,13 @@ soundloop2.stop() soundloop3.stop() switch(vibration_mode) - if("low") + if(EGGVIB_LOW) to_chat(user, span_notice("You set the vibration mode to low. Bzzz...")) soundloop1.start() - if("medium") + if(EGGVIB_MEDIUM) to_chat(user, span_notice("You set the vibration mode to medium. Bzzzz!")) soundloop2.start() - if("high") + if(EGGVIB_HIGH) to_chat(user, span_notice("You set the vibration mode to high. Careful with that thing!")) soundloop3.start() update_icon() @@ -230,11 +241,11 @@ soundloop1.stop() soundloop2.stop() soundloop3.stop() - if(vibration_mode == "low") + if(vibration_mode == EGGVIB_LOW) soundloop1.start() - if(vibration_mode == "medium") + if(vibration_mode == EGGVIB_MEDIUM) soundloop2.start() - if(vibration_mode == "high") + if(vibration_mode == EGGVIB_HIGH) soundloop3.start() else soundloop1.stop() @@ -289,14 +300,13 @@ soundloop2.stop() soundloop3.stop() if(toy_on) - if(vibration_mode == "low") + if(vibration_mode == EGGVIB_LOW) soundloop1.start() - if(vibration_mode == "medium") + if(vibration_mode == EGGVIB_MEDIUM) soundloop2.start() - if(vibration_mode == "high") + if(vibration_mode == EGGVIB_HIGH) soundloop3.start() - - if(!toy_on) + else soundloop1.stop() soundloop2.stop() soundloop3.stop() @@ -322,14 +332,18 @@ . = TRUE /obj/item/clothing/sextoy/eggvib/signalvib/toggle_mode() - vibration_mode = modes[vibration_mode] switch(vibration_mode) - if("low") - vibration_mode = "low" + if(EGGVIB_LOW) + vibration_mode = EGGVIB_MEDIUM play_lewd_sound(loc, 'sound/weapons/magin.ogg', 20, TRUE) - if("medium") - vibration_mode = "medium" + if(EGGVIB_MEDIUM) + vibration_mode = EGGVIB_HIGH play_lewd_sound(loc, 'sound/weapons/magin.ogg', 20, TRUE) - if("high") - vibration_mode = "high" + if(EGGVIB_HIGH) + vibration_mode = EGGVIB_LOW play_lewd_sound(loc, 'sound/weapons/magin.ogg', 20, TRUE) + +#undef EGGVIB_OFF +#undef EGGVIB_LOW +#undef EGGVIB_HIGH +#undef EGGVIB_MEDIUM diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/buttplug.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/buttplug.dm index 5bcc5129e03..f36ae0f6baf 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/buttplug.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/buttplug.dm @@ -40,6 +40,13 @@ "medium" = image(icon = src.icon, icon_state = "buttplug_pink_medium"), "big" = image(icon = src.icon, icon_state = "buttplug_pink_big")) +/obj/item/clothing/sextoy/buttplug/examine(mob/user) + . = ..() + if(!color_changed) + . += span_notice("Alt-click to change it's colors.") + else if(!form_changed) + . += span_notice("Alt-click to change it's size.") + /obj/item/clothing/sextoy/buttplug/click_alt(mob/user) if(!color_changed) var/choice = show_radial_menu(user, src, buttplug_designs, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE) @@ -53,7 +60,7 @@ color_changed = TRUE return CLICK_ACTION_SUCCESS else - if(form_changed == FALSE) + if(!form_changed) var/choice = show_radial_menu(user, src, buttplug_forms, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE) if(!choice) return CLICK_ACTION_BLOCKING diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/clamps.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/clamps.dm index 7e7b6dda7ca..00f5c762858 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/clamps.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/clamps.dm @@ -26,7 +26,7 @@ update_icon_state() - clamps_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi', "[initial(icon_state)]_[breast_type]_[breast_size]", ABOVE_ALL_MOB_LAYER + 0.1) //two arguments. Yes, all mob layer. Fuck person who was working on genitals, they're working wrong.ABOVE_NORMAL_TURF_LAYER + clamps_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi', "[initial(icon_state)]_[breast_type]_[breast_size]", -BODY_FRONT_UNDER_CLOTHES) //two arguments. Yes, all mob layer. Fuck person who was working on genitals, they're working wrong.ABOVE_NORMAL_TURF_LAYER update_icon() update_appearance() @@ -52,7 +52,7 @@ update_icon_state() - clamps_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi', "[initial(icon_state)]_[breast_type]_[breast_size]", ABOVE_ALL_MOB_LAYER + 0.1) //two arguments + clamps_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi', "[initial(icon_state)]_[breast_type]_[breast_size]", -BODY_FRONT_UNDER_CLOTHES) //two arguments update_icon() update_appearance() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm index 9feeb963a09..6ddd3f8c3b6 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm @@ -41,6 +41,11 @@ "human" = image(icon = src.icon, icon_state = "[base_icon_state]_human"), "tentacle" = image(icon = src.icon, icon_state = "[base_icon_state]_tentacle")) +/obj/item/clothing/sextoy/dildo/examine(mob/user) + . = ..() + if(!color_changed && change_sprite) + . += span_notice("Alt-click to change it's designs.") + /obj/item/clothing/sextoy/dildo/click_alt(mob/user) if(color_changed) return CLICK_ACTION_BLOCKING @@ -91,14 +96,16 @@ /obj/item/clothing/sextoy/dildo/attack(mob/living/carbon/human/target, mob/living/carbon/human/user) . = ..() - if(!ishuman(target) || (target.stat == DEAD)) //Don't. + if(target.stat == DEAD) + return + if(!ishuman(target)) //Don't. return - var/message = "" if(!target.check_erp_prefs(/datum/preference/toggle/erp/sex_toy, user, src)) to_chat(user, span_danger("[target] doesn't want you to do that.")) return + var/message = "" var/arousal_adjustment = 4 var/pleasure_adjustment = 5 var/emote_probability = 20 @@ -106,50 +113,63 @@ switch(user.zone_selected) //to let code know what part of body we gonna fuck if(BODY_ZONE_PRECISE_GROIN) var/obj/item/organ/external/genital/vagina = target.get_organ_slot(ORGAN_SLOT_VAGINA) - if(!vagina) - to_chat(user, span_danger("[target] don't have suitable genitalia for that!")) + if(!vagina?.is_exposed()) + to_chat(user, span_danger("Looks like [target]'s groin is covered!")) return FALSE - if(!(target.is_bottomless() || vagina.visibility_preference == GENITAL_ALWAYS_SHOW)) - to_chat(user, span_danger("[target]'s groin is covered!")) - return FALSE + message = (user == target) ? pick("rubs [target.p_their()] vagina with [src]", + "gently jams [target.p_their()] pussy with [src]", + "fucks [target.p_their()] vagina with [src]") \ + : pick("delicately rubs [target]'s vagina with [src]", + "shoves [src] deep into [target]'s vagina", + "jams [src] into [target]'s pussy", + "teases [target]'s pussy with [src]") - message = (user == target) ? pick("rubs [target.p_their()] vagina with [src]", "gently jams [target.p_their()] pussy with [src]", "fucks [target.p_their()] vagina with a [src]") : pick("delicately rubs [target]'s vagina with [src]", "uses [src] to fuck [target]'s vagina", "jams [target]'s pussy with [src]", "teasing [target]'s pussy with [src]") - - if(poly_size == "medium") - arousal_adjustment = 6 - pleasure_adjustment = 8 - emote_probability = 40 - possible_emotes = list("moan","twitch_s") - - if(poly_size == "big") - arousal_adjustment = 8 - pleasure_adjustment = 10 - emote_probability = 60 - possible_emotes = list("moan","twitch_s", "gasp") - target.adjust_pain(2) + switch(poly_size) + if("medium") + arousal_adjustment = 6 + pleasure_adjustment = 8 + emote_probability = 40 + possible_emotes = list("moan","twitch_s") + if("big") + arousal_adjustment = 8 + pleasure_adjustment = 10 + emote_probability = 60 + possible_emotes = list("moan","twitch_s", "gasp") + target.adjust_pain(2) if(side_double) - user.adjust_arousal(6) - user.adjust_pleasure(8) + arousal_adjustment += 6 + pleasure_adjustment += 8 if(BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_PRECISE_EYES) //Mouth only. Sorry, perverts. No eye/ear penetration for you today. if(target.is_mouth_covered()) to_chat(user, span_danger("Looks like [target]'s mouth is covered!")) return FALSE - message = (user == target) ? pick("licks [src] erotically", "sucks on [src], slowly inserting it into [target.p_their()] throat") : pick("fucks [target]'s mouth with [src]", "inserts [src] into [target]'s throat, choking [target.p_them()]", "forces [target] to suck [src]", "inserts [src] into [target]'s throat") + message = (user == target) ? pick("licks [src] seductively", + "sucks on [src], slowly inserting it into [target.p_their()] throat") \ + : pick("fucks [target]'s mouth with [src]", + "shoves [src] into [target]'s throat, choking [target.p_them()]", + "forces [target] to suck [src]", + "inserts [src] into [target]'s throat") arousal_adjustment = 4 pleasure_adjustment = 1 emote_probability = 70 possible_emotes = list("gasp", "moan") else - if(!target.is_bottomless()) - to_chat(user, span_danger("[target]'s anus is covered!")) + var/obj/item/organ/external/genital/anus = target.get_organ_slot(ORGAN_SLOT_ANUS) + if(!anus?.is_exposed()) + to_chat(user, span_danger("Looks like [target]'s anus is covered!")) return FALSE - message = (user == target) ? pick("puts [src] into [target.p_their()] anus", "slowly inserts [src] into [target.p_their()] ass") : pick("fucks [target]'s ass with [src]", "uses [src] to fuck [target]'s anus", "jams [target]'s ass with [src]", "roughly fucks [target]'s ass with [src], making [target.p_their()] eyes roll back") + message = (user == target) ? pick("puts [src] into [target.p_their()] anus", + "slowly inserts [src] into [target.p_their()] ass") \ + : pick("fucks [target]'s ass with [src]", + "uses [src] to fuck [target]'s anus", + "jams [target]'s ass with [src]", + "fucks [target]'s ass with [src], making [target.p_their()] eyes roll back") arousal_adjustment = 5 pleasure_adjustment = 5 emote_probability = 60 @@ -207,21 +227,24 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors "medium" = image(icon = src.icon, icon_state = "[base_icon_state]_medium"), "big" = image(icon = src.icon, icon_state = "[base_icon_state]_big")) +/obj/item/clothing/sextoy/dildo/custom_dildo/examine(mob/user) + . = ..() + if(!size_changed && color_changed && change_sprite) + . += span_notice("Alt-click to change it's size.") + /obj/item/clothing/sextoy/dildo/custom_dildo/click_alt(mob/living/user) - if(!size_changed) + if(!color_changed) + if(!istype(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) + return CLICK_ACTION_BLOCKING + customize(user) + color_changed = TRUE + else if (!size_changed) var/choice = show_radial_menu(user, src, dildo_sizes, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE) if(!choice) return CLICK_ACTION_BLOCKING poly_size = choice update_icon() size_changed = TRUE - else - if(color_changed) - return CLICK_ACTION_BLOCKING - if(!istype(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return CLICK_ACTION_BLOCKING - customize(user) - color_changed = TRUE return CLICK_ACTION_SUCCESS /obj/item/clothing/sextoy/dildo/custom_dildo/Initialize(mapload) @@ -248,10 +271,6 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors update_icon_state() return TRUE -/obj/item/clothing/sextoy/dildo/custom_dildo/examine(mob/user) - . = ..() - . += span_notice("
Alt-Click \the [src.name] to customize it.") - /obj/item/clothing/sextoy/dildo/custom_dildo/update_icon_state() . = ..() icon_state = "[base_icon_state]_[poly_size]" diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/feather.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/feather.dm index 575ccc7e6cc..0502508dff3 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/feather.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/feather.dm @@ -10,78 +10,69 @@ /obj/item/tickle_feather/attack(mob/living/target, mob/living/user) . = ..() - var/mob/living/carbon/human/carbon_target - if(istype(target,/mob/living/carbon/human)) - carbon_target = target - else if(istype(target,/mob/living/silicon/robot)) - // Just use target var, return if it isn't human or robot - else + if(target.stat == DEAD) return - if(!istype(user,/mob/living/carbon/human) && !istype(user,/mob/living/silicon/robot)) + var/mob/living/carbon/human/carbon_target = target + if(!carbon_target && !iscyborg(target)) return var/message = "" - var/targetedsomewhere = FALSE switch(user.zone_selected) //to let code know what part of body we gonna tickle if(BODY_ZONE_PRECISE_GROIN) - targetedsomewhere = TRUE - if(carbon_target && !carbon_target.is_bottomless()) - to_chat(user, span_danger("[target]'s groin is covered!")) + if(!carbon_target?.is_bottomless()) + to_chat(user, span_danger("Looks like [target]'s groin is covered!")) return - message = (user == target) ? pick("tickles [target.p_them()]self with [src]", "gently teases [target.p_their()] belly with [src]") : pick("teases [target]'s belly with [src]", "uses [src] to tickle [target]'s belly", "tickles [target] with [src]") - if(target.stat == DEAD) - return - if(prob(70)) - target.try_lewd_autoemote(pick("laugh", "giggle", "twitch", "twitch_s")) + message = (user == target) ? pick("tickles [target.p_them()]self with [src]", + "gently teases [target.p_their()] belly with [src]") \ + : pick("teases [target]'s belly with [src]", + "uses [src] to tickle [target]'s belly", + "tickles [target] with [src]") if(BODY_ZONE_CHEST) - targetedsomewhere = TRUE if(carbon_target) var/obj/item/organ/external/genital/badonkers = carbon_target.get_organ_slot(ORGAN_SLOT_BREASTS) - if(!(carbon_target.is_topless() || badonkers.visibility_preference == GENITAL_ALWAYS_SHOW)) - to_chat(user, span_danger("[target]'s chest is covered!")) + if(!badonkers?.is_exposed()) + to_chat(user, span_danger("Looks like [target]'s chest is covered!")) return - message = (user == target) ? pick("tickles [target.p_them()]self with [src]", "gently teases [target.p_their()] own nipples with [src]") : pick("teases [target]'s nipples with [src]", "uses [src] to tickle [target]'s left nipple", "uses [src] to tickle [target]'s right nipple") + + message = (user == target) ? pick("tickles [target.p_them()]self with [src]", + "gently teases [target.p_their()] own nipples with [src]") \ + : pick("teases [target]'s nipples with [src]", + "uses [src] to tickle [target]'s left nipple", + "uses [src] to tickle [target]'s right nipple") else - message = (user == target) ? pick("tickles [target.p_them()]self with [src]", "gently teases [target.p_their()] synthetic body with [src]") : pick("teases [target]'s touch sensors with [src]") - - if(target.stat == DEAD) - return - if(prob(70)) - target.try_lewd_autoemote(pick("laugh", "giggle", "twitch", "twitch_s", "moan", )) - + message = (user == target) ? pick("tickles [target.p_them()]self with [src]", + "gently teases [target.p_their()] synthetic body with [src]") \ + : pick("teases [target]'s touch sensors with [src]") if(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) - targetedsomewhere = TRUE - if(carbon_target && !carbon_target.has_feet()) - to_chat(user, span_danger("[target] doesn't have any feet!")) + if(!carbon_target?.has_feet(REQUIRE_GENITAL_EXPOSED)) + to_chat(user, span_danger("Looks like [target]'s feets are covered!")) return - if(carbon_target && !carbon_target.is_barefoot()) - to_chat(user, span_danger("[target]'s feet are covered!")) - return - message = (user == target) ? pick("tickles [target.p_them()]self with [src]", "gently teases [target.p_their()] own feet with [src]") : pick("teases [target]'s feet with [src]", "uses [src] to tickle [target]'s [user.zone_selected == BODY_ZONE_L_LEG ? "left" : "right"] foot", "uses [src] to tickle [target]'s toes") - if(target.stat == DEAD) - return - if(prob(70)) - target.try_lewd_autoemote(pick("laugh", "giggle", "twitch", "twitch_s", "moan", )) - + message = (user == target) ? pick("tickles [target.p_them()]self with [src]", + "gently teases [target.p_their()] own feet with [src]") \ + : pick("teases [target]'s feet with [src]", + "uses [src] to tickle [target]'s [user.zone_selected == BODY_ZONE_L_LEG ? "left" : "right"] foot", + "uses [src] to tickle [target]'s toes") if(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM) - targetedsomewhere = TRUE - if(carbon_target && !carbon_target.is_topless()) - to_chat(user, span_danger("[target]'s armpits are covered!")) + if(!carbon_target?.is_topless()) + to_chat(user, span_danger("Looks like [target]'s armpits are covered!")) return - message = (user == target) ? pick("tickles [target.p_them()]self with [src]", "gently teases [target.p_their()] own armpit with [src]") : pick("teases [target]'s right armpit with [src]", "uses [src] to tickle [target]'s [user.zone_selected == BODY_ZONE_L_ARM ? "left" : "right"] armpit", "uses [src] to tickle [target]'s underarm") - if(target.stat == DEAD) - return - if(prob(70)) - target.try_lewd_autoemote(pick("laugh", "giggle", "twitch", "twitch_s", "moan", )) - if(!targetedsomewhere) - return + + message = (user == target) ? pick("tickles [target.p_them()]self with [src]", + "gently teases [target.p_their()] own armpit with [src]") \ + : pick("teases [target]'s right armpit with [src]", + "uses [src] to tickle [target]'s [user.zone_selected == BODY_ZONE_L_ARM ? "left" : "right"] armpit", + "uses [src] to tickle [target]'s underarm") + else + return + + if(prob(70)) + target.try_lewd_autoemote(pick("laugh", "giggle", "twitch", "twitch_s", "moan", )) target.do_jitter_animation() target.adjustStaminaLoss(4) target.add_mood_event("tickled", /datum/mood_event/tickled) - if(carbon_target) - carbon_target.adjust_arousal(3) + carbon_target?.adjust_arousal(3) user.visible_message(span_purple("[user] [message]!")) play_lewd_sound(loc, \ pick( diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/fleshlight.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/fleshlight.dm index 02b25ecefd4..a30b4b671b7 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/fleshlight.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/fleshlight.dm @@ -27,6 +27,11 @@ "yellow" = image(icon = src.icon, icon_state = "[base_icon_state]_yellow"), ) +/obj/item/clothing/sextoy/fleshlight/examine(mob/user) + . = ..() + if(!color_changed) + . += span_notice("Alt-click to change it's color.") + /obj/item/clothing/sextoy/fleshlight/Initialize(mapload) . = ..() update_icon() @@ -54,30 +59,33 @@ . = ..() if(!istype(target)) return + if(target.stat == DEAD) + return - var/message = "" if(!target.check_erp_prefs(/datum/preference/toggle/erp/sex_toy, user, src)) to_chat(user, span_danger("[target] doesn't want you to do that!")) return - switch(user.zone_selected) //to let code know what part of body we gonna... Uhh... You get the point. - if(BODY_ZONE_PRECISE_GROIN) - var/obj/item/organ/external/genital/penis = target.get_organ_slot(ORGAN_SLOT_PENIS) - if(!penis) - to_chat(user, span_danger("[target] doesn't have a penis!")) - return - if(!(target.is_bottomless() || penis.visibility_preference == GENITAL_ALWAYS_SHOW)) - to_chat(user, span_danger("[target]'s groin is covered!")) - return - message = (user == target) ? pick("moans in ecstasy as [target.p_they()] use the [src]", "slowly moves [src] up and down on [target]'s penis, causing [target.p_them()] to bend in pleasure", "slightly shivers in pleasure as [target.p_they()] use [src]") : pick("uses [src] on [target]'s penis", "fucks [target] with [src]", "masturbates [target] with [src], causing [target.p_them()] to moan in ecstasy") - if(!(prob(40) && (target.stat != DEAD))) - return - target.try_lewd_autoemote(pick("twitch_s", "moan", "blush")) - target.adjust_arousal(6) - target.adjust_pleasure(9) - user.visible_message(span_purple("[user] [message]!")) - play_lewd_sound(loc, pick('modular_skyrat/modules/modular_items/lewd_items/sounds/bang1.ogg', - 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang2.ogg', - 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang3.ogg', - 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang4.ogg', - 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang5.ogg', - 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang6.ogg'), 70, 1, -1) + + var/obj/item/organ/external/genital/penis = target.get_organ_slot(ORGAN_SLOT_PENIS) + if(!penis?.is_exposed()) + to_chat(user, span_danger("Looks like [target]'s groin is covered!")) + return + + var/message = (user == target) ? pick("moans in ecstasy as [target.p_they()] fuck the [src]", + "slowly moves [src] up and down on [target]'s penis, causing [target.p_them()] to bend in pleasure", + "shivers in pleasure as [target.p_they()] move [src] on their penis") \ + : pick("uses [src] on [target]'s penis", + "fucks [target] with [src]", + "masturbates [target] with [src], causing [target.p_them()] to moan in ecstasy") + + if(prob(70)) + target.try_lewd_autoemote(pick("twitch_s", "moan", "blush")) + target.adjust_arousal(6) + target.adjust_pleasure(9) + user.visible_message(span_purple("[user] [message]!")) + play_lewd_sound(loc, pick('modular_skyrat/modules/modular_items/lewd_items/sounds/bang1.ogg', + 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang2.ogg', + 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang3.ogg', + 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang4.ogg', + 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang5.ogg', + 'modular_skyrat/modules/modular_items/lewd_items/sounds/bang6.ogg'), 70, 1, -1) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/kinky_shocker.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/kinky_shocker.dm index 1a6db2dcd12..1b4df0da2d7 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/kinky_shocker.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/kinky_shocker.dm @@ -108,193 +108,121 @@ /obj/item/kinky_shocker/attack(mob/living/target, mob/living/user) . = ..() - var/mob/living/carbon/human/carbon_target - if(istype(target,/mob/living/carbon/human)) - carbon_target = target - else if(istype(target,/mob/living/silicon/robot)) - // Just use target var, return if it isn't human or robot - else + var/mob/living/carbon/human/carbon_target = target + if(!carbon_target && !iscyborg(target)) return - if(!istype(user,/mob/living/carbon/human) && !istype(user,/mob/living/silicon/robot)) + if(target.stat == DEAD) return if(!shocker_on) to_chat(user, span_danger("[src] must be enabled before use!")) return - var/message = "" - var/targetedsomewhere = FALSE + if(!target.check_erp_prefs(/datum/preference/toggle/erp/sex_toy, user, src)) to_chat(user, span_danger("[target] doesn't want you to do that.")) return - deductcharge(cell_hit_cost) - play_lewd_sound(loc, 'sound/weapons/taserhit.ogg', 70, 1, -1) + + var/message = "" switch(user.zone_selected) //to let code know what part of body we gonna tickle if(BODY_ZONE_PRECISE_GROIN) - targetedsomewhere = TRUE - if(carbon_target) - var/obj/item/organ/external/genital/penis = carbon_target.get_organ_slot(ORGAN_SLOT_PENIS) - var/obj/item/organ/external/genital/vagina = carbon_target.get_organ_slot(ORGAN_SLOT_VAGINA) - if(vagina && penis) - if(carbon_target.is_bottomless() || (penis.visibility_preference == GENITAL_ALWAYS_SHOW && vagina.visibility_preference == GENITAL_ALWAYS_SHOW)) - message = (user == target) ? pick("leans [src] against [target.p_their()] penis, letting it shock it. Ouch...", - "shocks [target.p_their()] penis with [src]", - "leans [src] against [target.p_their()] vagina, letting it shock it. Ouch...", - "shocks [target.p_their()] pussy with [src]") : pick("uses [src] to shock [target]'s penis", "shocks [target]'s penis with [src]", - "leans [src] against [target]'s penis, turning it on", - "uses [src] to shock [target]'s vagina", - "shocks [target]'s pussy with [src]", - "leans the shocker against [target]'s vagina, turning it on") + var/obj/item/organ/external/genital/penis = target.get_organ_slot(ORGAN_SLOT_PENIS) + var/obj/item/organ/external/genital/vagina = target.get_organ_slot(ORGAN_SLOT_VAGINA) + var/penis_message = (user == target) ? pick("leans [src] against [target.p_their()] penis, letting it shock [target.p_them()]. Ouch...", + "shocks [target.p_their()] penis with [src]") \ + : pick("uses [src] to shock [target]'s penis", + "shocks [target]'s penis with [src]", + "leans [src] against [target]'s penis, turning it on") - else if(carbon_target.is_bottomless() || penis.visibility_preference == GENITAL_ALWAYS_SHOW) - message = (user == target) ? pick("leans [src] against [target.p_their()] penis, letting it shock it. Ouch...", - "shocks [target.p_their()] penis with [src]") : pick("uses [src] to shock [target]'s penis", - "shocks [target]'s penis with [src]", - "leans [src] against [target]'s penis, turning shocker on") + var/vagina_message = (user == target) ? pick("leans [src] against [target.p_their()] vagina, letting it shock [target.p_them()]. Ouch...", + "shocks [target.p_their()] pussy with [src]") \ + : pick("uses [src] to shock [target]'s vagina", + "shocks [target]'s pussy with [src]", + "leans [src] against [target]'s vagina, turning it on") - else if(carbon_target.is_bottomless() || vagina.visibility_preference == GENITAL_ALWAYS_SHOW) - message = (user == target) ? pick("leans [src] against [target.p_their()] vagina, letting it shock it. Ouch...", - "shocks [target.p_their()] pussy with [src]") : pick("uses [src] to shock [target]'s vagina", - "shocks [target]'s pussy with [src]", - "leans [src] against [target]'s vagina, turning it on") - else - to_chat(user, span_danger("Looks like [target]'s groin is covered!")) - return - - else if(penis) - if(carbon_target.is_bottomless() || penis.visibility_preference == GENITAL_ALWAYS_SHOW) - message = (user == target) ? pick("leans [src] against [target.p_their()] penis, letting it shock it. Ouch...", - "shocks [target.p_their()] penis with [src]") : pick("uses [src] to shock [target]'s penis", - "shocks [target]'s penis with [src]", - "leans [src] against [target]'s penis, turning shocker on") - else - to_chat(user, span_danger("Looks like [target]'s groin is covered!")) - return - - else if(vagina) - if(carbon_target.is_bottomless() || vagina.visibility_preference == GENITAL_ALWAYS_SHOW) - message = (user == target) ? pick("leans [src] against [target.p_their()] vagina, letting it shock it. Ouch...", - "shocks [target.p_their()] pussy with [src]") : pick("uses [src] to shock [target]'s vagina", - "shocks [target]'s pussy with [src]", - "leans [src] against [target]'s vagina, turning it on") - else - to_chat(user, span_danger("Looks like [target]'s groin is covered!")) - return - - else - if(carbon_target.is_bottomless()) - message = (user == target) ? pick("leans [src] against [target.p_their()] belly, letting it shock it. Ouch...", - "shocks [target.p_their()] tummy with [src]") : pick("uses [src] to shock [target]'s belly", - "shocks [target]'s tummy with [src]", - "leans [src] against [target]'s belly, turning it on") - else - to_chat(user, span_danger("Looks like [target]'s groin is covered!")) - return + if(penis?.is_exposed() && vagina?.is_exposed()) + message = pick(penis_message, vagina_message) + else if(vagina?.is_exposed()) + message = vagina_message + else if(penis?.is_exposed()) + message = penis_message + else if(carbon_target?.is_bottomless()) + message = (user == target) ? pick("leans [src] against [target.p_their()] belly, letting it shock [target.p_them()]. Ouch...", + "shocks [target.p_their()] tummy with [src]") \ + : pick("uses [src] to shock [target]'s belly", + "shocks [target]'s tummy with [src]", + "leans [src] against [target]'s belly, turning it on") + else if(iscyborg(target)) + message = (user == target) ? pick("leans [src] against [target.p_their()] synthetic genitals, letting it shock [target.p_them()]. Ouch...", + "shocks [target.p_their()] tummy with [src]") \ + : pick("uses [src] to shock [target]'s synthetic genitals", + "shocks [target]'s tummy with [src]", + "leans [src] against [target]'s synthetic genitals, turning it on") else - message = (user == target) ? pick("leans [src] against [target.p_their()] synthetic genitals, letting it shock them. Ouch...", - "shocks [target.p_their()] tummy with [src]") : pick("uses [src] to shock [target]'s synthetic genitals", - "shocks [target]'s tummy with [src]", - "leans [src] against [target]'s synthetic genitals, turning it on") + to_chat(user, span_danger("Looks like [target]'s groin is covered!")) + return if(BODY_ZONE_CHEST) - targetedsomewhere = TRUE - if(carbon_target) - var/obj/item/organ/external/genital/breasts = target.get_organ_slot(ORGAN_SLOT_BREASTS) - if(breasts) - if(breasts.visibility_preference == GENITAL_ALWAYS_SHOW || carbon_target.is_topless()) - message = (user == target) ? pick("leans [src] against [target.p_their()] breasts, letting it shock them.", - "shocks [target.p_their()] tits with [src]") : pick("uses [src] to shock [target]'s breasts", - "shocks [target]'s nipples with [src]", - "leans [src] against [target]'s tits, turning it on") - else - to_chat(user, span_danger("Looks like [target]'s chest is covered!")) - return - - else - if(carbon_target.is_topless()) - message = (user == target) ? pick("leans [src] against [target.p_their()] chest, letting it shock it.", - "shocks [target.p_their()] nipples with [src]") : pick("uses [src] to shock [target]'s chest", - "shocks [target]'s nipples with [src]", - "leans [src] against [target]'s chest, turning it on") - else - to_chat(user, span_danger("Looks like [target]'s chest is covered!")) - return + var/obj/item/organ/external/genital/breasts = target.get_organ_slot(ORGAN_SLOT_BREASTS) + if(breasts?.is_exposed()) + message = (user == target) ? pick("leans [src] against [target.p_their()] breasts, letting it shock [target.p_them()].", + "shocks [target.p_their()] tits with [src]") \ + : pick("uses [src] to shock [target]'s breasts", + "shocks [target]'s nipples with [src]", + "leans [src] against [target]'s tits, turning it on") + else if(carbon_target?.is_topless() || iscyborg(target)) + message = (user == target) ? pick("leans [src] against [target.p_their()] chest, letting it shock [target.p_them()].", + "shocks [target.p_their()] nipples with [src]") \ + : pick("uses [src] to shock [target]'s chest", + "shocks [target]'s nipples with [src]", + "leans [src] against [target]'s chest, turning it on") else - message = (user == target) ? pick("leans [src] against [target.p_their()] chest, letting it shock them.", - "shocks [target.p_their()] body with [src]") : pick("uses [src] to shock [target]'s chest", - "shocks [target]'s body with [src]", - "leans [src] against [target]'s chest, turning it on") + to_chat(user, span_danger("Looks like [target]'s chest is covered!")) + return - if(BODY_ZONE_R_ARM) - targetedsomewhere = TRUE - if(carbon_target) - if(!carbon_target.has_arms()) - to_chat(user, span_danger("[target] doesn't have any arms!")) - return - if(!carbon_target.is_hands_uncovered()) - to_chat(user, span_danger("[target]'s arms are covered!")) - return - message = (user == target) ? pick("leans [src] against [target.p_their()] right arm, letting it shock it.", - "shocks [target.p_their()] arm with [src]") : pick("uses [src] to shock [target]'s right arm", - "shocks [target]'s right arm with [src]", - "leans [src] against [target]'s right arm, turning it on") - - if(BODY_ZONE_L_ARM) - targetedsomewhere = TRUE - if(carbon_target) - if(!carbon_target.has_arms()) - to_chat(user, span_danger("[target] doesn't have any arms!")) - return - if(!carbon_target.is_hands_uncovered()) - to_chat(user, span_danger("[target]'s arms are covered!")) - return - message = (user == target) ? pick("leans [src] against [target.p_their()] left arm, letting it shock it.", - "shocks [target.p_their()] arm with [src]") : pick("uses [src] to shock [target]'s left arm", - "shocks [target]'s left arm with [src]", - "leans [src] against [target]'s left arm, turning it on") + if(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) + if(!carbon_target?.has_arms()) + to_chat(user, span_danger("Looks like [target] doesn't have any arms!")) + return + if(!carbon_target?.is_hands_uncovered()) + to_chat(user, span_danger("Looks like [target]'s arms are covered!")) + return + var/arm = user.zone_selected == BODY_ZONE_L_ARM ? "left arm" : "right arm" + message = (user == target) ? pick("leans [src] against [target.p_their()] [arm], letting it shock [target.p_them()].", + "shocks [target.p_their()] arm with [src]") \ + : pick("uses [src] to shock [target]'s [arm]", + "shocks [target]'s [arm] with [src]", + "leans [src] against [target]'s [arm], turning it on") if(BODY_ZONE_HEAD) - targetedsomewhere = TRUE - if(carbon_target && !carbon_target.is_head_uncovered()) - to_chat(user, span_danger("[target]'s head is covered!")) + if(!carbon_target?.is_head_uncovered()) + to_chat(user, span_danger("Looks like [target]'s head is covered!")) return - message = (user == target) ? pick("leans [src] against [target.p_their()] head, letting it shock it. Ouch! Why would they do that?!", - "shocks [target.p_their()] head with [src]") : pick("uses [src] to shock [target]'s head", - "shocks [target]'s neck with [src]", - "leans [src] against [target]'s neck, turning it on") + message = (user == target) ? pick("leans [src] against [target.p_their()] head, letting it shock [target.p_them()]. Ouch! Why would [target.p_they()] do that?!", + "shocks [target.p_their()] head with [src]") \ + : pick("uses [src] to shock [target]'s head", + "shocks [target]'s neck with [src]", + "leans [src] against [target]'s neck, turning it on") + if(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + if(!carbon_target?.has_feet()) + to_chat(user, span_danger("Looks like [target] doesn't have any legs!")) + return + if(!carbon_target?.is_barefoot()) + to_chat(user, span_danger("Looks like [target]'s toes are covered!")) + return + var/leg = user.zone_selected == BODY_ZONE_L_LEG ? "left leg" : "right leg" + message = (user == target) ? pick("leans [src] against [target.p_their()] [leg], letting it shock [target.p_them()].", + "shocks [target.p_their()] leg with [src]") \ + : pick("uses [src] to shock [target]'s [leg]", + "shocks [target]'s [user.zone_selected == BODY_ZONE_L_LEG ? "left foot" : "right foot"] with [src]", + "leans [src] against [target]'s [leg], turning it on") + else + to_chat(user, span_danger("You can't shock [target] there!")) + return - if(BODY_ZONE_L_LEG) - targetedsomewhere = TRUE - if(carbon_target && !carbon_target.has_feet()) - to_chat(user, span_danger("[target] doesn't have any legs!")) - return - if(carbon_target && !carbon_target.is_barefoot()) - to_chat(user, span_danger("[target]'s toes are covered!")) - return - message = (user == target) ? pick("leans [src] against [target.p_their()] left leg, letting it shock it.", - "shocks [target.p_their()] leg with [src]") : pick("uses [src] to shock [target]'s left leg", - "shocks [target]'s left foot with [src]", - "leans [src] against [target]'s left leg, turning it on") - - if(BODY_ZONE_R_LEG) - targetedsomewhere = TRUE - if(carbon_target && !carbon_target.has_feet()) - to_chat(user, span_danger("[target] doesn't have any legs!")) - return - if(carbon_target && !carbon_target.is_barefoot()) - to_chat(user, span_danger("[target]'s toes are covered!")) - return - message = (user == target) ? pick("leans [src] against [target.p_their()] right leg, letting it shock it.", - "shocks [target.p_their()] leg with [src]") : pick("uses [src] to shock [target]'s right leg", - "shocks [target]'s right foot with [src]", - "leans [src] against [target]'s right leg, turning it on") - - if(!targetedsomewhere) - return user.visible_message(span_purple("[user] [message]!")) - play_lewd_sound(loc, 'sound/weapons/taserhit.ogg') - if(target.stat == DEAD) - return + play_lewd_sound(loc, 'sound/weapons/taserhit.ogg', 70, 1, -1) + deductcharge(cell_hit_cost) if(prob(80)) target.try_lewd_autoemote(pick("twitch", "twitch_s", "shiver", "scream")) target.do_jitter_animation() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/leather_whip.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/leather_whip.dm index 475936eb6ff..8d50933f73f 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/leather_whip.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/leather_whip.dm @@ -35,8 +35,6 @@ /// Mutable appearance containing the whip's overlay var/mutable_appearance/whip_overlay - /// Assoc list of pain modes - var/list/modes = list("hard" = "weak", "weak" = "hard") /// Phrases to be said when the player attempts to talk when their speech is being modified var/list/moans = list("Mmmph...", "Hmmphh", "Mmmfhg", "Gmmmh...") /// Lower probability phrases to be said when talking. @@ -73,19 +71,19 @@ /// Radial menu helper /obj/item/clothing/mask/leatherwhip/proc/populate_whip_designs() whip_designs = list( - "pink" = image (icon = src.icon, icon_state = "leather_whip_pink_hard"), + "pink" = image(icon = src.icon, icon_state = "leather_whip_pink_hard"), "teal" = image(icon = src.icon, icon_state = "leather_whip_teal_hard")) /// Radial menu helper /obj/item/clothing/mask/leatherwhip/proc/populate_whip_forms() whip_forms = list( - "whip" = image (icon = src.icon, icon_state = "leather_whip_pink_hard"), + "whip" = image(icon = src.icon, icon_state = "leather_whip_pink_hard"), "crotch" = image(icon = src.icon, icon_state = "leather_crotch_pink_hard")) /// Radial menu helper /obj/item/clothing/mask/leatherwhip/proc/populate_whip_types() whip_types = list( - "weak" = image (icon = src.icon, icon_state = "leather_whip_pink_weak"), + "weak" = image(icon = src.icon, icon_state = "leather_whip_pink_weak"), "hard" = image(icon = src.icon, icon_state = "leather_crotch_pink_hard")) /obj/item/clothing/mask/leatherwhip/equipped(mob/target, slot) @@ -99,6 +97,13 @@ update_appearance() update_overlays() +/obj/item/clothing/mask/leatherwhip/examine(mob/user) + . = ..() + if(!color_changed) + . += span_notice("Alt-click to change it's color.") + else if(!form_changed) + . += span_notice("Alt-click to change it's form.") + //to change color /obj/item/clothing/mask/leatherwhip/click_alt(mob/user) if(!color_changed) @@ -110,9 +115,7 @@ update_icon_state() color_changed = TRUE return CLICK_ACTION_SUCCESS - else - if(form_changed) - return CLICK_ACTION_BLOCKING + else if(!form_changed) var/choice = show_radial_menu(user, src, whip_forms, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE) if(!choice) return CLICK_ACTION_BLOCKING @@ -121,6 +124,7 @@ update_icon_state() form_changed = TRUE return CLICK_ACTION_SUCCESS + return CLICK_ACTION_BLOCKING /// A check to see if the radial menu can be used /obj/item/clothing/mask/leatherwhip/proc/check_menu(mob/living/user) @@ -159,152 +163,135 @@ //safely discipline someone without damage /obj/item/clothing/mask/leatherwhip/attack(mob/living/target, mob/living/user) . = ..() - var/mob/living/carbon/human/carbon_target - if(istype(target,/mob/living/carbon/human)) - carbon_target = target - else if(istype(target,/mob/living/silicon/robot)) - // Just use target var, return if it isn't human or robot - else + if(target.stat == DEAD) return - if(!istype(user,/mob/living/carbon/human) && !istype(user,/mob/living/silicon/robot)) + var/mob/living/carbon/human/carbon_target = target + if(!carbon_target && !iscyborg(target)) return var/message = "" -//and there is code for successful check, so we are whipping someone + //and there is code for successful check, so we are whipping someone if(!target.check_erp_prefs(/datum/preference/toggle/erp/sex_toy, user, src)) to_chat(user, span_danger("[target] doesn't want you to do that.")) return - switch(user.zone_selected) //to let code know what part of body we gonna whip - if(BODY_ZONE_L_LEG) - if(carbon_target && !carbon_target.has_feet()) - to_chat(user, span_danger("[target] is missing their left leg!")) - return - if(current_whip_type == "hard") - message = (user == target) ? pick("Knocks [target.p_them()]self down with [src]", "Uses [src] to knock [target.p_them()]self on the ground") : pick("drops [target] to the ground with [src]", "uses [src] to put [target] on [target.p_their()] knees") - if(target.stat != DEAD) - if(prob(60)) - target.try_lewd_autoemote(pick("gasp", "shiver")) - if(prob(10)) - target.apply_status_effect(/datum/status_effect/subspace) - target.Paralyze(1)//don't touch it. It's domination tool, it should have ability to put someone on kneels. I already inserted check for PREF YOU CAN'T ABUSE THIS ITEM - target.adjust_pain(5) - play_lewd_sound(loc, 'sound/weapons/whip.ogg', 100) - else - message = (user == target) ? pick("knocks [target.p_them()]self down with [src]", "gently uses [src] to knock [target.p_them()]self on the ground") : pick("drops [target] to the ground with [src]", "uses [src] to put [target] on [target.p_their()] knees") - if(target.stat != DEAD) - if(prob(30)) - target.try_lewd_autoemote(pick("gasp", "shiver")) - if(prob(10)) - target.apply_status_effect(/datum/status_effect/subspace) - target.Paralyze(1) - target.adjust_pain(3) - play_lewd_sound(loc, 'sound/weapons/whip.ogg', 60) - if(BODY_ZONE_R_LEG) - if(carbon_target && !carbon_target.has_feet()) - to_chat(user, span_danger("[target] is missing their right leg!")) + switch(user.zone_selected) //to let code know what part of body we gonna whip + if(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + if(!carbon_target?.has_feet()) + to_chat(user, span_danger("Looks like [target] is missing their legs!")) return + if(current_whip_type == "hard") - message = (user == target) ? pick("knocks [target.p_them()]self down with [src]", "uses [src] to knock [target.p_them()]self on the ground") : pick("Hardly drops [target] on the ground with [src]", "uses [src] to put [target] on [target.p_their()] knees") - if(target.stat != DEAD) - if(prob(60)) - target.try_lewd_autoemote(pick("gasp", "shiver")) - if(prob(10)) - target.apply_status_effect(/datum/status_effect/subspace) + message = (user == target) ? pick("Knocks [target.p_them()]self down with [src]", + "Uses [src] to knock [target.p_them()]self on the ground") \ + : pick("drops [target] to the ground with [src]", + "Uses [src] to put [target] on [target.p_their()] knees") + + if(prob(60)) + target.try_lewd_autoemote(pick("gasp", "shiver")) + if(prob(10)) + target.apply_status_effect(/datum/status_effect/subspace) target.Paralyze(1)//don't touch it. It's domination tool, it should have ability to put someone on kneels. I already inserted check for PREF YOU CAN'T ABUSE THIS ITEM target.adjust_pain(5) play_lewd_sound(loc, 'sound/weapons/whip.ogg', 100) else - message = (user == target) ? pick("Knocks [target.p_them()]self down with [src]", "gently uses [src] to knock [target.p_them()]self on the ground") : pick("drops [target] to the ground with [src]", "uses [src] to put [target] on [target.p_their()] knees") - if(target.stat != DEAD) - if(prob(30)) - target.try_lewd_autoemote(pick("gasp", "shiver")) - if(prob(10)) - target.apply_status_effect(/datum/status_effect/subspace) + message = (user == target) ? pick("knocks [target.p_them()]self down with [src]", + "gently uses [src] to knock [target.p_them()]self on the ground") \ + : pick("drops [target] to the ground with [src]", + "uses [src] to put [target] on [target.p_their()] knees") + if(prob(30)) + target.try_lewd_autoemote(pick("gasp", "shiver")) + if(prob(10)) + target.apply_status_effect(/datum/status_effect/subspace) target.Paralyze(1) target.adjust_pain(3) play_lewd_sound(loc, 'sound/weapons/whip.ogg', 60) if(BODY_ZONE_HEAD) - message = (user == target) ? pick("wraps [src] around [target.p_their()] neck, choking [target.p_them()]self", "chokes [target.p_them()]self with [src]") : pick("chokes [target] with [src]", "twines [src] around [target]'s neck!") - if(prob(70) && (target.stat != DEAD)) + message = (user == target) ? pick("wraps [src] around [target.p_their()] neck, choking [target.p_them()]self", + "chokes [target.p_them()]self with [src]") \ + : pick("chokes [target] with [src]", + "twines [src] around [target]'s neck!") + if(prob(70)) target.try_lewd_autoemote(pick("gasp", "choke", "moan")) - if(carbon_target) - carbon_target.adjust_arousal(3) + carbon_target?.adjust_arousal(3) target.adjust_pain(5) play_lewd_sound(loc, 'modular_skyrat/modules/modular_items/lewd_items/sounds/latex.ogg', 80) if(BODY_ZONE_PRECISE_GROIN) - if(carbon_target && !carbon_target.is_bottomless()) - to_chat(user, span_danger("[target]'s butt is covered!")) + if(!carbon_target?.is_bottomless()) + to_chat(user, span_danger("Looks like [target]'s butt is covered!")) return if(current_whip_type == "weak") - message = (user == target) ? pick("whips [target.p_them()]self with [src]", "flogs [target.p_them()]self with [src]") :pick("playfully flogs [target]'s thighs with [src]", "flogs [target] with [src]", "mercilessly flogs [target] with [src]") - if(target.stat != DEAD) - if(prob(70)) - target.try_lewd_autoemote(pick("moan", "twitch")) - if(prob(10)) - target.apply_status_effect(/datum/status_effect/subspace) - if(carbon_target) - carbon_target.adjust_arousal(5) + message = (user == target) ? pick("whips [target.p_them()]self with [src]", + "flogs [target.p_them()]self with [src]") \ + : pick("playfully flogs [target]'s thighs with [src]", + "flogs [target] with [src]", "mercilessly flogs [target] with [src]") + if(prob(70)) + target.try_lewd_autoemote(pick("moan", "twitch")) + if(prob(10)) + target.apply_status_effect(/datum/status_effect/subspace) + carbon_target?.adjust_arousal(5) target.adjust_pain(5) target.apply_status_effect(/datum/status_effect/spanked) - if(HAS_TRAIT(target, TRAIT_MASOCHISM || TRAIT_BIMBO)) + if(HAS_TRAIT(target, TRAIT_MASOCHISM) || HAS_TRAIT(target, TRAIT_BIMBO)) target.add_mood_event("pervert spanked", /datum/mood_event/perv_spanked) play_lewd_sound(loc, 'sound/weapons/whip.ogg', 60) - if(current_whip_type == "hard") - message = (user == target) ? pick("roughly flogs [target.p_them()]self with [src]", "flogs [target.p_them()]self with [src]") : pick("playfully flogs [target]'s thighs with [src]", "flogs [target] with [src]", "mercilessly flogs [target] with [src]") - if(target.stat != DEAD) - if(prob(70)) - target.try_lewd_autoemote(pick("moan", "twitch", "twitch_s", "scream")) - if(prob(10)) - target.apply_status_effect(/datum/status_effect/subspace) - if(carbon_target) - carbon_target.adjust_arousal(3) + else + message = (user == target) ? pick("roughly flogs [target.p_them()]self with [src]", + "flogs [target.p_them()]self with [src]") \ + : pick("playfully flogs [target]'s thighs with [src]", + "flogs [target] with [src]", + "mercilessly flogs [target] with [src]") + if(prob(70)) + target.try_lewd_autoemote(pick("moan", "twitch", "twitch_s", "scream")) + if(prob(10)) + target.apply_status_effect(/datum/status_effect/subspace) + carbon_target?.adjust_arousal(3) target.adjust_pain(8) target.apply_status_effect(/datum/status_effect/spanked) - if(HAS_TRAIT(target, TRAIT_MASOCHISM || TRAIT_BIMBO)) + if(HAS_TRAIT(target, TRAIT_MASOCHISM) || HAS_TRAIT(target, TRAIT_BIMBO)) target.add_mood_event("pervert spanked", /datum/mood_event/perv_spanked) play_lewd_sound(loc, 'sound/weapons/whip.ogg', 100) else if(current_whip_type == "hard") - message = (user == target) ? pick("disciplines [target.p_them()]self with [src]", "lashes [target.p_them()]self with [src]") : pick("lashes [target] with [src]", "Uses [src] to discipline [target]", "disciplines [target] with [src]") - if(target.stat != DEAD) - if(prob(50)) - target.try_lewd_autoemote(pick("moan", "twitch", "twitch_s", "scream")) - if(prob(10)) - target.apply_status_effect(/datum/status_effect/subspace) - target.do_jitter_animation() + message = (user == target) ? pick("disciplines [target.p_them()]self with [src]", + "lashes [target.p_them()]self with [src]") \ + : pick("lashes [target] with [src]", + "Uses [src] to discipline [target]", + "disciplines [target] with [src]") + if(prob(10)) + target.apply_status_effect(/datum/status_effect/subspace) + target.do_jitter_animation() target.adjust_pain(7) play_lewd_sound(loc, 'sound/weapons/whip.ogg', 100) else - message = (user == target) ? pick("whips [target.p_them()]self with [src]", "lashes [target.p_them()]self with [src]") : pick("playfully lashes [target] with [src]", "disciplines [target] with [src]", "gently lashes [target] with [src]") - if(target.stat != DEAD) - if(prob(30)) - target.try_lewd_autoemote(pick("moan", "twitch")) - if(prob(10)) - target.apply_status_effect(/datum/status_effect/subspace) - target.do_jitter_animation() + message = (user == target) ? pick("whips [target.p_them()]self with [src]", + "lashes [target.p_them()]self with [src]") \ + : pick("playfully lashes [target] with [src]", + "disciplines [target] with [src]", + "gently lashes [target] with [src]") + if(prob(30)) + target.try_lewd_autoemote(pick("moan", "twitch")) + if(prob(10)) + target.apply_status_effect(/datum/status_effect/subspace) + target.do_jitter_animation() target.adjust_pain(4) - if(carbon_target) - carbon_target.adjust_arousal(5) + carbon_target?.adjust_arousal(5) play_lewd_sound(loc, 'sound/weapons/whip.ogg', 60) user.visible_message(span_purple("[user] [message]!")) //toggle low pain mode. Because sometimes screaming isn't good /obj/item/clothing/mask/leatherwhip/attack_self(mob/user) - toggle_mode() switch(current_whip_type) if("hard") - to_chat(user, span_notice("[src] is now hard. Someone need to be punished!")) - if("weak") + current_whip_type = "weak" to_chat(user, span_notice("[src] feels softer. Easy mode!")) + if("weak") + current_whip_type = "hard" + to_chat(user, span_notice("[src] is now hard. Someone need to be punished!")) update_icon() update_icon_state() - -/// Switches between hard and weak mode -/obj/item/clothing/mask/leatherwhip/proc/toggle_mode() - current_whip_type = modes[current_whip_type] diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/magic_wand.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/magic_wand.dm index 47edb7c10fa..aa56c1409af 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/magic_wand.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/magic_wand.dm @@ -1,3 +1,8 @@ +#define MAGIC_WAND_MODE_OFF "off" +#define MAGIC_WAND_MODE_LOW "low" +#define MAGIC_WAND_MODE_MEDIUM "medium" +#define MAGIC_WAND_MODE_HIGH "high" + /obj/item/clothing/sextoy/magic_wand name = "magic wand" desc = "Not sure where is magic in this thing, but if you press button - it makes funny vibrations" @@ -10,7 +15,7 @@ lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi' /// What mode the vibrator is on - var/vibration_mode = "off" + var/vibration_mode = MAGIC_WAND_MODE_OFF /// Looping sound called on process() var/datum/looping_sound/lewd/vibrator/low/soundloop1 /// Looping sound called on process() @@ -33,7 +38,7 @@ /obj/item/clothing/sextoy/magic_wand/Initialize(mapload) . = ..() - magicwand_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi', "magicwand", ABOVE_MOB_LAYER + 0.1) //two arguments + magicwand_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi', "magicwand", -BODY_FRONT_UNDER_CLOTHES) //two arguments update_icon_state() update_icon() @@ -56,7 +61,7 @@ /obj/item/clothing/sextoy/magic_wand/lewd_equipped(mob/living/carbon/human/user, slot) . = ..() - if(vibration_mode == "off" || !istype(user)) + if(vibration_mode == MAGIC_WAND_MODE_OFF || !istype(user)) return if(src == user.penis || src == user.vagina) START_PROCESSING(SSobj, src) @@ -72,15 +77,15 @@ var/adjustment_amount = 0 switch(vibration_mode) - if("low") + if(MAGIC_WAND_MODE_LOW) if(current_user.arousal < 30) adjustment_amount = 0.6 - if("medium") + if(MAGIC_WAND_MODE_MEDIUM) if(current_user.arousal < 60) adjustment_amount = 0.8 - if("high") + if(MAGIC_WAND_MODE_HIGH) adjustment_amount = 1 if(!adjustment_amount) @@ -91,37 +96,32 @@ /obj/item/clothing/sextoy/magic_wand/attack(mob/living/target, mob/living/user) . = ..() - - var/mob/living/carbon/human/carbon_target - if(istype(target,/mob/living/carbon/human)) - carbon_target = target - else if(istype(target,/mob/living/silicon/robot)) - // Just use target var, return if it isn't human or robot - else - return FALSE - if(!istype(user,/mob/living/carbon/human) && !istype(user,/mob/living/silicon/robot)) - return FALSE - - var/message = "" - if(vibration_mode == "off") - to_chat(user, span_warning("You must turn on the toy, to use it!")) + if(target.stat == DEAD) + return + var/mob/living/carbon/human/carbon_target = target + if(!carbon_target && !iscyborg(target)) return FALSE if(!target.check_erp_prefs(/datum/preference/toggle/erp/sex_toy, user, src)) to_chat(user, span_danger("Looks like [target] don't want you to do that.")) return FALSE + var/message = "" + if(vibration_mode == MAGIC_WAND_MODE_OFF) + to_chat(user, span_warning("You must turn on the toy, to use it!")) + return FALSE + var/first_adjective = "" var/second_adjective = "" switch(vibration_mode) - if("low") - first_adjective = "gently " - second_adjective = "delicately " + if(MAGIC_WAND_MODE_LOW) + first_adjective = "gently" + second_adjective = "delicately" - if("high") - first_adjective = "roughly " - second_adjective = "aggressively " + if(MAGIC_WAND_MODE_HIGH) + first_adjective = "roughly" + second_adjective = "aggressively" switch(user.zone_selected) if(BODY_ZONE_PRECISE_GROIN) @@ -132,59 +132,75 @@ if(!vagina && !penis) return FALSE - var/currently_bottomless = carbon_target.is_bottomless() - if(!currently_bottomless && !vagina?.visibility_preference && !penis?.visibility_preference) + if(!(vagina?.is_exposed() || penis?.is_exposed())) to_chat(user, span_danger("Looks like [carbon_target]'s groin is covered!")) return FALSE var/target_organs = list() - if(currently_bottomless || penis.visibility_preference == GENITAL_ALWAYS_SHOW) + if(penis?.is_exposed()) target_organs += "penis" - if(currently_bottomless || vagina.visibility_preference == GENITAL_ALWAYS_SHOW) + if(vagina?.is_exposed()) target_organs += "vagina" if(!length(target_organs)) return FALSE var/organ_to_use = pick(target_organs) - message = (user == target) ? pick("massages their [organ_to_use] with the [src]", "[first_adjective]teases their [organ_to_use] with [src]") : pick("[second_adjective]massages [target]'s [organ_to_use] with [src]", "uses [src] to [first_adjective]massage [target]'s [organ_to_use]", "leans the vibrator against [target]'s [organ_to_use]") - carbon_target.adjust_arousal((vibration_mode == "low" ? 4 : (vibration_mode == "high" ? 8 : 5))) - carbon_target.adjust_pleasure((vibration_mode == "low" ? 2 : (vibration_mode == "high" ? 10 : 5))) + message = (user == target) ? pick("massages their [organ_to_use] with the [src]", + "[first_adjective] teases their [organ_to_use] with [src]") \ + : pick("[second_adjective] massages [target]'s [organ_to_use] with [src]", + "uses [src] to [first_adjective] massage [target]'s [organ_to_use]", + "leans the vibrator against [target]'s [organ_to_use]") + carbon_target.adjust_arousal(vibration_mode == MAGIC_WAND_MODE_LOW ? 4 : (vibration_mode == MAGIC_WAND_MODE_HIGH ? 8 : 5)) + carbon_target.adjust_pleasure(vibration_mode == MAGIC_WAND_MODE_LOW ? 2 : (vibration_mode == MAGIC_WAND_MODE_HIGH ? 10 : 5)) else - message = (user == target) ? pick("massages their synthetic genitals with the [src]", "[first_adjective]teases their synthetic genitals with [src]") : pick("[second_adjective]massages [target]'s synthetic genitals with [src]", "uses [src] to [first_adjective]massage [target]'s synthetic genitals", "leans the vibrator against [target]'s synthetic genitals") + message = (user == target) ? pick("massages their synthetic genitals with the [src]", + "[first_adjective] teases their synthetic genitals with [src]") \ + : pick("[second_adjective] massages [target]'s synthetic genitals with [src]", + "uses [src] to [first_adjective] massage [target]'s synthetic genitals", + "leans the vibrator against [target]'s synthetic genitals") if(BODY_ZONE_CHEST) if(carbon_target) var/obj/item/organ/external/genital/breasts = carbon_target.get_organ_slot(ORGAN_SLOT_BREASTS) - if(!(carbon_target.is_topless() || breasts.visibility_preference == GENITAL_ALWAYS_SHOW)) + if(!breasts?.is_exposed()) to_chat(user, span_danger("Looks like [target]'s chest is covered!")) return FALSE var/breasts_or_nipples = breasts ? ORGAN_SLOT_BREASTS : ORGAN_SLOT_NIPPLES - message = (user == target) ? pick("massages their [breasts_or_nipples] with the [src]", "[first_adjective]teases their [breasts ? "tits" : ORGAN_SLOT_NIPPLES] with [src]") : pick("[second_adjective]teases [target]'s [breasts_or_nipples] with [src]", "uses [src] to[vibration_mode == " low" ? " slowly" : ""] massage [target]'s [breasts ? "tits" : ORGAN_SLOT_NIPPLES]", "uses [src] to tease [target]'s [breasts ? "boobs" : ORGAN_SLOT_NIPPLES]") - carbon_target.adjust_arousal((vibration_mode == "low" ? 3 : (vibration_mode == "high" ? 7 : 4))) - carbon_target.adjust_pleasure((vibration_mode == "low" ? 1 : (vibration_mode == "high" ? 9 : 4))) + message = (user == target) ? pick("massages their [breasts_or_nipples] with the [src]", + "[first_adjective] teases their [breasts ? "tits" : ORGAN_SLOT_NIPPLES] with [src]") \ + : pick("[second_adjective] teases [target]'s [breasts_or_nipples] with [src]", + "uses [src] to [vibration_mode == MAGIC_WAND_MODE_LOW ? "slowly" : ""] massage [target]'s [breasts ? "tits" : ORGAN_SLOT_NIPPLES]", + "uses [src] to tease [target]'s [breasts ? "boobs" : ORGAN_SLOT_NIPPLES]") + carbon_target.adjust_arousal((vibration_mode == MAGIC_WAND_MODE_LOW ? 3 : (vibration_mode == MAGIC_WAND_MODE_HIGH ? 7 : 4))) + carbon_target.adjust_pleasure((vibration_mode == MAGIC_WAND_MODE_LOW ? 1 : (vibration_mode == MAGIC_WAND_MODE_HIGH ? 9 : 4))) else - message = (user == target) ? pick("massages their bodily touch sensors with the [src]", "[first_adjective]teases their bodily touch sensors with [src]") : pick("[second_adjective]teases [target]'s bodily touch sensors with [src]", "uses [src] to[vibration_mode == " low" ? " slowly" : ""] massage [target]'s bodily touch sensors", "uses [src] to tease [target]'s bodily touch sensors") + message = (user == target) ? pick("massages their touch sensors with the [src]", + "[first_adjective] teases their touch sensors with [src]") \ + : pick("[second_adjective] teases [target]'s touch sensors with [src]", + "uses [src] to [vibration_mode == MAGIC_WAND_MODE_LOW ? "slowly" : ""] massage [target]'s touch sensors", + "uses [src] to tease [target]'s touch sensors") if(prob(30)) target.try_lewd_autoemote(pick("twitch_s", "moan")) user.visible_message(span_purple("[user] [message]!")) - play_lewd_sound(loc, 'modular_skyrat/modules/modular_items/lewd_items/sounds/vibrate.ogg', (vibration_mode == "low" ? 10 : (vibration_mode == "high" ? 30 : 20)), TRUE, pref_to_check = /datum/preference/toggle/erp/sex_toy_sounds) + play_lewd_sound(loc, 'modular_skyrat/modules/modular_items/lewd_items/sounds/vibrate.ogg', (vibration_mode == MAGIC_WAND_MODE_LOW ? 10 : (vibration_mode == MAGIC_WAND_MODE_HIGH ? 30 : 20)), TRUE, pref_to_check = /datum/preference/toggle/erp/sex_toy_sounds) /obj/item/clothing/sextoy/magic_wand/attack_self(mob/user) toggle_mode() + switch(vibration_mode) - if("low") - to_chat(user, span_notice("Vibration mode now is low. Bzzz...")) - if("medium") - to_chat(user, span_notice("Vibration mode now is medium. Bzzzz!")) - if("high") - to_chat(user, span_notice("Vibration mode now is high. Careful with that thing.")) - if("off") - to_chat(user, span_notice("[src] is now turned off. Fun time's over?")) + if(MAGIC_WAND_MODE_LOW) + to_chat(user, span_notice("Vibrator mode switched to low. Bzzz...")) + if(MAGIC_WAND_MODE_MEDIUM) + to_chat(user, span_notice("Vibrator mode switched to medium. Bzzzz!")) + if(MAGIC_WAND_MODE_HIGH) + to_chat(user, span_notice("Vibrator mode switched to high. Careful with that thing.")) + if(MAGIC_WAND_MODE_OFF) + to_chat(user, span_notice("[src] is turned off. Fun time's over?")) update_icon() update_icon_state() @@ -197,19 +213,24 @@ switch(vibration_mode) if("off") soundloop1.start() - vibration_mode = "low" + vibration_mode = MAGIC_WAND_MODE_LOW if("low") soundloop1.stop() soundloop2.start() - vibration_mode = "medium" + vibration_mode = MAGIC_WAND_MODE_MEDIUM if("medium") soundloop2.stop() soundloop3.start() - vibration_mode = "high" + vibration_mode = MAGIC_WAND_MODE_HIGH if("high") play_lewd_sound(loc, 'sound/weapons/magout.ogg', 20, TRUE) soundloop3.stop() - vibration_mode = "off" + vibration_mode = MAGIC_WAND_MODE_OFF + +#undef MAGIC_WAND_MODE_OFF +#undef MAGIC_WAND_MODE_LOW +#undef MAGIC_WAND_MODE_MEDIUM +#undef MAGIC_WAND_MODE_HIGH diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/spanking_pad.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/spanking_pad.dm index 81952e5b210..e55d3f3b762 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/spanking_pad.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/spanking_pad.dm @@ -43,6 +43,11 @@ icon_state = "[base_icon_state]_[current_color]" inhand_icon_state = "[base_icon_state]_[current_color]" +/obj/item/spanking_pad/examine(mob/user) + . = ..() + if(!color_changed) + . += span_notice("Alt-click to change it's color.") + /obj/item/spanking_pad/click_alt(mob/user) if(color_changed) return CLICK_ACTION_BLOCKING @@ -57,35 +62,35 @@ /obj/item/spanking_pad/attack(mob/living/target, mob/living/user) . = ..() - var/mob/living/carbon/human/carbon_target - if(istype(target,/mob/living/carbon/human)) - carbon_target = target - else if(istype(target,/mob/living/silicon/robot)) - // Just use target var, return if it isn't human or robot - else + if(target.stat == DEAD) return - if(!istype(user,/mob/living/carbon/human) && !istype(user,/mob/living/silicon/robot)) + var/mob/living/carbon/human/carbon_target = target + if(!carbon_target && !iscyborg(target)) return var/message = "" if(!target.check_erp_prefs(/datum/preference/toggle/erp/sex_toy, user, src)) to_chat(user, span_danger("[target] doesn't want you to do that.")) return - switch(user.zone_selected) //to let code know what part of body we gonna spank. - if(BODY_ZONE_PRECISE_GROIN) - if(carbon_target && !carbon_target.is_bottomless()) - to_chat(user, span_danger("[target]'s butt is covered!")) - return - message = (user == target) ? pick("spanks themselves with [src]", "uses [src] to slap their hips") : pick("slaps [target]'s hips with [src]", "uses [src] to slap [target]'s butt", "spanks [target] with [src], making a loud slapping noise", "slaps [target]'s thighs with [src]") - if(prob(40) && (target.stat != DEAD)) - target.try_lewd_autoemote(pick("twitch_s", "moan", "blush", "gasp")) - if(carbon_target) - carbon_target.adjust_arousal(2) - target.adjust_pain(4) - target.apply_status_effect(/datum/status_effect/spanked) - if(HAS_TRAIT(target, TRAIT_MASOCHISM || TRAIT_BIMBO)) - target.add_mood_event("pervert spanked", /datum/mood_event/perv_spanked) - if(prob(10) && (target.stat != DEAD)) - target.apply_status_effect(/datum/status_effect/subspace) - user.visible_message(span_purple("[user] [message]!")) - play_lewd_sound(loc, 'modular_skyrat/modules/modular_items/lewd_items/sounds/slap.ogg', 100, 1, -1) + + if(!carbon_target?.is_bottomless() && !iscyborg(target)) + to_chat(user, span_danger("[target]'s butt is covered!")) + return + + message = (user == target) ? pick("spanks themselves with [src]", + "uses [src] to slap their hips") \ + : pick("slaps [target]'s hips with [src]", + "uses [src] to slap [target]'s butt", + "spanks [target] with [src], making a loud slapping noise", + "slaps [target]'s thighs with [src]") + user.visible_message(span_purple("[user] [message]!")) + play_lewd_sound(loc, 'modular_skyrat/modules/modular_items/lewd_items/sounds/slap.ogg', 100, 1, -1) + if(prob(40)) + target.try_lewd_autoemote(pick("twitch_s", "moan", "blush", "gasp")) + if(prob(10)) + target.apply_status_effect(/datum/status_effect/subspace) + if(HAS_TRAIT(target, TRAIT_MASOCHISM) || HAS_TRAIT(target, TRAIT_BIMBO)) + target.add_mood_event("pervert spanked", /datum/mood_event/perv_spanked) + carbon_target?.adjust_arousal(2) + target.adjust_pain(4) + target.apply_status_effect(/datum/status_effect/spanked) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/torture_candle.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/torture_candle.dm index 3d24a3b649e..ee76fd9a070 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/torture_candle.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/torture_candle.dm @@ -108,10 +108,15 @@ open_flame() update_brightness() +/obj/item/bdsm_candle/examine(mob/user) + . = ..() + if(!color_changed && !lit) + . += span_notice("Alt-click to change it's color.") + else if(lit) + . += span_notice("Alt-click to snuff the flame out.") + /obj/item/bdsm_candle/click_alt(mob/user) - if(!lit) - if(color_changed) - return CLICK_ACTION_BLOCKING + if(!lit && !color_changed) var/choice = show_radial_menu(user, src, candle_designs, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE) if(!choice) return CLICK_ACTION_BLOCKING @@ -133,69 +138,70 @@ /obj/item/bdsm_candle/attack(mob/living/carbon/human/attacked, mob/living/carbon/human/user) . = ..() + if(attacked.stat == DEAD) + return if(!istype(attacked)) return var/message = "" - var/targeted_somewhere - if(!lit) - to_chat(user, span_danger("[src] needs to be lit to produce wax!")) - return if(!attacked.check_erp_prefs(/datum/preference/toggle/erp/sex_toy, user, src)) to_chat(user, span_danger("It looks like [attacked] don't want you to do that.")) return + if(!lit) + to_chat(user, span_danger("[src] needs to be lit to produce wax!")) + return switch(user.zone_selected) //to let code know what part of body we gonna wax if(BODY_ZONE_PRECISE_GROIN) - targeted_somewhere = TRUE var/obj/item/organ/external/genital/penis = attacked.get_organ_slot(ORGAN_SLOT_PENIS) var/obj/item/organ/external/genital/vagina = attacked.get_organ_slot(ORGAN_SLOT_VAGINA) - if((vagina && penis) && (attacked.is_bottomless() || vagina.visibility_preference == GENITAL_ALWAYS_SHOW && penis.visibility_preference == GENITAL_ALWAYS_SHOW)) - message = (user == attacked) ? pick("drips some wax on [attacked.p_their()] genitals, moaning in pleasure", - "drips some wax on [attacked.p_them()]self, moaning in pleasure as it reaches [attacked.p_their()] genitals") : pick( - "drips wax right on [attacked]'s genitalia. It slightly itches", - "drips hot wax from the [src] onto [attacked]'s genitalia, causing [attacked.p_them()] to shiver", - "tilts [src], dripping wax right onto [attacked]'s genitals, causing [attacked.p_them()] to moan", - "drips some wax onto [attacked]'s genitals, making [attacked.p_them()] moan in pleasure") - attacked.adjust_pain(PAIN_DEFAULT) + var/penis_message = (user == attacked) ? pick("drips some wax on [attacked.p_their()] penis, causing [attacked.p_them()] to moan in pleasure.", + "drips some wax on [attacked.p_them()]self, letting it reach [attacked.p_their()] penis.") \ + : pick("drips wax right on [attacked]'s penis. It slightly itches.", + "drips hot wax from [src] onto [attacked]'s penis, [attacked.p_they()] shivers slightly.", + "tilts the candle. Drops of wax, dripping from [src] onto [attacked]'s penis, made [attacked.p_them()] moan.") - else if(penis && (attacked.is_bottomless() || penis.visibility_preference == GENITAL_ALWAYS_SHOW)) - message = (user == attacked) ? pick("drips some wax on [attacked.p_their()] penis, causing [attacked.p_them()] to moan in pleasure", - "drips some wax on themselves, letting it reach his penis. he moans in pleasure.") : pick( - "drips wax right on [attacked]'s penis. It slightly itches.", - "drips hot wax from the [src] on the [attacked]'s penis, he slightly shivers.", - "tilts the candle. Drops of wax, dripping right from [src] right on the [attacked]'s penis, made him moan.") - attacked.adjust_pain(PAIN_DEFAULT) - - else if(vagina && (attacked.is_bottomless() || vagina.visibility_preference == GENITAL_ALWAYS_SHOW)) - message = (user == attacked) ? pick("drips some wax on themselves, letting it reach his vagina. He moans in pleasure.", "drips some wax on the [attacked]'s pussy, he moans in pleasure") : pick("drips some wax on the [attacked]'s vagina, he moans in pleasure", "tilts the candle. Wax slowly goes down, reaching the [attacked]'s vagina.", "tilts the candle. Drops of wax, dripping right from [src] right on the [attacked]'s pussy, made him moan.") - attacked.adjust_pain(PAIN_DEFAULT) + var/vagina_message = (user == attacked) ? pick("drips some wax on [attacked.p_them()]self, letting it reach [attacked.p_their()] vagina.", + "drips some wax onto [attacked.p_their()] pussy as [attacked.p_they()] moan in pleasure") \ + : pick("drips some wax on [attacked]'s vagina.", + "tilts the candle as the wax slowly drops down, reaching [attacked]'s vagina.", + "tilts the candle. Drops of wax, dripping from [src] onto [attacked]'s pussy, made [attacked.p_them()] moan.") + if(vagina?.is_exposed() && penis?.is_exposed()) + message = pick(penis_message, vagina_message) + else if(penis?.is_exposed()) + message = penis_message + else if(vagina?.is_exposed()) + message = vagina_message else if(attacked.is_bottomless()) - message = (user == attacked) ? pick("drips some wax on themselves, letting it reach his belly. He moans in pleasure.", "drips some wax on the [attacked]'s tummy, he moans in pleasure") : pick("drips some wax on the [attacked]'s belly, he moans in pleasure", "tilts the candle. Wax slowly goes down, reaching the [attacked]'s tummy.", "tilts the candle. Drops of wax, dripping right from [src] right on the [attacked]'s groin, made him moan.") - attacked.adjust_pain(PAIN_DEFAULT) - + message = (user == attacked) ? pick("drips some wax on [attacked.p_them()]self, letting it reach [attacked.p_their()] belly as [attacked.p_they()] moan in pleasure.", + "drips some wax on [attacked]'s tummy") \ + : pick("drips some wax on [attacked]'s belly", + "tilts the candle as the wax slowly drops down, reaching [attacked]'s tummy.", + "tilts the candle. Drops of wax, dripping from [src] onto [attacked]'s groin, made [attacked.p_them()] moan.") else to_chat(user, span_danger("Looks like [attacked]'s groin is covered!")) return + attacked.adjust_pain(PAIN_DEFAULT) if(BODY_ZONE_CHEST) - targeted_somewhere = TRUE var/obj/item/organ/external/genital/breasts = attacked.get_organ_slot(ORGAN_SLOT_BREASTS) - if(attacked.is_topless() || breasts.visibility_preference == GENITAL_ALWAYS_SHOW) + if(breasts?.is_exposed()) var/breasts_or_nipples = breasts ? ORGAN_SLOT_BREASTS : ORGAN_SLOT_NIPPLES - message = (user == attacked) ? pick("drips some wax on [attacked.p_their()] [breasts_or_nipples], releasing all [attacked.p_their()] lustness", "drips some wax right on [attacked.p_their()] [breasts ? "tits" : "chest"], making [attacked.p_their()] feel faint.") : pick("pours the wax that is slowly dripping from [src] onto [attacked]'s [breasts_or_nipples], [attacked.p_they()] shows pure enjoyment.", "tilts the candle. Right in the moment when wax drips on [attacked]'s [breasts_or_nipples], [attacked.p_they()] shivers", "tilts the candle. Just when hot drops of wax fell on [attacked]'s [breasts_or_nipples], [attacked.p_they()] quietly moans in pleasure") + message = (user == attacked) ? pick("drips some wax on [attacked.p_their()] [breasts_or_nipples], releasing all [attacked.p_their()] lustness", + "drips some wax right on [attacked.p_their()] [breasts ? "tits" : "chest"], making [attacked.p_their()] feel faint.") \ + : pick("pours the wax that is slowly dripping from [src] onto [attacked]'s [breasts_or_nipples], [attacked.p_they()] shows pure enjoyment.", + "tilts the candle. Right in the moment when wax drips on [attacked]'s [breasts_or_nipples], [attacked.p_they()] shivers", + "tilts the candle. Just when hot drops of wax fell on [attacked]'s [breasts_or_nipples], [attacked.p_they()] quietly moans in pleasure") attacked.adjust_pain(PAIN_DEFAULT * 0.66) else to_chat(user, span_danger("Looks like [attacked]'s chest is covered!")) return - - if(!targeted_somewhere) - return - if(attacked.stat != DEAD) - attacked.do_jitter_animation() - if(prob(50)) - attacked.try_lewd_autoemote(pick("twitch_s" , "gasp", "shiver")) + else + return + attacked.do_jitter_animation() + if(prob(50)) + attacked.try_lewd_autoemote(pick("twitch_s" , "gasp", "shiver")) user.visible_message(span_purple("[user] [message]!")) play_lewd_sound(loc, pick('modular_skyrat/modules/modular_items/lewd_items/sounds/vax1.ogg', 'modular_skyrat/modules/modular_items/lewd_items/sounds/vax2.ogg'), 70, TRUE) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibrator.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibrator.dm index 35b8ce8855e..c723119054c 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibrator.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibrator.dm @@ -1,6 +1,11 @@ #define DEFAULT_AROUSAL_INCREASE 4 #define DEFAULT_PLEASURE_INCREASE 2 +#define VIB_OFF "off" +#define VIB_LOW "low" +#define VIB_MEDIUM "medium" +#define VIB_HIGH "hard" + //This code huge and blocky, but we're working on update for... my god, 4 months. If you can upgrade it - do it, but don't remove or break something, test carefully. This item is insertable. /obj/item/clothing/sextoy/vibrator name = "vibrator" @@ -19,9 +24,7 @@ /// If the color has been changed before var/color_changed = FALSE /// Current vibration mode of the toy - var/vibration_mode = "off" - /// Assoc list of modes and what they'll convert to - var/list/modes = list("low" = "medium", "medium" = "hard", "hard" = "off", "off" = "low") + var/vibration_mode = VIB_OFF /// Looping sound used for the toy's audible bit var/datum/looping_sound/lewd/vibrator/low/soundloop1 /// Looping sound used for the toy's audible bit @@ -42,6 +45,11 @@ "yellow" = image(icon = src.icon, icon_state = "vibrator_yellow_low"), "green" = image(icon = src.icon, icon_state = "vibrator_green_low")) +/obj/item/clothing/sextoy/vibrator/examine(mob/user) + . = ..() + if(!color_changed) + . += span_notice("Alt-click to change it's design.") + /obj/item/clothing/sextoy/vibrator/click_alt(mob/user) if(color_changed) return @@ -93,13 +101,13 @@ if(!istype(user)) return if(toy_on) - if(vibration_mode == "low" && user.arousal < 40) //prevent non-stop cumming from wearing this thing + if(vibration_mode == VIB_LOW && user.arousal < 40) //prevent non-stop cumming from wearing this thing user.adjust_arousal(0.7 * seconds_per_tick) user.adjust_pleasure(0.7 * seconds_per_tick) - if(vibration_mode == "medium" && user.arousal < 70) + if(vibration_mode == VIB_MEDIUM && user.arousal < 70) user.adjust_arousal(1 * seconds_per_tick) user.adjust_pleasure(1 * seconds_per_tick) - if(vibration_mode == "hard") //no mercy + if(vibration_mode == VIB_HIGH) //no mercy user.adjust_arousal(1.5 * seconds_per_tick) user.adjust_pleasure(1.5 * seconds_per_tick) else if(!toy_on && user.arousal < 30) @@ -109,11 +117,12 @@ //SHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODESHITCODE /obj/item/clothing/sextoy/vibrator/attack(mob/living/carbon/human/target, mob/living/carbon/human/user) . = ..() + if(target.stat == DEAD) + return if(!istype(target)) return var/message = "" - var/targetedsomewhere = FALSE if(!toy_on) to_chat(user, span_notice("[src] must be on to use it!")) return @@ -121,87 +130,106 @@ to_chat(user, span_danger("Looks like [target] don't want you to do that.")) return + var/vibration_adj = "" + switch(vibration_mode) + if(VIB_LOW) + vibration_adj = pick("gently", "delicately") + if(VIB_HIGH) + vibration_adj = pick("roughly", "aggressively") + switch(user.zone_selected) //to let code know what part of body we gonna vibe if(BODY_ZONE_PRECISE_GROIN) - targetedsomewhere = TRUE var/obj/item/organ/external/genital/penis = target.get_organ_slot(ORGAN_SLOT_PENIS) var/obj/item/organ/external/genital/vagina = target.get_organ_slot(ORGAN_SLOT_VAGINA) - if((vagina && penis) && (vagina.visibility_preference == GENITAL_ALWAYS_SHOW && penis.visibility_preference == GENITAL_ALWAYS_SHOW || target.is_bottomless())) - message = (user == target) ? pick("massages their vagina with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their pussy with [src]", "massages their penis with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their penis with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] massages [target]'s vagina with [src]", "uses [src] to [vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] massage [target]'s crotch", "leans the massager against [target]'s pussy", "[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] massages [target]'s penis with [src]", "uses [src] to [vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] massage [target]'s penis", "leans the massager against [target]'s penis") - target.adjust_arousal(DEFAULT_AROUSAL_INCREASE) - target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE) - - else if(vagina && (vagina.visibility_preference == GENITAL_ALWAYS_SHOW || target.is_bottomless())) - message = (user == target) ? pick("massages their vagina with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their pussy with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] massages [target]'s vagina with [src]", "uses [src] to [vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] massage [target]'s crotch", "leans the massager against [target]'s pussy") - target.adjust_arousal(DEFAULT_AROUSAL_INCREASE) - target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE) - - else if(penis && (penis.visibility_preference == GENITAL_ALWAYS_SHOW || target.is_bottomless())) - message = (user == target) ? pick("massages their penis with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their penis with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] massages [target]'s penis with [src]", "uses [src] to [vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] massage [target]'s penis", "leans the massager against [target]'s penis") - target.adjust_arousal(DEFAULT_AROUSAL_INCREASE) - target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE) - + var/penis_message = (user == target) ? pick("massages their penis with the [src]", + "[vibration_adj] teases their penis with [src]") \ + : pick("[vibration_adj] massages [target]'s penis with [src]", + "uses [src] to [vibration_adj] massage [target]'s penis", + "leans the massager against [target]'s penis") + var/vagina_message = (user == target) ? pick("massages their vagina with the [src]", + "[vibration_adj] teases their pussy with [src]") \ + : pick("[vibration_adj] massages [target]'s vagina with [src]", + "uses [src] to [vibration_adj] massage [target]'s crotch", + "leans the massager against [target]'s pussy") + if(vagina?.is_exposed() && penis?.is_exposed()) + message = pick(penis_message, vagina_message) + else if(vagina?.is_exposed()) + message = vagina_message + else if(penis?.is_exposed()) + message = penis_message else to_chat(user, span_danger("Looks like [target]'s groin is covered!")) return - if(prob(50) && (target.stat != DEAD)) + target.adjust_arousal(DEFAULT_AROUSAL_INCREASE) + target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE) + if(prob(50)) target.try_lewd_autoemote(pick("twitch_s", "moan", "blush")) if(BODY_ZONE_CHEST) - targetedsomewhere = TRUE var/obj/item/organ/external/genital/breasts = target.get_organ_slot(ORGAN_SLOT_BREASTS) - if(target.is_topless() || breasts.visibility_preference == GENITAL_ALWAYS_SHOW) + if(breasts?.is_exposed()) var/breasts_or_nipples = breasts ? ORGAN_SLOT_BREASTS : ORGAN_SLOT_NIPPLES - message = (user == target) ? pick("massages their [breasts_or_nipples] with the [src]", "[vibration_mode == "low" ? "gently" : ""][vibration_mode = "hard" ? "roughly" : ""] teases their tits with [src]") : pick("[vibration_mode == "low" ? "delicately" : ""][vibration_mode = "hard" ? "aggressively" : ""] teases [target]'s [breasts_or_nipples] with [src]", "uses [src] to[vibration_mode == "low" ? " slowly" : ""] massage [target]'s [breasts ? "tits" : ORGAN_SLOT_NIPPLES]", "uses [src] to tease [target]'s [breasts ? "boobs" : ORGAN_SLOT_NIPPLES]", "rubs [target]'s [breasts ? "tits" : ORGAN_SLOT_NIPPLES] with [src]") - target.adjust_arousal(DEFAULT_AROUSAL_INCREASE) - target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE * 0.5) - if(prob(30) && (target.stat != DEAD)) - target.try_lewd_autoemote(pick("twitch_s", "moan")) - + message = (user == target) ? pick("massages their [breasts_or_nipples] with the [src]", + "[vibration_adj] teases their tits with [src]") \ + : pick("[vibration_adj] teases [target]'s [breasts_or_nipples] with [src]", + "uses [src] to [vibration_adj] massage [target]'s [breasts ? "tits" : ORGAN_SLOT_NIPPLES]", + "uses [src] to tease [target]'s [breasts ? "boobs" : ORGAN_SLOT_NIPPLES]", + "rubs [target]'s [breasts ? "tits" : ORGAN_SLOT_NIPPLES] with [src]") else to_chat(user, span_danger("Looks like [target]'s chest is covered!")) return - if(!targetedsomewhere) - return + + target.adjust_arousal(DEFAULT_AROUSAL_INCREASE) + target.adjust_pleasure(DEFAULT_PLEASURE_INCREASE * 0.5) + if(prob(30)) + target.try_lewd_autoemote(pick("twitch_s", "moan")) + else + return user.visible_message(span_purple("[user] [message]!")) play_lewd_sound(loc, 'modular_skyrat/modules/modular_items/lewd_items/sounds/vibrate.ogg', 10, TRUE) /obj/item/clothing/sextoy/vibrator/attack_self(mob/user, obj/item/attack_item) toggle_mode() switch(vibration_mode) - if("low") + if(VIB_LOW) to_chat(user, span_notice("Vibration mode now is low. Bzzz...")) - if("medium") + if(VIB_MEDIUM) to_chat(user, span_notice("Vibration mode now is medium. Bzzzz!")) - if("hard") - to_chat(user, span_notice("Vibration mode now is hard. Careful with that thing.")) - if("off") + if(VIB_HIGH) + to_chat(user, span_notice("Vibration mode now is high. Careful with that thing.")) + if(VIB_OFF) to_chat(user, span_notice("Vibrator turned off. Fun's over?")) update_icon() update_icon_state() /obj/item/clothing/sextoy/vibrator/proc/toggle_mode() - vibration_mode = modes[vibration_mode] switch(vibration_mode) - if("low") + if(VIB_OFF) + vibration_mode = VIB_LOW toy_on = TRUE play_lewd_sound(loc, 'sound/weapons/magin.ogg', 20, TRUE) soundloop1.start() - if("medium") - toy_on = TRUE + if(VIB_LOW) + vibration_mode = VIB_MEDIUM play_lewd_sound(loc, 'sound/weapons/magin.ogg', 20, TRUE) soundloop1.stop() soundloop2.start() - if("hard") - toy_on = TRUE + if(VIB_MEDIUM) + vibration_mode = VIB_HIGH play_lewd_sound(loc, 'sound/weapons/magin.ogg', 20, TRUE) soundloop2.stop() soundloop3.start() - if("off") + if(VIB_HIGH) + vibration_mode = VIB_OFF toy_on = FALSE play_lewd_sound(loc, 'sound/weapons/magout.ogg', 20, TRUE) soundloop3.stop() #undef DEFAULT_AROUSAL_INCREASE #undef DEFAULT_PLEASURE_INCREASE + +#undef VIB_OFF +#undef VIB_LOW +#undef VIB_MEDIUM +#undef VIB_HIGH diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibroring.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibroring.dm index 03b1ca6ade5..5bdf297bd7b 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibroring.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibroring.dm @@ -36,6 +36,11 @@ "pink" = image(icon = src.icon, icon_state = "vibroring_pink_off"), "teal" = image(icon = src.icon, icon_state = "vibroring_teal_off")) +/obj/item/clothing/sextoy/vibroring/examine(mob/user) + . = ..() + if(!color_changed) + . += span_notice("Alt-click to change it's color.") + /obj/item/clothing/sextoy/vibroring/click_alt(mob/user) if(color_changed) return CLICK_ACTION_BLOCKING diff --git a/modular_skyrat/modules/pixel_shift/code/pixel_shift_component.dm b/modular_skyrat/modules/pixel_shift/code/pixel_shift_component.dm index 9603d3d5a20..3a8808bd257 100644 --- a/modular_skyrat/modules/pixel_shift/code/pixel_shift_component.dm +++ b/modular_skyrat/modules/pixel_shift/code/pixel_shift_component.dm @@ -1,15 +1,23 @@ /datum/component/pixel_shift dupe_mode = COMPONENT_DUPE_UNIQUE - /// Whether the mob is pixel shifted or not - var/is_shifted = FALSE - /// If we are in the shifting setting. - var/shifting = TRUE - /// Takes the four cardinal direction defines. Any atoms moving into this atom's tile will be allowed to from the added directions. - var/passthroughable = NONE - /// The maximum amount of pixels allowed to move in the turf. + //whether or not parent is shifting + var/shifting + //whether or not parent is shifting items + var/shifting_items + //whether or not parent is tilting + var/tilting + //how tilted the parent is + var/how_tilted + //the maximum amount of tilt parent can achieve + var/maximum_tilt = 45 + //the maximum amount we/an item can move var/maximum_pixel_shift = 16 - /// The amount of pixel shift required to make the parent passthroughable. - var/passable_shift_threshold = 8 + //If we are shifted + var/is_shifted = FALSE + //Allows atoms entering Parent's turf to pass through freely from given directions + var/passthroughable = NONE + //Amount of shifting necessary to make the parent passthroughable + var/passthrough_threshold = 8 /datum/component/pixel_shift/Initialize(...) . = ..() @@ -17,28 +25,59 @@ return COMPONENT_INCOMPATIBLE /datum/component/pixel_shift/RegisterWithParent() + RegisterSignal(parent, COMSIG_KB_MOB_ITEM_PIXEL_SHIFT_DOWN, PROC_REF(item_pixel_shift_down)) + RegisterSignal(parent, COMSIG_KB_MOB_ITEM_PIXEL_SHIFT_UP, PROC_REF(item_pixel_shift_up)) RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_DOWN, PROC_REF(pixel_shift_down)) RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_UP, PROC_REF(pixel_shift_up)) + RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_TILT_DOWN, PROC_REF(pixel_tilt_down)) + RegisterSignal(parent, COMSIG_KB_MOB_PIXEL_TILT_UP, PROC_REF(pixel_tilt_up)) RegisterSignals(parent, list(COMSIG_LIVING_RESET_PULL_OFFSETS, COMSIG_LIVING_SET_PULL_OFFSET, COMSIG_MOVABLE_MOVED), PROC_REF(unpixel_shift)) RegisterSignal(parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(pre_move_check)) RegisterSignal(parent, COMSIG_LIVING_CAN_ALLOW_THROUGH, PROC_REF(check_passable)) - /datum/component/pixel_shift/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_KB_MOB_ITEM_PIXEL_SHIFT_DOWN) + UnregisterSignal(parent, COMSIG_KB_MOB_ITEM_PIXEL_SHIFT_UP) + UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_TILT_DOWN) + UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_TILT_UP) UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_DOWN) UnregisterSignal(parent, COMSIG_KB_MOB_PIXEL_SHIFT_UP) + UnregisterSignal(parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE) UnregisterSignal(parent, COMSIG_LIVING_RESET_PULL_OFFSETS) UnregisterSignal(parent, COMSIG_LIVING_SET_PULL_OFFSET) UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) - UnregisterSignal(parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE) UnregisterSignal(parent, COMSIG_LIVING_CAN_ALLOW_THROUGH) -/// Overrides Move to Pixel Shift. +//locks our movement when holding our keybinds /datum/component/pixel_shift/proc/pre_move_check(mob/source, new_loc, direct) SIGNAL_HANDLER - if(shifting) + if(shifting_items || shifting || tilting) pixel_shift(source, direct) return COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE +//procs for tilting parent + +/datum/component/pixel_shift/proc/pixel_tilt_down() + SIGNAL_HANDLER + tilting = TRUE + return COMSIG_KB_ACTIVATED + +/datum/component/pixel_shift/proc/pixel_tilt_up() + SIGNAL_HANDLER + tilting = FALSE + +//Procs for shifting items + +/datum/component/pixel_shift/proc/item_pixel_shift_down() + SIGNAL_HANDLER + shifting_items = TRUE + return COMSIG_KB_ACTIVATED + +/datum/component/pixel_shift/proc/item_pixel_shift_up() + SIGNAL_HANDLER + shifting_items = FALSE + +//Procs for shifting mobs + /// Checks if the parent is considered passthroughable from a direction. Projectiles will ignore the check and hit. /datum/component/pixel_shift/proc/check_passable(mob/source, atom/movable/mover, border_dir) SIGNAL_HANDLER @@ -64,37 +103,69 @@ var/mob/living/owner = parent owner.pixel_x = owner.body_position_pixel_x_offset + owner.base_pixel_x owner.pixel_y = owner.body_position_pixel_y_offset + owner.base_pixel_y + owner.transform = turn(owner.transform, -how_tilted) qdel(src) /// In-turf pixel movement which can allow things to pass through if the threshold is met. /datum/component/pixel_shift/proc/pixel_shift(mob/source, direct) passthroughable = NONE var/mob/living/owner = parent - switch(direct) - if(NORTH) - if(owner.pixel_y <= maximum_pixel_shift + owner.base_pixel_y) - owner.pixel_y++ - is_shifted = TRUE - if(EAST) - if(owner.pixel_x <= maximum_pixel_shift + owner.base_pixel_x) - owner.pixel_x++ - is_shifted = TRUE - if(SOUTH) - if(owner.pixel_y >= -maximum_pixel_shift + owner.base_pixel_y) - owner.pixel_y-- - is_shifted = TRUE - if(WEST) - if(owner.pixel_x >= -maximum_pixel_shift + owner.base_pixel_x) - owner.pixel_x-- - is_shifted = TRUE + if(shifting_items) + var/atom/pulled_atom = source.pulling + if(!isitem(pulled_atom)) + return + var/obj/item/pulled_item = pulled_atom + switch(direct) + if(NORTH) + if(pulled_item.pixel_y <= maximum_pixel_shift + pulled_item.base_pixel_y) + pulled_item.pixel_y++ + if(EAST) + if(pulled_item.pixel_x <= maximum_pixel_shift + pulled_item.base_pixel_x) + pulled_item.pixel_x++ + if(SOUTH) + if(pulled_item.pixel_y >= -maximum_pixel_shift + pulled_item.base_pixel_y) + pulled_item.pixel_y-- + if(WEST) + if(pulled_item.pixel_x >= -maximum_pixel_shift + pulled_item.base_pixel_x) + pulled_item.pixel_x-- + else if(shifting) + switch(direct) + if(NORTH) + if(owner.pixel_y <= maximum_pixel_shift + owner.base_pixel_y) + owner.pixel_y++ + is_shifted = TRUE + if(EAST) + if(owner.pixel_x <= maximum_pixel_shift + owner.base_pixel_x) + owner.pixel_x++ + is_shifted = TRUE + if(SOUTH) + if(owner.pixel_y >= -maximum_pixel_shift + owner.base_pixel_y) + owner.pixel_y-- + is_shifted = TRUE + if(WEST) + if(owner.pixel_x >= -maximum_pixel_shift + owner.base_pixel_x) + owner.pixel_x-- + is_shifted = TRUE + else if(tilting) + switch(direct) + if(EAST) + if(how_tilted <= maximum_tilt) + owner.transform = turn(owner.transform, 1) + how_tilted++ + is_shifted = TRUE + if(WEST) + if(how_tilted >= -maximum_tilt) + owner.transform = turn(owner.transform, -1) + how_tilted-- + is_shifted = TRUE // Yes, I know this sets it to true for everything if more than one is matched. // Movement doesn't check diagonals, and instead just checks EAST or WEST, depending on where you are for those. - if(owner.pixel_y > passable_shift_threshold) + if(owner.pixel_y > passthrough_threshold) passthroughable |= EAST | SOUTH | WEST - else if(owner.pixel_y < -passable_shift_threshold) + else if(owner.pixel_y < -passthrough_threshold) passthroughable |= NORTH | EAST | WEST - if(owner.pixel_x > passable_shift_threshold) + if(owner.pixel_x > passthrough_threshold) passthroughable |= NORTH | SOUTH | WEST - else if(owner.pixel_x < -passable_shift_threshold) + else if(owner.pixel_x < -passthrough_threshold) passthroughable |= NORTH | EAST | SOUTH diff --git a/modular_skyrat/modules/pixel_shift/code/pixel_shift_keybind.dm b/modular_skyrat/modules/pixel_shift/code/pixel_shift_keybind.dm index 2375b350a33..149e97a9223 100644 --- a/modular_skyrat/modules/pixel_shift/code/pixel_shift_keybind.dm +++ b/modular_skyrat/modules/pixel_shift/code/pixel_shift_keybind.dm @@ -1,3 +1,22 @@ +/datum/keybinding/mob/item_pixel_shift + hotkey_keys = list("V") + name = "item_pixel_shift" + full_name = "Item Pixel Shift" + description = "Shift a pulled item's offset" + category = CATEGORY_MISC + keybind_signal = COMSIG_KB_MOB_ITEM_PIXEL_SHIFT_DOWN + +/datum/keybinding/mob/item_pixel_shift/down(client/user) + . = ..() + if(.) + return + user.mob.AddComponent(/datum/component/pixel_shift) + SEND_SIGNAL(user.mob, COMSIG_KB_MOB_ITEM_PIXEL_SHIFT_DOWN) + +/datum/keybinding/mob/item_pixel_shift/up(client/user) + . = ..() + SEND_SIGNAL(user.mob, COMSIG_KB_MOB_ITEM_PIXEL_SHIFT_UP) + /datum/keybinding/mob/pixel_shift hotkey_keys = list("B") name = "pixel_shift" @@ -10,8 +29,28 @@ . = ..() if(.) return - user.mob.add_pixel_shift_component() + user.mob.AddComponent(/datum/component/pixel_shift) + SEND_SIGNAL(user.mob, COMSIG_KB_MOB_PIXEL_SHIFT_DOWN) /datum/keybinding/mob/pixel_shift/up(client/user) . = ..() SEND_SIGNAL(user.mob, COMSIG_KB_MOB_PIXEL_SHIFT_UP) + +/datum/keybinding/mob/pixel_tilting + hotkey_keys = list("N") + name = "Pixel Tilting" + full_name = "Pixel Tilt" + description = "Shift a mob's rotational value" + category = CATEGORY_MOVEMENT + keybind_signal = COMSIG_KB_MOB_PIXEL_TILT_DOWN + +/datum/keybinding/mob/pixel_tilting/down(client/user) + . = ..() + if(.) + return + user.mob.AddComponent(/datum/component/pixel_shift) + SEND_SIGNAL(user.mob, COMSIG_KB_MOB_PIXEL_TILT_DOWN) + +/datum/keybinding/mob/pixel_tilting/up(client/user) + . = ..() + SEND_SIGNAL(user.mob, COMSIG_KB_MOB_PIXEL_TILT_UP) diff --git a/modular_skyrat/modules/pixel_shift/code/pixel_shift_mob.dm b/modular_skyrat/modules/pixel_shift/code/pixel_shift_mob.dm deleted file mode 100644 index dbdd1e8d83f..00000000000 --- a/modular_skyrat/modules/pixel_shift/code/pixel_shift_mob.dm +++ /dev/null @@ -1,6 +0,0 @@ -/// Adds pixel_shift component on call. Default proc does nothing. -/mob/proc/add_pixel_shift_component() - return - -/mob/living/add_pixel_shift_component() - AddComponent(/datum/component/pixel_shift) diff --git a/modular_skyrat/modules/primitive_production/code/primitive.dm b/modular_skyrat/modules/primitive_production/code/primitive.dm index f1260e7b9ac..71defc64471 100644 --- a/modular_skyrat/modules/primitive_production/code/primitive.dm +++ b/modular_skyrat/modules/primitive_production/code/primitive.dm @@ -8,6 +8,34 @@ ) skill_item_path = /obj/item/clothing/neck/cloak/skill_reward/primitive +/datum/skill/primitive/level_gained(datum/mind/mind, new_level, old_level, silent) + . = ..() + mind.current.apply_status_effect(/datum/status_effect/primitive_skill, new_level) + + +/datum/status_effect/primitive_skill + status_type = STATUS_EFFECT_REFRESH + tick_interval = 0.2 SECONDS + alert_type = null + var/stored_level = SKILL_LEVEL_NOVICE + +/datum/status_effect/primitive_skill/refresh(effect, new_level) + . = ..() + stored_level = new_level + + +/datum/status_effect/primitive_skill/tick(seconds_between_ticks) + for(var/atom/potential_farm in view(3, owner)) + var/datum/component/simple_farm/farm_component = potential_farm.GetComponent(/datum/component/simple_farm) + if(!farm_component) + continue + + var/obj/structure/simple_farm/farm = locate() in get_turf(farm_component.atom_parent) + farm?.increase_level(stored_level) + + + + /obj/item/clothing/neck/cloak/skill_reward/primitive name = "legendary survivalist's cloak" desc = "Those who wear this cloak take the responsibility that comes with it: that they may be last survivor of their race. \ diff --git a/modular_skyrat/modules/quirks/echolocation/echolocation.dm b/modular_skyrat/modules/quirks/echolocation/echolocation.dm new file mode 100644 index 00000000000..2fa3f5fc30a --- /dev/null +++ b/modular_skyrat/modules/quirks/echolocation/echolocation.dm @@ -0,0 +1,106 @@ +/datum/quirk/echolocation + name = "Echolocation" + desc = "Though your eyes no longer function, you accommodate for it by some means of extrasensory echolocation and sensitive hearing. Beware: if you're ever deafened, you'll also lose your echolocation until you recover!" + gain_text = span_notice("The slightest sounds map your surroundings.") + lose_text = span_notice("The world resolves into colour and clarity.") + value = -14 + icon = FA_ICON_EAR_LISTEN + mob_trait = TRAIT_GOOD_HEARING + medical_record_text = "Patient's eyes are biologically nonfunctional. Hearing tests indicate almost supernatural acuity." + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE + mail_goodies = list(/obj/item/clothing/glasses/sunglasses, /obj/item/cane/white) + /// where we store easy access to the character's echolocation component (for stuff like drugs) + var/datum/component/echolocation/esp + /// where we store access to the client colour we make + var/datum/client_colour/echolocation_custom/esp_color + /// The action we add with this quirk in add(), used for easy deletion later + var/datum/action/cooldown/spell/added_action + +/datum/quirk/echolocation/add(client/client_source) + // echolocation component handles blinding us already so we don't need to worry about that + var/mob/living/carbon/human/human_holder = quirk_holder + // set up the desired echo group from our quirk preferences + var/client_echo_group = LOWER_TEXT(client_source?.prefs.read_preference(/datum/preference/choiced/echolocation_key)) + if (isnull(client_echo_group)) + client_echo_group = "echolocation" + if (client_echo_group == "psychic") + client_echo_group = "psyker" // set this non-player-facing so they share echolocation with coded chaplain psykers/pirates and the like + + // Get the prefs + var/client_show_outline = client_source?.prefs.read_preference(/datum/preference/toggle/echolocation_overlay) + var/col = color_hex2color_matrix(client_source?.prefs.read_preference(/datum/preference/color/echolocation_outline)) + + human_holder.AddComponent(\ + /datum/component/echolocation, \ + blocking_trait = TRAIT_DEAF, \ + cooldown_time = 2 SECONDS, \ + echo_range = 7, \ + echo_group = client_echo_group, \ + images_are_static = FALSE, \ + use_echo = FALSE, \ + show_own_outline = client_show_outline, \ + personal_color = col \ + ) + esp = human_holder.GetComponent(/datum/component/echolocation) + + human_holder.remove_client_colour(/datum/client_colour/monochrome/blind) + esp_color = human_holder.add_client_colour(/datum/client_colour/echolocation_custom) + esp_color.update_colour(col) + + // add an action/spell to allow the player to toggle echolocation off for a bit (eyestrain on longer rounds, or just roleplay) + var/datum/action/cooldown/spell/echolocation_toggle/toggle_action = new /datum/action/cooldown/spell/echolocation_toggle() + toggle_action.Grant(human_holder) + added_action = toggle_action + RegisterSignal(human_holder, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine_text)) + +/datum/quirk/echolocation/remove() + QDEL_NULL(esp) // echolocation component removal handles graceful disposal of everything above + QDEL_NULL(added_action) // remove the stall action, too + var/mob/living/carbon/human/human_holder = quirk_holder + human_holder.remove_client_colour(/datum/client_colour/echolocation_custom) // clean up the custom colour override we added + UnregisterSignal(human_holder, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine_text)) + +/datum/quirk/echolocation/proc/on_examine_text(client/client_source, mob/user, list/examine_list) + SIGNAL_HANDLER + var/mob/living/carbon/human/human_holder = quirk_holder + var/datum/quirk/echolocation/echo = human_holder.get_quirk(/datum/quirk/echolocation) + var/datum/component/echolocation/quirk_esp = echo.esp + + if(quirk_esp.stall == TRUE) + return + examine_list += span_cyan("[human_holder.p_They()] [human_holder.p_have()] [human_holder.p_their()] ears perked up, listening closely to even slightest noise.") + +/datum/client_colour/echolocation_custom + colour = COLOR_MATRIX_SEPIATONE + priority = 1 + override = TRUE + +/datum/action/cooldown/spell/echolocation_toggle + name = "Toggle echolocation" + desc = "Decide whether you want to stop echolocating (or start again). Useful if you need a break - it's not an easy process!" + spell_requirements = NONE + cooldown_time = 2 SECONDS + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "blink" + +/datum/action/cooldown/spell/echolocation_toggle/is_valid_target(atom/cast_on) + return ishuman(cast_on) + +/datum/action/cooldown/spell/echolocation_toggle/cast(mob/living/carbon/human/cast_on) + . = ..() + var/datum/quirk/echolocation/echo = cast_on.get_quirk(/datum/quirk/echolocation) + if (isnull(echo)) + return + + var/datum/component/echolocation/quirk_esp = echo.esp + if (isnull(quirk_esp)) + return + + if (quirk_esp.stall) + quirk_esp.stall = FALSE + cast_on.balloon_alert(cast_on, "started echolocating!") + cast_on.visible_message(span_notice("[cast_on] perks up, suddenly seeming more vigilant!")) + else + quirk_esp.stall = TRUE + cast_on.balloon_alert(cast_on, "stopped echolocating!") + cast_on.visible_message(span_notice("[cast_on] relaxes slightly, seeming less vigilant for the moment.")) diff --git a/modular_skyrat/modules/quirks/echolocation/echolocation_component.dm b/modular_skyrat/modules/quirks/echolocation/echolocation_component.dm new file mode 100644 index 00000000000..9edecdd9014 --- /dev/null +++ b/modular_skyrat/modules/quirks/echolocation/echolocation_component.dm @@ -0,0 +1,7 @@ +/datum/component/echolocation + /// Should the mob see itself outlined? + var/show_own_outline = FALSE + /// Are we temporarily halting visual processing on this component? + var/stall = FALSE + /// The color of the echolocation user when seen by other echolocators + var/echo_color = "#ffffff" diff --git a/modular_skyrat/modules/quirks/echolocation/echolocation_pref.dm b/modular_skyrat/modules/quirks/echolocation/echolocation_pref.dm new file mode 100644 index 00000000000..1806e3a305a --- /dev/null +++ b/modular_skyrat/modules/quirks/echolocation/echolocation_pref.dm @@ -0,0 +1,52 @@ +/datum/quirk_constant_data/echolocation + associated_typepath = /datum/quirk/echolocation + customization_options = list(/datum/preference/color/echolocation_outline, /datum/preference/choiced/echolocation_key, /datum/preference/toggle/echolocation_overlay) + +// Client preference for echolocation outline colour +/datum/preference/color/echolocation_outline + savefile_key = "echolocation_outline" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_MANUALLY_RENDERED + +/datum/preference/color/echolocation_outline/is_accessible(datum/preferences/preferences) + if (!..(preferences)) + return FALSE + + return "Echolocation" in preferences.all_quirks + +/datum/preference/color/echolocation_outline/apply_to_human(mob/living/carbon/human/target, value) + return + +// Client preference for echolocation key type +/datum/preference/choiced/echolocation_key + category = PREFERENCE_CATEGORY_MANUALLY_RENDERED + savefile_key = "echolocation_key" + savefile_identifier = PREFERENCE_CHARACTER + +/datum/preference/choiced/echolocation_key/is_accessible(datum/preferences/preferences) + if (!..(preferences)) + return FALSE + + return "Echolocation" in preferences.all_quirks + +/datum/preference/choiced/echolocation_key/init_possible_values() + var/list/values = list("Extrasensory", "Psychic", "Auditory/Vibrational") + return values + +/datum/preference/choiced/echolocation_key/apply_to_human(mob/living/carbon/human/target, value) + return + +// Client preference for whether we display the echolocation overlay or not +/datum/preference/toggle/echolocation_overlay + category = PREFERENCE_CATEGORY_MANUALLY_RENDERED + savefile_key = "echolocation_use_echo" + savefile_identifier = PREFERENCE_CHARACTER + +/datum/preference/toggle/echolocation_overlay/is_accessible(datum/preferences/preferences) + if (!..(preferences)) + return FALSE + + return "Echolocation" in preferences.all_quirks + +/datum/preference/toggle/echolocation_overlay/apply_to_human(mob/living/carbon/human/target, value) + return diff --git a/modular_skyrat/master_files/code/datums/traits/good.dm b/modular_skyrat/modules/quirks/good.dm similarity index 100% rename from modular_skyrat/master_files/code/datums/traits/good.dm rename to modular_skyrat/modules/quirks/good.dm diff --git a/modular_skyrat/master_files/code/datums/traits/negative.dm b/modular_skyrat/modules/quirks/negative.dm similarity index 100% rename from modular_skyrat/master_files/code/datums/traits/negative.dm rename to modular_skyrat/modules/quirks/negative.dm diff --git a/modular_skyrat/master_files/code/datums/traits/neutral.dm b/modular_skyrat/modules/quirks/neutral.dm similarity index 100% rename from modular_skyrat/master_files/code/datums/traits/neutral.dm rename to modular_skyrat/modules/quirks/neutral.dm diff --git a/modular_skyrat/modules/reagent_forging/code/forge_items.dm b/modular_skyrat/modules/reagent_forging/code/forge_items.dm index efa4bfd997d..4db2587dc29 100644 --- a/modular_skyrat/modules/reagent_forging/code/forge_items.dm +++ b/modular_skyrat/modules/reagent_forging/code/forge_items.dm @@ -263,7 +263,7 @@ icon_state = "coil" /obj/item/forging/incomplete_bow - name = "incomplete bow" + name = "incomplete longbow" desc = "A wooden bow that has yet to be strung." icon_state = "nostring_bow" diff --git a/modular_skyrat/modules/synths/code/surgery/mechanic_steps.dm b/modular_skyrat/modules/synths/code/surgery/mechanic_steps.dm index 8389c9e1a79..35309a62670 100644 --- a/modular_skyrat/modules/synths/code/surgery/mechanic_steps.dm +++ b/modular_skyrat/modules/synths/code/surgery/mechanic_steps.dm @@ -1,6 +1,6 @@ //cut wires /datum/surgery_step/cut_wires - name = "cut wires" + name = "cut wires (wirecutters)" implements = list( TOOL_WIRECUTTER = 100, TOOL_SCALPEL = 75, @@ -25,7 +25,7 @@ //pry off plating /datum/surgery_step/pry_off_plating - name = "pry off plating" + name = "pry off plating (crowbar)" implements = list( TOOL_CROWBAR = 100, TOOL_HEMOSTAT = 10, @@ -47,7 +47,7 @@ //weld plating /datum/surgery_step/weld_plating - name = "weld plating" + name = "weld plating (welder)" implements = list( TOOL_WELDER = 100, ) @@ -69,7 +69,7 @@ //replace wires /datum/surgery_step/replace_wires - name = "replace wires" + name = "replace wires (cable coil)" implements = list(/obj/item/stack/cable_coil = 100) time = 2.4 SECONDS var/cableamount = 5 @@ -98,7 +98,7 @@ //add plating /datum/surgery_step/add_plating - name = "add plating" + name = "add plating (iron sheet)" implements = list(/obj/item/stack/sheet/iron = 100) time = 2.4 SECONDS var/ironamount = 5 diff --git a/modular_skyrat/modules/synths/code/surgery/robot_brain_surgery.dm b/modular_skyrat/modules/synths/code/surgery/robot_brain_surgery.dm index 6dfd7f291bc..bffd2e715fe 100644 --- a/modular_skyrat/modules/synths/code/surgery/robot_brain_surgery.dm +++ b/modular_skyrat/modules/synths/code/surgery/robot_brain_surgery.dm @@ -26,7 +26,7 @@ return TRUE /datum/surgery_step/fix_robot_brain - name = "fix posibrain" + name = "fix posibrain (multitool)" implements = list( TOOL_MULTITOOL = 100, TOOL_HEMOSTAT = 35, @@ -79,3 +79,42 @@ user.visible_message(span_warning("[user] suddenly notices that the posibrain [user.p_they()] [user.p_were()] working on is not there anymore."), span_warning("You suddenly notice that the posibrain you were working on is not there anymore.")) return FALSE + +/datum/surgery/robot_trauma_surgery + name = "Reticulate Posibrain Splines (Blessed Lobotomy)" + desc = "A surgical procedure that refurbishes low level components in the posibrain, to fix the strongest trauma errors." + possible_locs = list(BODY_ZONE_CHEST) // The brains are in the chest + requires_bodypart_type = BODYTYPE_ROBOTIC + target_mobtypes = list(/mob/living/carbon/human) + steps = list( + /datum/surgery_step/mechanic_open, + /datum/surgery_step/mechanic_unwrench, + /datum/surgery_step/pry_off_plating, + /datum/surgery_step/prepare_electronics, + /datum/surgery_step/fix_robot_brain/advanced, + /datum/surgery_step/mechanic_close, + ) + +/datum/surgery_step/fix_robot_brain/advanced + name = "reticulate splines (multitool)" + repeatable = FALSE + chems_needed = list( + /datum/reagent/catalyst_agent/speed/medicine, + ) + +/datum/surgery_step/fix_robot_brain/advanced/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, + target, + span_notice("You succeed in reticulating [target]'s splines."), + "[user] successfully fixes [target]'s posibrain!", + "[user] completes the surgery on [target]'s posibrain.", + ) + + target.setOrganLoss(ORGAN_SLOT_BRAIN, target.get_organ_loss(ORGAN_SLOT_BRAIN) - 60) //we set damage in this case in order to clear the "failing" flag + target.cure_all_traumas(TRAUMA_RESILIENCE_MAGIC) + playsound(source = get_turf(target), soundin = 'sound/magic/repulse.ogg', vol = 75, vary = TRUE, falloff_distance = 2) + if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed)) + target.mind.remove_antag_datum(/datum/antagonist/brainwashed) + if(prob(75)) + target.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_MAGIC) + return ..() diff --git a/modular_skyrat/modules/tribal_extended/code/ammo/reusable/arrow.dm b/modular_skyrat/modules/tribal_extended/code/ammo/reusable/arrow.dm index 5fd451bb0f4..9ab3c46d87e 100644 --- a/modular_skyrat/modules/tribal_extended/code/ammo/reusable/arrow.dm +++ b/modular_skyrat/modules/tribal_extended/code/ammo/reusable/arrow.dm @@ -17,8 +17,8 @@ /obj/projectile/bullet/arrow/ash name = "ashen arrow" desc = "An arrow made of hardened ash." - faction_bonus_force = 60 - damage = 15//lower me to 20 or 15 + faction_bonus_force = 90 + damage = 30 nemesis_paths = list( /mob/living/simple_animal/hostile/asteroid, /mob/living/basic/mining, @@ -29,7 +29,7 @@ /obj/projectile/bullet/arrow/bone name = "bone arrow" desc = "An arrow made from bone and sinew." - faction_bonus_force = 35 + faction_bonus_force = 120 damage = 35 armour_penetration = 20 wound_bonus = -30 @@ -42,7 +42,7 @@ embed_type = /datum/embed_data/bone_arrow /datum/embed_data/bone_arrow - embed_chance = 33 + embed_chance = 35 fall_chance = 3 jostle_chance = 4 ignore_throwspeed_threshold = TRUE @@ -54,7 +54,7 @@ /obj/projectile/bullet/arrow/bronze name = "bronze arrow" desc = "A bronze-tipped arrow." - faction_bonus_force = 90 + faction_bonus_force = 140 damage = 30 armour_penetration = 30 nemesis_paths = list( diff --git a/modular_skyrat/modules/tribal_extended/code/crafting.dm b/modular_skyrat/modules/tribal_extended/code/crafting.dm index adf21657bd9..3a029eed7f8 100644 --- a/modular_skyrat/modules/tribal_extended/code/crafting.dm +++ b/modular_skyrat/modules/tribal_extended/code/crafting.dm @@ -3,3 +3,10 @@ desc = "A long piece of string that looks like a cable coil." icon = 'modular_skyrat/modules/tribal_extended/icons/crafting.dmi' icon_state = "silkstring" + +/obj/item/dice/d6/bone + name = "bone die" + desc = "A die carved from a creature's bone. Dried blood marks the indented pits." + icon = 'modular_skyrat/modules/tribal_extended/icons/dice.dmi' + icon_state = "db6" + microwave_riggable = FALSE // You can't melt bone in the microwave diff --git a/modular_skyrat/modules/tribal_extended/code/recipes.dm b/modular_skyrat/modules/tribal_extended/code/recipes.dm index e9739121276..0266edca53b 100644 --- a/modular_skyrat/modules/tribal_extended/code/recipes.dm +++ b/modular_skyrat/modules/tribal_extended/code/recipes.dm @@ -5,16 +5,6 @@ time = 5 SECONDS category = CAT_MISC -/datum/crafting_recipe/wood_bow - name = "Wooden Bow" - result = /obj/item/gun/ballistic/bow/longbow - reqs = list( - /obj/item/stack/sheet/mineral/wood = 25, - /obj/item/weaponcrafting/silkstring = 2, - ) - time = 30 SECONDS - category = CAT_WEAPON_RANGED - /datum/crafting_recipe/pipebow name = "Pipe Bow" result = /obj/item/gun/ballistic/bow/tribalbow/pipe @@ -26,47 +16,38 @@ time = 45 SECONDS category = CAT_WEAPON_RANGED -/datum/crafting_recipe/arrow - name = "Arrow" - result = /obj/item/ammo_casing/arrow - reqs = list( - /obj/item/stack/sheet/mineral/wood = 1, - /obj/item/stack/sheet/cloth= 1, - /obj/item/stack/rods = 1, - ) - time = 1.5 SECONDS - category = CAT_WEAPON_AMMO - /datum/crafting_recipe/bone_arrow name = "Bone Arrow" result = /obj/item/ammo_casing/arrow/bone reqs = list( /obj/item/stack/sheet/bone = 1, - /obj/item/ammo_casing/arrow/ash = 1, + /obj/item/ammo_casing/arrow = 1, ) - time = 1.5 SECONDS category = CAT_WEAPON_AMMO + non_craftable = TRUE + steps = list("Reinforce the arrow with sinew.") /datum/crafting_recipe/ashen_arrow name = "Ashen Arrow" result = /obj/item/ammo_casing/arrow/ash reqs = list( - /obj/item/stack/rods = 2, + /obj/item/ammo_casing/arrow = 1, /obj/item/stack/sheet/sinew = 1, - /obj/item/stack/ore/glass/basalt = 10, ) - time = 1.5 SECONDS category = CAT_WEAPON_AMMO + non_craftable = TRUE + steps = list("Reinforce the arrow with sinew.") /datum/crafting_recipe/bronze_arrow name = "Bronze arrow" result = /obj/item/ammo_casing/arrow/bronze reqs = list( - /obj/item/ammo_casing/arrow/ash = 1, + /obj/item/ammo_casing/arrow = 1, /obj/item/stack/tile/bronze = 1, ) - time = 1.5 SECONDS category = CAT_WEAPON_AMMO + non_craftable = TRUE + steps = list("Reinforce the arrowhead with bronze.") /datum/crafting_recipe/goliathshield name = "Goliath shield" @@ -108,3 +89,12 @@ ) time = 20 SECONDS category = CAT_WEAPON_RANGED + +/datum/crafting_recipe/bonedice + name = "Bone Die" + result = /obj/item/dice/d6/bone + time = 5 SECONDS + reqs = list( + /obj/item/stack/sheet/bone = 1, + ) + category = CAT_EQUIPMENT diff --git a/modular_skyrat/modules/tribal_extended/code/weapons/bow.dm b/modular_skyrat/modules/tribal_extended/code/weapons/bow.dm index d44b35ee1ff..4c8655d4430 100644 --- a/modular_skyrat/modules/tribal_extended/code/weapons/bow.dm +++ b/modular_skyrat/modules/tribal_extended/code/weapons/bow.dm @@ -4,33 +4,37 @@ righthand_file = 'modular_skyrat/modules/tribal_extended/icons/bows_righthand.dmi' worn_icon = 'modular_skyrat/modules/tribal_extended/icons/back.dmi' inhand_icon_state = "bow" - icon_state = "bow_unloaded" + icon_state = null base_icon_state = "bow" worn_icon_state = "bow" slot_flags = ITEM_SLOT_BACK + projectile_damage_multiplier = 0.5 + force = 20 /obj/item/gun/ballistic/bow/tribalbow/update_icon() . = ..() - icon_state = "[base_icon_state]_[get_ammo() ? (chambered ? "firing" : "loaded") : "unloaded"]" + icon_state = "[base_icon_state][drawn ? "_drawn" : ""]" + +/obj/item/gun/ballistic/bow/tribalbow/update_overlays() + . = ..() + if(chambered) + . += "[chambered.base_icon_state][drawn ? "_drawn" : ""]" /obj/item/gun/ballistic/bow/tribalbow/ashen name = "bone bow" desc = "Some sort of primitive projectile weapon made of bone and wrapped sinew, oddly robust." icon = 'modular_skyrat/modules/tribal_extended/icons/projectile.dmi' - icon_state = "ashenbow_unloaded" + icon_state = "ashenbow" base_icon_state = "ashenbow" inhand_icon_state = "ashenbow" worn_icon_state = "ashenbow" - force = 20 /obj/item/gun/ballistic/bow/tribalbow/pipe name = "pipe bow" desc = "Portable and sleek, but you'd be better off hitting someone with a pool noodle." icon = 'modular_skyrat/modules/tribal_extended/icons/projectile.dmi' - icon_state = "pipebow_unloaded" + icon_state = "pipebow" base_icon_state = "pipebow" - inhand_icon_state = "pipebow" worn_icon_state = "pipebow" - force = 10 slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_SUITSTORE diff --git a/modular_skyrat/modules/tribal_extended/icons/ammo.dmi b/modular_skyrat/modules/tribal_extended/icons/ammo.dmi index 08720fe1fb0..8fb9d7a695a 100644 Binary files a/modular_skyrat/modules/tribal_extended/icons/ammo.dmi and b/modular_skyrat/modules/tribal_extended/icons/ammo.dmi differ diff --git a/modular_skyrat/modules/tribal_extended/icons/dice.dmi b/modular_skyrat/modules/tribal_extended/icons/dice.dmi new file mode 100644 index 00000000000..f597bc60c02 Binary files /dev/null and b/modular_skyrat/modules/tribal_extended/icons/dice.dmi differ diff --git a/modular_skyrat/modules/tribal_extended/icons/projectile.dmi b/modular_skyrat/modules/tribal_extended/icons/projectile.dmi index 9cb037bce25..3dfc194ae30 100644 Binary files a/modular_skyrat/modules/tribal_extended/icons/projectile.dmi and b/modular_skyrat/modules/tribal_extended/icons/projectile.dmi differ diff --git a/sound/items/attributions.txt b/sound/items/attributions.txt index a9e708c477c..9ad1a09d8cb 100644 --- a/sound/items/attributions.txt +++ b/sound/items/attributions.txt @@ -24,6 +24,21 @@ plastic_pick_up.ogg - https://freesound.org/people/Jessica190091/sounds/491304/ plastic_drop.ogg - https://freesound.org/people/martian/sounds/338854/ , License: CC0 } - edited by sadboysuss +{ +gun_drop.ogg - FN FAL Rifle Load and Cock 01.mp3 by PNMCarrieRailfan -- https://freesound.org/s/682029/ -- License: Attribution NonCommercial 4.0 +gun_pick_up.ogg - FN FAL Rifle Unload and Cock.mp3 by PNMCarrieRailfan -- https://freesound.org/s/682031/ -- License: Attribution NonCommercial 4.0 +handcuffs_drop.ogg - handcuffs.ogg by kimuracarter -- https://freesound.org/s/528749/ -- License: Attribution 3.0 +handcuffs_pick_up.ogg - handcuffs.ogg by kimuracarter -- https://freesound.org/s/528749/ -- License: Attribution 3.0 +plastic_shield_drop.ogg - made by sadboysuss -- License: CC-by-SA +plastic_shield_pick_up.ogg - made by sadboysuss -- License: CC-by-SA +stun_baton_drop.ogg - Fn P90 Submachine Gun 5.7Mm. Mechan; Empty Mag Inserted Into And Pulled Out Slow And Various 02 by PNMCarrieRailfan -- https://freesound.org/s/682041/ -- License: Attribution NonCommercial 4.0 +stun_baton_pick_up.ogg - Fn P90 Submachine Gun 5.7Mm. Mechan; Empty Mag Inserted Into And Pulled Out Slow And Various 02 by PNMCarrieRailfan -- https://freesound.org/s/682041/ -- License: Attribution NonCommercial 4.0 +pepper_spray_drop.ogg - Spray Paint Shake Slow Five.wav by cbakos -- https://freesound.org/s/200376/ -- License: Creative Commons 0 +pepper_spray_pick_up.ogg - Spray Paint Shake Slow Five.wav by cbakos -- https://freesound.org/s/200376/ -- License: Creative Commons 0 +grenade_drop.ogg - made by sadboysuss -- License: CC-by-SA +grenade_pick_up.ogg - made by sadboysuss -- License: CC-by-SA +} - edited by sadboysuss + { skin_drop.ogg - https://freesound.org/people/Crinkem/sounds/501015/ , License: CC4 skin_pick_up.ogg - https://freesound.org/people/Crinkem/sounds/501015/ , License CC3 diff --git a/sound/items/grenade_drop.ogg b/sound/items/grenade_drop.ogg new file mode 100644 index 00000000000..04627811cd1 Binary files /dev/null and b/sound/items/grenade_drop.ogg differ diff --git a/sound/items/grenade_pick_up.ogg b/sound/items/grenade_pick_up.ogg new file mode 100644 index 00000000000..d257659f761 Binary files /dev/null and b/sound/items/grenade_pick_up.ogg differ diff --git a/sound/items/gun_drop.ogg b/sound/items/gun_drop.ogg new file mode 100644 index 00000000000..21b83bc91d6 Binary files /dev/null and b/sound/items/gun_drop.ogg differ diff --git a/sound/items/gun_pick_up.ogg b/sound/items/gun_pick_up.ogg new file mode 100644 index 00000000000..6bf6b45a16b Binary files /dev/null and b/sound/items/gun_pick_up.ogg differ diff --git a/sound/items/handcuff_finish.ogg b/sound/items/handcuff_finish.ogg new file mode 100644 index 00000000000..92096837835 Binary files /dev/null and b/sound/items/handcuff_finish.ogg differ diff --git a/sound/items/handcuffs_drop.ogg b/sound/items/handcuffs_drop.ogg new file mode 100644 index 00000000000..85b7f172e48 Binary files /dev/null and b/sound/items/handcuffs_drop.ogg differ diff --git a/sound/items/handcuffs_pick_up.ogg b/sound/items/handcuffs_pick_up.ogg new file mode 100644 index 00000000000..d3fdc3450bd Binary files /dev/null and b/sound/items/handcuffs_pick_up.ogg differ diff --git a/sound/items/holster.ogg b/sound/items/holster.ogg new file mode 100644 index 00000000000..984e7ad4fea Binary files /dev/null and b/sound/items/holster.ogg differ diff --git a/sound/items/pepper_spray_drop.ogg b/sound/items/pepper_spray_drop.ogg new file mode 100644 index 00000000000..e071c65d3bc Binary files /dev/null and b/sound/items/pepper_spray_drop.ogg differ diff --git a/sound/items/pepper_spray_pick_up.ogg b/sound/items/pepper_spray_pick_up.ogg new file mode 100644 index 00000000000..a474bbd91b3 Binary files /dev/null and b/sound/items/pepper_spray_pick_up.ogg differ diff --git a/sound/items/plastic_shield_drop.ogg b/sound/items/plastic_shield_drop.ogg new file mode 100644 index 00000000000..4d07b48d481 Binary files /dev/null and b/sound/items/plastic_shield_drop.ogg differ diff --git a/sound/items/plastic_shield_pick_up.ogg b/sound/items/plastic_shield_pick_up.ogg new file mode 100644 index 00000000000..e18e9617b77 Binary files /dev/null and b/sound/items/plastic_shield_pick_up.ogg differ diff --git a/sound/items/stun_baton_drop.ogg b/sound/items/stun_baton_drop.ogg new file mode 100644 index 00000000000..1d5d59e9012 Binary files /dev/null and b/sound/items/stun_baton_drop.ogg differ diff --git a/sound/items/stun_baton_pick_up.ogg b/sound/items/stun_baton_pick_up.ogg new file mode 100644 index 00000000000..6b87e531fc4 Binary files /dev/null and b/sound/items/stun_baton_pick_up.ogg differ diff --git a/tgstation.dme b/tgstation.dme index b85e066fce4..f7b938a27a0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1007,6 +1007,7 @@ #include "code\datums\ai\basic_mobs\basic_subtrees\find_food.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\find_paper_and_write.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\find_parent.dm" +#include "code\datums\ai\basic_mobs\basic_subtrees\find_targets_prioritize_traits.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\flee_target.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\go_for_swim.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\maintain_distance.dm" @@ -2589,6 +2590,7 @@ #include "code\game\objects\items\granters\crafting\combat_baking.dm" #include "code\game\objects\items\granters\crafting\death_sandwich.dm" #include "code\game\objects\items\granters\crafting\desserts.dm" +#include "code\game\objects\items\granters\crafting\fletching.dm" #include "code\game\objects\items\granters\crafting\pipegun.dm" #include "code\game\objects\items\granters\crafting\rebarxbowsyndie.dm" #include "code\game\objects\items\granters\crafting\regal_condor.dm" @@ -6509,9 +6511,6 @@ #include "modular_skyrat\master_files\code\datums\status_effects\debuffs\debuffs.dm" #include "modular_skyrat\master_files\code\datums\storage\storage.dm" #include "modular_skyrat\master_files\code\datums\storage\subtypes\pockets.dm" -#include "modular_skyrat\master_files\code\datums\traits\good.dm" -#include "modular_skyrat\master_files\code\datums\traits\negative.dm" -#include "modular_skyrat\master_files\code\datums\traits\neutral.dm" #include "modular_skyrat\master_files\code\datums\votes\_vote_datum.dm" #include "modular_skyrat\master_files\code\datums\votes\map_vote.dm" #include "modular_skyrat\master_files\code\game\atoms.dm" @@ -8208,7 +8207,6 @@ #include "modular_skyrat\modules\pet_owner\pet_owner.dm" #include "modular_skyrat\modules\pixel_shift\code\pixel_shift_component.dm" #include "modular_skyrat\modules\pixel_shift\code\pixel_shift_keybind.dm" -#include "modular_skyrat\modules\pixel_shift\code\pixel_shift_mob.dm" #include "modular_skyrat\modules\player_ranks\code\preferences.dm" #include "modular_skyrat\modules\player_ranks\code\world_topic.dm" #include "modular_skyrat\modules\player_ranks\code\player_rank_controller\_player_rank_controller.dm" @@ -8277,6 +8275,12 @@ #include "modular_skyrat\modules\QOL\code\_under.dm" #include "modular_skyrat\modules\QOL\code\datums\components\crafting\recipes\recipes_misc.dm" #include "modular_skyrat\modules\QOL\code\game\objects\items\mop.dm" +#include "modular_skyrat\modules\quirks\good.dm" +#include "modular_skyrat\modules\quirks\negative.dm" +#include "modular_skyrat\modules\quirks\neutral.dm" +#include "modular_skyrat\modules\quirks\echolocation\echolocation.dm" +#include "modular_skyrat\modules\quirks\echolocation\echolocation_component.dm" +#include "modular_skyrat\modules\quirks\echolocation\echolocation_pref.dm" #include "modular_skyrat\modules\radiosound\code\headset.dm" #include "modular_skyrat\modules\reagent_forging\code\anvil.dm" #include "modular_skyrat\modules\reagent_forging\code\crafting_bench.dm" diff --git a/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx b/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx index 7b799e96552..88520752b1e 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx @@ -188,6 +188,8 @@ export const AntagInfoMalf = (props) => { items.push({ id: item.name, name: item.name, + icon: item.icon, + icon_state: item.icon_state, category: category.name, cost: `${item.cost} PT`, desc: item.desc, diff --git a/tgui/packages/tgui/interfaces/AntagInfoSpy.tsx b/tgui/packages/tgui/interfaces/AntagInfoSpy.tsx index 98ed0ae72d2..19aee4dfb0f 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoSpy.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoSpy.tsx @@ -1,8 +1,13 @@ import { Section, Stack } from 'tgui-core/components'; +import { BooleanLike } from 'tgui-core/react'; import { useBackend } from '../backend'; import { Window } from '../layouts'; -import { Objective, ObjectivePrintout } from './common/Objectives'; +import { + Objective, + ObjectivePrintout, + ReplaceObjectivesButton, +} from './common/Objectives'; const greenText = { fontWeight: 'italics', @@ -18,13 +23,15 @@ type Data = { antag_name: string; uplink_location: string | null; objectives: Objective[]; + can_change_objective: BooleanLike; }; export const AntagInfoSpy = () => { const { data } = useBackend(); - const { antag_name, uplink_location, objectives } = data; + const { antag_name, uplink_location, objectives, can_change_objective } = + data; return ( - + { objectives={objectives} /> + + + { + + } + diff --git a/tgui/packages/tgui/interfaces/ChemMaster.tsx b/tgui/packages/tgui/interfaces/ChemMaster.tsx index 62692588c65..6a2becf3eb0 100644 --- a/tgui/packages/tgui/interfaces/ChemMaster.tsx +++ b/tgui/packages/tgui/interfaces/ChemMaster.tsx @@ -5,6 +5,8 @@ import { Button, ColorBox, Divider, + DmIcon, + Icon, LabeledList, NumberInput, ProgressBar, @@ -13,7 +15,7 @@ import { Table, Tooltip, } from 'tgui-core/components'; -import { BooleanLike, classes } from 'tgui-core/react'; +import { BooleanLike } from 'tgui-core/react'; import { capitalize } from 'tgui-core/string'; import { useBackend } from '../backend'; @@ -22,6 +24,7 @@ import { Beaker, BeakerReagent } from './common/BeakerDisplay'; type Container = { icon: string; + icon_state: string; ref: string; name: string; volume: number; @@ -375,6 +378,8 @@ const ContainerButton = (props: CategoryButtonProps) => { const { isPrinting, selectedContainerRef, suggestedContainerRef } = data; const { category, container, showPreferredContainer } = props; const isPillPatch = ['pills', 'patches'].includes(category.name); + const fallback = ; + const fallbackPillPatch = ; return ( { }); }} > - diff --git a/tgui/packages/tgui/interfaces/InteractionMenu.tsx b/tgui/packages/tgui/interfaces/InteractionMenu.tsx index 7b83319cfbe..27605655420 100644 --- a/tgui/packages/tgui/interfaces/InteractionMenu.tsx +++ b/tgui/packages/tgui/interfaces/InteractionMenu.tsx @@ -48,7 +48,7 @@ export const InteractionMenu = (props) => { {(block_interact && Unable to Interact) || ( Able to Interact )} - +
{categories.map((category) => ( @@ -78,59 +78,60 @@ export const InteractionMenu = (props) => { ))}
-
- {lewd_slots.length > 0 ? ( -
- - {lewd_slots.map((element: LewdSlot) => { - return ( - - - - ); - })} - -
- ) : ( - '' - )} + + {element.img ? ( + + ) : ( + + )} + + + + ); + })} +
+ + ) : ( + '' + )} +
); diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/echolocation.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/echolocation.tsx new file mode 100644 index 00000000000..f232cb16e5b --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/echolocation.tsx @@ -0,0 +1,24 @@ +// THIS IS A Skyrat SECTOR UI FILE +import { + CheckboxInput, + Feature, + FeatureChoiced, + FeatureColorInput, + FeatureToggle, +} from '../../base'; +import { FeatureDropdownInput } from '../../dropdowns'; + +export const echolocation_outline: Feature = { + name: 'Echo outline color', + component: FeatureColorInput, +}; + +export const echolocation_key: FeatureChoiced = { + name: 'Echolocation group', + component: FeatureDropdownInput, +}; + +export const echolocation_use_echo: FeatureToggle = { + name: 'Display own overlay', + component: CheckboxInput, +}; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx index 60818536339..28ae2fe2179 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx @@ -54,11 +54,21 @@ export const penis_sheath: Feature = { export const penis_length: FeatureNumeric = { name: 'Penis Length', + description: + 'Value is measured in inches.\ + This value is limited to 20 for characters with a body size <= 1, \ + or without the oversized trait. The maximum allowed value scales up\ + based on the body size of a character, up to a max of 36.', component: FeatureNumberInput, }; export const penis_girth: FeatureNumeric = { name: 'Penis Girth', + description: + 'Value is circumference, measured in inches.\ + This value is limited to 15 for characters with a body size <= 1, \ + or without the oversized trait. The maximum allowed value scales up\ + based on the body size of a character, up to a max of 20.', component: FeatureNumberInput, }; diff --git a/tgui/packages/tgui/interfaces/SmartVend.tsx b/tgui/packages/tgui/interfaces/SmartVend.tsx index 67a37c0241c..9023afacbc7 100644 --- a/tgui/packages/tgui/interfaces/SmartVend.tsx +++ b/tgui/packages/tgui/interfaces/SmartVend.tsx @@ -4,7 +4,7 @@ import { useState } from 'react'; import { DmIcon, Icon } from 'tgui-core/components'; import { useBackend } from '../backend'; -import { Button, Input, NoticeBox, Section } from '../components'; +import { Box, Button, Input, NoticeBox, Section, Stack } from '../components'; import { Window } from '../layouts'; type Item = { @@ -20,29 +20,31 @@ type Data = { name: string; isdryer: BooleanLike; drying: BooleanLike; + default_list_view: BooleanLike; }; +enum MODE { + tile, + list, +} + export const SmartVend = (props) => { const { act, data } = useBackend(); const [searchText, setSearchText] = useState(''); + const [displayMode, setDisplayMode] = useState( + data.default_list_view ? MODE.list : MODE.tile, + ); const search = createSearch(searchText, (item: Item) => item.name); const contents = searchText.length > 0 ? Object.values(data.contents).filter(search) : Object.values(data.contents); - - const fallback = ( - - ); return (
{ {data.drying ? 'Stop drying' : 'Dry'} ) : ( - setSearchText(value)} - /> + <> + setSearchText(value)} + /> + - )} - - )) + contents.map((item) => + displayMode === MODE.tile ? ( + + ) : ( + + ), + ) )}
); }; + +const ItemTile = ({ item }) => { + const { act } = useBackend(); + const fallback = ( + + ); + return ( + + + )} + + + {item.name} + + + ) as any; +}; + +const ItemList = ({ item }) => { + const { act } = useBackend(); + const fallback = ( + + ); + return ( + + + + + + {item.name} + + + + + {item.amount > 1 && ( + + {`x${item.amount}`} + + )} + + + + + + + + ) as any; +}; diff --git a/tgui/packages/tgui/interfaces/Uplink/GenericUplink.tsx b/tgui/packages/tgui/interfaces/Uplink/GenericUplink.tsx index 6f69b6671eb..c6558321b69 100644 --- a/tgui/packages/tgui/interfaces/Uplink/GenericUplink.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/GenericUplink.tsx @@ -1,9 +1,13 @@ import { BooleanLike } from 'common/react'; import { useState } from 'react'; +import { Tooltip } from 'tgui-core/components'; +import { useBackend } from '../../backend'; import { Box, Button, + DmIcon, + Icon, Input, NoticeBox, Section, @@ -19,6 +23,7 @@ type GenericUplinkProps = { }; export const GenericUplink = (props: GenericUplinkProps) => { + const { act } = useBackend(); const { currency = 'cr', categories, @@ -36,43 +41,71 @@ export const GenericUplink = (props: GenericUplinkProps) => { }); return ( -
{currency}} - buttons={ - <> - Search - setSearchText(value)} - mx={1} - /> - - - } - > - - {searchText.length === 0 && ( - - + + + + + + + + + +
+ + + ); }; export type Item = { id: string | number; name: string; + icon: string; + icon_state: string; category: string; cost: JSX.Element | string; desc: JSX.Element | string; @@ -109,22 +144,86 @@ export type ItemListProps = { const ItemList = (props: ItemListProps) => { const { compactMode, items, handleBuy } = props; + const fallback = ( + + ); return ( - + {items.map((item, index) => ( - -
handleBuy(item)} - /> - } - > - {compactMode ? null : item.desc} + +
+ + + + + + + + {compactMode ? ( + + + {item.name} + + + + + + + + + + + ) : ( +
handleBuy(item)} + > + {item.cost} + + } + > + + {item.desc} + +
+ )} +
+
))} diff --git a/tgui/packages/tgui/interfaces/Uplink/PrimaryObjectiveMenu.tsx b/tgui/packages/tgui/interfaces/Uplink/PrimaryObjectiveMenu.tsx index ee6e81160d3..f0364e88d9f 100644 --- a/tgui/packages/tgui/interfaces/Uplink/PrimaryObjectiveMenu.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/PrimaryObjectiveMenu.tsx @@ -12,19 +12,17 @@ export const PrimaryObjectiveMenu = (props: PrimaryObjectiveMenuProps) => { const { act } = useBackend(); const { primary_objectives, final_objective, can_renegotiate } = props; return ( -
-
- - { - 'Agent, your Primary Objectives are as follows. Complete these at all costs.' - } - - - { - 'Completing Secondary Objectives may allow you to aquire additional equipment.' - } - -
+
+ + WELCOME, AGENT. + + + Your Primary Objectives are as follows. Complete these at all costs. + + + Completing Secondary Objectives may allow you to aquire additional + equipment. + {final_objective && ( { )} -
- - {primary_objectives.map((prim_obj, index) => ( - - - - ))} - -
+ + {primary_objectives.map((prim_obj, index) => ( + + + + ))} + {!!can_renegotiate && (
); }; diff --git a/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx b/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx index e8951e367a9..d67dd37391e 100644 --- a/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx @@ -90,7 +90,7 @@ export const dangerLevelsTooltip = ( color="white" className={value.gradient} style={{ - borderRadius: '5px', + borderRadius: '2px', display: 'inline-block', }} px={0.8} @@ -137,11 +137,12 @@ export const calculateDangerLevel = ( color="white" className={dangerLevel.gradient} style={{ - borderRadius: '5px', + borderRadius: '2px', display: 'inline-block', }} px={0.8} py={0.6} + textAlign="center" > {dangerLevel.title} ({displayedProgression}) diff --git a/tgui/packages/tgui/interfaces/Uplink/index.tsx b/tgui/packages/tgui/interfaces/Uplink/index.tsx index 4949fc94ee7..3ed7d34a214 100644 --- a/tgui/packages/tgui/interfaces/Uplink/index.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/index.tsx @@ -7,6 +7,7 @@ import { Box, Button, Dimmer, + NoticeBox, Section, Stack, Tabs, @@ -27,6 +28,8 @@ import { PrimaryObjectiveMenu } from './PrimaryObjectiveMenu'; type UplinkItem = { id: string; name: string; + icon: string; + icon_state: string; cost: number; desc: string; category: string; @@ -90,6 +93,8 @@ type ServerData = { type ItemExtraData = Item & { extraData: { ref?: string; + icon: string; + icon_state: string; }; }; @@ -198,7 +203,6 @@ export class Uplink extends Component<{}, UplinkState> { shop_locked, } = data; const { allItems, allCategories, currentTab } = this.state as UplinkState; - const itemsToAdd = [...allItems]; const items: ItemExtraData[] = []; itemsToAdd.push(...extra_purchasable); @@ -224,19 +228,21 @@ export class Uplink extends Component<{}, UplinkState> { items.push({ id: item.id, name: item.name, + icon: item.icon, + icon_state: item.icon_state, category: item.category, desc: ( - - {item.desc} + <> + {item.desc} {(item.lock_other_purchases && ( - + Taking this item will lock you from further purchasing from the marketplace. Additionally, if you have already purchased an item, you will not be able to purchase this. - + )) || null} - + ), cost: ( @@ -259,6 +265,8 @@ export class Uplink extends Component<{}, UplinkState> { (item.lock_other_purchases && purchased_items > 0), extraData: { ref: item.ref, + icon: item.icon, + icon_state: item.icon_state, }, }); } @@ -274,25 +282,14 @@ export class Uplink extends Component<{}, UplinkState> { // Round it and convert it into a percentage progressionPercentage = Math.round(progressionPercentage * 1000) / 10; return ( - - - - -
- - - - SyndOS Version 3.17   - - Connection Secure - - - - WELCOME, AGENT. - - - - + + + + {!!has_progression && ( + +
+ + { } > {/* If we have no progression, - just give them a generic title */} + just give them a generic title */} {has_progression ? calculateDangerLevel(progression_points, false) : calculateDangerLevel(dangerDefault, false)} - - - {telecrystals} TC - - - -
-
- -
- - - - {!!has_objectives && ( - <> - this.setState({ currentTab: 0 })} - > - Primary Objectives - - this.setState({ currentTab: 1 })} - > - Secondary Objectives - - - )} - this.setState({ currentTab: 2 })} - > - Market - - - - {!!lockable && ( - -
-
+ + + + {!!has_objectives && ( + <> + this.setState({ currentTab: 0 })} + > + Primary Objectives + + this.setState({ currentTab: 1 })} + > + Secondary Objectives + + + )} + this.setState({ currentTab: 2 })} + > + Market + + + + + {!!lockable && ( + + + + )} +
+
+
+ )} {(currentTab === 0 && has_objectives && ( { handleRequestObjectives={() => act('regenerate_objectives')} /> )) || ( -
+ <> { @@ -471,7 +483,7 @@ export class Uplink extends Component<{}, UplinkState> { )) || null} -
+ )}