diff --git a/.github/gbp.toml b/.github/gbp.toml index 70032056dfe..fe086e79b55 100644 --- a/.github/gbp.toml +++ b/.github/gbp.toml @@ -9,6 +9,7 @@ reset_label = "GBP: Reset" "Code Improvement" = 2 "Documentation" = 1 "Feature" = -6 +"Good First PR" = 6 "Feedback" = 2 "Fix" = 3 "Grammar and Formatting" = 1 diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml index 420cf0c9688..f317e6b1a1a 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -79,8 +79,12 @@ jobs: - name: Check Define Sanity if: steps.linter-setup.conclusion == 'success' && !cancelled() run: tools/bootstrap/python -m define_sanity.check + - name: Check Trait Validity + if: steps.linter-setup.conclusion == 'success' && !cancelled() + run: tools/bootstrap/python -m trait_validity.check - name: Run DreamChecker if: steps.linter-setup.conclusion == 'success' && !cancelled() + shell: bash run: ~/dreamchecker 2>&1 | bash tools/ci/annotate_dm.sh - name: Run Map Checks if: steps.linter-setup.conclusion == 'success' && !cancelled() diff --git a/_maps/skyrat/automapper/automapper_config.toml b/_maps/skyrat/automapper/automapper_config.toml index 1683d43dae8..00c9ae33593 100644 --- a/_maps/skyrat/automapper/automapper_config.toml +++ b/_maps/skyrat/automapper/automapper_config.toml @@ -197,39 +197,6 @@ required_map = "IceBoxStation.dmm" coordinates = [202, 16, 2] trait_name = "Station" -# KILOSTATION MAP EDITS -# Kilostation Arrivals -[templates.kilostation_arrivals] -map_files = ["kilostation_arrivals.dmm"] -directory = "_maps/skyrat/automapper/templates/kilostation/" -required_map = "KiloStation.dmm" -coordinates = [151, 80, 1] -trait_name = "Station" - -# Kilostation ERT Bay and Barber -[templates.kilostation_ert_bay] -map_files = ["kilostation_ert_bay.dmm"] -directory = "_maps/skyrat/automapper/templates/kilostation/" -required_map = "KiloStation.dmm" -coordinates = [77, 151, 1] -trait_name = "Station" - -# Kilostation Cryo -[templates.kilostation_cryo] -map_files = ["kilostation_cryo.dmm"] -directory = "_maps/skyrat/automapper/templates/kilostation/" -required_map = "KiloStation.dmm" -coordinates = [59, 118, 1] -trait_name = "Station" - -# Kilostation Armory -[templates.kilostation_armory] -map_files = ["kilostation_armory.dmm"] -directory = "_maps/skyrat/automapper/templates/kilostation/" -required_map = "KiloStation.dmm" -coordinates = [81, 80, 1] -trait_name = "Station" - # TRAMSTATION MAP EDITS # Tramstation Arrivals [templates.tramstation_arrivals] diff --git a/_maps/skyrat/automapper/templates/kilostation/kilostation_armory.dmm b/_maps/skyrat/automapper/templates/kilostation/kilostation_armory.dmm deleted file mode 100644 index 229c3d31bd0..00000000000 --- a/_maps/skyrat/automapper/templates/kilostation/kilostation_armory.dmm +++ /dev/null @@ -1,144 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"e" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/bot, -/obj/structure/window/reinforced/spawner/directional/south, -/obj/structure/window/reinforced/spawner/directional/east, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/secure_closet/armory_kiboko, -/turf/open/floor/iron/showroomfloor, -/area/station/ai_monitored/security/armory) -"q" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/bot, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/microfusion, -/turf/open/floor/iron/showroomfloor, -/area/station/ai_monitored/security/armory) -"u" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/bot, -/obj/structure/rack, -/obj/item/clothing/head/helmet/sec{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/clothing/head/helmet/sec, -/obj/item/clothing/head/helmet/sec{ - pixel_x = 3; - pixel_y = -3 - }, -/obj/item/clothing/suit/armor/vest/alt/sec{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/clothing/suit/armor/vest/alt/sec, -/obj/item/clothing/suit/armor/vest/alt/sec{ - pixel_x = 3; - pixel_y = -3 - }, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/security/armory) -"w" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/bot, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/window/reinforced/spawner/directional/east, -/obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/smg, -/turf/open/floor/iron/showroomfloor, -/area/station/ai_monitored/security/armory) -"G" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/bot, -/obj/structure/window/reinforced/spawner/directional/south, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/shotguns, -/turf/open/floor/iron/showroomfloor, -/area/station/ai_monitored/security/armory) -"N" = ( -/obj/item/clothing/mask/gas/sechailer{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/clothing/mask/gas/sechailer, -/obj/item/clothing/mask/gas/sechailer{ - pixel_x = 3; - pixel_y = -3 - }, -/obj/item/flashlight/seclite, -/obj/item/flashlight/seclite, -/obj/item/flashlight/seclite, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/decal/cleanable/cobweb, -/obj/machinery/airalarm/directional/west, -/obj/structure/table, -/obj/item/storage/barricade{ - pixel_y = -5 - }, -/obj/item/storage/barricade, -/obj/item/storage/barricade{ - pixel_y = 5 - }, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/security/armory) -"S" = ( -/turf/template_noop, -/area/template_noop) - -(1,1,1) = {" -N -S -S -S -"} -(2,1,1) = {" -u -S -S -S -"} -(3,1,1) = {" -S -S -w -e -"} -(4,1,1) = {" -S -S -q -G -"} diff --git a/_maps/skyrat/automapper/templates/kilostation/kilostation_arrivals.dmm b/_maps/skyrat/automapper/templates/kilostation/kilostation_arrivals.dmm deleted file mode 100644 index dc4d9060ab2..00000000000 --- a/_maps/skyrat/automapper/templates/kilostation/kilostation_arrivals.dmm +++ /dev/null @@ -1,357 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/open/floor/plating/airless, -/area/space) -"e" = ( -/obj/effect/turf_decal/bot, -/obj/machinery/computer/shuttle/arrivals/recall{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/entry) -"f" = ( -/turf/closed/wall/rust, -/area/station/hallway/secondary/entry) -"h" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/effect/turf_decal/box, -/turf/open/floor/iron, -/area/station/hallway/secondary/entry) -"i" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/stripes/line, -/obj/item/radio/intercom/directional/east, -/turf/open/floor/iron, -/area/station/hallway/secondary/entry) -"j" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/light/small/directional/west, -/obj/machinery/status_display/shuttle/directional/west{ - shuttle_id = "arrivals_shuttle" - }, -/turf/open/floor/iron, -/area/station/hallway/secondary/entry) -"k" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/sign/warning/vacuum/external, -/turf/open/floor/plating, -/area/station/hallway/secondary/entry) -"n" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/item/pen, -/obj/effect/turf_decal/loading_area{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/entry) -"p" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron, -/area/station/hallway/secondary/entry) -"q" = ( -/turf/closed/wall, -/area/station/hallway/secondary/entry) -"r" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/bluespace_vendor/directional/west, -/turf/open/floor/iron, -/area/station/hallway/secondary/entry) -"s" = ( -/obj/effect/turf_decal/stripes/line, -/obj/structure/flora/bush/pale/style_random, -/obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"t" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/light/small/directional/east, -/obj/machinery/status_display/shuttle/directional/east{ - shuttle_id = "arrivals_shuttle" - }, -/turf/open/floor/iron, -/area/station/hallway/secondary/entry) -"v" = ( -/obj/effect/turf_decal/stripes/line, -/obj/structure/flora/grass/jungle/a/style_random, -/obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"x" = ( -/obj/effect/turf_decal/bot, -/obj/structure/closet/emcloset, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/machinery/light/small/directional/south, -/obj/structure/sign/poster/contraband/random/directional/south, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/entry) -"z" = ( -/obj/effect/spawner/random/vending/colavend, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/entry) -"A" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/hallway/secondary/entry) -"D" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"E" = ( -/obj/machinery/door/airlock/external{ - name = "Arrival Shuttle Airlock" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/entry) -"F" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/station/hallway/secondary/entry) -"G" = ( -/obj/machinery/door/airlock/external{ - name = "Arrival Shuttle Airlock"; - space_dir = 2 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/entry) -"I" = ( -/obj/structure/sign/warning/docking, -/turf/closed/wall, -/area/station/hallway/secondary/entry) -"J" = ( -/obj/effect/turf_decal/tile/red, -/turf/open/floor/iron, -/area/station/hallway/secondary/entry) -"M" = ( -/turf/closed/mineral/random/labormineral, -/area/space/nearstation) -"O" = ( -/obj/docking_port/stationary{ - dir = 4; - dwidth = 1; - height = 13; - shuttle_id = "arrivals_stationary"; - name = "arrivals"; - width = 5 - }, -/turf/open/floor/plating/airless, -/area/space) -"S" = ( -/obj/effect/turf_decal/stripes/line, -/obj/structure/flora/grass/jungle/b/style_random, -/obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"T" = ( -/obj/structure/sign/warning/secure_area{ - name = "EMERGENCY STORAGE" - }, -/turf/closed/wall, -/area/station/hallway/secondary/entry) -"V" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/vending/clothing, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/entry) -"W" = ( -/obj/machinery/door/airlock/external{ - name = "Arrival Shuttle Airlock" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/effect/landmark/navigate_destination, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/entry) -"X" = ( -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/structure/closet/firecloset, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/entry) -"Y" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/landmark/start/assistant, -/turf/open/floor/iron, -/area/station/hallway/secondary/entry) - -(1,1,1) = {" -x -f -M -S -a -a -a -a -"} -(2,1,1) = {" -X -q -M -v -a -O -a -a -"} -(3,1,1) = {" -T -f -q -I -a -a -a -a -"} -(4,1,1) = {" -r -E -j -G -a -a -a -a -"} -(5,1,1) = {" -A -F -F -F -a -a -a -a -"} -(6,1,1) = {" -h -n -F -s -a -a -a -a -"} -(7,1,1) = {" -Y -V -k -v -a -a -a -a -"} -(8,1,1) = {" -J -z -F -D -a -a -a -a -"} -(9,1,1) = {" -J -e -F -v -a -a -a -a -"} -(10,1,1) = {" -p -F -F -F -a -a -a -a -"} -(11,1,1) = {" -i -W -t -G -a -a -a -a -"} -(12,1,1) = {" -f -q -f -I -a -a -a -a -"} diff --git a/_maps/skyrat/automapper/templates/kilostation/kilostation_cryo.dmm b/_maps/skyrat/automapper/templates/kilostation/kilostation_cryo.dmm deleted file mode 100644 index d3035bcc07a..00000000000 --- a/_maps/skyrat/automapper/templates/kilostation/kilostation_cryo.dmm +++ /dev/null @@ -1,204 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/closed/wall, -/area/station/common/cryopods) -"c" = ( -/obj/structure/table, -/obj/item/clipboard, -/obj/item/screwdriver{ - pixel_y = 16 - }, -/turf/open/floor/iron/dark, -/area/station/maintenance/port/greater) -"d" = ( -/obj/effect/turf_decal/bot, -/obj/structure/frame/computer{ - anchored = 1; - dir = 1 - }, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/maintenance/port/greater) -"e" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "greylair"; - name = "Lair Privacy Shutter" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) -"g" = ( -/turf/open/floor/iron, -/area/station/common/cryopods) -"j" = ( -/obj/machinery/computer/cryopod/directional/east, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/common/cryopods) -"l" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/station/common/cryopods) -"o" = ( -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/common/cryopods) -"r" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "greylair"; - name = "Lair Privacy Shutter" - }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) -"u" = ( -/obj/effect/turf_decal/bot, -/obj/structure/frame/computer{ - anchored = 1; - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark, -/area/station/maintenance/port/greater) -"x" = ( -/obj/machinery/cryopod, -/obj/effect/turf_decal/siding/white, -/obj/machinery/airalarm/directional/east, -/turf/open/floor/iron/dark, -/area/station/common/cryopods) -"z" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Cryopods" - }, -/obj/effect/landmark/navigate_destination, -/turf/open/floor/iron, -/area/station/common/cryopods) -"A" = ( -/obj/machinery/cryopod, -/obj/effect/turf_decal/siding/white, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark, -/area/station/common/cryopods) -"D" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/common/cryopods) -"J" = ( -/obj/effect/turf_decal/siding/white{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/obj/machinery/camera/directional/east, -/obj/machinery/time_clock/directional/east, -/obj/item/kirbyplants/random, -/turf/open/floor/iron/dark, -/area/station/common/cryopods) -"O" = ( -/obj/machinery/cryopod, -/obj/effect/turf_decal/siding/white, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark, -/area/station/common/cryopods) -"Q" = ( -/obj/structure/table, -/obj/item/storage/briefcase/secure, -/obj/item/taperecorder, -/obj/structure/sign/warning/electric_shock/directional/south, -/turf/open/floor/iron/dark, -/area/station/maintenance/port/greater) -"R" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "greylair"; - name = "Lair Privacy Shutter" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/port/greater) -"S" = ( -/obj/machinery/cryopod{ - dir = 1 - }, -/obj/effect/turf_decal/siding/white{ - dir = 9 - }, -/turf/open/floor/iron/dark, -/area/station/common/cryopods) -"U" = ( -/turf/closed/wall, -/area/station/maintenance/port/greater) -"W" = ( -/obj/machinery/cryopod, -/obj/effect/turf_decal/siding/white, -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/machinery/light/directional/west, -/turf/open/floor/iron/dark, -/area/station/common/cryopods) -"X" = ( -/obj/effect/turf_decal/bot, -/obj/structure/frame/computer{ - anchored = 1; - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark, -/area/station/maintenance/port/greater) - -(1,1,1) = {" -Q -a -a -a -a -a -"} -(2,1,1) = {" -d -r -W -o -g -l -"} -(3,1,1) = {" -X -e -O -g -g -z -"} -(4,1,1) = {" -u -R -A -D -S -l -"} -(5,1,1) = {" -c -r -x -j -J -l -"} -(6,1,1) = {" -U -a -a -a -a -a -"} diff --git a/_maps/skyrat/automapper/templates/kilostation/kilostation_ert_bay.dmm b/_maps/skyrat/automapper/templates/kilostation/kilostation_ert_bay.dmm deleted file mode 100644 index 34e0fbcad74..00000000000 --- a/_maps/skyrat/automapper/templates/kilostation/kilostation_ert_bay.dmm +++ /dev/null @@ -1,3119 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"ad" = ( -/obj/structure/transit_tube/diagonal/topleft, -/obj/structure/lattice/catwalk, -/turf/open/space/basic, -/area/space/nearstation) -"an" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/sign/poster/official/random/directional/east, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"aK" = ( -/obj/machinery/newscaster/directional/east, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"bb" = ( -/obj/machinery/door/airlock/maintenance/external{ - name = "Transit Intersection" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/effect/mapping_helpers/airlock/unres{ - dir = 8 - }, -/obj/effect/mapping_helpers/airlock/access/any/medical/maintenance, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"bj" = ( -/obj/machinery/bluespace_vendor/directional/east, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/airlock/public/glass{ - name = "Salon Hallway" - }, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/caution/stand_clear, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"bB" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/sign/poster/contraband/random/directional/south, -/obj/structure/cable, -/obj/effect/mapping_helpers/burnt_floor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"bH" = ( -/obj/structure/transit_tube/diagonal/crossing/topleft, -/obj/structure/lattice/catwalk, -/turf/open/space/basic, -/area/space/nearstation) -"bV" = ( -/obj/structure/chair/sofa/bench/right{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"ca" = ( -/obj/machinery/airalarm/directional/north, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"cc" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"cf" = ( -/obj/machinery/firealarm/directional/west, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"cm" = ( -/obj/structure/filingcabinet/employment, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"cW" = ( -/obj/structure/fans/tiny/forcefield{ - dir = 1 - }, -/obj/structure/sign/warning/vacuum/external/directional/east, -/obj/machinery/door/poddoor/preopen{ - name = "Dock Shutter" - }, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"cX" = ( -/obj/structure/closet/secure_closet/nanotrasen_consultant/station, -/obj/item/assembly/flash/handheld, -/obj/machinery/status_display/ai/directional/north, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"df" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron/dark/corner{ - dir = 1 - }, -/area/station/hallway/primary/fore) -"ds" = ( -/obj/structure/chair/sofa/bench/right{ - dir = 8 - }, -/obj/effect/landmark/start/assistant, -/obj/effect/turf_decal/tile/green, -/turf/open/floor/iron/dark/corner, -/area/station/hallway/primary/fore) -"dC" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners{ - dir = 8 - }, -/turf/open/floor/iron/cafeteria, -/area/station/service/barber) -"dG" = ( -/obj/machinery/camera/directional/north, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"dV" = ( -/obj/effect/spawner/structure/window/hollow/reinforced/middle, -/obj/structure/transit_tube, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"dY" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"dZ" = ( -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"ew" = ( -/obj/structure/sign/departments/custodian, -/turf/closed/wall, -/area/station/maintenance/fore) -"ey" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners{ - dir = 8 - }, -/obj/machinery/vending/barbervend, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron/cafeteria, -/area/station/service/barber) -"eL" = ( -/obj/structure/closet{ - name = "maid locker" - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/bot, -/obj/effect/decal/cleanable/dirt, -/obj/item/clothing/gloves/color/white, -/obj/item/clothing/accessory/maidapron{ - pixel_x = -4; - pixel_y = -4 - }, -/obj/item/clothing/shoes/laceup, -/obj/structure/mirror/directional/north, -/turf/open/floor/iron/dark, -/area/station/maintenance/fore) -"eQ" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/box/mousetraps{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/item/flashlight, -/obj/structure/noticeboard/directional/north, -/turf/open/floor/iron/dark, -/area/station/maintenance/fore) -"eZ" = ( -/obj/machinery/door/airlock/maintenance, -/obj/effect/mapping_helpers/airlock/abandoned, -/obj/structure/barricade/wooden/crude, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/unres{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/access/all/service/janitor, -/turf/open/floor/iron/dark, -/area/station/maintenance/fore) -"fb" = ( -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"fc" = ( -/obj/effect/turf_decal/siding/white{ - dir = 5 - }, -/obj/machinery/vending/coffee, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"fr" = ( -/obj/machinery/light/directional/west, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"fx" = ( -/obj/structure/cable, -/obj/machinery/light/directional/south, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"fA" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/window/reinforced/spawner/directional/north, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"fF" = ( -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/effect/spawner/random/vending/snackvend, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"fR" = ( -/obj/structure/sign/warning/secure_area, -/turf/closed/wall, -/area/space/nearstation) -"fT" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/effect/mapping_helpers/burnt_floor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"gk" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/closet/firecloset, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron/dark/corner{ - dir = 1 - }, -/area/station/hallway/primary/fore) -"gv" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron/dark/corner{ - dir = 8 - }, -/area/station/hallway/primary/fore) -"gw" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/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/iron, -/area/station/hallway/primary/fore) -"gx" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"gy" = ( -/obj/structure/chair/sofa/bench{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"gH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"gW" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"gX" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/obj/machinery/holopad, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"ha" = ( -/obj/structure/sign/departments/holy{ - pixel_y = 30 - }, -/turf/open/floor/iron/stairs/right{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"hd" = ( -/obj/machinery/firealarm/directional/south, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"hg" = ( -/obj/structure/window/reinforced/spawner/directional/south, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"hj" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"hs" = ( -/obj/machinery/light/directional/south, -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/structure/sign/poster/official/random/directional/south, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"hS" = ( -/obj/structure/transit_tube/diagonal/crossing/topleft, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"iv" = ( -/obj/structure/cable, -/turf/open/floor/iron/stairs/old{ - dir = 8 - }, -/area/station/maintenance/fore/lesser) -"iy" = ( -/obj/machinery/door/airlock/maintenance, -/obj/effect/mapping_helpers/airlock/unres{ - dir = 8 - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"iD" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"iM" = ( -/obj/structure/fans/tiny/forcefield{ - dir = 1 - }, -/obj/machinery/door/poddoor/preopen{ - name = "Dock Shutter" - }, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"iV" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"jA" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/box/lights/mixed{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/item/storage/belt/janitor, -/obj/item/storage/bag/trash, -/obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6/directional/north, -/obj/effect/decal/cleanable/cobweb, -/turf/open/floor/iron/dark, -/area/station/maintenance/fore) -"jC" = ( -/obj/structure/chair/sofa/bench{ - dir = 8 - }, -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"jJ" = ( -/obj/structure/transit_tube/crossing, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"jK" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"jS" = ( -/obj/machinery/light/directional/north, -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"jV" = ( -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"jY" = ( -/obj/effect/landmark/carpspawn, -/turf/open/space/basic, -/area/space) -"kh" = ( -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"ku" = ( -/obj/machinery/camera/directional/north, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"kz" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/preopen{ - name = "Privacy Shutter"; - id = "nt_rep_priv_2" - }, -/turf/open/floor/plating, -/area/station/command/heads_quarters/nt_rep) -"kE" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"kI" = ( -/obj/effect/turf_decal/siding/white{ - dir = 6 - }, -/obj/effect/spawner/random/vending/colavend, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"kP" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/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/iron, -/area/station/hallway/primary/fore) -"lr" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/machinery/newscaster/directional/north, -/obj/machinery/camera/directional/north{ - c_tag = "Fore Hallway Monastary Tube"; - name = "fore camera" - }, -/obj/structure/chair/sofa/bench, -/obj/effect/landmark/start/assistant, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"lw" = ( -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/transit_tube/crossing, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"lU" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners{ - dir = 8 - }, -/obj/structure/closet/secure_closet/barber, -/obj/effect/decal/cleanable/dirt, -/obj/item/pushbroom, -/obj/item/reagent_containers/spray/cleaner, -/obj/machinery/firealarm/directional/west, -/obj/effect/decal/cleanable/cobweb, -/obj/machinery/light_switch/directional/north, -/turf/open/floor/iron/cafeteria, -/area/station/service/barber) -"mi" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/grille, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"mU" = ( -/obj/structure/chair/sofa/bench{ - dir = 8 - }, -/obj/effect/landmark/start/assistant, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"mZ" = ( -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"nc" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/disposalpipe/segment, -/obj/structure/window/reinforced/spawner/directional/south, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"ne" = ( -/turf/closed/wall, -/area/space/nearstation) -"nv" = ( -/obj/machinery/airalarm/directional/east, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"nA" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/bot, -/obj/structure/sink/directional/east, -/obj/item/reagent_containers/cup/bucket, -/obj/item/mop, -/obj/effect/turf_decal/stripes/corner, -/obj/machinery/button/door/directional/south{ - id = "maidbay"; - name = "Maid Bay Toggle" - }, -/obj/structure/sign/poster/contraband/random/directional/west, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"nE" = ( -/obj/structure/chair/sofa/bench{ - dir = 8 - }, -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/effect/landmark/start/assistant, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"nF" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/iron/dark/corner{ - dir = 8 - }, -/area/station/hallway/primary/fore) -"nN" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"nS" = ( -/obj/structure/chair/sofa/bench/corner{ - dir = 8 - }, -/obj/effect/turf_decal/tile/green, -/obj/machinery/camera/directional/south, -/turf/open/floor/iron/dark/corner, -/area/station/hallway/primary/fore) -"nW" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"oi" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/structure/extinguisher_cabinet/directional/east, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"oR" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/preopen{ - name = "Privacy Shutter"; - id = "nt_rep_priv" - }, -/turf/open/floor/plating, -/area/station/command/heads_quarters/nt_rep) -"oZ" = ( -/obj/effect/decal/cleanable/dirt, -/turf/closed/wall/r_wall/rust, -/area/station/command/heads_quarters/nt_rep) -"pf" = ( -/turf/closed/wall, -/area/station/maintenance/fore) -"qg" = ( -/obj/structure/closet/crate, -/obj/item/hand_labeler, -/obj/item/storage/crayons, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"qj" = ( -/obj/structure/chair/sofa/bench/right{ - dir = 8 - }, -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"qr" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"qM" = ( -/obj/machinery/button/door/directional/north{ - name = "Privacy Shutters Control"; - id = "nt_rep_priv" - }, -/obj/structure/table/wood, -/obj/item/folder/yellow{ - pixel_x = 8; - pixel_y = -1 - }, -/obj/item/folder/red{ - pixel_x = -4; - pixel_y = -2 - }, -/obj/item/folder/white{ - pixel_x = 4; - pixel_y = 3 - }, -/obj/item/folder/blue{ - pixel_y = 6; - pixel_x = -2 - }, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"qS" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/structure/noticeboard/directional/north{ - dir = 2; - name = "Chapel Notice Board" - }, -/obj/machinery/light/directional/north, -/obj/structure/chair/sofa/bench/right, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"qU" = ( -/obj/effect/turf_decal/tile/green, -/turf/open/floor/iron/dark/corner, -/area/station/hallway/primary/fore) -"rk" = ( -/obj/effect/turf_decal/siding/white{ - dir = 1 - }, -/obj/machinery/newscaster/directional/west, -/obj/effect/landmark/start/barber, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"rt" = ( -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/east, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"rz" = ( -/obj/structure/closet/crate/bin, -/obj/machinery/camera/directional/north, -/obj/structure/noticeboard/directional/north, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"rE" = ( -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/item/kirbyplants/random, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"rL" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 8 - }, -/obj/machinery/light_switch/directional/south, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"rT" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"su" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"sz" = ( -/obj/effect/turf_decal/stripes/line{ - 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/iron, -/area/station/hallway/primary/fore) -"tg" = ( -/turf/closed/wall/rust, -/area/station/maintenance/fore) -"tx" = ( -/obj/structure/transit_tube/crossing, -/obj/effect/turf_decal/sand/plating, -/obj/structure/window/reinforced/spawner/directional/south, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"tz" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/sign/warning/secure_area/directional/east, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"tU" = ( -/obj/item/radio/intercom/directional/south, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"ud" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"uf" = ( -/obj/effect/landmark/start/nanotrasen_consultant, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"uj" = ( -/obj/structure/lattice, -/obj/structure/grille/broken, -/turf/open/space/basic, -/area/space/nearstation) -"uI" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/blobstart, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"uM" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/machinery/button/curtain{ - id = "barbershopcurtains1"; - pixel_x = -25; - pixel_y = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"uX" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/machinery/firealarm/directional/north, -/obj/structure/chair/sofa/bench, -/obj/effect/landmark/start/assistant, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"vp" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"vs" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"vE" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"vJ" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners{ - dir = 8 - }, -/obj/machinery/airalarm/directional/west, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/cafeteria, -/area/station/service/barber) -"vS" = ( -/obj/effect/turf_decal/siding/wood/corner{ - dir = 8 - }, -/obj/structure/table/wood, -/obj/item/camera_film{ - pixel_x = -5; - pixel_y = 9 - }, -/obj/item/camera_film, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"vV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"wh" = ( -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"wF" = ( -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"wK" = ( -/obj/machinery/door/airlock/public{ - name = "Massage Parlour" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door/firedoor, -/turf/open/floor/iron, -/area/station/service/barber) -"wL" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Ferry Dock" - }, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/caution/stand_clear, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"wQ" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Barbershop" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door/firedoor, -/turf/open/floor/iron, -/area/station/service/barber) -"wT" = ( -/obj/structure/cable, -/obj/effect/turf_decal/siding/wood/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"xV" = ( -/turf/closed/wall/r_wall/rust, -/area/station/command/heads_quarters/nt_rep) -"yd" = ( -/obj/structure/chair/sofa/bench/left{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/turf/open/floor/iron/dark/corner, -/area/station/hallway/primary/fore) -"yC" = ( -/turf/closed/wall/rust, -/area/station/service/barber) -"yM" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"zb" = ( -/turf/closed/wall/r_wall, -/area/station/command/heads_quarters/nt_rep) -"ze" = ( -/obj/machinery/light/directional/south, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"zf" = ( -/obj/structure/lattice, -/obj/structure/sign/warning/secure_area/directional/south, -/turf/open/space/basic, -/area/space/nearstation) -"zu" = ( -/obj/machinery/light/directional/east, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"zF" = ( -/obj/structure/table/wood, -/obj/item/paper_bin{ - pixel_y = 4 - }, -/obj/item/pen/fountain, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"zR" = ( -/obj/effect/spawner/structure/window, -/obj/structure/curtain/cloth/fancy/mechanical{ - id = "barbershopcurtains1"; - name = "Massage Parlour Drapes" - }, -/turf/open/floor/plating, -/area/station/service/barber) -"zZ" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/grimy, -/area/station/hallway/primary/fore) -"Ag" = ( -/turf/closed/wall/rust, -/area/station/maintenance/fore/lesser) -"AB" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"Be" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/structure/bed/pod, -/obj/machinery/firealarm/directional/north, -/obj/machinery/camera/directional/west, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"Bs" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/obj/machinery/camera/directional/east{ - c_tag = "NT Consultant's Office"; - name = "command camera" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"Bx" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"BU" = ( -/obj/effect/turf_decal/siding/white{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/obj/effect/landmark/start/barber, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"BZ" = ( -/obj/structure/transit_tube/diagonal/crossing/topleft, -/turf/open/space/basic, -/area/space/nearstation) -"Ce" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"Cf" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/firealarm/directional/south, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"Cm" = ( -/obj/structure/flora/rock/style_random, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"Da" = ( -/obj/structure/chair/sofa/bench/left{ - dir = 8 - }, -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"Dh" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"Dl" = ( -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"Dp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/radio/intercom/directional/east, -/obj/machinery/camera/directional/east, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"DC" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Salon Hallway" - }, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/caution/stand_clear, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"DJ" = ( -/turf/closed/wall/rust, -/area/station/command/heads_quarters/nt_rep) -"Ef" = ( -/obj/machinery/light/directional/north, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"Eg" = ( -/turf/closed/wall, -/area/station/hallway/primary/fore) -"Eh" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron/dark/corner{ - dir = 8 - }, -/area/station/hallway/primary/fore) -"Ek" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"En" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Ferry Dock" - }, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/caution/stand_clear, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"Ev" = ( -/obj/structure/chair/office, -/obj/effect/landmark/start/nanotrasen_consultant, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"EG" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/obj/structure/chair/office{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"EI" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners{ - dir = 8 - }, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/directional/west, -/turf/open/floor/iron/cafeteria, -/area/station/service/barber) -"EO" = ( -/obj/structure/transit_tube/curved/flipped, -/turf/open/space/basic, -/area/space/nearstation) -"EP" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"EX" = ( -/obj/structure/table/wood, -/obj/item/stamp{ - pixel_y = 8; - pixel_x = -6 - }, -/obj/item/stamp/denied{ - pixel_x = -6; - pixel_y = 2 - }, -/obj/item/stamp/centcom{ - pixel_x = 6; - pixel_y = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"Fg" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/iron/dark/corner{ - dir = 8 - }, -/area/station/hallway/primary/fore) -"Fi" = ( -/turf/closed/wall, -/area/station/service/barber) -"Fl" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"Fz" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"FM" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"FQ" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"FU" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/cafeteria, -/area/station/service/barber) -"Gh" = ( -/turf/open/space/basic, -/area/space) -"Gw" = ( -/obj/structure/chair/sofa/bench/left, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"GN" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/maintenance, -/obj/effect/mapping_helpers/airlock/unres{ - dir = 4 - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, -/obj/effect/mapping_helpers/burnt_floor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"GU" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/sign/poster/random/directional/north, -/obj/structure/cable, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"GX" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/iron/dark/corner{ - dir = 8 - }, -/area/station/hallway/primary/fore) -"Ho" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/item/radio/intercom/directional/west, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"HJ" = ( -/obj/machinery/light/directional/south, -/obj/effect/turf_decal/stripes/corner, -/obj/structure/noticeboard/directional/south, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"HV" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/structure/table/reinforced/rglass, -/obj/item/hairbrush{ - pixel_x = 6; - pixel_y = 9 - }, -/obj/item/clothing/gloves/latex, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"HW" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"Ia" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"Ib" = ( -/turf/closed/wall, -/area/station/maintenance/fore/lesser) -"Iv" = ( -/obj/machinery/light/directional/north, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"IX" = ( -/obj/structure/table/wood, -/obj/item/taperecorder{ - pixel_y = 5; - pixel_x = 5 - }, -/obj/item/camera{ - pixel_x = -4 - }, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"Ja" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/landmark/event_spawn, -/obj/structure/cable, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"Jl" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"Jm" = ( -/obj/structure/cable, -/obj/machinery/status_display/ai/directional/south, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"Jn" = ( -/obj/structure/chair/sofa/bench{ - dir = 8 - }, -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/effect/landmark/start/assistant, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"Jq" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"JP" = ( -/obj/machinery/camera/directional/south, -/obj/effect/decal/cleanable/dirt, -/obj/item/radio/intercom/directional/south, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"KA" = ( -/obj/machinery/photocopier, -/obj/machinery/button/door/directional/north{ - id = "nt_rep_priv_2"; - name = "Privacy Shutters Control" - }, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"KE" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"KL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/turf_decal/bot, -/obj/structure/reagent_dispensers/fueltank, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"Lw" = ( -/obj/structure/transit_tube/diagonal/topleft, -/turf/open/space/basic, -/area/space/nearstation) -"LI" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"Me" = ( -/obj/structure/lattice, -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) -"Mt" = ( -/turf/closed/wall/rust, -/area/station/hallway/primary/fore) -"Mu" = ( -/obj/structure/flora/rock/pile/style_2, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"Mw" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners{ - dir = 8 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/cafeteria, -/area/station/service/barber) -"MG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"MO" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/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/hallway/primary/fore) -"MP" = ( -/turf/closed/wall/rust, -/area/space/nearstation) -"Ng" = ( -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/obj/effect/turf_decal/siding/wood{ - dir = 4 - }, -/obj/structure/filingcabinet/chestdrawer, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"Nu" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/effect/landmark/generic_maintenance_landmark, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"NU" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"Op" = ( -/obj/machinery/light/directional/east, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"Oq" = ( -/obj/docking_port/stationary{ - dheight = 3; - dir = 8; - dwidth = 8; - height = 11; - shuttle_id = "ferry_home"; - name = "Port Bay 2"; - width = 20 - }, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"Oy" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron/dark/corner{ - dir = 8 - }, -/area/station/hallway/primary/fore) -"OJ" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"OO" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/light/directional/north, -/obj/structure/closet/emcloset, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/turf/open/floor/iron/dark/corner{ - dir = 1 - }, -/area/station/hallway/primary/fore) -"OR" = ( -/obj/machinery/modular_computer/preset/command{ - dir = 4 - }, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) -"OY" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"Pd" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/structure/sign/poster/official/random/directional/west, -/turf/open/floor/iron/dark/corner{ - dir = 8 - }, -/area/station/hallway/primary/fore) -"Po" = ( -/obj/structure/table/reinforced/rglass, -/obj/item/reagent_containers/dropper, -/obj/item/hairbrush/comb{ - pixel_y = 10 - }, -/obj/machinery/button/curtain{ - id = "barbershopcurtains"; - pixel_x = 10; - pixel_y = -26 - }, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"Pt" = ( -/obj/structure/fans/tiny/forcefield{ - dir = 1 - }, -/obj/structure/sign/warning/vacuum/external/directional/west, -/obj/machinery/door/poddoor/preopen{ - name = "Dock Shutter" - }, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"Pw" = ( -/obj/structure/transit_tube, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"PD" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"Qy" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"Re" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners{ - dir = 8 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/cafeteria, -/area/station/service/barber) -"Rf" = ( -/obj/structure/chair/sofa/bench{ - dir = 8 - }, -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/effect/landmark/start/assistant, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"Rj" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"Ry" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/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/iron, -/area/station/hallway/primary/fore) -"RA" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/fore/lesser) -"Sa" = ( -/obj/structure/chair/sofa/bench/left{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"Sg" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"SC" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"SH" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/obj/structure/chair/office{ - dir = 1 - }, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"Th" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/radio/intercom/directional/east, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"TD" = ( -/obj/structure/transit_tube, -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/cobweb, -/turf/open/floor/iron/grimy, -/area/station/hallway/primary/fore) -"TG" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"TS" = ( -/turf/template_noop, -/area/template_noop) -"TU" = ( -/obj/structure/table/reinforced/rglass, -/obj/item/razor{ - pixel_x = -6 - }, -/obj/item/reagent_containers/spray/barbers_aid{ - pixel_x = 6 - }, -/obj/machinery/light/directional/south, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"Uc" = ( -/obj/structure/transit_tube/diagonal/topleft, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"Ul" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/food/pie_smudge, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"Um" = ( -/obj/structure/flora/rock/pile/style_random, -/turf/open/misc/asteroid/airless, -/area/space/nearstation) -"Uw" = ( -/turf/open/floor/iron/dark, -/area/station/hallway/primary/fore) -"UZ" = ( -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"Vp" = ( -/obj/structure/chair/comfy/barber_chair, -/obj/effect/turf_decal/siding/white{ - dir = 1 - }, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"VG" = ( -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"Wi" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, -/area/station/hallway/primary/fore) -"WA" = ( -/obj/effect/spawner/structure/window, -/obj/structure/curtain/cloth/fancy/mechanical{ - id = "barbershopcurtains"; - name = "Barber Shop Drapes" - }, -/turf/open/floor/plating, -/area/station/service/barber) -"WE" = ( -/obj/machinery/door/airlock/corporate{ - name = "NT Consultant's Office" - }, -/obj/effect/mapping_helpers/airlock/access/all/cent_com/rep_door, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door/firedoor, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/command/heads_quarters/nt_rep) -"WY" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/structure/chair/office/light{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/effect/landmark/start/barber, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"Xo" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/firealarm/directional/east, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark/corner{ - dir = 4 - }, -/area/station/hallway/primary/fore) -"Xp" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"XI" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"XJ" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/spawner/random/structure/crate, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"XL" = ( -/turf/closed/mineral/random/labormineral, -/area/space/nearstation) -"XP" = ( -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"Yl" = ( -/obj/structure/table/reinforced/rglass, -/obj/structure/mirror/directional/south, -/obj/item/lipstick/random{ - pixel_x = -6; - pixel_y = -5 - }, -/obj/item/lipstick/random, -/obj/item/reagent_containers/spray/quantum_hair_dye{ - pixel_x = 9 - }, -/turf/open/floor/iron/dark, -/area/station/service/barber) -"YD" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"YS" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"Zb" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/wood, -/area/station/command/heads_quarters/nt_rep) -"Ze" = ( -/obj/structure/transit_tube/crossing, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating/airless, -/area/space/nearstation) -"Zv" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/hallway/primary/fore) -"ZN" = ( -/obj/structure/table/wood, -/turf/open/floor/carpet/executive, -/area/station/command/heads_quarters/nt_rep) - -(1,1,1) = {" -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -jY -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -BZ -dZ -Gh -Gh -Gh -Gh -Dl -Dl -vs -XL -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -"} -(2,1,1) = {" -XL -Gh -Gh -Gh -Gh -Dl -Dl -Gh -Gh -Gh -nN -nN -nN -nN -nN -nN -Gh -Gh -Gh -Gh -Gh -Gh -ad -dZ -dZ -dZ -dZ -dZ -XP -gW -vE -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -"} -(3,1,1) = {" -XL -Dl -Gh -Gh -Dl -Dl -Dl -Dl -Gh -nN -nN -rE -wh -kh -rE -nN -nN -Gh -Gh -Gh -Gh -Gh -Gh -Lw -Dl -Dl -Dl -Dl -Dl -Dl -hj -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -"} -(4,1,1) = {" -XL -Dl -Dl -Gh -Mu -Dl -Dl -Dl -Dl -nN -Uw -Rj -jK -jK -cc -Uw -nN -Dl -Dl -Dl -Dl -Gh -Dl -Dl -hS -Dl -Dl -Dl -Dl -Dl -hj -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -"} -(5,1,1) = {" -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -nN -nN -jK -bV -mU -gy -Sa -jV -nN -nN -Dl -Mu -Dl -Dl -Dl -Dl -Dl -Uc -Dl -Dl -Dl -XL -hj -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -TS -"} -(6,1,1) = {" -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Eg -rz -jK -LI -Uw -jK -ud -Uw -tU -Eg -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Uc -Dl -Gh -Gh -yM -OJ -YS -TS -TS -TS -TS -TS -TS -TS -TS -TS -"} -(7,1,1) = {" -Dl -Dl -Mt -Mt -Eg -nN -nN -nN -Eg -jS -qj -Rf -Jn -jC -nE -Da -hs -Mt -Mt -nN -nN -nN -Eg -Eg -nN -Eg -Gh -bH -dZ -dZ -dZ -fR -hj -TS -TS -TS -TS -TS -TS -TS -TS -TS -"} -(8,1,1) = {" -Gh -Gh -Eg -ku -cf -EP -nW -MG -nW -nW -wF -rT -wF -wF -XI -nW -nW -jV -fc -fF -kI -wF -fr -EP -nW -nN -Gh -dZ -Lw -Gh -Gh -dZ -hj -TS -TS -TS -TS -TS -TS -TS -TS -TS -"} -(9,1,1) = {" -Gh -Gh -Eg -Ef -AB -Jl -Jl -Fl -Fl -Fl -sz -sz -Fl -Fl -Fl -sz -sz -Fl -Fl -Fl -Fl -Fl -Fl -Dh -MG -nN -Gh -dZ -dZ -Lw -Gh -XP -yM -OJ -OJ -OJ -OJ -nc -fA -RA -TS -TS -"} -(10,1,1) = {" -Gh -Gh -Pt -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -HW -iD -nN -Gh -Gh -dZ -dZ -EO -Ze -Pw -Pw -Ze -Pw -Pw -tx -lw -jJ -dV -TD -"} -(11,1,1) = {" -Gh -Gh -iM -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -HW -hd -Eg -dZ -dZ -dZ -dZ -dZ -XP -tz -Dl -Dl -Dl -Dl -hg -rt -gH -Fz -zZ -"} -(12,1,1) = {" -Gh -Gh -iM -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -HW -JP -Eg -Gh -Gh -dZ -Gh -dZ -dZ -Fi -Fi -yC -Fi -Fi -yC -Ib -bb -Ag -ha -"} -(13,1,1) = {" -Gh -Gh -iM -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -Wi -kE -nN -Gh -Gh -Fi -yC -Fi -yC -yC -lU -EI -vJ -rk -Po -Ib -vp -Ib -qS -"} -(14,1,1) = {" -Gh -Gh -iM -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -MO -nW -nN -Gh -Gh -yC -Be -uM -Ho -yC -ey -Mw -dC -Vp -Yl -Ib -iv -Ag -uX -"} -(15,1,1) = {" -Gh -Gh -iM -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -gw -nW -nN -Gh -Gh -yC -HV -WY -SC -wK -FU -Re -Re -BU -TU -Ib -GU -Ib -lr -"} -(16,1,1) = {" -Gh -Gh -iM -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -gw -HJ -Eg -nN -nN -Fi -zR -zR -zR -Fi -WA -WA -wQ -WA -WA -Ag -iy -Ib -Gw -"} -(17,1,1) = {" -Gh -Gh -iM -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -Oq -jV -jV -jV -jV -jV -jV -jV -jV -HW -FQ -En -gv -Oy -En -gv -GX -GX -Pd -GX -GX -Fg -nF -nF -nF -Eh -DC -Ce -"} -(18,1,1) = {" -Gh -Gh -iM -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -gw -TG -wL -gx -NU -wL -UZ -fb -Bx -Zv -Zv -Xo -su -su -FM -su -dY -bj -oi -"} -(19,1,1) = {" -Gh -Gh -iM -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -gw -ze -Eg -nN -nN -Eg -Eg -Eg -OO -wF -qU -zb -oR -oR -WE -oZ -GN -pf -tg -"} -(20,1,1) = {" -Gh -Gh -cW -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -jV -gw -VG -nN -Dl -Dl -Dl -Dl -Mt -gk -wF -yd -xV -qM -vS -rL -zb -bB -pf -qg -"} -(21,1,1) = {" -Gh -Gh -Eg -Iv -iV -Sg -Sg -Qy -Qy -Qy -kP -Jq -kP -kP -kP -kP -Jq -Jq -Jq -KE -Jq -Jq -Jq -Ry -wF -nN -Dl -Dl -Dl -Um -Mt -df -ds -nS -zb -IX -uf -Jm -xV -fT -pf -pf -"} -(22,1,1) = {" -Gh -Gh -Eg -dG -nW -nW -Th -an -kE -nW -Ia -Op -wF -wF -wF -wF -nv -Dp -nW -nW -kE -wF -Op -Xp -wF -nN -Dl -Dl -Dl -Dl -Eg -Mt -xV -kz -xV -Ng -wT -fx -zb -Ek -Ja -qr -"} -(23,1,1) = {" -Gh -Gh -Mt -nN -nN -nN -Eg -Mt -nN -nN -nN -Eg -Eg -nN -nN -nN -Eg -Eg -nN -nN -nN -Eg -Eg -nN -nN -Mt -Dl -Dl -Gh -XL -XL -XL -xV -KA -OR -ZN -gX -Zb -zb -XJ -OY -KL -"} -(24,1,1) = {" -Gh -Gh -Gh -Gh -Gh -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Cm -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Gh -Gh -XL -XL -XL -zb -ca -Ev -EX -EG -Cf -xV -ew -eZ -pf -"} -(25,1,1) = {" -Gh -Gh -Gh -Gh -Gh -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Dl -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -jY -Gh -XL -XL -DJ -cX -mZ -zF -SH -YD -zb -jA -PD -nA -"} -(26,1,1) = {" -Gh -Gh -Gh -Gh -Dl -Dl -Dl -Um -XL -XL -Dl -Dl -Dl -Dl -Dl -Dl -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -Gh -XL -zb -cm -aK -zu -Bs -YD -zb -eL -Nu -vV -"} -(27,1,1) = {" -Gh -Gh -Gh -Gh -Dl -Dl -XL -XL -XL -MP -mi -fR -XL -Dl -Um -XL -fR -dZ -uj -Me -Me -Me -dZ -fR -dZ -uj -Me -Me -Me -Me -zf -ne -xV -zb -zb -zb -zb -zb -xV -eQ -Ul -uI -"} diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index d619da64d48..5df4128be62 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -171,9 +171,9 @@ DEFINE_BITFIELD(status_flags, list( #define SHOVE_KNOCKDOWN_TABLE 20 #define SHOVE_KNOCKDOWN_COLLATERAL 1 #define SHOVE_CHAIN_PARALYZE 30 -//Shove slowdown -#define SHOVE_SLOWDOWN_LENGTH 30 -#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier +//Staggered slowdown, an effect caused by shoving and a few other features, such as tackling +#define STAGGERED_SLOWDOWN_LENGTH 30 +#define STAGGERED_SLOWDOWN_STRENGTH 0.85 //multiplier //Shove disarming item list GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( /obj/item/gun))) diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 4998f10849e..903182b21db 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -12,6 +12,8 @@ /// from /obj/item/toy/crayon/spraycan/afterattack: (user, spraycan, color_is_dark) #define COMSIG_OBJ_PAINTED "obj_painted" #define DONT_USE_SPRAYCAN_CHARGES (1<<0) +/// from /obj/obj_reskin: (mob/user, skin) +#define COMSIG_OBJ_RESKIN "obj_reskin" // /obj/machinery signals @@ -308,6 +310,8 @@ #define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency" ///called from base of /obj/item/radio/proc/talk_into(): (atom/movable/M, message, channel) #define COMSIG_RADIO_NEW_MESSAGE "radio_new_message" +///called from base of /obj/item/radio/proc/on_receive_messgae(): (list/data) +#define COMSIG_RADIO_RECEIVE_MESSAGE "radio_receive_message" // /obj/item/pen signals @@ -361,9 +365,9 @@ // /obj/projectile signals (sent to the firer) -///from base of /obj/projectile/proc/on_hit(), like COMSIG_PROJECTILE_ON_HIT but on the projectile itself and with the hit limb (if any): (atom/movable/firer, atom/target, angle, hit_limb) +///from base of /obj/projectile/proc/on_hit(), like COMSIG_PROJECTILE_ON_HIT but on the projectile itself and with the hit limb (if any): (atom/movable/firer, atom/target, angle, hit_limb, blocked) #define COMSIG_PROJECTILE_SELF_ON_HIT "projectile_self_on_hit" -///from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, angle, hit_limb) +///from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, angle, hit_limb, blocked) #define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit" ///from base of /obj/projectile/proc/fire(): (obj/projectile, atom/original_target) #define COMSIG_PROJECTILE_BEFORE_FIRE "projectile_before_fire" @@ -387,6 +391,9 @@ ///sent to targets during the process_hit proc of projectiles #define COMSIG_FIRE_CASING "fire_casing" +///from the base of /obj/item/ammo_casing/ready_proj() : (atom/target, mob/living/user, quiet, zone_override, atom/fired_from) +#define COMSIG_CASING_READY_PROJECTILE "casing_ready_projectile" + ///sent to the projectile after an item is spawned by the projectile_drop element: (new_item) #define COMSIG_PROJECTILE_ON_SPAWN_DROP "projectile_on_spawn_drop" ///sent to the projectile when spawning the item (shrapnel) that may be embedded: (new_item) @@ -448,6 +455,12 @@ #define COMSIG_ITEM_AFTERATTACK_SECONDARY "item_afterattack_secondary" ///from base of obj/item/attack_qdeleted(): (atom/target, mob/user, params) #define COMSIG_ITEM_ATTACK_QDELETED "item_attack_qdeleted" +///from base of obj/item/embedded(): (atom/target, obj/item/bodypart/part) +#define COMSIG_ITEM_EMBEDDED "item_embedded" +///from base of datum/component/embedded/safeRemove(): (mob/living/carbon/victim) +#define COMSIG_ITEM_UNEMBEDDED "item_unembedded" +/// from base of obj/item/failedEmbed() +#define COMSIG_ITEM_FAILED_EMBED "item_failed_embed" ///from /obj/item/assembly/proc/pulsed(mob/pulser) #define COMSIG_ASSEMBLY_PULSED "assembly_pulsed" @@ -481,3 +494,12 @@ /// from /obj/structure/cursed_slot_machine/determine_victor() when someone finally wins. #define COMSIG_GLOB_CURSED_SLOT_MACHINE_WON "cursed_slot_machine_won" + +/// from /datum/component/dart_insert/add_to_dart() : (obj/item/ammo_casing, mob/user) +#define COMSIG_DART_INSERT_ADDED "dart_insert_added" + +/// from /datum/component/dart_insert/remove_from_dart() : (obj/ammo_casing/dart, mob/user) +#define COMSIG_DART_INSERT_REMOVED "dart_insert_removed" + +/// from /datum/component/dart_insert/on_reskin() +#define COMSIG_DART_INSERT_PARENT_RESKINNED "dart_insert_parent_reskinned" diff --git a/code/__DEFINES/nozzle_define.dm b/code/__DEFINES/nozzle_define.dm new file mode 100644 index 00000000000..06b43c1acc6 --- /dev/null +++ b/code/__DEFINES/nozzle_define.dm @@ -0,0 +1,4 @@ +/// 3 differnt modes for the firefighter extinquisher +#define EXTINGUISHER 0 +#define RESIN_LAUNCHER 1 +#define RESIN_FOAM 2 diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 03a3bf49ebb..768f1faa514 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -114,6 +114,11 @@ #define set_dizzy(duration) set_timed_status_effect(duration, /datum/status_effect/dizziness) #define set_dizzy_if_lower(duration) set_timed_status_effect(duration, /datum/status_effect/dizziness, TRUE) +#define adjust_staggered(duration) adjust_timed_status_effect(duration, /datum/status_effect/staggered) +#define adjust_staggered_up_to(duration, up_to) adjust_timed_status_effect(duration, /datum/status_effect/staggered, up_to) +#define set_staggered(duration) set_timed_status_effect(duration, /datum/status_effect/staggered) +#define set_staggered_if_lower(duration) set_timed_status_effect(duration, /datum/status_effect/staggered, TRUE) + #define adjust_jitter(duration) adjust_timed_status_effect(duration, /datum/status_effect/jitter) #define adjust_jitter_up_to(duration, up_to) adjust_timed_status_effect(duration, /datum/status_effect/jitter, up_to) #define set_jitter(duration) set_timed_status_effect(duration, /datum/status_effect/jitter) diff --git a/code/__DEFINES/surgery.dm b/code/__DEFINES/surgery.dm index dcdd1394253..6f078c28724 100644 --- a/code/__DEFINES/surgery.dm +++ b/code/__DEFINES/surgery.dm @@ -43,6 +43,8 @@ #define BODYPART_PSEUDOPART (1<<1) /// Bodypart did not match the owner's default bodypart limb_id when surgically implanted #define BODYPART_IMPLANTED (1<<2) +/// Bodypart never displays as a husk +#define BODYPART_UNHUSKABLE (1<<3) // Bodypart change blocking flags ///Bodypart does not get replaced during set_species() diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 6c774453782..98a8df19b7c 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -75,6 +75,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_GUN_NATURAL "gunnatural" /// Causes death-like unconsciousness #define TRAIT_DEATHCOMA "deathcoma" +/// The mob has the stasis effect. +/// Does nothing on its own, applied via status effect. +#define TRAIT_STASIS "in_stasis" /// Makes the owner appear as dead to most forms of medical examination #define TRAIT_FAKEDEATH "fakedeath" #define TRAIT_DISFIGURED "disfigured" @@ -121,6 +124,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NUKEIMMUNE "nuke_immunity" /// Can't be given viruses #define TRAIT_VIRUSIMMUNE "virus_immunity" +/// Won't become a husk under any circumstances +#define TRAIT_UNHUSKABLE "trait_unhuskable" /// Reduces the chance viruses will spread to this mob, and if the mob has a virus, slows its advancement #define TRAIT_VIRUS_RESISTANCE "virus_resistance" #define TRAIT_GENELESS "geneless" @@ -159,10 +164,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NOBLOOD "noblood" /// This just means that the carbon will always have functional liverless metabolism #define TRAIT_LIVERLESS_METABOLISM "liverless_metabolism" +/// This carbon can't be overdosed by chems +#define TRAIT_OVERDOSEIMMUNE "overdose_immune" /// Humans with this trait cannot be turned into zombies #define TRAIT_NO_ZOMBIFY "no_zombify" -/// Humans with this trait cannot be affected by changeling transformation stings -#define TRAIT_NO_TRANSFORMATION_STING "no_transformation_sting" /// Carbons with this trait can't have their DNA copied by diseases nor changelings #define TRAIT_NO_DNA_COPY "no_dna_copy" /// Carbons with this trait cant have their dna scrambled by genetics or a disease retrovirus. @@ -209,6 +214,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///Added to mob or mind, changes the icons of the fish shown in the minigame UI depending on the possible reward. #define TRAIT_REVEAL_FISH "reveal_fish" +/// Added to a mob, allows that mob to experience flavour-based moodlets when examining food +#define TRAIT_REMOTE_TASTING "remote_tasting" + /// Stops the mob from slipping on water, or banana peels, or pretty much anything that doesn't have [GALOSHES_DONT_HELP] set #define TRAIT_NO_SLIP_WATER "noslip_water" /// Stops the mob from slipping on permafrost ice (not any other ice) (but anything with [SLIDE_ICE] set) @@ -535,6 +543,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Disables the floating animation. See above. #define TRAIT_NO_FLOATING_ANIM "no-floating-animation" +/// Cannot be turned into a funny skeleton by the plasma river +#define TRAIT_NO_PLASMA_TRANSFORM "no_plasma_transform" + /// Weather immunities, also protect mobs inside them. #define TRAIT_LAVA_IMMUNE "lava_immune" //Used by lava turfs and The Floor Is Lava. #define TRAIT_ASHSTORM_IMMUNE "ashstorm_immune" @@ -975,4 +986,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Trait given to mobs that we do not want to mindswap #define TRAIT_NO_MINDSWAP "no_mindswap" +/// Trait given to foam darts that have an insert in them +#define TRAIT_DART_HAS_INSERT "dart_has_insert" // END TRAIT DEFINES diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index f6cb654b1d5..039533cffa5 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -103,6 +103,8 @@ #define VV_HK_ARMOR_MOD "mod_obj_armor" // /atom/movable +#define VV_HK_OBSERVE_FOLLOW "observe_follow" +#define VV_HK_GET_MOVABLE "get_movable" #define VV_HK_DEADCHAT_PLAYS "deadchat_plays" // /obj @@ -138,7 +140,6 @@ #define VV_HK_GIVE_GUARDIAN_SPIRIT "give_guardian_spirit" // /mob/living/carbon -#define VV_HK_MAKE_AI "aiify" #define VV_HK_MODIFY_BODYPART "mod_bodypart" #define VV_HK_MODIFY_ORGANS "organs_modify" #define VV_HK_MARTIAL_ART "give_martial_art" diff --git a/code/__DEFINES/~skyrat_defines/DNA.dm b/code/__DEFINES/~skyrat_defines/DNA.dm index 8e9c220c9e1..62ad2f08429 100644 --- a/code/__DEFINES/~skyrat_defines/DNA.dm +++ b/code/__DEFINES/~skyrat_defines/DNA.dm @@ -6,10 +6,6 @@ // Defines for whether an accessory should have one or three colors to choose for #define USE_ONE_COLOR 31 #define USE_MATRIXED_COLORS 32 -// Defines for some extra inherent traits -#define TRAIT_REVIVES_BY_HEALING "trait_revives_by_healing" -#define TRAIT_ROBOTIC_DNA_ORGANS "trait_robotic_dna_organs" -//Also.. yes for some reason specie traits and accessory defines are together //Defines for processing reagents, for synths, IPC's and Vox #define PROCESS_ORGANIC 1 //Only processes reagents with "ORGANIC" or "ORGANIC | SYNTHETIC" @@ -34,9 +30,14 @@ // Defines for mutant bodyparts indexes #define MUTANT_INDEX_NAME "name" +#define MUTANT_INDEX_CAN_RANDOMIZE "can_randomize" #define MUTANT_INDEX_COLOR_LIST "color" #define MUTANT_INDEX_EMISSIVE_LIST "emissive" +// Defines for default mutant bodyparts indexes +#define MUTANTPART_NAME 1 +#define MUTANTPART_CAN_RANDOMIZE 2 + // Defines for markings indexes #define MARKING_INDEX_COLOR 1 #define MARKING_INDEX_EMISSIVE 2 diff --git a/code/__DEFINES/~skyrat_defines/combat.dm b/code/__DEFINES/~skyrat_defines/combat.dm index 54659715cc3..a29811e9349 100644 --- a/code/__DEFINES/~skyrat_defines/combat.dm +++ b/code/__DEFINES/~skyrat_defines/combat.dm @@ -1,4 +1,3 @@ -#define PUNCH_STAMINA_MULTIPLIER 2.6 //Stamina threshold from which resisting a grab becomes hard #define STAMINA_THRESHOLD_HARD_RESIST 80 diff --git a/code/__DEFINES/~skyrat_defines/lewd_defines.dm b/code/__DEFINES/~skyrat_defines/lewd_defines.dm index a1edae8aa01..7674131b090 100644 --- a/code/__DEFINES/~skyrat_defines/lewd_defines.dm +++ b/code/__DEFINES/~skyrat_defines/lewd_defines.dm @@ -11,23 +11,6 @@ #define REQUIRE_GENITAL_UNEXPOSED 2 #define REQUIRE_GENITAL_ANY 3 -#define TRAIT_MASOCHISM "masochism" -#define TRAIT_SADISM "sadism" -#define TRAIT_NEVERBONER "neverboner" -#define TRAIT_BIMBO "bimbo" -#define TRAIT_RIGGER "rigger" -#define TRAIT_ROPEBUNNY "rope bunny" -///traits gained by brain traumas, can be removed if the brain trauma is gone -#define APHRO_TRAIT "aphro" -///traits gained by quirks, cannot be removed unless the quirk itself is gone -#define LEWDQUIRK_TRAIT "lewdquirks" -///traits gained by chemicals, you get the idea -#define LEWDCHEM_TRAIT "lewdchem" - -#define STRAPON_TRAIT "strapon" - -#define CONDOM_BROKEN "broken" - #define BREAST_SIZE_FLATCHESTED "Flatchested" #define BREAST_SIZE_A "A" #define BREAST_SIZE_B "B" diff --git a/code/__DEFINES/~skyrat_defines/robot_defines.dm b/code/__DEFINES/~skyrat_defines/robot_defines.dm index 8dde8079fb6..935fe1db1c8 100644 --- a/code/__DEFINES/~skyrat_defines/robot_defines.dm +++ b/code/__DEFINES/~skyrat_defines/robot_defines.dm @@ -6,20 +6,6 @@ #define SKIN_FEATURES "skin_features" //for the new system of borg making -//Defines for model features, set in the model_features list of a robot model datum. Are they a dogborg? Is the model small? etc. -/// Cyborgs with unique sprites for when they get totally broken down. -#define R_TRAIT_UNIQUEWRECK "unique_wreck" -/// Or when tipped over. -#define R_TRAIT_UNIQUETIP "unique_tip" -/// 64x32 skins -#define R_TRAIT_WIDE "wide_borg" -/// 32x64 skins -#define R_TRAIT_TALL "tall_borg" -/// Any model small enough to reject the shrinker upgrade. -#define R_TRAIT_SMALL "small_chassis" -/// Any model that has a custom front panel -#define R_TRAIT_UNIQUEPANEL "unique_openpanel" - // Icon file locations for modular borg icons #define CYBORG_ICON_STANDARD 'modular_skyrat/modules/borgs/icons/robots.dmi' diff --git a/code/__DEFINES/~skyrat_defines/traits.dm b/code/__DEFINES/~skyrat_defines/traits.dm index f099b57f260..f49d0bbe413 100644 --- a/code/__DEFINES/~skyrat_defines/traits.dm +++ b/code/__DEFINES/~skyrat_defines/traits.dm @@ -1,101 +1,5 @@ -// Defines for some extra traits -#define TRAIT_NO_HUSK "no_husk" -#define TRAIT_NORUNNING "norunning" // You walk! -#define TRAIT_EXCITABLE "wagwag" //Will wag when patted! -#define TRAIT_OXYIMMUNE "oxyimmune" // Immune to oxygen damage, ideally give this to all non-breathing species or bad stuff will happen -#define TRAIT_PERSONALSPACE "personalspace" // Block/counter-attack ass-slaps -#define TRAIT_MOOD_NOEXAMINE "mood_noexamine" // Can't assess your own mood -#define TRAIT_DNR "do_not_revive" // Can't be revived without supernatural means or admin intervention -#define TRAIT_HARD_SOLES "hard_soles" // No step on glass -#define TRAIT_SENSITIVESNOUT "sensitive_snout" // Snout hurts when booped -#define TRAIT_DETECTIVE "detective_ability" //Given to the detective, if they have this, they can see syndicate special descriptions. -#define TRAIT_FREE_GHOST "free_ghost" // Can ghost and return freely with this trait -#define GLOVES_TRAIT "gloves_trait" //Traits associated with wearing gloves -#define QUIRK_LINGUIST "Linguist" // Extra language point. -#define GLUED_ITEM_TRAIT "glued-item" // This is for glued items, undroppable. Syndie glue applies this. -#define TRAIT_STICKY_FINGERS "sticky_fingers" //This is so a mob can strip items faster and picks them up after -/// This makes trait makes it so that the person cannot be infected by the zombie virus. -#define TRAIT_MUTANT_IMMUNE "mutant_immune" -/// adds -6 quirk to negative quirks for free points. -#define TRAIT_GIFTED "gifted" - -//AdditionalEmotes *turf traits -#define TRAIT_WATER_ASPECT "water_aspect" -#define TRAIT_WEBBING_ASPECT "webbing_aspect" -#define TRAIT_FLORAL_ASPECT "floral_aspect" -#define TRAIT_ASH_ASPECT "ash_aspect" -#define TRAIT_SPARKLE_ASPECT "sparkle_aspect" - -/// Allows the user to instantly reload. -#define TRAIT_INSTANT_RELOAD "instant_reload" - -// Trait sources -#define GHOSTROLE_TRAIT "ghostrole" // SKYRAT EDIT ADDITION -- Ghost Cafe Traits - -/// One can breath under water, you get me? -#define TRAIT_WATER_BREATHING "water_breathing" - -/// The trait which Akulas inherit, for their species mechanic revolving around wet_stacks -#define TRAIT_SLICK_SKIN "slick_skin" -/// The trait which is applied when a `slick skin` trait haver actually gets wet_stacks -#define TRAIT_SLIPPERY "slippery" /// The minimum amount of tiles a TRAIT_SLIPPERY haver will slide on slip #define SLIPPERY_MIN 5 /// The maximum amount of tiles a TRAIT_SLIPPERY haver will slide on slip #define SLIPPERY_MAX 9 - -/// Under the effect of a numbling agent, such as morphine, for surgery. -#define TRAIT_NUMBED "numbed" - -// felinid traits -#define TRAIT_FELINE "feline_aspect" - -// canine traits -#define TRAIT_CANINE "canine_aspect" - -// avian traits -#define TRAIT_AVIAN "avian_aspect" - -// chameleon mutation -#define TRAIT_CHAMELEON_SKIN "chameleon_skin" - -//Makes sure that people cant be cult sacrificed twice. -#define TRAIT_SACRIFICED "sacrificed" - -/// The trait that determines if someone has the oversized quirk. -#define TRAIT_OVERSIZED "trait_oversized" - -/// Cargo Loader trait -#define TRAIT_TRASHMAN "trait_trashman" - -/// Trait source for xeno innate abilities -#define TRAIT_XENO_INNATE "xeno_innate" -/// Trait source for something added BY a xeno ability -#define TRAIT_XENO_ABILITY_GIVEN "xeno_ability_given" -/// Determines if something can receive healing from a xeno -#define TRAIT_XENO_HEAL_AURA "trait_xeno_heal_aura" - -/// Trait that was granted by a reagent. -#define REAGENT_TRAIT "reagent" - -/// trait that lets you do flips with a style meter -#define TRAIT_STYLISH "stylish" - -/// trait that lets you do xenoarch magnification -#define TRAIT_XENOARCH_QUALIFIED "trait_xenoarch_qualified" - -/// Traits granted by glassblowing -#define GLASSBLOWING_TRAIT "glassblowing" - -/// Trait that is applied whenever someone or something is glassblowing -#define TRAIT_CURRENTLY_GLASSBLOWING "currently_glassblowing" - -/// Trait that was granted by a NIFSoft -#define NIFSOFT_TRAIT "nifsoft" - -/// Trait given to a piece of eyewear that allows the user to use NIFSoft HUDs -#define TRAIT_NIFSOFT_HUD_GRANTER "nifsoft_hud_granter" - -/// Trait given to a brain that is able to accept souls from a RSD -#define TRAIT_RSD_COMPATIBLE "rsd_compatible" diff --git a/code/__HELPERS/colors.dm b/code/__HELPERS/colors.dm index cc3d083f640..58f4d61ea30 100644 --- a/code/__HELPERS/colors.dm +++ b/code/__HELPERS/colors.dm @@ -17,6 +17,18 @@ return final_color +/// Given a color in the format of "#RRGGBB" or "#RRGGBBAA", gives back a 4 entry list with the number values of each +/proc/split_color(color) + var/list/output = list() + output += hex2num(copytext(color, 2, 4)) + output += hex2num(copytext(color, 4, 6)) + output += hex2num(copytext(color, 6, 8)) + if(length(color) == 9) + output += hex2num(copytext(color, 8, 10)) + else + output += 255 + return output + ///Returns a random color picked from a list, has 2 modes (0 and 1), mode 1 doesn't pick white, black or gray /proc/random_colour(mode = 0) switch(mode) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 8eacab9e2d5..c6fa9d09ac8 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -17,9 +17,9 @@ //SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION /* init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails, GLOB.tails_list, add_blank = TRUE) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human, add_blank = TRUE) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard, add_blank = TRUE) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey, GLOB.tails_list_monkey, add_blank = TRUE) init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm index 116fb34fad5..c28357eb478 100644 --- a/code/__HELPERS/maths.dm +++ b/code/__HELPERS/maths.dm @@ -217,3 +217,8 @@ return max(new_value, threshold) if(sign == -1) return min(new_value, threshold * -1) + +/// Takes two values x and y, and returns 1/((1/x) + y) +/// Useful for providing an additive modifier to a value that is used as a divisor, such as `/obj/projectile/var/speed` +/proc/reciprocal_add(x, y) + return 1/((1/x)+y) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index df98ab953fa..5a408937a04 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -58,7 +58,7 @@ /proc/random_backpack() return pick(GLOB.backpacklist) -//SKYRAT EDIT REMOVAL - CUSTOMIZATION (moved to modular) +// SKYRAT EDIT REMOVAL - CUSTOMIZATION (moved to modular) /* /proc/random_features() if(!GLOB.tails_list.len) @@ -113,9 +113,8 @@ "tail_monkey" = "Monkey", "pod_hair" = pick(GLOB.pod_hair_list), )) - */ - //SKYRAT EDIT REMOVAL END - +*/ +//SKYRAT EDIT REMOVAL END /proc/random_hairstyle(gender) switch(gender) @@ -589,8 +588,6 @@ GLOBAL_LIST_EMPTY(species_list) #define ISADVANCEDTOOLUSER(mob) (HAS_TRAIT(mob, TRAIT_ADVANCEDTOOLUSER) && !HAS_TRAIT(mob, TRAIT_DISCOORDINATED_TOOL_USER)) -#define IS_IN_STASIS(mob) (mob.has_status_effect(/datum/status_effect/grouped/stasis) || mob.has_status_effect(/datum/status_effect/embryonic)) - /// Gets the client of the mob, allowing for mocking of the client. /// You only need to use this if you know you're going to be mocking clients somewhere else. #define GET_CLIENT(mob) (##mob.client || ##mob.mock_client) @@ -631,7 +628,6 @@ GLOBAL_LIST_EMPTY(species_list) moblist += mob_to_sort // SKYRAT EDIT END - SOULCATCHERS return moblist - ///returns a mob type controlled by a specified ckey /proc/get_mob_by_ckey(key) if(!key) diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index dbf9a47f9f7..afb15912694 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -30,9 +30,9 @@ GLOBAL_LIST_EMPTY(legs_list) GLOBAL_LIST_EMPTY(animated_spines_list) //Mutant Human bits -GLOBAL_LIST_EMPTY(tails_list) -GLOBAL_LIST_EMPTY(tails_list_human) //Only exists for preference choices. Use "tails_list" otherwise. -GLOBAL_LIST_EMPTY(tails_list_lizard) //See above! +GLOBAL_LIST_EMPTY(tails_list_human) +GLOBAL_LIST_EMPTY(tails_list_lizard) +GLOBAL_LIST_EMPTY(tails_list_monkey) GLOBAL_LIST_EMPTY(ears_list) GLOBAL_LIST_EMPTY(wings_list) GLOBAL_LIST_EMPTY(wings_open_list) diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index a54799b7bb1..05aa4e419a2 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -351,6 +351,7 @@ GLOBAL_LIST_INIT(rarity_loot, list(//rare: really good items /obj/item/disk/nuclear/fake = 1, /obj/item/disk/surgery/advanced_plastic_surgery = 1, /obj/item/skillchip/brainwashing = 1, + /obj/item/skillchip/intj = 1, /obj/item/tattoo_kit = 1, /obj/item/folder/ancient_paperwork = 1, ) = 1, diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 34ec53044f2..9bd3cf35b48 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -204,7 +204,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_GARLIC_BREATH" = TRAIT_GARLIC_BREATH, "TRAIT_GENELESS" = TRAIT_GENELESS, "TRAIT_GIANT" = TRAIT_GIANT, - "TRAIT_GIFTED" = TRAIT_GIFTED, // SKYRAT EDIT ADDITION "TRAIT_GONE_FISHING" = TRAIT_GONE_FISHING, "TRAIT_GOOD_HEARING" = TRAIT_GOOD_HEARING, "TRAIT_GRABWEAKNESS" = TRAIT_GRABWEAKNESS, @@ -275,6 +274,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NEVER_WOUNDED" = TRAIT_NEVER_WOUNDED, "TRAIT_NICE_SHOT" = TRAIT_NICE_SHOT, "TRAIT_NIGHT_VISION" = TRAIT_NIGHT_VISION, + "TRAIT_NO_ACCENT" = TRAIT_NO_ACCENT, //FF add - autoaccent "TRAIT_NO_AUGMENTS" = TRAIT_NO_AUGMENTS, "TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY, "TRAIT_NO_DEBRAIN_OVERLAY" = TRAIT_NO_DEBRAIN_OVERLAY, @@ -282,12 +282,13 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NO_DNA_SCRAMBLE" = TRAIT_NO_DNA_SCRAMBLE, "TRAIT_NO_FLOATING_ANIM" = TRAIT_NO_FLOATING_ANIM, "TRAIT_NO_GLIDE" = TRAIT_NO_GLIDE, + "TRAIT_NO_PLASMA_TRANSFORM" = TRAIT_NO_PLASMA_TRANSFORM, "TRAIT_NO_GUN_AKIMBO" = TRAIT_NO_GUN_AKIMBO, "TRAIT_NO_IMMOBILIZE" = TRAIT_NO_IMMOBILIZE, "TRAIT_NO_JUMPSUIT" = TRAIT_NO_JUMPSUIT, "TRAIT_NO_MINDSWAP" = TRAIT_NO_MINDSWAP, "TRAIT_NO_MIRROR_REFLECTION" = TRAIT_NO_MIRROR_REFLECTION, - //"TRAIT_NO_PLASMA_TRANSFORM" = TRAIT_NO_PLASMA_TRANSFORM, SKYRAT EDIT - TODO - These require transformation sting pr + "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, @@ -320,6 +321,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NUKEIMMUNE" = TRAIT_NUKEIMMUNE, "TRAIT_OIL_FRIED" = TRAIT_OIL_FRIED, "TRAIT_ORBITING_FORBIDDEN" = TRAIT_ORBITING_FORBIDDEN, + "TRAIT_OVERDOSEIMMUNE" = TRAIT_OVERDOSEIMMUNE, "TRAIT_OVERWATCH_IMMUNE" = TRAIT_OVERWATCH_IMMUNE, "TRAIT_OVERWATCHED" = TRAIT_OVERWATCHED, "TRAIT_PACIFISM" = TRAIT_PACIFISM, @@ -327,6 +329,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_PARALYSIS_L_LEG" = TRAIT_PARALYSIS_L_LEG, "TRAIT_PARALYSIS_R_ARM" = TRAIT_PARALYSIS_R_ARM, "TRAIT_PARALYSIS_R_LEG" = TRAIT_PARALYSIS_R_LEG, + "TRAIT_PARROT_PERCHED" = TRAIT_PARROT_PERCHED, "TRAIT_PASSTABLE" = TRAIT_PASSTABLE, "TRAIT_PERFECT_ATTACKER" = TRAIT_PERFECT_ATTACKER, "TRAIT_PERMANENTLY_MORTAL" = TRAIT_PERMANENTLY_MORTAL, @@ -351,6 +354,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_REAGENT_SCANNER" = TRAIT_REAGENT_SCANNER, "TRAIT_RECENTLY_BLOCKED_MAGIC" = TRAIT_RECENTLY_BLOCKED_MAGIC, "TRAIT_RELAYING_ATTACKER" = TRAIT_RELAYING_ATTACKER, + "TRAIT_REMOTE_TASTING" = TRAIT_REMOTE_TASTING, "TRAIT_RESEARCH_SCANNER" = TRAIT_RESEARCH_SCANNER, "TRAIT_RESISTCOLD" = TRAIT_RESISTCOLD, "TRAIT_RESISTHEAT" = TRAIT_RESISTHEAT, @@ -366,14 +370,13 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ROCK_METAMORPHIC" = TRAIT_ROCK_METAMORPHIC, "TRAIT_ROD_SUPLEX" = TRAIT_ROD_SUPLEX, "TRAIT_SABRAGE_PRO" = TRAIT_SABRAGE_PRO, - "TRAIT_SACRIFICED" = TRAIT_SACRIFICED, // SKYRAT EDIT ADDITION + "TRAIT_SACRIFICED" = TRAIT_SACRIFICED, "TRAIT_SECURITY_HUD" = TRAIT_SECURITY_HUD, "TRAIT_SEE_GLASS_COLORS" = TRAIT_SEE_GLASS_COLORS, "TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE, "TRAIT_SETTLER" = TRAIT_SETTLER, "TRAIT_SHAVED" = TRAIT_SHAVED, "TRAIT_SHIFTY_EYES" = TRAIT_SHIFTY_EYES, - "TRAIT_OVERSIZED" = TRAIT_OVERSIZED, //SKYRAT EDIT ADDITION - Leaving this here so that it hopefully doesn't cause conflicts again in the future(?) "TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE, "TRAIT_SIGN_LANG" = TRAIT_SIGN_LANG, "TRAIT_SILENT_FOOTSTEPS" = TRAIT_SILENT_FOOTSTEPS, @@ -394,7 +397,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SPRAY_PAINTABLE" = TRAIT_SPRAY_PAINTABLE, "TRAIT_STABLEHEART" = TRAIT_STABLEHEART, "TRAIT_STABLELIVER" = TRAIT_STABLELIVER, - //"TRAIT_STASIS" = TRAIT_STASIS, TODO - SKYRAT EDIT - TODO - These require transformation sting pr + "TRAIT_STASIS" = TRAIT_STASIS, "TRAIT_STRONG_GRABBER" = TRAIT_STRONG_GRABBER, "TRAIT_STUNIMMUNE" = TRAIT_STUNIMMUNE, "TRAIT_SUCCUMB_OVERRIDE" = TRAIT_SUCCUMB_OVERRIDE, @@ -423,7 +426,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_UNBREAKABLE" = TRAIT_UNBREAKABLE, "TRAIT_UNDENSE" = TRAIT_UNDENSE, "TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE" = TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE, - //"TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE, SKYRAT EDIT - TODO - These require transformation sting pr + "TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE, "TRAIT_UNINTELLIGIBLE_SPEECH" = TRAIT_UNINTELLIGIBLE_SPEECH, "TRAIT_UNKNOWN" = TRAIT_UNKNOWN, "TRAIT_UNNATURAL_RED_GLOWY_EYES" = TRAIT_UNNATURAL_RED_GLOWY_EYES, @@ -474,6 +477,9 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_UNCATCHABLE" = TRAIT_UNCATCHABLE, "TRAIT_WIELDED" = TRAIT_WIELDED, ), + /obj/item/ammo_casing = list( + "TRAIT_DART_HAS_INSERT" = TRAIT_DART_HAS_INSERT, + ), /obj/item/bodypart = list( "TRAIT_DISABLED_BY_WOUND" = TRAIT_DISABLED_BY_WOUND, "TRAIT_IGNORED_BY_LIVING_FLESH" = TRAIT_IGNORED_BY_LIVING_FLESH, @@ -550,8 +556,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_TURF_IGNORE_SLIPPERY" = TRAIT_TURF_IGNORE_SLIPPERY, "TRAIT_TURF_IGNORE_SLOWDOWN" = TRAIT_TURF_IGNORE_SLOWDOWN, ), -<<<<<<< HEAD -======= // SKYRAT EDIT ADDITION START - SKYRAT TRAITS /obj/item/toy/plush/skyrat = list( "TRAIT_AFFECTION_AVERSION" = TRAIT_AFFECTION_AVERSION, @@ -623,7 +627,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_XENO_INNATE" = TRAIT_XENO_INNATE, ), // SKYRAT EDIT ADDITION END ->>>>>>> 800ad77ed (Adds Affection Aversion quirk (#25194)) )) /// value -> trait name, list of ALL traits that exist in the game, used for any type of accessing. diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index ad15a697f40..164bf0b6f01 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -129,7 +129,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY, "TRAIT_NO_DNA_COPY" = TRAIT_NO_DNA_COPY, "TRAIT_NO_GLIDE" = TRAIT_NO_GLIDE, - //"TRAIT_NO_PLASMA_TRANSFORM" = TRAIT_NO_PLASMA_TRANSFORM, SKYRAT EDIT - TODO - These require transformation sting pr + "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, @@ -215,7 +215,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_UI_BLOCKED" = TRAIT_UI_BLOCKED, "TRAIT_UNDENSE" = TRAIT_UNDENSE, "TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE" = TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE, - //"TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE, SKYRAT EDIT - TODO - These require transformation sting pr + "TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE, "TRAIT_UNINTELLIGIBLE_SPEECH" = TRAIT_UNINTELLIGIBLE_SPEECH, "TRAIT_UNKNOWN" = TRAIT_UNKNOWN, "TRAIT_UNNATURAL_RED_GLOWY_EYES" = TRAIT_UNNATURAL_RED_GLOWY_EYES, @@ -276,8 +276,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( /obj/item/organ/internal/lungs = list( "TRAIT_SPACEBREATHING" = TRAIT_SPACEBREATHING, ), -<<<<<<< HEAD -======= // SKYRAT EDIT ADDITION START - SKYRAT TRAITS /obj/item/toy/plush/skyrat = list( "TRAIT_AFFECTION_AVERSION" = TRAIT_AFFECTION_AVERSION, @@ -349,7 +347,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_XENO_INNATE" = TRAIT_XENO_INNATE, ), // SKYRAT EDIT ADDITION END ->>>>>>> 800ad77ed (Adds Affection Aversion quirk (#25194)) )) /// value -> trait name, generated as needed for adminning. diff --git a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index 486f9411934..7dd453163c5 100644 --- a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -123,12 +123,18 @@ ///Sprite accessories are singletons, stored list("Big Snout" = instance of /datum/sprite_accessory/snout/big), so here we get that singleton /datum/bodypart_overlay/mutant/proc/fetch_sprite_datum(datum/sprite_accessory/accessory_path) - var/list/feature_list = get_global_feature_list() - - return feature_list[initial(accessory_path.name)] + return fetch_sprite_datum_from_name(initial(accessory_path.name)) ///Get the singleton from the sprite name /datum/bodypart_overlay/mutant/proc/fetch_sprite_datum_from_name(accessory_name) var/list/feature_list = get_global_feature_list() - - return feature_list[accessory_name] + var/found = feature_list[accessory_name] + if(found) + return found + + if(!length(feature_list)) + CRASH("External organ [type] returned no sprite datums from get_global_feature_list(), so no accessories could be found!") + else if(accessory_name) + CRASH("External organ [type] couldn't find sprite accessory [accessory_name]!") + else + CRASH("External organ [type] had fetch_sprite_datum called with a null accessory name!") diff --git a/code/datums/components/dart_insert.dm b/code/datums/components/dart_insert.dm new file mode 100644 index 00000000000..19eea67ab3a --- /dev/null +++ b/code/datums/components/dart_insert.dm @@ -0,0 +1,163 @@ +/** + * Component for allowing items to be inserted into foam darts. + * The parent can register signal handlers for `COMSIG_DART_INSERT_ADDED`, + * `COMSIG_DART_INSERT_REMOVED` to define custom behavior for when the item + * is added to/removed from a dart, and `COMSIG_DART_INSERT_GET_VAR_MODIFIERS` + * to define the modifications the item makes to the vars of the fired projectile. + */ +/datum/component/dart_insert + /// List for tracking the modifications this component has made to the vars of the containing projectile + var/list/var_modifiers + /// A reference to the ammo casing this component's parent was inserted into + var/obj/item/ammo_casing/holder_casing + /// A reference to the projectile this component's parent was inserted into + var/obj/projectile/holder_projectile + /// The icon file used for the overlay applied over the containing ammo casing + var/casing_overlay_icon + /// The icon state used for the overlay applied over the containing ammo casing + var/casing_overlay_icon_state + /// The icon file used for the overlay applied over the containing projectile + var/projectile_overlay_icon + /// The icon state used for the overlay applied over the containing projectile + var/projectile_overlay_icon_state + /// Optional callback to invoke when acquiring projectile var modifiers + var/datum/callback/modifier_getter + +/datum/component/dart_insert/Initialize(_casing_overlay_icon, _casing_overlay_icon_state, _projectile_overlay_icon, _projectile_overlay_icon_state, datum/callback/_modifier_getter) + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + casing_overlay_icon = _casing_overlay_icon + casing_overlay_icon_state = _casing_overlay_icon_state + projectile_overlay_icon = _projectile_overlay_icon + projectile_overlay_icon_state = _projectile_overlay_icon_state + modifier_getter = _modifier_getter + +/datum/component/dart_insert/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(on_preattack)) + RegisterSignal(parent, COMSIG_OBJ_RESKIN, PROC_REF(on_reskin)) + +/datum/component/dart_insert/UnregisterFromParent() + . = ..() + var/obj/item/parent_item = parent + var/parent_loc = parent_item.loc + if(parent_loc && (parent_loc == holder_casing || parent_loc == holder_projectile)) + parent_item.forceMove(get_turf(parent_item)) + remove_from_dart(holder_casing, holder_projectile) + UnregisterSignal(parent, COMSIG_ITEM_PRE_ATTACK) + +/datum/component/dart_insert/proc/on_preattack(datum/source, atom/target, mob/user, params) + SIGNAL_HANDLER + var/obj/item/ammo_casing/foam_dart/dart = target + if(!istype(dart)) + return + if(!dart.modified) + to_chat(user, span_warning("The safety cap prevents you from inserting [parent] into [dart].")) + return COMPONENT_CANCEL_ATTACK_CHAIN + if(HAS_TRAIT(dart, TRAIT_DART_HAS_INSERT)) + to_chat(user, span_warning("There's already something in [dart].")) + return COMPONENT_CANCEL_ATTACK_CHAIN + add_to_dart(dart, user) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/datum/component/dart_insert/proc/on_reskin(datum/source, mob/user, skin) + SIGNAL_HANDLER + SEND_SIGNAL(parent, COMSIG_DART_INSERT_PARENT_RESKINNED) + +/datum/component/dart_insert/proc/add_to_dart(obj/item/ammo_casing/dart, mob/user) + var/obj/projectile/dart_projectile = dart.loaded_projectile + var/obj/item/parent_item = parent + if(user) + if(!user.transferItemToLoc(parent_item, dart_projectile)) + return + to_chat(user, span_notice("You insert [parent_item] into [dart].")) + else + parent_item.forceMove(dart_projectile) + ADD_TRAIT(dart, TRAIT_DART_HAS_INSERT, REF(src)) + RegisterSignal(dart, COMSIG_ITEM_ATTACK_SELF, PROC_REF(on_dart_attack_self)) + RegisterSignal(dart, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_dart_examine_more)) + RegisterSignals(parent, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED), PROC_REF(on_leave_dart)) + RegisterSignal(dart, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_casing_update_overlays)) + RegisterSignal(dart_projectile, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_projectile_update_overlays)) + RegisterSignals(dart_projectile, list(COMSIG_PROJECTILE_ON_SPAWN_DROP, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED), PROC_REF(on_spawn_drop)) + apply_var_modifiers(dart_projectile) + dart.harmful = dart_projectile.damage > 0 || dart_projectile.wound_bonus > 0 || dart_projectile.bare_wound_bonus > 0 + SEND_SIGNAL(parent, COMSIG_DART_INSERT_ADDED, dart) + dart.update_appearance() + dart_projectile.update_appearance() + holder_casing = dart + holder_projectile = dart_projectile + +/datum/component/dart_insert/proc/remove_from_dart(obj/item/ammo_casing/dart, obj/projectile/projectile, mob/user) + holder_casing = null + holder_projectile = null + if(istype(dart)) + UnregisterSignal(dart, list(COMSIG_ITEM_ATTACK_SELF, COMSIG_ATOM_EXAMINE_MORE, COMSIG_ATOM_UPDATE_OVERLAYS)) + REMOVE_TRAIT(dart, TRAIT_DART_HAS_INSERT, REF(src)) + dart.update_appearance() + if(istype(projectile)) + remove_var_modifiers(projectile) + UnregisterSignal(projectile, list(COMSIG_PROJECTILE_ON_SPAWN_DROP, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED, COMSIG_ATOM_UPDATE_OVERLAYS)) + if(dart?.loaded_projectile == projectile) + dart.harmful = projectile.damage > 0 || projectile.wound_bonus > 0 || projectile.bare_wound_bonus > 0 + projectile.update_appearance() + SEND_SIGNAL(parent, COMSIG_DART_INSERT_REMOVED, dart, projectile, user) + UnregisterSignal(parent, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED)) + if(user) + INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, put_in_hands), parent) + to_chat(user, span_notice("You remove [parent] from [dart].")) + +/datum/component/dart_insert/proc/on_dart_attack_self(datum/source, mob/user) + SIGNAL_HANDLER + remove_from_dart(holder_casing, holder_projectile, user) + +/datum/component/dart_insert/proc/on_dart_examine_more(datum/source, mob/user, list/examine_list) + var/obj/item/parent_item = parent + examine_list += span_notice("You can see a [parent_item.name] inserted into it.") + +/datum/component/dart_insert/proc/on_leave_dart() + SIGNAL_HANDLER + remove_from_dart(holder_casing, holder_projectile) + +/datum/component/dart_insert/proc/on_spawn_drop(datum/source, obj/item/ammo_casing/new_casing) + SIGNAL_HANDLER + UnregisterSignal(parent, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED)) + add_to_dart(new_casing) + +/datum/component/dart_insert/proc/on_casing_update_overlays(datum/source, list/new_overlays) + SIGNAL_HANDLER + new_overlays += mutable_appearance(casing_overlay_icon, casing_overlay_icon_state) + +/datum/component/dart_insert/proc/on_projectile_update_overlays(datum/source, list/new_overlays) + SIGNAL_HANDLER + new_overlays += mutable_appearance(projectile_overlay_icon, projectile_overlay_icon_state) + +/datum/component/dart_insert/proc/apply_var_modifiers(obj/projectile/projectile) + var_modifiers = istype(modifier_getter) ? modifier_getter.Invoke() : list() + projectile.damage += var_modifiers["damage"] + if(var_modifiers["speed"]) + var_modifiers["speed"] = reciprocal_add(projectile.speed, var_modifiers["speed"]) - projectile.speed + projectile.speed += var_modifiers["speed"] + projectile.armour_penetration += var_modifiers["armour_penetration"] + projectile.wound_bonus += var_modifiers["wound_bonus"] + projectile.bare_wound_bonus += var_modifiers["bare_wound_bonus"] + projectile.demolition_mod += var_modifiers["demolition_mod"] + if(islist(var_modifiers["embedding"])) + var/list/embed_params = var_modifiers["embedding"] + for(var/embed_param in embed_params - "ignore_throwspeed_threshold") + LAZYADDASSOC(projectile.embedding, embed_param, embed_params[embed_param]) + projectile.updateEmbedding() + +/datum/component/dart_insert/proc/remove_var_modifiers(obj/projectile/projectile) + projectile.damage -= var_modifiers["damage"] + projectile.speed -= var_modifiers["speed"] + projectile.armour_penetration -= var_modifiers["armour_penetration"] + projectile.wound_bonus -= var_modifiers["wound_bonus"] + projectile.bare_wound_bonus -= var_modifiers["bare_wound_bonus"] + projectile.demolition_mod -= var_modifiers["demolition_mod"] + if(islist(var_modifiers["embedding"])) + var/list/embed_params = var_modifiers["embedding"] + for(var/embed_param in embed_params - "ignore_throwspeed_threshold") + LAZYADDASSOC(projectile.embedding, embed_param, -embed_params[embed_param]) + projectile.updateEmbedding() + var_modifiers.Cut() diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index f4d7b5d7369..b62121d30d0 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -228,6 +228,7 @@ limb._unembed_object(weapon) UnregisterSignal(weapon, list(COMSIG_MOVABLE_MOVED, COMSIG_QDELETING)) // have to do it here otherwise we trigger weaponDeleted() + SEND_SIGNAL(weapon, COMSIG_ITEM_UNEMBEDDED, victim) if(!weapon.unembedded()) // if it hasn't deleted itself due to drop del UnregisterSignal(weapon, list(COMSIG_MOVABLE_MOVED, COMSIG_QDELETING)) if(to_hands) diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index 1e724f0e404..9986b2a4d43 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -264,6 +264,16 @@ Behavior that's still missing from this component that original food items had t for(var/datum/reagent/reagent as anything in owner.reagents.reagent_list) examine_list += span_notice("- [reagent.name] [reagent.volume]u: [round(reagent.purity * 100)]% pure") + if(!HAS_TRAIT(user, TRAIT_REMOTE_TASTING)) + return + var/fraction = min(bite_consumption / owner.reagents.total_volume, 1) + checkLiked(fraction, user) + if (!owner.reagents.get_reagent_amount(/datum/reagent/consumable/salt)) + examine_list += span_notice("It could use a little more Sodium Chloride...") + if (isliving(user)) + var/mob/living/living_user = user + living_user.taste(owner.reagents) + /datum/component/edible/proc/UseFromHand(obj/item/source, mob/living/M, mob/living/user) SIGNAL_HANDLER diff --git a/code/datums/components/irradiated.dm b/code/datums/components/irradiated.dm index c8a57f3761a..bffd56459bf 100644 --- a/code/datums/components/irradiated.dm +++ b/code/datums/components/irradiated.dm @@ -96,7 +96,7 @@ process_tox_damage(human_parent, seconds_per_tick) /datum/component/irradiated/proc/should_halt_effects(mob/living/carbon/human/target) - if (IS_IN_STASIS(target)) + if (HAS_TRAIT(target, TRAIT_STASIS)) return TRUE if (HAS_TRAIT(target, TRAIT_HALT_RADIATION_EFFECTS)) diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index a5b5606bf72..1148e2b5993 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -96,7 +96,7 @@ to_chat(user, span_warning("You're not ready to tackle!")) return - if(user.has_movespeed_modifier(/datum/movespeed_modifier/shove)) // can't tackle if you just got shoved + if(user.get_timed_status_effect_duration(/datum/status_effect/staggered)) // can't tackle if you're staggered to_chat(user, span_warning("You're too off balance to tackle!")) return @@ -131,12 +131,9 @@ * Check [rollTackle()][/datum/component/tackler/proc/rollTackle] for a more thorough explanation on the modifiers at play. * * Then, we figure out what effect we want, and we get to work! Note that with standard gripper gloves and no modifiers, the range of rolls is (-3, 3). The results are as follows, based on what we rolled: - * * -inf to -5: Seriously botched tackle, tackler suffers a concussion, brute damage, and a 3 second paralyze, target suffers nothing - * * -4 to -2: weak tackle, tackler gets 3 second knockdown, target gets shove slowdown but is otherwise fine - * * -1 to 0: decent tackle, tackler gets up a bit quicker than the target - * * 1: solid tackle, tackler has more of an advantage getting up quicker - * * 2 to 4: expert tackle, tackler has sizeable advantage and lands on their feet with a free passive grab - * * 5 to inf: MONSTER tackle, tackler gets up immediately and gets a free aggressive grab, target takes sizeable stamina damage from the hit and is paralyzed for one and a half seconds and knocked down for three seconds + * * -inf to -1: We have a negative roll result, which means something unfortunate or less than ideal happens to our sacker! Could mean just getting knocked down, but it could also mean they get a concussion. Ouch. + * * 0: We get a relatively neutral result, mildly favouring the tackler. + * * 1 to inf: We get a positive roll result, which means we get a reasonable to significant advantage against the target! * * Finally, we return a bitflag to [COMSIG_MOVABLE_IMPACT] that forces the hitpush to false so that we don't knock them away. */ @@ -155,53 +152,74 @@ return var/mob/living/carbon/target = hit - var/mob/living/carbon/human/T = target - var/mob/living/carbon/human/S = user - var/tackle_word = isfeline(user) ? "pounce" : "tackle" //If cat, "pounce" instead of "tackle". // SKYRAT EDIT - FELINE TRAITS. Was: isfelinid(user) + var/tackle_word = isfeline(user) ? "pounce" : "tackle" //If cat, "pounce" instead of "tackle". // SKYRAT EDIT - FELINE TRAITS - ORIGINAL : var/tackle_word = isfelinid(user) ? "pounce" : "tackle" + + if(target.check_block(user, 0, user.name, attack_type = LEAP_ATTACK)) + user.visible_message(span_danger("[user]'s tackle is blocked by [target], softening the effect!"), span_userdanger("Your tackle is blocked by [target], softening the effect!"), ignored_mobs = target) + to_chat(target, span_userdanger("[target] blocks [user]'s tackle attempt, softening the effect!")) + neutral_outcome(user, target, tackle_word) //Forces a neutral outcome so you're not screwed too much from being blocked while tackling + return var/roll = rollTackle(target) tackling = FALSE tackle.gentle = TRUE switch(roll) - if(-INFINITY to -5) - user.visible_message(span_danger("[user] botches [user.p_their()] [tackle_word] and slams [user.p_their()] head into [target], knocking [user.p_them()]self silly!"), span_userdanger("You botch your [tackle_word] and slam your head into [target], knocking yourself silly!"), ignored_mobs = target) - to_chat(target, span_userdanger("[user] botches [user.p_their()] [tackle_word] and slams [user.p_their()] head into you, knocking [user.p_them()]self silly!")) + if(-INFINITY to -1) + negative_outcome(user, target, roll, tackle_word) //OOF - user.Paralyze(3 SECONDS) - var/obj/item/bodypart/head/hed = user.get_bodypart(BODY_ZONE_HEAD) - if(hed) - hed.receive_damage(brute = 15, updating_health = TRUE, wound_bonus = CANT_WOUND) - user.gain_trauma(/datum/brain_trauma/mild/concussion) + if(0) //nothing good, nothing bad + neutral_outcome(user, target, tackle_word) - if(-4 to -2) // glancing blow at best - user.visible_message(span_warning("[user] lands a weak [tackle_word] on [target], briefly knocking [target.p_them()] off-balance!"), span_userdanger("You land a weak [tackle_word] on [target], briefly knocking [target.p_them()] off-balance!"), ignored_mobs = target) - to_chat(target, span_userdanger("[user] lands a weak [tackle_word] on you, briefly knocking you off-balance!")) + if(1 to INFINITY) + positive_outcome(user, target, roll, tackle_word) - user.Knockdown(30) - if(ishuman(target) && !T.has_movespeed_modifier(/datum/movespeed_modifier/shove)) - T.add_movespeed_modifier(/datum/movespeed_modifier/shove) // maybe define a slightly more severe/longer slowdown for this - addtimer(CALLBACK(T, TYPE_PROC_REF(/mob/living/carbon, clear_shove_slowdown)), SHOVE_SLOWDOWN_LENGTH * 2) + return COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH - if(-1 to 0) // decent hit, both parties are about equally inconvenienced - user.visible_message(span_warning("[user] lands a passable [tackle_word] on [target], sending them both tumbling!"), span_userdanger("You land a passable [tackle_word] on [target], sending you both tumbling!"), ignored_mobs = target) - to_chat(target, span_userdanger("[user] lands a passable [tackle_word] on you, sending you both tumbling!")) +/** + * Our positive tackling outcomes. + * + * We pass our tackle result here to determine the potential outcome of the tackle. Typically, this results in a very poor state for the tackled, and a positive outcome for the tackler. + * + * First, we determine severity by taking our roll result, multiplying it by 10, and then rolling within that value. + * + * If our target is human, their armor will reduce the severity of the roll. We pass along any MELEE armor as a percentage reduction. + * If they're not human (such as a carbon), we give them a small grace of a 10% reduction. + * + * Finally, we figure out what effect our target receives. Note that all positive outcomes inflict staggered, resulting in a much harder time escaping the potential grab: + * * 1 to 20: Our target is briefly stunned and knocked down. suffers 30 stamina damage, and our tackler is also knocked down. + * * 21 to 49: Our target is knocked down, dealt 40 stamina damage, and put into a passive grab. Given they are staggered, this means the target must resist to escape! + * * 50 to inf: Our target is hit with a significant chunk of stamina damage, put into an aggressive grab, and knocked down. They're probably not escaping after this. If our tackler is stamcrit when they land this, so is our target. +*/ - target.adjustStaminaLoss(stamina_cost) - target.Paralyze(0.5 SECONDS) - user.Knockdown(2 SECONDS) - target.Knockdown(2.5 SECONDS) +/datum/component/tackler/proc/positive_outcome(mob/living/carbon/user, mob/living/carbon/target, roll = 1, tackle_word = "tackle") + var/potential_outcome = (roll * 10) - if(1 to 2) // solid hit, tackler has a slight advantage + if(ishuman(target)) + var/mob/living/carbon/human/human_target = target + var/target_armor = human_target.run_armor_check(BODY_ZONE_CHEST, MELEE) + potential_outcome *= ((100 - target_armor) /100) + else + potential_outcome *= 0.9 + + var/mob/living/carbon/human/human_target = target + var/mob/living/carbon/human/human_sacker = user + + switch(potential_outcome) + if(-INFINITY to 0) //I don't want to know how this has happened, okay? + neutral_outcome(user, target, roll, tackle_word) //Default to neutral + + if(1 to 20) user.visible_message(span_warning("[user] lands a solid [tackle_word] on [target], knocking them both down hard!"), span_userdanger("You land a solid [tackle_word] on [target], knocking you both down hard!"), ignored_mobs = target) to_chat(target, span_userdanger("[user] lands a solid [tackle_word] on you, knocking you both down hard!")) - target.adjustStaminaLoss(30) + target.apply_damage(30, STAMINA) target.Paralyze(0.5 SECONDS) user.Knockdown(1 SECONDS) target.Knockdown(2 SECONDS) + target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS) - if(3 to 4) // really good hit, the target is definitely worse off here. Without positive modifiers, this is as good a tackle as you can land + if(21 to 49) // really good hit, the target is definitely worse off here. Without positive modifiers, this is as good a tackle as you can land user.visible_message(span_warning("[user] lands an expert [tackle_word] on [target], knocking [target.p_them()] down hard while landing on [user.p_their()] feet with a passive grip!"), span_userdanger("You land an expert [tackle_word] on [target], knocking [target.p_them()] down hard while landing on your feet with a passive grip!"), ignored_mobs = target) to_chat(target, span_userdanger("[user] lands an expert [tackle_word] on you, knocking you down hard and maintaining a passive grab!")) @@ -209,22 +227,24 @@ user.SetKnockdown(0, ignore_canstun = TRUE) user.get_up(TRUE) user.forceMove(get_turf(target)) - target.adjustStaminaLoss(40) + target.apply_damage(40, STAMINA) target.Paralyze(0.5 SECONDS) target.Knockdown(3 SECONDS) + target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS) if(ishuman(target) && ishuman(user)) - INVOKE_ASYNC(S.dna.species, TYPE_PROC_REF(/datum/species, grab), S, T) - S.setGrabState(GRAB_PASSIVE) + INVOKE_ASYNC(human_sacker.dna.species, TYPE_PROC_REF(/datum/species, grab), human_sacker, human_target) + human_sacker.setGrabState(GRAB_PASSIVE) - if(5 to INFINITY) // absolutely BODIED + if(50 to INFINITY) // absolutely BODIED var/stamcritted_user = HAS_TRAIT_FROM(user, TRAIT_INCAPACITATED, STAMINA) - if(stamcritted_user) // in case the user went into stamcrit from the tackle itself and cannot actually aggro grab (since they will be crit) we make the tackle a bit more effective on the target + if(stamcritted_user) // in case the user went into stamcrit from the tackle itself and cannot actually aggro grab (since they will be crit) we make the tackle effectivelly mutually assured...stamina crit user.visible_message(span_warning("[user] lands a monsterly reckless [tackle_word] on [target], knocking both of them senseless!"), span_userdanger("You land a monsterly reckless [tackle_word] on [target], knocking both of you senseless!"), ignored_mobs = target) to_chat(target, span_userdanger("[user] lands a monsterly reckless [tackle_word] on you, knocking the both of you senseless!")) user.forceMove(get_turf(target)) - target.adjustStaminaLoss(60) + target.apply_damage(100, STAMINA) // CRASHING THIS PLANE WITH NO SURVIVORS target.Paralyze(1 SECONDS) target.Knockdown(5 SECONDS) + target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 3, 10 SECONDS) else user.visible_message(span_warning("[user] lands a monster [tackle_word] on [target], knocking [target.p_them()] senseless and applying an aggressive pin!"), span_userdanger("You land a monster [tackle_word] on [target], knocking [target.p_them()] senseless and applying an aggressive pin!"), ignored_mobs = target) to_chat(target, span_userdanger("[user] lands a monster [tackle_word] on you, knocking you senseless and aggressively pinning you!")) @@ -233,15 +253,90 @@ user.SetKnockdown(0, ignore_canstun = TRUE) user.get_up(TRUE) user.forceMove(get_turf(target)) - target.adjustStaminaLoss(40) + target.apply_damage(60, STAMINA) target.Paralyze(0.5 SECONDS) target.Knockdown(3 SECONDS) + target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 3, 10 SECONDS) if(ishuman(target) && ishuman(user)) - INVOKE_ASYNC(S.dna.species, TYPE_PROC_REF(/datum/species, grab), S, T) - S.setGrabState(GRAB_AGGRESSIVE) + INVOKE_ASYNC(human_sacker.dna.species, TYPE_PROC_REF(/datum/species, grab), human_sacker, human_target) + human_sacker.setGrabState(GRAB_AGGRESSIVE) +/** + * Our neutral tackling outcome. + * + * Our tackler and our target are staggered. The target longer than the tackler. However, the tackler stands up after this outcome. This is maybe less neutral than it appears, but the tackler initiated, so... + * This outcome also occurs when our target has blocked the tackle in some way, preventing situations where someone tackling into a blocker is too severely punished as a result. Hence, this has its own proc. +*/ - return COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH +/datum/component/tackler/proc/neutral_outcome(mob/living/carbon/user, mob/living/carbon/target, roll = 1, tackle_word = "tackle") + + + user.visible_message(span_warning("[user] lands a [tackle_word] on [target], briefly staggering them both!"), span_userdanger("You land a [tackle_word] on [target], briefly staggering [target.p_them()] and yourself!"), ignored_mobs = target) + to_chat(target, span_userdanger("[user] lands a [tackle_word] on you, briefly staggering you both!")) + + user.get_up(TRUE) + user.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 10 SECONDS) + target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS) //okay maybe slightly good for the sacker, it's a mild benefit okay? + +/** + * Our negative tackling outcomes. + * + * We pass our tackle result here to determine the potential outcome of the tackle. Typically, this results in a very poor state for the tackler, and a mostly okay outcome for the tackled. + * + * First, we determine severity by taking our roll result, multiplying it by -10, and then rolling within that value. + * + * If our tackler is human, their armor will reduce the severity of the roll. We pass along any MELEE armor as a percentage reduction. + * If they're not human (such as a carbon), we give them a small grace of a 10% reduction. + * + * Finally, we figure out what effect our target receives and what our tackler receives: + * * 1 to 20: Our tackler is knocked down and become staggered, and our target suffers stamina damage and is knocked staggered. So not all bad, but the target most likely can punish you for this. + * * 21 to 49: Our tackler is knocked down, suffers stamina damage, and is staggered. Ouch. + * * 50 to inf: Our tackler suffers a catastrophic failure, receiving significant stamina damage, a concussion, and is paralyzed for 3 seconds. Oh, and they're staggered for a LONG time. +*/ + +/datum/component/tackler/proc/negative_outcome(mob/living/carbon/user, mob/living/carbon/target, roll = -1, tackle_word = "tackle") + var/potential_roll_outcome = (roll * -10) + + if(ishuman(user)) + var/mob/living/carbon/human/human_sacker = target + var/attacker_armor = human_sacker.run_armor_check(BODY_ZONE_CHEST, MELEE) + potential_roll_outcome *= ((100 - attacker_armor) /100) + else + potential_roll_outcome *= 0.9 + + var/actual_roll = rand(1, potential_roll_outcome) + + switch(actual_roll) + + if(-INFINITY to 0) //I don't want to know how this has happened, okay? + neutral_outcome(user, target, roll, tackle_word) //Default to neutral + + if(1 to 20) // It's not completely terrible! But you are somewhat vulernable for doing it. + user.visible_message(span_warning("[user] lands a weak [tackle_word] on [target], briefly staggering [target.p_them()]!"), span_userdanger("You land a weak [tackle_word] on [target], briefly staggering [target.p_them()]!"), ignored_mobs = target) + to_chat(target, span_userdanger("[user] lands a weak [tackle_word] on you, staggering you!")) + + user.Knockdown(1 SECONDS) + user.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS) + target.apply_damage(20, STAMINA) + target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS) + + if(21 to 49) // oughe + user.visible_message(span_warning("[user] lands a dreadful [tackle_word] on [target], briefly knocking [user.p_them()] to the ground!"), span_userdanger("You land a dreadful [tackle_word] on [target], briefly knocking you to the ground!"), ignored_mobs = target) + to_chat(target, span_userdanger("[user] lands a dreadful [tackle_word] on you, briefly knocking [user.p_them()] to the ground!")) + + user.Knockdown(3 SECONDS) + user.apply_damage(40, STAMINA) + user.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS) + + if(50 to INFINITY) // It has been decided that you will suffer + user.visible_message(span_danger("[user] botches [user.p_their()] [tackle_word] and slams [user.p_their()] head into [target], knocking [user.p_them()]self silly!"), span_userdanger("You botch your [tackle_word] and slam your head into [target], knocking yourself silly!"), ignored_mobs = target) + to_chat(target, span_userdanger("[user] botches [user.p_their()] [tackle_word] and slams [user.p_their()] head into you, knocking [user.p_them()]self silly!")) + + user.Paralyze(3 SECONDS) + user.apply_damage(80, STAMINA) + user.apply_damage(20, BRUTE, BODY_ZONE_HEAD) + user.gain_trauma(/datum/brain_trauma/mild/concussion) + user.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 3, 10 SECONDS) /** * This handles all of the modifiers for the actual carbon-on-carbon tackling, and gets its own proc because of how many there are (with plenty more in mind!) @@ -266,14 +361,21 @@ else if(target_drunkenness > 30) defense_mod -= 1 + //Arms contribute a great deal to potential tackling prowess and defense. Better arms = better bonus + var/obj/item/bodypart/arm/defender_arm = target.get_active_hand() + + if(defender_arm) //the target may not actually have arms + defense_mod += (defender_arm.unarmed_effectiveness/10) + else //sucks to be you if you don't though haha + defense_mod -= 2 + if(HAS_TRAIT(target, TRAIT_CLUMSY)) defense_mod -= 2 if(HAS_TRAIT(target, TRAIT_FAT)) // chonkers are harder to knock over defense_mod += 1 if(HAS_TRAIT(target, TRAIT_GRABWEAKNESS)) defense_mod -= 2 - if(HAS_TRAIT(target, TRAIT_DWARF)) - defense_mod -= 2 + if(HAS_TRAIT(target, TRAIT_GIANT)) defense_mod += 2 if(target.get_organic_health() < 50) @@ -289,15 +391,15 @@ if(ishuman(target)) var/mob/living/carbon/human/tackle_target = target + if(tackle_target.get_mob_height() <= HUMAN_HEIGHT_SHORTEST) //WHO ARE YOU CALLING SHORT? + defense_mod -= 2 + if(isnull(tackle_target.wear_suit) && isnull(tackle_target.w_uniform)) // who honestly puts all of their effort into tackling a naked guy? defense_mod += 2 if(tackle_target.mob_negates_gravity()) defense_mod += 1 if(tackle_target.is_shove_knockdown_blocked()) // riot armor and such defense_mod += 5 - if(tackle_target.is_holding_item_of_type(/obj/item/shield)) - defense_mod += 2 - var/obj/item/organ/external/tail/lizard/el_tail = tackle_target.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) if(HAS_TRAIT(tackle_target, TRAIT_TACKLING_TAILED_DEFENDER) && !el_tail) @@ -308,6 +410,15 @@ // OF-FENSE var/mob/living/carbon/sacker = parent var/sacker_drunkenness = sacker.get_drunk_amount() + + //Arms contribute a great deal to potential tackling prowess and defense. Better arms = better bonus + var/obj/item/bodypart/arm/sacker_arm = sacker.get_active_hand() + + if(sacker_arm) //I have no idea how you would be tackling without hands, but just in case + attack_mod += (sacker_arm.unarmed_effectiveness/10) + else //I don't want to know how you got to this point but if you have, fuck you, good luck tackling without ARMS + attack_mod -= 4 + if(sacker_drunkenness > 60) // you're far too drunk to hold back! attack_mod += 1 else if(sacker_drunkenness > 30) // if you're only a bit drunk though, you're just sloppy @@ -315,10 +426,10 @@ if(HAS_TRAIT(sacker, TRAIT_CLUMSY)) attack_mod -= 2 - if(HAS_TRAIT(sacker, TRAIT_DWARF)) - attack_mod -= 2 if(HAS_TRAIT(sacker, TRAIT_GIANT)) attack_mod += 2 + if(HAS_TRAIT(sacker, TRAIT_NOGUNS)) //Those dedicated to martial combat are particularly skilled tacklers + attack_mod += 2 if(HAS_TRAIT(sacker, TRAIT_TACKLING_WINGED_ATTACKER)) var/obj/item/organ/external/wings/moth/sacker_moth_wing = sacker.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS) @@ -328,16 +439,22 @@ if(sacker_wing) attack_mod += 2 - if(ishuman(target)) - var/mob/living/carbon/human/S = sacker + if(ishuman(sacker)) + var/mob/living/carbon/human/human_sacker = sacker - var/suit_slot = S.get_item_by_slot(ITEM_SLOT_OCLOTHING) - if(suit_slot && (istype(suit_slot,/obj/item/clothing/suit/armor/riot))) // tackling in riot armor is more effective, but tiring + if(human_sacker.get_mob_height() <= HUMAN_HEIGHT_SHORTEST) //JUST YOU WAIT TILL I FIND A CHAIR, BUDDY, THEN YOU'LL BE SORRY + attack_mod -= 2 + + if(human_sacker.mob_mood.sanity_level == SANITY_INSANE) //I've gone COMPLETELY INSANE + attack_mod += 15 + human_sacker.adjustStaminaLoss(100) //AHAHAHAHAHAHAHAHA + + if(human_sacker.is_shove_knockdown_blocked()) // tackling with riot specialized armor, like riot armor, is effective but tiring attack_mod += 2 - sacker.adjustStaminaLoss(20) + human_sacker.adjustStaminaLoss(20) - var/r = rand(-3, 3) - defense_mod + attack_mod + skill_mod - return r + var/randomized_tackle_roll = rand(-3, 3) - defense_mod + attack_mod + skill_mod + return randomized_tackle_roll /** diff --git a/code/datums/components/udder.dm b/code/datums/components/udder.dm index 7a2f7b56b7b..3c8a0297897 100644 --- a/code/datums/components/udder.dm +++ b/code/datums/components/udder.dm @@ -10,11 +10,11 @@ var/datum/callback/on_milk_callback //udder_type and reagent_produced_typepath are typepaths, not reference -/datum/component/udder/Initialize(udder_type = /obj/item/udder, datum/callback/on_milk_callback, datum/callback/on_generate_callback, reagent_produced_typepath = /datum/reagent/consumable/milk) +/datum/component/udder/Initialize(udder_type = /obj/item/udder, datum/callback/on_milk_callback, datum/callback/on_generate_callback, reagent_produced_override) if(!isliving(parent)) //technically is possible to drop this on carbons... but you wouldn't do that to me, would you? return COMPONENT_INCOMPATIBLE udder = new udder_type(null) - udder.add_features(parent, on_generate_callback, reagent_produced_typepath) + udder.add_features(parent, on_generate_callback, reagent_produced_override) src.on_milk_callback = on_milk_callback /datum/component/udder/RegisterWithParent() @@ -67,6 +67,8 @@ var/reagent_produced_typepath = /datum/reagent/consumable/milk ///how much the udder holds var/size = 50 + ///the probability that the udder will produce the reagent (0 - 100) + var/production_probability = 5 ///mob that has the udder component var/mob/living/udder_mob ///optional proc to callback to when the udder generates milk @@ -78,11 +80,12 @@ ///hunger key we set to look for food var/hunger_key = BB_CHECK_HUNGRY -/obj/item/udder/proc/add_features(parent, callback, reagent = /datum/reagent/consumable/milk) +/obj/item/udder/proc/add_features(parent, callback, reagent_override) udder_mob = parent on_generate_callback = callback create_reagents(size, REAGENT_HOLDER_ALIVE) - reagent_produced_typepath = reagent + if(reagent_override) + reagent_produced_typepath = reagent_override initial_conditions() if(isnull(require_consume_type)) return @@ -157,12 +160,13 @@ */ /obj/item/udder/proc/generate() if(!isnull(require_consume_type) && !(locate(require_consume_type) in src)) - return - if(prob(95)) - return + return FALSE + if(!prob(production_probability)) + return FALSE reagents.add_reagent(reagent_produced_typepath, rand(5, 10), added_purity = 1) if(on_generate_callback) on_generate_callback.Invoke(reagents.total_volume, reagents.maximum_volume) + return TRUE /** * Proc called from attacking the component parent with the correct item, moves reagents into the glass basically. diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index 7783465aabd..48ca9506e2e 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -24,7 +24,7 @@ return FALSE //Only species that can be spread by transformation sting can be spread by the retrovirus - if(HAS_TRAIT(affected_mob, TRAIT_NO_TRANSFORMATION_STING) || HAS_TRAIT(affected_mob, TRAIT_NO_DNA_COPY)) + if(HAS_TRAIT(affected_mob, TRAIT_NO_DNA_COPY)) cure() return FALSE diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 2d745cb6290..d27779387ed 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -84,8 +84,9 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) var/blood_type ///The type of mutant race the player is if applicable (i.e. potato-man) var/datum/species/species = new /datum/species/human - ///first value is mutant color - var/list/features = list("FFF") + /// Assoc list of feature keys to their value + /// Note if you set these manually, and do not update [unique_features] afterwards, it will likely be reset. + var/list/features = list("mcolor" = "#FFFFFF") ///Stores the hashed values of the person's non-human features var/unique_features ///Stores the real name of the person who originally got this dna datum. Used primarely for changelings, @@ -135,12 +136,17 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) destination.dna.features = features.Copy() destination.dna.real_name = real_name destination.dna.temporary_mutations = temporary_mutations.Copy() + //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION + destination.dna.mutant_bodyparts = mutant_bodyparts.Copy() + destination.dna.body_markings = body_markings.Copy() + destination.dna.update_body_size() + //SKYRAT EDIT ADDITION END if(transfer_SE) destination.dna.mutation_index = mutation_index destination.dna.default_mutation_genes = default_mutation_genes if(transfer_species) //destination.set_species(species.type, icon_update=0) - ORIGINAL - destination.set_species(species.type, TRUE, null, features.Copy(), mutant_bodyparts.Copy(), body_markings.Copy()) //SKYRAT EDIT CHANGE - CUSTOMIZATION + destination.set_species(species.type, TRUE, FALSE, features.Copy(), mutant_bodyparts.Copy(), body_markings.Copy()) //SKYRAT EDIT CHANGE - CUSTOMIZATION /datum/dna/proc/copy_dna(datum/dna/new_dna) new_dna.unique_enzymes = unique_enzymes @@ -381,7 +387,9 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(DNA_LIZARD_MARKINGS_BLOCK) set_uni_feature_block(blocknumber, construct_block(GLOB.body_markings_list.Find(features["body_markings"]), GLOB.body_markings_list.len)) if(DNA_TAIL_BLOCK) - set_uni_feature_block(blocknumber, construct_block(GLOB.tails_list.Find(features["tail_lizard"]), GLOB.tails_list.len)) + set_uni_feature_block(blocknumber, construct_block(GLOB.tails_list_human.Find(features["tail_cat"]), GLOB.tails_list_human.len)) + if(DNA_LIZARD_TAIL_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.tails_list_lizard.Find(features["tail_lizard"]), GLOB.tails_list_lizard.len)) if(DNA_SNOUT_BLOCK) set_uni_feature_block(blocknumber, construct_block(GLOB.snouts_list.Find(features["snout"]), GLOB.snouts_list.len)) if(DNA_HORNS_BLOCK) @@ -468,25 +476,41 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(message) to_chat(holder, message) -//used to update dna UI, UE, and dna.real_name. +/// Updates the UI, UE, and UF of the DNA according to the features, appearance, name, etc. of the DNA / holder. /datum/dna/proc/update_dna_identity() unique_identity = generate_unique_identity() unique_enzymes = generate_unique_enzymes() unique_features = generate_unique_features() -//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular) -/* -/datum/dna/proc/initialize_dna(newblood_type, skip_index = FALSE) +/** + * Sets up DNA codes and initializes some features. + * + * * newblood_type - Optional, the blood type to set the DNA to + * * create_mutation_blocks - If true, generate_dna_blocks is called, which is used to set up mutation blocks (what a mob can naturally mutate). + * * randomize_features - If true, all entries in the features list will be randomized. + */ +/datum/dna/proc/initialize_dna(newblood_type, create_mutation_blocks = TRUE, randomize_features = TRUE) if(newblood_type) blood_type = newblood_type - unique_enzymes = generate_unique_enzymes() - unique_identity = generate_unique_identity() - if(!skip_index) //I hate this + if(create_mutation_blocks) //I hate this generate_dna_blocks() - features = random_features() - unique_features = generate_unique_features() -*/ -//SKYRAT EDIT REMOVAL END + mutant_bodyparts = species.get_mutant_bodyparts(features, existing_mutant_bodyparts = randomize_features ? list() : mutant_bodyparts) // SKYRAT EDIT ADDITION + if(randomize_features) + /* SKYRAT EDIT REMOVAL - We don't really want this, do we? We get the same effect from get_mutant_bodyparts() on our end, but without mixing up weird species features. + var/static/list/all_species_protoypes + if(isnull(all_species_protoypes)) + all_species_protoypes = list() + for(var/species_path in subtypesof(/datum/species)) + all_species_protoypes += new species_path() + + for(var/datum/species/random_species as anything in all_species_protoypes) + features |= random_species.randomize_features() + SKYRAT EDIT REMOVAL END */ + body_markings = species.get_random_body_markings(features) // SKYRAT EDIT ADDITION + + features["mcolor"] = "#[random_color()]" + + update_dna_identity() /datum/dna/stored //subtype used by brain mob's stored_dna @@ -519,9 +543,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human -//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/code/datums/dna.dm) -/* -/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) +/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE, list/override_features, list/override_mutantparts, list/override_markings) // SKYRAT EDIT CHANGE - ORIGINAL: /mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) if(QDELETED(src)) CRASH("You're trying to change your species post deletion, this is a recipe for madness") if(isnull(mrace)) @@ -547,10 +569,32 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if (old_species.properly_gained) old_species.on_species_loss(src, new_race, pref_load) + // SKYRAT EDIT ADDITION START - BODYPARTS AND FEATURES + // We need to instantiate the list with compatible mutant parts so we don't break things + + if(override_mutantparts && override_mutantparts.len) + for(var/feature in dna.mutant_bodyparts) + override_mutantparts[feature] = dna.mutant_bodyparts[feature] + dna.mutant_bodyparts = override_mutantparts + + if(override_markings && override_markings.len) + for(var/feature in dna.body_markings) + override_markings[feature] = dna.body_markings[feature] + dna.body_markings = override_markings + + if(override_features && override_features.len) + for(var/feature in dna.features) + override_features[feature] = dna.features[feature] + dna.features = override_features + + apply_customizable_dna_features_to_species() + dna.unique_features = dna.generate_unique_features() + + dna.update_body_size() + // SKYRAT EDIT ADDITION END + dna.species.on_species_gain(src, old_species, pref_load) log_mob_tag("TAG: [tag] SPECIES: [key_name(src)] \[[mrace]\]") -*/ -//SKYRAT EDIT REMOVAL END /mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) ..() diff --git a/code/datums/elements/caseless.dm b/code/datums/elements/caseless.dm index a8a1d3df3e4..587a32f2b30 100644 --- a/code/datums/elements/caseless.dm +++ b/code/datums/elements/caseless.dm @@ -13,15 +13,23 @@ if(!isammocasing(target)) return ELEMENT_INCOMPATIBLE src.reusable = reusable + RegisterSignal(target, COMSIG_CASING_READY_PROJECTILE, PROC_REF(on_ready_projectile)) RegisterSignal(target, COMSIG_FIRE_CASING, PROC_REF(on_fired_casing)) -/datum/element/caseless/proc/on_fired_casing(obj/item/ammo_casing/shell, atom/target, mob/living/user, fired_from, randomspread, spread, zone_override, params, distro, obj/projectile/proj) +/datum/element/caseless/proc/on_ready_projectile(obj/item/ammo_casing/shell, atom/target, mob/living/user, quiet, zone_override, atom/fired_from) SIGNAL_HANDLER + var/obj/projectile/proj = shell.loaded_projectile if(isnull(proj)) return if(reusable) + if(!ispath(proj.shrapnel_type)) + proj.shrapnel_type = shell.type + proj.updateEmbedding() proj.AddElement(/datum/element/projectile_drop, shell.type) +/datum/element/caseless/proc/on_fired_casing(obj/item/ammo_casing/shell, atom/target, mob/living/user, fired_from, randomspread, spread, zone_override, params, distro, obj/projectile/proj) + SIGNAL_HANDLER + if(isgun(fired_from)) var/obj/item/gun/shot_from = fired_from if(shot_from.chambered == shell) diff --git a/code/datums/memory/key_memories.dm b/code/datums/memory/key_memories.dm index 5cc581f14c7..d777df72e38 100644 --- a/code/datums/memory/key_memories.dm +++ b/code/datums/memory/key_memories.dm @@ -191,3 +191,25 @@ "[protagonist_name] being implanted by a scientist.", "[protagonist_name] having surgery done on them by a scientist.", ) + +/datum/memory/key/permabrig_crimes + var/crimes + +/datum/memory/key/permabrig_crimes/New( + datum/mind/memorizer_mind, + atom/protagonist, + atom/deuteragonist, + atom/antagonist, + crimes, +) + src.crimes = crimes + return ..() + +/datum/memory/key/permabrig_crimes/get_names() + return list("[protagonist_name]'s crime of \"[crimes]\".") + +/datum/memory/key/permabrig_crimes/get_starts() + return list( + "[protagonist_name] being arrested by security for [crimes].", + "[protagonist_name] committing the crimes of [crimes].", + ) diff --git a/code/datums/mutations/tongue_spike.dm b/code/datums/mutations/tongue_spike.dm index b33b78d7d1b..e6249041250 100644 --- a/code/datums/mutations/tongue_spike.dm +++ b/code/datums/mutations/tongue_spike.dm @@ -73,6 +73,7 @@ unembedded() /obj/item/hardened_spike/embedded(atom/target) + . = ..() if(isbodypart(target)) missed = FALSE @@ -121,6 +122,7 @@ var/embedded_once_alread = FALSE /obj/item/hardened_spike/chem/embedded(mob/living/carbon/human/embedded_mob) + . = ..() if(embedded_once_alread) return embedded_once_alread = TRUE diff --git a/code/datums/mutations/void_magnet.dm b/code/datums/mutations/void_magnet.dm index d6636b0b630..48f04eda636 100644 --- a/code/datums/mutations/void_magnet.dm +++ b/code/datums/mutations/void_magnet.dm @@ -60,7 +60,7 @@ /datum/action/cooldown/spell/void/cursed/proc/on_life(mob/living/source, seconds_per_tick, times_fired) SIGNAL_HANDLER - if(!isliving(source) || IS_IN_STASIS(source) || source.stat == DEAD || HAS_TRAIT(source, TRAIT_NO_TRANSFORM)) + if(!isliving(source) || HAS_TRAIT(source, TRAIT_STASIS) || source.stat == DEAD || HAS_TRAIT(source, TRAIT_NO_TRANSFORM)) return if(!is_valid_target(source)) diff --git a/code/datums/quirks/negative_quirks/allergic.dm b/code/datums/quirks/negative_quirks/allergic.dm index d6a510f62b6..64b4c560bde 100644 --- a/code/datums/quirks/negative_quirks/allergic.dm +++ b/code/datums/quirks/negative_quirks/allergic.dm @@ -48,7 +48,7 @@ if(!iscarbon(quirk_holder)) return - if(IS_IN_STASIS(quirk_holder)) + if(HAS_TRAIT(quirk_holder, TRAIT_STASIS)) return if(quirk_holder.stat == DEAD) diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm index 44f77fc1d76..c0c6578437e 100644 --- a/code/datums/sprite_accessories.dm +++ b/code/datums/sprite_accessories.dm @@ -1783,11 +1783,13 @@ color_src = HAIR_COLOR /datum/sprite_accessory/tails/monkey - name = "Monkey" icon = 'icons/mob/human/species/monkey/monkey_tail.dmi' - icon_state = "monkey" color_src = FALSE +/datum/sprite_accessory/tails/monkey/standard + name = "Monkey" + icon_state = "monkey" + /datum/sprite_accessory/pod_hair icon = 'icons/mob/human/species/podperson_hair.dmi' em_block = TRUE diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index fccb6a5d8f5..2865a230f43 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -278,8 +278,8 @@ . = ..() if(!.) return - owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_NUMBED), TRAIT_STATUS_EFFECT(id))//SKYRAT EDIT START - STASIS APPLIES NUMBING - owner.throw_alert("stasis numbed", /atom/movable/screen/alert/numbed) //SKYRAT EDIT END + owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS, TRAIT_NUMBED), TRAIT_STATUS_EFFECT(id)) // SKYRAT EDIT CHANGE - ORIGINAL: owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS), TRAIT_STATUS_EFFECT(id)) + owner.throw_alert("stasis numbed", /atom/movable/screen/alert/numbed) //SKYRAT EDIT ADDITION - STASIS APPLIES NUMBED owner.add_filter("stasis_status_ripple", 2, list("type" = "ripple", "flags" = WAVE_BOUNDED, "radius" = 0, "size" = 2)) var/filter = owner.get_filter("stasis_status_ripple") animate(filter, radius = 0, time = 0.2 SECONDS, size = 2, easing = JUMP_EASING, loop = -1, flags = ANIMATION_PARALLEL) @@ -294,8 +294,8 @@ owner.Sleeping(15 SECONDS) //SKYRAT EDIT END /datum/status_effect/grouped/stasis/on_remove() - owner.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_NUMBED), TRAIT_STATUS_EFFECT(id)) //SKYRAT EDIT START - STASIS END REMOVES NUMBING - owner.clear_alert("stasis numbed") //SKYRAT EDIT END + owner.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS, TRAIT_NUMBED), TRAIT_STATUS_EFFECT(id)) // SKYRAT EDIT CHANGE - ORIGINAL: owner.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS), TRAIT_STATUS_EFFECT(id)) + owner.clear_alert("stasis numbed") //SKYRAT EDIT ADDITION - STASIS APPLIED NUMBED owner.remove_filter("stasis_status_ripple") update_time_of_death() if(iscarbon(owner)) diff --git a/code/datums/status_effects/debuffs/dna_transformation.dm b/code/datums/status_effects/debuffs/dna_transformation.dm new file mode 100644 index 00000000000..33b6eb1d913 --- /dev/null +++ b/code/datums/status_effects/debuffs/dna_transformation.dm @@ -0,0 +1,91 @@ +/// Transforms a carbon mob into a new DNA for a set amount of time, +/// then turns them back to how they were before transformation. +/datum/status_effect/temporary_transformation + id = "temp_dna_transformation" + tick_interval = -1 + duration = 1 MINUTES // set in on creation, this just needs to be any value to process + alert_type = null + /// A reference to a COPY of the DNA that the mob will be transformed into. + var/datum/dna/new_dna + /// A reference to a COPY of the DNA of the mob prior to transformation. + var/datum/dna/old_dna + +/datum/status_effect/temporary_transformation/Destroy() + . = ..() // parent must be called first, so we clear DNA refs AFTER transforming back... yeah i know + QDEL_NULL(new_dna) + QDEL_NULL(old_dna) + +/datum/status_effect/temporary_transformation/on_creation(mob/living/new_owner, new_duration = 1 MINUTES, datum/dna/dna_to_copy) + src.duration = (new_duration == INFINITY) ? -1 : new_duration + src.new_dna = new() + src.old_dna = new() + dna_to_copy.copy_dna(new_dna) + return ..() + +/datum/status_effect/temporary_transformation/on_apply() + if(!iscarbon(owner)) + return FALSE + + var/mob/living/carbon/transforming = owner + if(!transforming.has_dna()) + return FALSE + + // Save the old DNA + transforming.dna.copy_dna(old_dna) + // Makes them into the new DNA + new_dna.transfer_identity(transforming) + transforming.real_name = new_dna.real_name + transforming.name = transforming.get_visible_name() + transforming.updateappearance(mutcolor_update = TRUE) + transforming.domutcheck() + return TRUE + +/datum/status_effect/temporary_transformation/on_remove() + var/mob/living/carbon/transforming = owner + + if(!QDELING(owner)) // Don't really need to do appearance stuff if we're being deleted + old_dna.transfer_identity(transforming) + transforming.updateappearance(mutcolor_update = TRUE) + transforming.domutcheck() + + transforming.real_name = old_dna.real_name // Name is fine though + transforming.name = transforming.get_visible_name() + +/datum/status_effect/temporary_transformation/trans_sting + /// Tracks the time left on the effect when the owner last died. Used to pause the effect. + var/time_before_pause = -1 + /// Signals which we react to to determine if we should pause the effect. + var/static/list/update_on_signals = list( + COMSIG_MOB_STATCHANGE, + SIGNAL_ADDTRAIT(TRAIT_STASIS), + SIGNAL_REMOVETRAIT(TRAIT_STASIS), + SIGNAL_ADDTRAIT(TRAIT_DEATHCOMA), + SIGNAL_REMOVETRAIT(TRAIT_DEATHCOMA), + ) + +/datum/status_effect/temporary_transformation/trans_sting/on_apply() + . = ..() + if(!.) + return + RegisterSignals(owner, update_on_signals, PROC_REF(pause_effect)) + pause_effect(owner) // for if we sting a dead guy + +/datum/status_effect/temporary_transformation/trans_sting/on_remove() + . = ..() + UnregisterSignal(owner, update_on_signals) + +/datum/status_effect/temporary_transformation/trans_sting/proc/pause_effect(mob/living/source) + SIGNAL_HANDLER + + // Pause if we're dead, appear dead, or in stasis + if(source.stat == DEAD || HAS_TRAIT(source, TRAIT_DEATHCOMA) || HAS_TRAIT(source, TRAIT_STASIS)) + if(duration == -1) + return // Already paused + + time_before_pause = duration - world.time + duration = -1 + + // Resume if we're none of the above and also were paused + else if(time_before_pause != -1) + duration = time_before_pause + world.time + time_before_pause = -1 diff --git a/code/datums/status_effects/debuffs/drowsiness.dm b/code/datums/status_effects/debuffs/drowsiness.dm index ebf1f43796c..cd99e879066 100644 --- a/code/datums/status_effects/debuffs/drowsiness.dm +++ b/code/datums/status_effects/debuffs/drowsiness.dm @@ -29,7 +29,7 @@ /datum/status_effect/drowsiness/tick(seconds_between_ticks) // You do not feel drowsy while unconscious or in stasis - if(owner.stat >= UNCONSCIOUS || IS_IN_STASIS(owner)) + if(owner.stat >= UNCONSCIOUS || HAS_TRAIT(owner, TRAIT_STASIS)) return // Resting helps against drowsiness diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm index e46915922e5..061c008def8 100644 --- a/code/datums/status_effects/debuffs/drunk.dm +++ b/code/datums/status_effects/debuffs/drunk.dm @@ -65,7 +65,7 @@ /datum/status_effect/inebriated/tick(seconds_between_ticks) // Drunk value does not decrease while dead or in stasis - if(owner.stat == DEAD || IS_IN_STASIS(owner)) + if(owner.stat == DEAD || HAS_TRAIT(owner, TRAIT_STASIS)) return // Every tick, the drunk value decrases by diff --git a/code/datums/status_effects/debuffs/staggered.dm b/code/datums/status_effects/debuffs/staggered.dm new file mode 100644 index 00000000000..5723bc16013 --- /dev/null +++ b/code/datums/status_effects/debuffs/staggered.dm @@ -0,0 +1,41 @@ +/datum/status_effect/staggered + id = "staggered" + tick_interval = 0.5 SECONDS + alert_type = null + remove_on_fullheal = TRUE + +/datum/status_effect/staggered/on_creation(mob/living/new_owner, duration = 10 SECONDS) + src.duration = duration + return ..() + +/datum/status_effect/staggered/on_apply() + + //a very mild animation, but you can't stagger the dead. + if(owner.stat == DEAD) + owner.do_stagger_animation(duration / 10) + return FALSE + + RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(clear_staggered)) + owner.add_movespeed_modifier(/datum/movespeed_modifier/staggered) + return TRUE + +/datum/status_effect/staggered/on_remove() + UnregisterSignal(owner, COMSIG_LIVING_DEATH) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/staggered) + // Resetting both X on remove so we're back to normal + owner.pixel_x = owner.base_pixel_x + +/// Signal proc that self deletes our staggered effect +/datum/status_effect/staggered/proc/clear_staggered(datum/source) + SIGNAL_HANDLER + + qdel(src) + +/datum/status_effect/staggered/tick(seconds_between_ticks) + owner.do_stagger_animation() + +/// Helper proc that causes the mob to do a stagger animation. +/// Doesn't change significantly, just meant to represent swaying back and forth +/mob/living/proc/do_stagger_animation() + animate(src, pixel_x = 4, time = 0.2 SECONDS, loop = 6, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL) + animate(pixel_x = -4, time = 0.2 SECONDS, flags = ANIMATION_RELATIVE) diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index 48b14f36cd0..416fe031341 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -526,7 +526,7 @@ monkey_tail.Insert(human_mob, drop_if_replaced = FALSE) var/datum/species/human_species = human_mob.dna?.species if(human_species) - human_species.randomize_features(human_mob) + human_species.randomize_active_features(human_mob) human_species.randomize_active_underwear(human_mob) owner.remove_status_effect(/datum/status_effect/eigenstasium) diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index d4624acbb92..1df5ff689ff 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -75,7 +75,7 @@ /datum/wound/blunt/bone/handle_process(seconds_per_tick, times_fired) . = ..() - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle) diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index 39e91d06fb6..c041c4fd003 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -36,7 +36,7 @@ /datum/wound/burn/flesh/handle_process(seconds_per_tick, times_fired) - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return . = ..() diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm index ec166584632..7304d21365c 100644 --- a/code/datums/wounds/pierce.dm +++ b/code/datums/wounds/pierce.dm @@ -64,7 +64,7 @@ return BLOOD_FLOW_STEADY /datum/wound/pierce/bleed/handle_process(seconds_per_tick, times_fired) - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return set_blood_flow(min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW)) diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index 4475d95f508..d17b59cf80b 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -134,7 +134,7 @@ /datum/wound/slash/flesh/handle_process(seconds_per_tick, times_fired) - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return // in case the victim has the NOBLOOD trait, the wound will simply not clot on it's own diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 9208ea7a9a2..b200e688caa 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1460,12 +1460,6 @@ animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform=rotated_transform, time = 1, easing=BACK_EASING|EASE_IN, flags = ANIMATION_PARALLEL) animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform=initial_transform, time = 2, easing=SINE_EASING, flags = ANIMATION_PARALLEL) -/atom/movable/vv_get_dropdown() - . = ..() - . += "" - . += "" - - /* Language procs * Unless you are doing something very specific, these are the ones you want to use. */ @@ -1630,6 +1624,9 @@ /atom/movable/vv_get_dropdown() . = ..() + VV_DROPDOWN_OPTION("", "---------") + VV_DROPDOWN_OPTION(VV_HK_OBSERVE_FOLLOW, "Observe Follow") + VV_DROPDOWN_OPTION(VV_HK_GET_MOVABLE, "Get Movable") VV_DROPDOWN_OPTION(VV_HK_EDIT_PARTICLES, "Edit Particles") VV_DROPDOWN_OPTION(VV_HK_DEADCHAT_PLAYS, "Start/Stop Deadchat Plays") VV_DROPDOWN_OPTION(VV_HK_ADD_FANTASY_AFFIX, "Add Fantasy Affix") @@ -1640,6 +1637,19 @@ if(!.) return + if(href_list[VV_HK_OBSERVE_FOLLOW]) + if(!check_rights(R_ADMIN)) + return + usr.client?.admin_follow(src) + + if(href_list[VV_HK_GET_MOVABLE]) + if(!check_rights(R_ADMIN)) + return + + if(QDELETED(src)) + return + forceMove(get_turf(usr)) + if(href_list[VV_HK_EDIT_PARTICLES] && check_rights(R_VAREDIT)) var/client/C = usr.client C?.open_particle_editor(src) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 946bdb6d6cb..1a62fa0261b 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -64,11 +64,17 @@ /obj/machinery/autolathe/ui_static_data(mob/user) var/list/data = materials.ui_static_data() - data["designs"] = handle_designs(stored_research.researched_designs) + var/max_available = materials.total_amount() + for(var/datum/material/container_mat as anything in materials.materials) + var/available = materials.materials[container_mat] + if(available) + max_available = max(max_available, available) + + data["designs"] = handle_designs(stored_research.researched_designs, max_available) if(imported_designs.len) - data["designs"] += handle_designs(imported_designs) + data["designs"] += handle_designs(imported_designs, max_available) if(hacked) - data["designs"] += handle_designs(stored_research.hacked_designs) + data["designs"] += handle_designs(stored_research.hacked_designs, max_available) return data @@ -83,7 +89,7 @@ return data -/obj/machinery/autolathe/proc/handle_designs(list/designs) +/obj/machinery/autolathe/proc/handle_designs(list/designs, max_available) var/list/output = list() var/datum/asset/spritesheet/research_designs/spritesheet = get_asset_datum(/datum/asset/spritesheet/research_designs) @@ -108,7 +114,13 @@ else cost[i] = design_cost - max_multiplier = min(max_multiplier, 50, round((istype(mat) ? materials.get_material_amount(i) : 0) / design_cost)) + var/mat_available + if(istype(mat)) //regular mat + mat_available = materials.get_material_amount(mat) + else //category mat means we can make it from any mat, use largest available mat + mat_available = max_available + + max_multiplier = min(max_multiplier, 50, round(mat_available / design_cost)) //create & send ui data var/icon_size = spritesheet.icon_size_id(design.id) @@ -208,6 +220,7 @@ materials.use_materials(materials_used, coeff, multiplier) to_chat(usr, span_notice("You print [multiplier] item(s) from the [src]")) update_static_data_for_all_viewers() + //print item icon_state = "autolathe_n" var/time_per_item = is_stack ? 32 : ((32 * coeff * multiplier) ** 0.8) / multiplier @@ -215,21 +228,26 @@ return TRUE +/obj/machinery/autolathe/crowbar_act(mob/living/user, obj/item/tool) + if(default_deconstruction_crowbar(tool)) + return TOOL_ACT_TOOLTYPE_SUCCESS + +/obj/machinery/autolathe/screwdriver_act_secondary(mob/living/user, obj/item/tool) + if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", tool)) + return TOOL_ACT_TOOLTYPE_SUCCESS + /obj/machinery/autolathe/attackby(obj/item/attacking_item, mob/living/user, params) + if(user.combat_mode) //so we can hit the machine + return ..() + if(busy) balloon_alert(user, "it's busy!") return TRUE - if(default_deconstruction_crowbar(attacking_item)) - return TRUE - if(panel_open && is_wire_tool(attacking_item)) wires.interact(user) return TRUE - if(user.combat_mode) //so we can hit the machine - return ..() - if(machine_stat) return TRUE @@ -258,45 +276,16 @@ balloon_alert(user, "close the panel first!") return FALSE - if(istype(attacking_item, /obj/item/storage/bag/trash)) - for(var/obj/item/content_item in attacking_item.contents) - if(!do_after(user, 0.5 SECONDS, src)) - return FALSE - attackby(content_item, user) - return TRUE - return ..() -/obj/machinery/autolathe/attackby_secondary(obj/item/weapon, mob/living/user, params) - . = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - if(busy) - balloon_alert(user, "it's busy!") - return - - if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", weapon)) - return - - if(machine_stat) - return SECONDARY_ATTACK_CALL_NORMAL - - if(panel_open) - balloon_alert(user, "close the panel first!") - return - - return SECONDARY_ATTACK_CALL_NORMAL - /obj/machinery/autolathe/proc/AfterMaterialInsert(container, obj/item/item_inserted, last_inserted_id, mats_consumed, amount_inserted, atom/context) SIGNAL_HANDLER - if(ispath(item_inserted, /obj/item/stack/ore/bluespace_crystal)) - use_power(SHEET_MATERIAL_AMOUNT / 10) - else if(item_inserted.has_material_type(/datum/material/glass)) - flick("autolathe_r", src)//plays glass insertion animation by default otherwise - else - flick("autolathe_o", src)//plays metal insertion animation + flick("autolathe_[item_inserted.has_material_type(/datum/material/glass) ? "r" : "o"]", src) - use_power(min(active_power_usage * 0.25, amount_inserted / 100)) - update_static_data_for_all_viewers() + use_power(min(active_power_usage * 0.25, amount_inserted / 100)) + + update_static_data_for_all_viewers() /obj/machinery/autolathe/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) . = ..() @@ -311,7 +300,6 @@ /obj/machinery/autolathe/proc/make_items(list/picked_materials, multiplier, is_stack, mob/user, time_per_item) var/atom/our_loc = drop_location() var/atom/drop_loc = get_step(src, drop_direction) - var/client_awarded = FALSE busy = TRUE SStgui.update_uis(src) //so ui immediatly knows its busy @@ -327,12 +315,10 @@ //custom materials for toolboxes if(length(picked_materials)) - new_item.set_custom_materials(picked_materials, 1 / multiplier) //Ensure we get the non multiplied amount - if(!client_awarded) //so we dont award the medal multiple times - for(var/datum/material/mat in picked_materials) - if(!istype(mat, /datum/material/glass) && !istype(mat, /datum/material/iron)) - user.client.give_award(/datum/award/achievement/misc/getting_an_upgrade, user) - client_awarded = TRUE + new_item.set_custom_materials(picked_materials) //Ensure we get the non multiplied amount + for(var/datum/material/mat in picked_materials) + if(!istype(mat, /datum/material/glass) && !istype(mat, /datum/material/iron)) + user.client.give_award(/datum/award/achievement/misc/getting_an_upgrade, user) //no need to call if ontop of us if(drop_direction) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 415dacc9f17..f875617bd40 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -156,4 +156,7 @@ /obj/machinery/recharge_station/proc/process_occupant(seconds_per_tick) if(!occupant) return - SEND_SIGNAL(occupant, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, recharge_speed * seconds_per_tick / 2, repairs, sendmats) + var/main_draw = use_power_from_net(recharge_speed * seconds_per_tick, take_any = TRUE) //Pulls directly from the Powernet to dump into the cell + if(!main_draw) + return + SEND_SIGNAL(occupant, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, main_draw, repairs, sendmats) diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index 8bcdba43d05..b3020c8d749 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -52,7 +52,7 @@ /obj/machinery/stasis/Exited(atom/movable/gone, direction) if(gone == occupant) var/mob/living/L = gone - if(IS_IN_STASIS(L)) + if(HAS_TRAIT(L, TRAIT_STASIS)) thaw_them(L) return ..() @@ -139,9 +139,9 @@ return var/mob/living/L_occupant = occupant if(stasis_running()) - if(!IS_IN_STASIS(L_occupant)) + if(!HAS_TRAIT(L_occupant, TRAIT_STASIS)) chill_out(L_occupant) - else if(IS_IN_STASIS(L_occupant)) + else if(HAS_TRAIT(L_occupant, TRAIT_STASIS)) thaw_them(L_occupant) /obj/machinery/stasis/screwdriver_act(mob/living/user, obj/item/I) diff --git a/code/game/machinery/telecomms/broadcasting.dm b/code/game/machinery/telecomms/broadcasting.dm index 97ecd19e470..e8ecb72393f 100644 --- a/code/game/machinery/telecomms/broadcasting.dm +++ b/code/game/machinery/telecomms/broadcasting.dm @@ -155,7 +155,7 @@ radios += independent_radio for(var/obj/item/radio/called_radio as anything in radios) - called_radio.on_recieve_message() + called_radio.on_recieve_message(data) // From the list of radios, find all mobs who can hear those. var/list/receive = get_hearers_in_radio_ranges(radios) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d592cd0790b..55cdf19f960 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1177,7 +1177,8 @@ return ..() /obj/item/proc/embedded(atom/embedded_target, obj/item/bodypart/part) - return + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_ITEM_EMBEDDED, embedded_target, part) /obj/item/proc/unembedded() if(item_flags & DROPDEL && !QDELETED(src)) @@ -1206,6 +1207,8 @@ ///In case we want to do something special (like self delete) upon failing to embed in something. /obj/item/proc/failedEmbed() + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_ITEM_FAILED_EMBED) if(item_flags & DROPDEL && !QDELETED(src)) qdel(src) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 1bc96c35122..1a356686a74 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -388,7 +388,8 @@ return TRUE return FALSE -/obj/item/radio/proc/on_recieve_message() +/obj/item/radio/proc/on_recieve_message(list/data) + SEND_SIGNAL(src, COMSIG_RADIO_RECEIVE_MESSAGE, data) flick_overlay_view(overlay_speaker_active, 5 SECONDS) /obj/item/radio/ui_state(mob/user) diff --git a/code/game/objects/items/rcd/RCD.dm b/code/game/objects/items/rcd/RCD.dm index 297c8a1eabd..ab97026a6a1 100644 --- a/code/game/objects/items/rcd/RCD.dm +++ b/code/game/objects/items/rcd/RCD.dm @@ -138,14 +138,14 @@ var/list/structures_to_ignore if(istype(target, /obj/structure/grille)) if(is_full_tile) //if we are trying to build full-tile windows we ignore the grille - structures_to_ignore = list(target) - else //no building directional windows on grills - return FALSE + structures_to_ignore = list(/obj/structure/grille) + else //when building directional windows we ignore the grill and other directional windows + structures_to_ignore = list(/obj/structure/grille, /obj/structure/window) else //for directional windows we ignore other directional windows as they can be in diffrent directions on the turf. structures_to_ignore = list(/obj/structure/window) //check if we can build our window on the grill - if(target_turf.is_blocked_turf(exclude_mobs = !is_full_tile, source_atom = null, ignore_atoms = structures_to_ignore, type_list = !is_full_tile)) + if(target_turf.is_blocked_turf(exclude_mobs = !is_full_tile, source_atom = null, ignore_atoms = structures_to_ignore, type_list = TRUE)) playsound(loc, 'sound/machines/click.ogg', 50, TRUE) balloon_alert(user, "something is blocking the turf") return FALSE diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 37c95a418db..b1aff8deff5 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -555,7 +555,7 @@ if(robot.model.model_select_icon == "nomod") to_chat(usr, span_warning("Default models cannot take expand or shrink upgrades.")) return FALSE - if((R_TRAIT_WIDE in robot.model.model_features) || (R_TRAIT_TALL in robot.model.model_features)) + if((TRAIT_R_WIDE in robot.model.model_features) || (TRAIT_R_TALL in robot.model.model_features)) to_chat(usr, span_warning("This unit's chassis cannot be enlarged any further.")) return FALSE // SKYRAT EDIT END @@ -598,7 +598,6 @@ /obj/item/borg/upgrade/rped/action(mob/living/silicon/robot/R, user = usr) . = ..() if(.) - var/obj/item/storage/part_replacer/cyborg/RPED = locate() in R if(RPED) to_chat(user, span_warning("This unit is already equipped with a RPED module!")) @@ -615,6 +614,38 @@ if (RPED) R.model.remove_module(RPED, TRUE) +/obj/item/borg/upgrade/inducer + name = "engineering integrated power inducer" + desc = "An integrated inducer that can charge a device's internal cell from power provided by the cyborg." + require_model = TRUE + model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) + model_flags = BORG_MODEL_ENGINEERING + +/obj/item/borg/upgrade/inducer/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + var/obj/item/inducer/cyborg/inter_inducer = locate() in R + if(inter_inducer) + return FALSE + inter_inducer = new(R.model) + R.model.basic_modules += inter_inducer + R.model.add_module(inter_inducer, FALSE, TRUE) + inter_inducer.cell = R.cell + +/obj/item/borg/upgrade/inducer/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + var/obj/item/inducer/cyborg/inter_inducer = locate() in R.model + if (inter_inducer) + R.model.remove_module(inter_inducer, TRUE) + inter_inducer.cell = null + +/obj/item/inducer/cyborg + name = "Internal inducer" + powertransfer = 1500 + icon = 'icons/obj/tools.dmi' + icon_state = "inducer-engi" + /obj/item/borg/upgrade/pinpointer name = "medical cyborg crew pinpointer" desc = "A crew pinpointer module for the medical cyborg. Permits remote access to the crew monitor." diff --git a/code/game/objects/items/storage/garment.dm b/code/game/objects/items/storage/garment.dm index 9398b675b1b..e9ff2f28ce1 100644 --- a/code/game/objects/items/storage/garment.dm +++ b/code/game/objects/items/storage/garment.dm @@ -82,6 +82,7 @@ new /obj/item/clothing/under/rank/security/head_of_security/grey(src) new /obj/item/clothing/under/rank/security/head_of_security/parade(src) new /obj/item/clothing/under/rank/security/head_of_security/parade/female(src) + new /obj/item/clothing/gloves/tackler/combat(src) new /obj/item/clothing/suit/armor/hos(src) new /obj/item/clothing/suit/armor/hos/hos_formal(src) new /obj/item/clothing/suit/armor/hos/trenchcoat/winter(src) diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index 7a75ba88674..7cb0afc2079 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -28,10 +28,14 @@ /obj/item/seeds, /obj/item/stack/medical, /obj/item/toy/crayon, + /obj/item/clothing/accessory/dogtag, /obj/item/coin, - /obj/item/food/chococoin, + /obj/item/coupon, /obj/item/dice, /obj/item/disk, + /obj/item/flashlight/pen, + /obj/item/folder/biscuit, + /obj/item/food/chococoin, /obj/item/implanter, /obj/item/laser_pointer, /obj/item/lighter, @@ -44,8 +48,11 @@ /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/pill, /obj/item/screwdriver, + /obj/item/seeds, /obj/item/spess_knife, - /obj/item/stamp), + /obj/item/stack/medical, + /obj/item/stamp, + /obj/item/toy/crayon), list(/obj/item/screwdriver/power)) /obj/item/storage/wallet/Exited(atom/movable/gone, direction) diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 558c287e1e5..29dcdbcf702 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -205,11 +205,6 @@ to_chat(user, span_notice("You [amount_per_transfer_from_this == 10 ? "remove" : "affix"] the nozzle. You'll now use [amount_per_transfer_from_this] units per spray.")) //ATMOS FIRE FIGHTING BACKPACK - -#define EXTINGUISHER 0 -#define RESIN_LAUNCHER 1 -#define RESIN_FOAM 2 - /obj/item/watertank/atmos name = "backpack firefighter tank" desc = "A refrigerated and pressurized backpack tank with extinguisher nozzle, intended to fight fires. Swaps between extinguisher, resin launcher and a smaller scale resin foamer." diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 1c34e75c3d1..a7263520ad8 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -292,7 +292,7 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) * Arguments: * * M The mob choosing a reskin option */ -/obj/proc/reskin_obj(mob/M) +/obj/proc/reskin_obj(mob/user) if(!LAZYLEN(unique_reskin)) return @@ -302,14 +302,15 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) items += list("[reskin_option]" = item_image) sort_list(items) - var/pick = show_radial_menu(M, src, items, custom_check = CALLBACK(src, PROC_REF(check_reskin_menu), M), radius = 38, require_near = TRUE) + var/pick = show_radial_menu(user, src, items, custom_check = CALLBACK(src, PROC_REF(check_reskin_menu), user), radius = 38, require_near = TRUE) if(!pick) return if(!unique_reskin[pick]) return current_skin = pick icon_state = unique_reskin[pick] - to_chat(M, "[src] is now skinned as '[pick].'") + to_chat(user, "[src] is now skinned as '[pick].'") + SEND_SIGNAL(src, COMSIG_OBJ_RESKIN, user, pick) /** * Checks if we are allowed to interact with a radial menu for reskins diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index b9c80fd7f6c..ddb588db782 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -380,11 +380,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) new /obj/item/stack/rods(get_turf(loc), 2) qdel(src) - - - /obj/item/chair/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 == UNARMED_ATTACK && prob(hit_reaction_chance)) + if(attack_type == UNARMED_ATTACK && prob(hit_reaction_chance) || attack_type == LEAP_ATTACK && prob(hit_reaction_chance)) owner.visible_message(span_danger("[owner] fends off [attack_text] with [src]!")) return TRUE return FALSE diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index f25c9cfec5d..3a2b54b74f5 100755 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -109,6 +109,7 @@ new /obj/item/radio/headset/headset_sec/alt(src) new /obj/item/clothing/glasses/hud/security/sunglasses(src) new /obj/item/flashlight/seclite(src) + new /obj/item/clothing/gloves/tackler(src) /obj/structure/closet/secure_closet/security/sec diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index bb82c6fb294..73f3972ef83 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -68,7 +68,13 @@ var/cost = 0 var/delay = 0 - if(the_rcd.rcd_design_path == /obj/structure/window/fulltile) + if(the_rcd.rcd_design_path == /obj/structure/window) + cost = 4 + delay = 2 SECONDS + else if(the_rcd.rcd_design_path == /obj/structure/window/reinforced) + cost = 6 + delay = 2.5 SECONDS + else if(the_rcd.rcd_design_path == /obj/structure/window/fulltile) cost = 8 delay = 3 SECONDS else if(the_rcd.rcd_design_path == /obj/structure/window/reinforced/fulltile) @@ -101,8 +107,13 @@ var/obj/structure/window/window_path = rcd_data["[RCD_DESIGN_PATH]"] if(!ispath(window_path)) CRASH("Invalid window path type in RCD: [window_path]") - if(!initial(window_path.fulltile)) //only fulltile windows can be built here - return FALSE + + //checks if its a valid build direction + if(!initial(window_path.fulltile)) + if(!valid_build_direction(loc, user.dir, is_fulltile = FALSE)) + balloon_alert(user, "window already here!") + return FALSE + var/obj/structure/window/WD = new window_path(T, user.dir) WD.set_anchored(TRUE) return TRUE diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 4260e7ba19f..a1676f0d39f 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -26,7 +26,6 @@ var/fulltile = FALSE var/glass_type = /obj/item/stack/sheet/glass var/glass_amount = 1 - var/mutable_appearance/crack_overlay var/real_explosion_block //ignore this, just use explosion_block var/break_sound = SFX_SHATTER var/knock_sound = 'sound/effects/glassknock.ogg' @@ -419,11 +418,9 @@ var/ratio = atom_integrity / max_integrity ratio = CEILING(ratio*4, 1) * 25 - cut_overlay(crack_overlay) if(ratio > 75) return - crack_overlay = mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer+0.1)) - . += crack_overlay + . += mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer+0.1)) /obj/structure/window/should_atmos_process(datum/gas_mixture/air, exposed_temperature) return exposed_temperature > T0C + heat_resistance diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index 3b382069f58..cce5a49e993 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -368,37 +368,40 @@ /turf/open/lava/plasma/do_burn(atom/movable/burn_target, seconds_per_tick = 1) . = TRUE - if(isobj(burn_target)) - return FALSE // Does nothing against objects. Old code. + if(!isliving(burn_target)) + return FALSE var/mob/living/burn_living = burn_target - burn_living.adjustFireLoss(2) - if(QDELETED(burn_living)) - return - burn_living.adjust_fire_stacks(20) //dipping into a stream of plasma would probably make you more flammable than usual - burn_living.adjust_bodytemperature(-rand(50,65)) //its cold, man - if(!ishuman(burn_living) || SPT_PROB(65, seconds_per_tick)) + var/need_mob_update + // This is from plasma, so it should obey plasma biotype requirements + need_mob_update += burn_living.adjustToxLoss(15, updating_health = FALSE, required_biotype = MOB_ORGANIC) + need_mob_update += burn_living.adjustFireLoss(25, updating_health = FALSE) + if(need_mob_update) + burn_living.updatehealth() + + if(QDELETED(burn_living) \ + || !ishuman(burn_living) \ + || HAS_TRAIT(burn_living, TRAIT_NODISMEMBER) \ + || HAS_TRAIT(burn_living, TRAIT_NO_PLASMA_TRANSFORM) \ + || SPT_PROB(65, seconds_per_tick) \ + ) return + var/mob/living/carbon/human/burn_human = burn_living - var/datum/species/burn_species = burn_human.dna.species - if(istype(burn_species, /datum/species/plasmaman) || istype(burn_species, /datum/species/android)) //ignore plasmamen/robotic species - return - var/list/plasma_parts = list()//a list of the organic parts to be turned into plasma limbs - var/list/robo_parts = list()//keep a reference of robotic parts so we know if we can turn them into a plasmaman + var/list/immune_parts = list() // Parts we can't transform because they're not organic or can't be dismembered + var/list/transform_parts = list() // Parts we want to transform + for(var/obj/item/bodypart/burn_limb as anything in burn_human.bodyparts) - if(IS_ORGANIC_LIMB(burn_limb) && burn_limb.limb_id != SPECIES_PLASMAMAN) //getting every organic, non-plasmaman limb (augments/androids are immune to this) - plasma_parts += burn_limb - if(IS_ROBOTIC_LIMB(burn_limb)) - robo_parts += burn_limb + if(!IS_ORGANIC_LIMB(burn_limb) || !burn_limb.can_dismember()) + immune_parts += burn_limb + continue + if(burn_limb.limb_id == SPECIES_PLASMAMAN) + continue + transform_parts += burn_limb - var/need_mob_update - need_mob_update += burn_human.adjustToxLoss(15, updating_health = FALSE, required_biotype = MOB_ORGANIC) // This is from plasma, so it should obey plasma biotype requirements - need_mob_update += burn_human.adjustFireLoss(25, updating_health = FALSE) - if(need_mob_update) - burn_human.updatehealth() - if(plasma_parts.len) - var/obj/item/bodypart/burn_limb = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs + if(length(transform_parts)) + var/obj/item/bodypart/burn_limb = pick_n_take(transform_parts) burn_human.emote("scream") var/obj/item/bodypart/plasmalimb switch(burn_limb.body_zone) //get plasmaman limb to swap in @@ -414,16 +417,20 @@ plasmalimb = new /obj/item/bodypart/chest/plasmaman if(BODY_ZONE_HEAD) plasmalimb = new /obj/item/bodypart/head/plasmaman + burn_human.del_and_replace_bodypart(plasmalimb) burn_human.update_body_parts() burn_human.emote("scream") burn_human.visible_message(span_warning("[burn_human]'s [burn_limb.plaintext_zone] melts down to the bone!"), \ - span_userdanger("You scream out in pain as your [burn_limb.plaintext_zone] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!")) - if(!plasma_parts.len && !robo_parts.len) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman - burn_human.ignite_mob() - burn_human.set_species(/datum/species/plasmaman) - burn_human.visible_message(span_warning("[burn_human] bursts into a brilliant purple flame as [burn_human.p_their()] entire body is that of a skeleton!"), \ - span_userdanger("Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!")) + span_userdanger("You scream out in pain as your [burn_limb.plaintext_zone] melts down to the bone, held together only by strands of purple fungus!")) + + // If all of your limbs are plasma then congrats: you are plasma man + if(length(immune_parts) || length(transform_parts)) + return + burn_human.ignite_mob() + burn_human.set_species(/datum/species/plasmaman) + burn_human.visible_message(span_warning("[burn_human] bursts into flame as the last of [burn_human.p_their()] body is coated in fungus!"), \ + span_userdanger("Your senses numb as what remains of your flesh sloughs off, revealing the plasma-encrusted bone beneath!")) //mafia specific tame happy plasma (normal atmos, no slowdown) /turf/open/lava/plasma/mafia diff --git a/code/game/world.dm b/code/game/world.dm index de638624319..99cffb74ad2 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -190,7 +190,7 @@ GLOBAL_VAR(restart_counter) data["tick_usage"] = world.tick_usage data["tick_lag"] = world.tick_lag data["time"] = world.time - data["timestamp"] = logger.unix_timestamp_string() + data["timestamp"] = rustg_unix_timestamp() return data /world/proc/SetupLogs() diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 36dd0416bde..c23b37e14f1 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -10,36 +10,28 @@ user << browse(create_panel_helper(create_mob_html), "window=create_mob;size=425x475") -/proc/randomize_human(mob/living/carbon/human/human) - if(human.dna.species.sexes) - human.gender = pick(MALE, FEMALE, PLURAL, NEUTER) - else - human.gender = PLURAL +/** + * Randomizes everything about a human, including DNA and name + */ +/proc/randomize_human(mob/living/carbon/human/human, randomize_mutations = FALSE) + human.gender = human.dna.species.sexes ? pick(MALE, FEMALE, PLURAL, NEUTER) : PLURAL human.physique = human.gender human.real_name = human.dna?.species.random_name(human.gender) || random_unique_name(human.gender) - human.name = human.real_name - human.hairstyle = random_hairstyle(human.gender) - human.facial_hairstyle = random_facial_hairstyle(human.gender) - human.hair_color = "#[random_color()]" - human.facial_hair_color = human.hair_color - var/random_eye_color = random_eye_color() - human.eye_color_left = random_eye_color - human.eye_color_right = random_eye_color - human.dna.blood_type = random_blood_type() - human.dna.features["mcolor"] = "#[random_color()]" + human.name = human.get_visible_name() + human.set_hairstyle(random_hairstyle(human.gender), update = FALSE) + human.set_facial_hairstyle(random_facial_hairstyle(human.gender), update = FALSE) + human.set_haircolor("#[random_color()]", update = FALSE) + human.set_facial_haircolor(human.hair_color, update = FALSE) + human.eye_color_left = random_eye_color() + human.eye_color_right = human.eye_color_left + human.skin_tone = random_skin_tone() human.dna.species.randomize_active_underwear_only(human) - /*SKYRAT EDIT OLD - for(var/datum/species/species_path as anything in subtypesof(/datum/species)) - var/datum/species/new_species = new species_path - new_species.randomize_features(human) - SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION*/ - human.dna.species.randomize_features(human) - human.dna.mutant_bodyparts = human.dna.species.get_random_mutant_bodyparts(human.dna.features) - human.dna.body_markings = human.dna.species.get_random_body_markings(human.dna.features) + // Needs to be called towards the end to update all the UIs just set above + human.dna.initialize_dna(newblood_type = random_blood_type(), create_mutation_blocks = randomize_mutations, randomize_features = TRUE) + // SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION human.dna.species.mutant_bodyparts = human.dna.mutant_bodyparts.Copy() human.dna.species.body_markings = human.dna.body_markings.Copy() - //SKYRAT EDIT ADDITION END - human.dna.species.spec_updatehealth(human) - human.dna.update_dna_identity() - human.updateappearance() - human.update_body(is_creating = TRUE) + // SKYRAT EDIT ADDITION END + // Snowflake for Ethereals + human.updatehealth() + human.updateappearance(mutcolor_update = TRUE) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 808117057fd..e909fdfc0ad 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -940,11 +940,13 @@ attempted_fake_scar.fake = TRUE user.regenerate_icons() - + user.name = user.get_visible_name() + current_profile = chosen_profile // SKYRAT EDIT START chosen_dna.transfer_identity(user, TRUE) user.updateappearance(mutcolor_update = TRUE, eyeorgancolor_update = TRUE) user.regenerate_icons() + user.name = user.get_visible_name() current_profile = chosen_profile // SKYRAT EDIT END //THE FLUFFY FRONTIER EDIT ADDITION BEGIN - Blooper diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index eb6ccccd8b5..f8c1bfc5160 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -66,38 +66,61 @@ to_chat(target, span_warning("You feel a tiny prick.")) return 1 -//SKYRAT EDIT REMOVAL BEGIN - CHANGELING_TRANSFORMATION_REMOVAL -/* /datum/action/changeling/sting/transformation name = "Transformation Sting" - desc = "We silently sting a human, injecting a retrovirus that forces them to transform. Costs 50 chemicals." - helptext = "The victim will transform much like a changeling would. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human." + desc = "We silently sting an organism, injecting a retrovirus that forces them to transform." + helptext = "The victim will transform much like a changeling would. \ + For complex humanoids, the transformation is temporarily, but the duration is paused while the victim is dead or in stasis. \ + For more simple humanoids, such as monkeys, the transformation is permanent. \ + Does not provide a warning to others. Mutations will not be transferred." button_icon_state = "sting_transform" - chemical_cost = 50 - dna_cost = 3 - var/datum/changeling_profile/selected_dna = null + chemical_cost = 33 // Low enough that you can sting only two people in quick succession + dna_cost = 2 + /// A reference to our active profile, which we grab DNA from + VAR_FINAL/datum/changeling_profile/selected_dna + /// Duration of the sting + var/sting_duration = 8 MINUTES + +/datum/action/changeling/sting/transformation/Grant(mob/grant_to) + . = ..() + build_all_button_icons(UPDATE_BUTTON_NAME) -/datum/action/changeling/sting/transformation/Trigger(trigger_flags) - var/mob/user = usr +/datum/action/changeling/sting/transformation/update_button_name(atom/movable/screen/movable/action_button/button, force) + . = ..() + button.desc += " Lasts [DisplayTimeText(sting_duration)] for humans, but duration is paused while dead or in stasis." + button.desc += " Costs [chemical_cost] chemicals." + +/datum/action/changeling/sting/transformation/Destroy() + selected_dna = null + return ..() + +/datum/action/changeling/sting/transformation/set_sting(mob/user) + selected_dna = null var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling.chosen_sting) - unset_sting(user) + var/datum/changeling_profile/new_selected_dna = changeling.select_dna() + if(QDELETED(src) || QDELETED(changeling) || QDELETED(user)) return - selected_dna = changeling.select_dna() - if(!selected_dna) - return - if(HAS_TRAIT(user, TRAIT_NO_TRANSFORMATION_STING)) - user.balloon_alert(user, "incompatible DNA!") + if(!new_selected_dna || changeling.chosen_sting || selected_dna) // selected other sting or other DNA while sleeping return + selected_dna = new_selected_dna return ..() /datum/action/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target) . = ..() if(!.) return - if(!iscarbon(target) || HAS_TRAIT(target, TRAIT_HUSK) || HAS_TRAIT(target, TRAIT_NO_TRANSFORMATION_STING)) + // Similar checks here are ran to that of changeling can_absorb_dna - + // Logic being that if their DNA is incompatible with us, it's also bad for transforming + if(!iscarbon(target) \ + || !target.has_dna() \ + || HAS_TRAIT(target, TRAIT_HUSK) \ + || HAS_TRAIT(target, TRAIT_BADDNA) \ + || (HAS_TRAIT(target, TRAIT_NO_DNA_COPY) && !ismonkey(target))) // sure, go ahead, make a monk-clone user.balloon_alert(user, "incompatible DNA!") return FALSE + if(target.has_status_effect(/datum/status_effect/temporary_transformation/trans_sting)) + user.balloon_alert(user, "already transformed!") + return FALSE return TRUE /datum/action/changeling/sting/transformation/sting_action(mob/living/user, mob/living/target) @@ -113,8 +136,6 @@ to_chat(user, final_message) return TRUE return FALSE -*/ -//SKYRAT EDIT REMOVAL END /datum/action/changeling/sting/false_armblade name = "False Armblade Sting" diff --git a/code/modules/antagonists/nightmare/nightmare_species.dm b/code/modules/antagonists/nightmare/nightmare_species.dm index 2db4ca2bb2c..068bb2b6c5c 100644 --- a/code/modules/antagonists/nightmare/nightmare_species.dm +++ b/code/modules/antagonists/nightmare/nightmare_species.dm @@ -20,7 +20,6 @@ TRAIT_NOHUNGER, TRAIT_NOBLOOD, TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, TRAIT_NODISMEMBER, TRAIT_NEVER_WOUNDED, ) diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm index 060f7bfdd8f..d86531b5429 100644 --- a/code/modules/atmospherics/machinery/datum_pipeline.dm +++ b/code/modules/atmospherics/machinery/datum_pipeline.dm @@ -325,11 +325,9 @@ if(gas_visuals[icon_file]) return gas_visuals[icon_file] - var/obj/effect/abstract/new_overlay = new + var/obj/effect/abstract/gas_visual/new_overlay = new new_overlay.icon = icon_file - new_overlay.appearance_flags = RESET_COLOR | KEEP_APART - new_overlay.vis_flags = VIS_INHERIT_ICON_STATE | VIS_INHERIT_LAYER | VIS_INHERIT_PLANE | VIS_INHERIT_ID - new_overlay.color = gasmix_color + new_overlay.ChangeColor(gasmix_color) gas_visuals[icon_file] = new_overlay return new_overlay @@ -337,8 +335,8 @@ /// Called when the gasmix color has changed and the gas visuals need to be updated. /datum/pipeline/proc/UpdateGasVisuals() for(var/icon/source as anything in gas_visuals) - var/obj/effect/abstract/overlay = gas_visuals[source] - animate(overlay, time=5, color=gasmix_color) + var/obj/effect/abstract/gas_visual/overlay = gas_visuals[source] + overlay.ChangeColor(gasmix_color) /// After updating, this proc handles looking at the new gas mixture and blends the colors together according to percentage of the gas mix. /datum/pipeline/proc/CalculateGasmixColor(datum/gas_mixture/source) @@ -370,3 +368,24 @@ if(gasmix_color != current_color) gasmix_color = current_color UpdateGasVisuals() + +/obj/effect/abstract/gas_visual + appearance_flags = RESET_COLOR | KEEP_APART + vis_flags = VIS_INHERIT_ICON_STATE | VIS_INHERIT_LAYER | VIS_INHERIT_PLANE | VIS_INHERIT_ID + var/current_color + var/color_filter + +/obj/effect/abstract/gas_visual/Initialize(mapload) + . = ..() + color_filter = filter(type="color", color=matrix()) + filters += color_filter + color_filter = filters[filters.len] + if(current_color) + animate(color_filter, color=current_color, time=5) + +/obj/effect/abstract/gas_visual/proc/ChangeColor(new_color) + current_color = new_color + if(isnull(color_filter)) + // Called before init + return + animate(color_filter, time=5, color=new_color) diff --git a/code/modules/bitrunning/components/netpod_healing.dm b/code/modules/bitrunning/components/netpod_healing.dm index 8cb363517de..98fdb5ba021 100644 --- a/code/modules/bitrunning/components/netpod_healing.dm +++ b/code/modules/bitrunning/components/netpod_healing.dm @@ -49,6 +49,13 @@ id = "embryonic" alert_type = /atom/movable/screen/alert/status_effect/embryonic +/datum/status_effect/embryonic/on_apply() + ADD_TRAIT(owner, TRAIT_STASIS, TRAIT_STATUS_EFFECT(id)) + return TRUE + +/datum/status_effect/embryonic/on_remove() + REMOVE_TRAIT(owner, TRAIT_STASIS, TRAIT_STATUS_EFFECT(id)) + /atom/movable/screen/alert/status_effect/embryonic name = "Embryonic Stasis" icon_state = "netpod_stasis" diff --git a/code/modules/client/preferences/pixel_size.dm b/code/modules/client/preferences/pixel_size.dm index cb166e0139a..ea375d91e43 100644 --- a/code/modules/client/preferences/pixel_size.dm +++ b/code/modules/client/preferences/pixel_size.dm @@ -4,7 +4,7 @@ savefile_identifier = PREFERENCE_PLAYER minimum = 0 - maximum = 3 + maximum = 5 step = 0.5 diff --git a/code/modules/clothing/gloves/tacklers.dm b/code/modules/clothing/gloves/tacklers.dm index 888ecac39ee..986d8356b1a 100644 --- a/code/modules/clothing/gloves/tacklers.dm +++ b/code/modules/clothing/gloves/tacklers.dm @@ -21,7 +21,7 @@ /// See: [/datum/component/tackler/var/speed] var/tackle_speed = 1 /// See: [/datum/component/tackler/var/skill_mod] - var/skill_mod = 0 + var/skill_mod = 1 /obj/item/clothing/gloves/tackler/Destroy() tackler = null diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 118c28c0e51..e7d87f34bca 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -254,9 +254,7 @@ if(14 to 25) // 1.3ish% chance to stumble and be a bit off balance (like being disarmed) to_chat(our_guy, span_danger("You stumble a bit on your untied shoelaces!")) - if(!our_guy.has_movespeed_modifier(/datum/movespeed_modifier/shove)) - our_guy.add_movespeed_modifier(/datum/movespeed_modifier/shove) - addtimer(CALLBACK(our_guy, TYPE_PROC_REF(/mob/living/carbon, clear_shove_slowdown)), SHOVE_SLOWDOWN_LENGTH) + our_guy.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 10 SECONDS) if(26 to 1000) wiser = FALSE diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index e2af151e49d..ae8b786fbef 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -369,13 +369,14 @@ /obj/item/clothing/suit/armor/swat name = "MK.I SWAT Suit" - desc = "A tactical suit first developed in a joint effort by the defunct IS-ERI and Nanotrasen in 2321 for military operations. It has a minor slowdown, but offers decent protection." + desc = "A tactical suit first developed in a joint effort by the defunct IS-ERI and Nanotrasen in 2321 for military operations. \ + It has a minor slowdown, but offers decent protection and helps the wearer resist shoving in close quarters." icon_state = "heavy" inhand_icon_state = "swat_suit" armor_type = /datum/armor/armor_swat strip_delay = 120 resistance_flags = FIRE_PROOF | ACID_PROOF - clothing_flags = THICKMATERIAL + clothing_flags = BLOCKS_SHOVE_KNOCKDOWN | THICKMATERIAL cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT_OFF heat_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS diff --git a/code/modules/jobs/job_types/prisoner.dm b/code/modules/jobs/job_types/prisoner.dm index 33369d44ce4..cf4c9f65910 100644 --- a/code/modules/jobs/job_types/prisoner.dm +++ b/code/modules/jobs/job_types/prisoner.dm @@ -45,6 +45,7 @@ var/datum/crime/past_crime = new(crime.name, crime.desc, "Central Command", "Indefinite.") target_record.crimes += past_crime to_chat(crewmember, span_warning("You are imprisoned for \"[crime_name]\".")) + crewmember.add_mob_memory(/datum/memory/key/permabrig_crimes, crimes = crime_name) /datum/outfit/job/prisoner name = "Prisoner" @@ -69,7 +70,6 @@ if(!crime_name) return var/datum/prisoner_crime/crime = GLOB.prisoner_crimes[crime_name] - var/list/limbs_to_tat = new_prisoner.bodyparts.Copy() for(var/i in 1 to crime.tattoos) if(!length(SSpersistence.prison_tattoos_to_use) || visualsOnly) diff --git a/code/modules/library/skill_learning/skill_station.dm b/code/modules/library/skill_learning/skill_station.dm index d7fb5b7ff8e..697b34d742e 100644 --- a/code/modules/library/skill_learning/skill_station.dm +++ b/code/modules/library/skill_learning/skill_station.dm @@ -9,7 +9,8 @@ icon_state = "implantchair" occupant_typecache = list(/mob/living/carbon) //todo make occupant_typecache per type state_open = TRUE - interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND //Don't call ui_interac by default - we only want that when inside + // Only opens UI when inside; also, you can use the machine while lying down (for paraplegics and the like) + interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_IGNORE_MOBILITY circuit = /obj/item/circuitboard/machine/skill_station /// Currently implanting/removing var/working = FALSE diff --git a/code/modules/library/skill_learning/skillchip.dm b/code/modules/library/skill_learning/skillchip.dm index 762e8e0162c..89822976993 100644 --- a/code/modules/library/skill_learning/skillchip.dm +++ b/code/modules/library/skill_learning/skillchip.dm @@ -498,4 +498,13 @@ activate_message = span_notice("You feel the knowledge and passion of several sunbaked, seasoned fishermen burn within you.") deactivate_message = span_notice("You no longer feel like casting a fishing rod by the sunny riverside.") +/obj/item/skillchip/intj + name = "Integrated Intuitive Thinking and Judging skillchip" + auto_traits = list(TRAIT_REMOTE_TASTING) + skill_name = "Mental Flavour Calculus" + skill_description = "When examining food, you can experience the flavours just as well as if you were eating it." + skill_icon = FA_ICON_DRUMSTICK_BITE + activate_message = span_notice("You think of your favourite food and realise that you can rotate its flavour in your mind.") + deactivate_message = span_notice("You feel your food-based mind palace crumbling...") + #undef SKILLCHIP_CATEGORY_GENERAL diff --git a/code/modules/logging/log_holder.dm b/code/modules/logging/log_holder.dm index 7d8386e77b6..1cea0e554be 100644 --- a/code/modules/logging/log_holder.dm +++ b/code/modules/logging/log_holder.dm @@ -107,7 +107,7 @@ GENERAL_PROTECT_DATUM(/datum/log_holder) return switch(action) - if("re-render") + if("refresh") cache_ui_data() SStgui.update_uis(src) return TRUE @@ -121,7 +121,7 @@ GENERAL_PROTECT_DATUM(/datum/log_holder) CRASH("Attempted to call init_logging twice!") round_id = GLOB.round_id - logging_start_timestamp = unix_timestamp_string() + logging_start_timestamp = rustg_unix_timestamp() log_categories = list() disabled_categories = list() @@ -243,13 +243,10 @@ GENERAL_PROTECT_DATUM(/datum/log_holder) if(human_readable_enabled) rustg_file_write("\[[human_readable_timestamp()]\] Starting up round ID [round_id].\n - -------------------------\n", category_instance.get_output_file(null, "log")) -/datum/log_holder/proc/unix_timestamp_string() // pending change to rust-g - return RUSTG_CALL(RUST_G, "unix_timestamp")() - /datum/log_holder/proc/human_readable_timestamp(precision = 3) var/start = time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss") // now we grab the millis from the rustg timestamp - var/rustg_stamp = unix_timestamp_string() + var/rustg_stamp = rustg_unix_timestamp() var/list/timestamp = splittext(rustg_stamp, ".") #ifdef UNIT_TESTS if(length(timestamp) != 2) diff --git a/code/modules/mafia/controller_ui.dm b/code/modules/mafia/controller_ui.dm index cc901392d22..578555d21f4 100644 --- a/code/modules/mafia/controller_ui.dm +++ b/code/modules/mafia/controller_ui.dm @@ -29,6 +29,8 @@ if(turn) data["turn"] = " - Day [turn]" + if(phase == MAFIA_PHASE_JUDGEMENT) + data["person_voted_up_ref"] = REF(on_trial) if(phase == MAFIA_PHASE_SETUP) data["lobbydata"] = list() for(var/key in GLOB.mafia_signup + GLOB.mafia_bad_signup + GLOB.pda_mafia_signup) @@ -41,8 +43,10 @@ data["timeleft"] = next_phase_timer ? timeleft(next_phase_timer) : 0 var/datum/mafia_role/user_role = get_role_player(user) + if(user_role) data["user_notes"] = user_role.written_notes + data["player_voted_up"] = (user_role == on_trial) var/list/ui_messages = list() for(var/i = user_role.role_messages.len to 1 step -1) ui_messages.Add(list(list( @@ -56,6 +60,9 @@ player_info["name"] = role.body.real_name player_info["ref"] = REF(role) player_info["alive"] = role.game_status == MAFIA_ALIVE + player_info["role_revealed"] = FALSE + if(role.role_flags & ROLE_REVEALED) + player_info["role_revealed"] = role.name player_info["possible_actions"] = list() if(user_role) //not observer diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm index 359c3edf4ea..6494f4252e5 100644 --- a/code/modules/mapping/mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers.dm @@ -917,7 +917,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) if(new_human_species) new_human.set_species(new_human_species) new_human_species = new_human.dna.species - new_human_species.randomize_features(new_human) new_human.fully_replace_character_name(new_human.real_name, new_human_species.random_name(new_human.gender, TRUE, TRUE)) else stack_trace("failed to spawn cadaver with species ID [species_to_pick]") //if it's invalid they'll just be a human, so no need to worry too much aside from yelling at the server owner lol. diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm index 797426058a1..91edf40615c 100644 --- a/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm +++ b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm @@ -95,5 +95,9 @@ icon_living = "snowlegion_head" icon_dead = "snowlegion_head" +/mob/living/basic/legion_brood/snow/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_SNOWSTORM_IMMUNE, INNATE_TRAIT) + /mob/living/basic/legion_brood/snow/get_legion_type(mob/living/target) return /mob/living/basic/mining/legion/snow diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm index ef6d846970d..64facb5cfa3 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm @@ -33,7 +33,6 @@ /mob/living/basic/mining/lobstrosity/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_SNOWSTORM_IMMUNE, INNATE_TRAIT) AddElement(/datum/element/mob_grabber) AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) AddElement(/datum/element/basic_eating, food_types = target_foods) diff --git a/code/modules/mob/living/basic/lavaland/mining.dm b/code/modules/mob/living/basic/lavaland/mining.dm index 0b6c4f321b6..3bcdd1ceaa6 100644 --- a/code/modules/mob/living/basic/lavaland/mining.dm +++ b/code/modules/mob/living/basic/lavaland/mining.dm @@ -22,7 +22,7 @@ /mob/living/basic/mining/Initialize(mapload) . = ..() - add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE), INNATE_TRAIT) + add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE), INNATE_TRAIT) AddElement(/datum/element/mob_killed_tally, "mobs_killed_mining") var/static/list/vulnerable_projectiles if(!vulnerable_projectiles) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 9d54d95516d..8f29a7d2be7 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -433,6 +433,7 @@ desc = "A piece of juicy meat found in an ayy lmao's head." icon_state = "brain-x" brain_size = 1.3 + organ_traits = list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP, TRAIT_LITERATE, TRAIT_REMOTE_TASTING) ////////////////////////////////////TRAUMAS//////////////////////////////////////// diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 2e2674e14e7..147079ae720 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -3,7 +3,7 @@ /mob/living/carbon/alien/larva/Life(seconds_per_tick = SSMOBS_DT, times_fired) if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) return - if(!..() || IS_IN_STASIS(src) || (amount_grown >= max_grown)) + if(!..() || HAS_TRAIT(src, TRAIT_STASIS) || (amount_grown >= max_grown)) return // We're dead, in stasis, or already grown. // GROW! amount_grown = min(amount_grown + (0.5 * seconds_per_tick), max_grown) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 6a34c7fd005..5d8d6dd425c 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1063,7 +1063,6 @@ /mob/living/carbon/vv_get_dropdown() . = ..() VV_DROPDOWN_OPTION("", "---------") - VV_DROPDOWN_OPTION(VV_HK_MAKE_AI, "Make AI") VV_DROPDOWN_OPTION(VV_HK_MODIFY_BODYPART, "Modify bodypart") VV_DROPDOWN_OPTION(VV_HK_MODIFY_ORGANS, "Modify organs") VV_DROPDOWN_OPTION(VV_HK_MARTIAL_ART, "Give Martial Arts") @@ -1121,12 +1120,6 @@ to_chat(usr, "Failed to replace bodypart! They might be incompatible.") admin_ticket_log("[key_name_admin(usr)] has attempted to modify the bodyparts of [src]") - if(href_list[VV_HK_MAKE_AI]) - if(!check_rights(R_SPAWN)) - return - if(tgui_alert(usr,"Confirm mob type change?",,list("Transform","Cancel")) != "Transform") - return - usr.client.holder.Topic("vv_override", list("makeai"=href_list[VV_HK_TARGET])) if(href_list[VV_HK_MODIFY_ORGANS]) if(!check_rights(NONE)) return diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 2032eb511ff..0eb3945af8c 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -383,21 +383,14 @@ if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types)) //It's too expensive we'll get caught target_held_item = null - if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove)) - target.add_movespeed_modifier(/datum/movespeed_modifier/shove) - target.emote("sway") - if(target_held_item) - append_message = "loosening [target.p_their()] grip on [target_held_item]" - target.visible_message(span_danger("[target.name]'s grip on \the [target_held_item] loosens!"), //He's already out what are you doing - span_warning("Your grip on \the [target_held_item] loosens!"), null, COMBAT_MESSAGE_RANGE) - addtimer(CALLBACK(target, TYPE_PROC_REF(/mob/living/carbon, clear_shove_slowdown)), SHOVE_SLOWDOWN_LENGTH) - - else if(target_held_item) + if(target_held_item && target.get_timed_status_effect_duration(/datum/status_effect/staggered)) target.dropItemToGround(target_held_item) append_message = "causing [target.p_them()] to drop [target_held_item]" target.visible_message(span_danger("[target.name] drops \the [target_held_item]!"), span_warning("You drop \the [target_held_item]!"), null, COMBAT_MESSAGE_RANGE) + target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 10 SECONDS) + log_combat(src, target, "shoved", append_message) /mob/living/carbon/proc/is_shove_knockdown_blocked() //If you want to add more things that block shove knockdown, extend this @@ -406,12 +399,6 @@ return TRUE return FALSE -/mob/living/carbon/proc/clear_shove_slowdown() - remove_movespeed_modifier(/datum/movespeed_modifier/shove) - var/active_item = get_active_held_item() - if(is_type_in_typecache(active_item, GLOB.shove_disarming_types)) - visible_message(span_warning("[name] regains their grip on \the [active_item]!"), span_warning("You regain your grip on \the [active_item]"), null, COMBAT_MESSAGE_RANGE) - /mob/living/carbon/blob_act(obj/structure/blob/B) if (stat == DEAD) return diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index b847b7a73da..a5a41ef0b1f 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -858,19 +858,30 @@ GLOBAL_LIST_EMPTY(features_by_species) randomize_active_underwear_only(human_mob) human_mob.update_body() -///Proc that will randomize all the external organs (i.e. horns, frills, tails etc.) of a species' associated mob -/datum/species/proc/randomize_external_organs(mob/living/carbon/human/human_mob) +/datum/species/proc/randomize_active_features(mob/living/carbon/human/human_mob) + var/list/new_features = randomize_features() + for(var/feature_key in new_features) + human_mob.dna.features[feature_key] = new_features[feature_key] + human_mob.updateappearance(mutcolor_update = TRUE) + +/** + * Returns a list of features, randomized, to be used by DNA + */ +/datum/species/proc/randomize_features() + SHOULD_CALL_PARENT(TRUE) + + var/list/new_features = list() + var/static/list/organs_to_randomize = list() for(var/obj/item/organ/external/organ_path as anything in external_organs) - var/obj/item/organ/external/randomized_organ = human_mob.get_organ_by_type(organ_path) - if(randomized_organ) - var/datum/bodypart_overlay/mutant/overlay = randomized_organ.bodypart_overlay - var/new_look = pick(overlay.get_global_feature_list()) - human_mob.dna.features["[overlay.feature_key]"] = new_look - mutant_bodyparts["[overlay.feature_key]"] = new_look - -///Proc that randomizes all the appearance elements (external organs, markings, hair etc.) of a species' associated mob. Function set by child procs -/datum/species/proc/randomize_features(mob/living/carbon/human/human_mob) - return + var/overlay_path = initial(organ_path.bodypart_overlay) + var/datum/bodypart_overlay/mutant/sample_overlay = organs_to_randomize[overlay_path] + if(isnull(sample_overlay)) + sample_overlay = new overlay_path() + organs_to_randomize[overlay_path] = sample_overlay + + new_features["[sample_overlay.feature_key]"] = pick(sample_overlay.get_global_feature_list()) + + return new_features /datum/species/proc/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) SHOULD_CALL_PARENT(TRUE) @@ -1057,7 +1068,7 @@ GLOBAL_LIST_EMPTY(features_by_species) affected.blood_volume = min(affected.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM) affected.reagents.del_reagent(chem.type) return COMSIG_MOB_STOP_REAGENT_CHECK - if(!chem.overdosed && chem.overdose_threshold && chem.volume >= chem.overdose_threshold) + if(!chem.overdosed && chem.overdose_threshold && chem.volume >= chem.overdose_threshold && !HAS_TRAIT(affected, TRAIT_OVERDOSEIMMUNE)) chem.overdosed = TRUE chem.overdose_start(affected) affected.log_message("has started overdosing on [chem.name] at [chem.volume] units.", LOG_GAME) @@ -1119,9 +1130,6 @@ GLOBAL_LIST_EMPTY(features_by_species) // ATTACK PROCS // ////////////////// -/datum/species/proc/spec_updatehealth(mob/living/carbon/human/H) - return - /datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(SEND_SIGNAL(target, COMSIG_CARBON_PRE_HELP, user, attacker_style) & COMPONENT_BLOCK_HELP_ACT) return TRUE @@ -1167,14 +1175,14 @@ GLOBAL_LIST_EMPTY(features_by_species) return FALSE user.do_attack_animation(target, atk_effect) - //has our target been shoved recently? If so, they're off-balance and we get an easy hit. - var/off_balance = FALSE + //has our target been shoved recently? If so, they're staggered and we get an easy hit. + var/staggered = FALSE //Someone in a grapple is much more vulnerable to being harmed by punches. var/grappled = FALSE - if(target.has_movespeed_modifier(/datum/movespeed_modifier/shove)) - off_balance = TRUE + if(target.get_timed_status_effect_duration(/datum/status_effect/staggered)) + staggered = TRUE if(target.pulledby && target.pulledby.grab_state >= GRAB_AGGRESSIVE) grappled = TRUE @@ -1186,7 +1194,7 @@ GLOBAL_LIST_EMPTY(features_by_species) var/miss_chance = 100//calculate the odds that a punch misses entirely. considers stamina and brute damage of the puncher. punches miss by default to prevent weird cases if(attacking_bodypart.unarmed_damage_low) - if((target.body_position == LYING_DOWN) || HAS_TRAIT(user, TRAIT_PERFECT_ATTACKER) || off_balance) //kicks and attacks against off-balance targets never miss (provided your species deals more than 0 damage) + if((target.body_position == LYING_DOWN) || HAS_TRAIT(user, TRAIT_PERFECT_ATTACKER) || staggered) //kicks and attacks against staggered targets never miss (provided your species deals more than 0 damage) miss_chance = 0 else miss_chance = clamp(UNARMED_MISS_CHANCE_BASE - limb_accuracy + user.getStaminaLoss() + (user.getBruteLoss()*0.5), 0, UNARMED_MISS_CHANCE_MAX) //Limb miss chance + various damage. capped at 80 so there is at least a chance to land a hit. @@ -1221,16 +1229,16 @@ GLOBAL_LIST_EMPTY(features_by_species) target.force_say() log_combat(user, target, grappled ? "grapple punched" : "kicked") target.apply_damage(damage, attack_type, affecting, armor_block - limb_accuracy, attack_direction = attack_direction) - target.apply_damage(damage * PUNCH_STAMINA_MULTIPLIER, STAMINA, affecting, armor_block - limb_accuracy) // SKYRAT EDIT CHANGE - ORIGINAL : target.apply_damage(damage * 1.5, STAMINA, affecting, armor_block - limb_accuracy) + target.apply_damage(damage*1.5, STAMINA, affecting, armor_block - limb_accuracy) else // Normal attacks do not gain the benefit of armor penetration. target.apply_damage(damage, attack_type, affecting, armor_block, attack_direction = attack_direction, sharpness = unarmed_sharpness) //SKYRAT EDIT - Applies sharpness if it does - ORIGINAL: target.apply_damage(damage, attack_type, affecting, armor_block, attack_direction = attack_direction) - target.apply_damage(damage * PUNCH_STAMINA_MULTIPLIER, STAMINA, affecting, armor_block) //SKYRAT EDIT CHANGE: target.apply_damage(damage*1.5, STAMINA, affecting, armor_block) + target.apply_damage(damage*1.5, STAMINA, affecting, armor_block) if(damage >= 9) target.force_say() log_combat(user, target, "punched") - //If we rolled a punch high enough to hit our stun threshold, or our target is off-balance and they have at least 40 damage+stamina loss, we knock them down - if((target.stat != DEAD) && prob(limb_accuracy) || (target.stat != DEAD) && off_balance && (target.getStaminaLoss() + user.getBruteLoss()) >= 40) + //If we rolled a punch high enough to hit our stun threshold, or our target is staggered and they have at least 40 damage+stamina loss, we knock them down + if((target.stat != DEAD) && prob(limb_accuracy) || (target.stat != DEAD) && staggered && (target.getStaminaLoss() + user.getBruteLoss()) >= 40) target.visible_message(span_danger("[user] knocks [target] down!"), \ span_userdanger("You're knocked down by [user]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, user) to_chat(user, span_danger("You knock [target] down!")) @@ -1307,7 +1315,7 @@ GLOBAL_LIST_EMPTY(features_by_species) return //Only stabilise core temp when alive and not in statis - if(humi.stat < DEAD && !IS_IN_STASIS(humi)) + if(humi.stat < DEAD && !HAS_TRAIT(humi, TRAIT_STASIS)) body_temperature_core(humi, seconds_per_tick, times_fired) //These do run in statis @@ -1315,7 +1323,7 @@ GLOBAL_LIST_EMPTY(features_by_species) body_temperature_alerts(humi, seconds_per_tick, times_fired) //Do not cause more damage in statis - if(!IS_IN_STASIS(humi)) + if(!HAS_TRAIT(humi, TRAIT_STASIS)) body_temperature_damage(humi, seconds_per_tick, times_fired) /** diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 3c29bf93847..44fe6d1a1c0 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -75,9 +75,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) cut_overlays(TRUE) /mob/living/carbon/human/dummy/setup_human_dna() - create_dna() - randomize_human(src) - dna.initialize_dna(skip_index = TRUE) //Skip stuff that requires full round init. + randomize_human(src, randomize_mutations = FALSE) /mob/living/carbon/human/dummy/log_mob_tag(text) return @@ -89,7 +87,6 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) return consistent_entry /proc/create_consistent_human_dna(mob/living/carbon/human/target) - target.dna.initialize_dna(skip_index = TRUE) /* SKYRAT EDIT START - Customization - ORIGINAL: target.dna.features["mcolor"] = COLOR_VIBRANT_LIME target.dna.features["ethcolor"] = COLOR_WHITE @@ -109,6 +106,17 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) target.dna.features["mcolor"] = COLOR_VIBRANT_LIME target.dna.features["ethcolor"] = COLOR_WHITE // SKYRAT EDIT END + target.dna.initialize_dna(create_mutation_blocks = FALSE, randomize_features = FALSE) + // UF and UI are nondeterministic, even though the features are the same some blocks will randomize slightly + // In practice this doesn't matter, but this is for the sake of 100%(ish) consistency + var/static/consistent_UF + var/static/consistent_UI + if(isnull(consistent_UF) || isnull(consistent_UI)) + consistent_UF = target.dna.unique_features + consistent_UI = target.dna.unique_identity + else + target.dna.unique_features = consistent_UF + target.dna.unique_identity = consistent_UI /// Provides a dummy that is consistently bald, white, naked, etc. /mob/living/carbon/human/dummy/consistent @@ -122,11 +130,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) /mob/living/carbon/human/consistent/setup_human_dna() create_consistent_human_dna(src) - -/mob/living/carbon/human/consistent/update_body(is_creating) - ..() - if(is_creating) - fully_replace_character_name(real_name, "John Doe") + fully_replace_character_name(real_name, "John Doe") /mob/living/carbon/human/consistent/domutcheck() return // We skipped adding any mutations so this runtimes diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index b7b6456b775..94c7143060c 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -487,7 +487,7 @@ //SKYRAT EDIT ADDITION END //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION - for(var/genital in possible_genitals) + for(var/genital in GLOB.possible_genitals) if(dna.species.mutant_bodyparts[genital]) var/datum/sprite_accessory/genital/G = GLOB.sprite_accessories[genital][dna.species.mutant_bodyparts[genital][MUTANT_INDEX_NAME]] if(G) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0905a4ac40f..be84d857ed6 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -54,9 +54,7 @@ ADD_TRAIT(src, TRAIT_AGEUSIA, NO_TONGUE_TRAIT) /mob/living/carbon/human/proc/setup_human_dna() - //initialize dna. for spawned humans; overwritten by other code - randomize_human(src) - dna.initialize_dna() + randomize_human(src, randomize_mutations = TRUE) /mob/living/carbon/human/Destroy() QDEL_NULL(physiology) @@ -1001,7 +999,6 @@ /mob/living/carbon/human/updatehealth() . = ..() - dna?.species.spec_updatehealth(src) if(HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN)) remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown) remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index aed1beafd16..602ab7d24c1 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -181,7 +181,7 @@ gloves = equipping //SKYRAT EDIT ADDITION - ERP UPDATE if(gloves.breakouttime) - ADD_TRAIT(src, TRAIT_RESTRAINED, GLOVES_TRAIT) + ADD_TRAIT(src, TRAIT_RESTRAINED, TRAIT_GLOVES) stop_pulling() update_mob_action_buttons() //SKYRAT EDIT ADDITION END @@ -280,7 +280,7 @@ else if(I == gloves) //SKYRAT EDIT ADDITION - ERP UPDATE if(gloves.breakouttime) //when unequipping a straightjacket - REMOVE_TRAIT(src, TRAIT_RESTRAINED, GLOVES_TRAIT) + REMOVE_TRAIT(src, TRAIT_RESTRAINED, TRAIT_GLOVES) drop_all_held_items() //suit is restraining update_mob_action_buttons() //certain action buttons may be usable again. //SKYRAT EDIT ADDITION END diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 2e061d32a6b..be355bddbea 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -28,7 +28,7 @@ //Body temperature stability and damage dna.species.handle_body_temperature(src, seconds_per_tick, times_fired) - if(!IS_IN_STASIS(src)) + if(!HAS_TRAIT(src, TRAIT_STASIS)) if(stat != DEAD) //handle active mutations for(var/datum/mutation/human/human_mutation as anything in dna.mutations) diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm index 345e30264ba..74d2bedf3a7 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -3,14 +3,15 @@ id = SPECIES_ABDUCTOR sexes = FALSE inherent_traits = list( - TRAIT_NO_UNDERWEAR, + TRAIT_CHUNKYFINGERS_IGNORE_BATON, + TRAIT_NEVER_WOUNDED, + TRAIT_NOBLOOD, TRAIT_NOBREATH, + TRAIT_NODISMEMBER, TRAIT_NOHUNGER, + TRAIT_NO_UNDERWEAR, + TRAIT_REMOTE_TASTING, TRAIT_VIRUSIMMUNE, - TRAIT_NOBLOOD, - TRAIT_CHUNKYFINGERS_IGNORE_BATON, - TRAIT_NODISMEMBER, - TRAIT_NEVER_WOUNDED ) mutanttongue = /obj/item/organ/internal/tongue/abductor mutantstomach = null diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm index 55f13dbfabf..5988ad3b890 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -3,25 +3,26 @@ id = SPECIES_ANDROID examine_limb_id = SPECIES_HUMAN inherent_traits = list( - TRAIT_NO_UNDERWEAR, TRAIT_GENELESS, TRAIT_LIMBATTACHMENT, + TRAIT_LIVERLESS_METABOLISM, + TRAIT_NOBLOOD, TRAIT_NOBREATH, TRAIT_NOCLONELOSS, + TRAIT_NOCRITDAMAGE, TRAIT_NOFIRE, TRAIT_NOHUNGER, - TRAIT_LIVERLESS_METABOLISM, + TRAIT_NO_DNA_COPY, + TRAIT_NO_PLASMA_TRANSFORM, + TRAIT_NO_UNDERWEAR, + TRAIT_OVERDOSEIMMUNE, TRAIT_PIERCEIMMUNE, TRAIT_RADIMMUNE, TRAIT_RESISTCOLD, TRAIT_RESISTHEAT, - TRAIT_RESISTLOWPRESSURE, TRAIT_RESISTHIGHPRESSURE, + TRAIT_RESISTLOWPRESSURE, TRAIT_TOXIMMUNE, - TRAIT_NOBLOOD, - TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, - TRAIT_NOCRITDAMAGE, ) inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index 4c28d190eff..7850dee6734 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -55,24 +55,24 @@ QDEL_NULL(ethereal_light) return ..() -/datum/species/ethereal/on_species_gain(mob/living/carbon/new_ethereal, datum/species/old_species, pref_load) +/datum/species/ethereal/on_species_gain(mob/living/carbon/human/new_ethereal, datum/species/old_species, pref_load) . = ..() if(!ishuman(new_ethereal)) return - var/mob/living/carbon/human/ethereal = new_ethereal - default_color = ethereal.dna.features["ethcolor"] + default_color = new_ethereal.dna.features["ethcolor"] fixed_hair_color = default_color r1 = GETREDPART(default_color) g1 = GETGREENPART(default_color) b1 = GETBLUEPART(default_color) - RegisterSignal(ethereal, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag_act)) - RegisterSignal(ethereal, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act)) - RegisterSignal(ethereal, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) - RegisterSignal(ethereal, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) - ethereal_light = ethereal.mob_light(light_type = /obj/effect/dummy/lighting_obj/moblight/species) - spec_updatehealth(ethereal) + RegisterSignal(new_ethereal, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag_act)) + RegisterSignal(new_ethereal, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act)) + RegisterSignal(new_ethereal, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) + RegisterSignal(new_ethereal, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) + RegisterSignal(new_ethereal, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(refresh_light_color)) + ethereal_light = new_ethereal.mob_light(light_type = /obj/effect/dummy/lighting_obj/moblight/species) + refresh_light_color(new_ethereal) new_ethereal.set_safe_hunger_level() - update_mail_goodies(ethereal) + update_mail_goodies(new_ethereal) var/obj/item/organ/internal/heart/ethereal/ethereal_heart = new_ethereal.get_organ_slot(ORGAN_SLOT_HEART) ethereal_heart.ethereal_color = default_color @@ -82,10 +82,13 @@ limb.update_limb(is_creating = TRUE) /datum/species/ethereal/on_species_loss(mob/living/carbon/human/former_ethereal, datum/species/new_species, pref_load) - UnregisterSignal(former_ethereal, COMSIG_ATOM_EMAG_ACT) - UnregisterSignal(former_ethereal, COMSIG_ATOM_EMP_ACT) - UnregisterSignal(former_ethereal, COMSIG_LIGHT_EATER_ACT) - UnregisterSignal(former_ethereal, COMSIG_HIT_BY_SABOTEUR) + UnregisterSignal(former_ethereal, list( + COMSIG_ATOM_EMAG_ACT, + COMSIG_ATOM_EMP_ACT, + COMSIG_HIT_BY_SABOTEUR, + COMSIG_LIGHT_EATER_ACT, + COMSIG_LIVING_HEALTH_UPDATE, + )) QDEL_NULL(ethereal_light) return ..() @@ -104,12 +107,14 @@ return randname -/datum/species/ethereal/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["ethcolor"] = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)] +/datum/species/ethereal/randomize_features() + var/list/features = ..() + features["ethcolor"] = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)] + return features -/datum/species/ethereal/spec_updatehealth(mob/living/carbon/human/ethereal) - . = ..() - if(!ethereal_light) +/datum/species/ethereal/proc/refresh_light_color(mob/living/carbon/human/ethereal) + SIGNAL_HANDLER + if(isnull(ethereal_light)) return if(default_color != ethereal.dna.features["ethcolor"]) var/new_color = ethereal.dna.features["ethcolor"] @@ -136,39 +141,38 @@ ethereal.set_facial_haircolor(dead_color, override = TRUE, update = FALSE) ethereal.set_haircolor(dead_color, override = TRUE, update = TRUE) -/datum/species/ethereal/proc/on_emp_act(mob/living/carbon/human/H, severity, protection) +/datum/species/ethereal/proc/on_emp_act(mob/living/carbon/human/source, severity, protection) SIGNAL_HANDLER if(protection & EMP_PROTECT_SELF) return EMPeffect = TRUE - spec_updatehealth(H) - to_chat(H, span_notice("You feel the light of your body leave you.")) + refresh_light_color(source) + to_chat(source, span_notice("You feel the light of your body leave you.")) switch(severity) if(EMP_LIGHT) - addtimer(CALLBACK(src, PROC_REF(stop_emp), H), 10 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 10 seconds + addtimer(CALLBACK(src, PROC_REF(stop_emp), source), 10 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 10 seconds if(EMP_HEAVY) - addtimer(CALLBACK(src, PROC_REF(stop_emp), H), 20 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 20 seconds + addtimer(CALLBACK(src, PROC_REF(stop_emp), source), 20 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 20 seconds -/datum/species/ethereal/proc/on_saboteur(datum/source, disrupt_duration) +/datum/species/ethereal/proc/on_saboteur(mob/living/carbon/human/source, disrupt_duration) SIGNAL_HANDLER - var/mob/living/carbon/human/our_target = source EMPeffect = TRUE - spec_updatehealth(our_target) - to_chat(our_target, span_warning("Something inside of you crackles in a bad way.")) - our_target.take_bodypart_damage(burn = 3, wound_bonus = CANT_WOUND) - addtimer(CALLBACK(src, PROC_REF(stop_emp), our_target), disrupt_duration, TIMER_UNIQUE|TIMER_OVERRIDE) + refresh_light_color(source) + to_chat(source, span_warning("Something inside of you crackles in a bad way.")) + source.take_bodypart_damage(burn = 3, wound_bonus = CANT_WOUND) + addtimer(CALLBACK(src, PROC_REF(stop_emp), source), disrupt_duration, TIMER_UNIQUE|TIMER_OVERRIDE) return COMSIG_SABOTEUR_SUCCESS -/datum/species/ethereal/proc/on_emag_act(mob/living/carbon/human/H, mob/user) +/datum/species/ethereal/proc/on_emag_act(mob/living/carbon/human/source, mob/user) SIGNAL_HANDLER if(emageffect) return FALSE emageffect = TRUE if(user) - to_chat(user, span_notice("You tap [H] on the back with your card.")) - H.visible_message(span_danger("[H] starts flickering in an array of colors!")) - handle_emag(H) - addtimer(CALLBACK(src, PROC_REF(stop_emag), H), 2 MINUTES) //Disco mode for 2 minutes! This doesn't affect the ethereal at all besides either annoying some players, or making someone look badass. + to_chat(user, span_notice("You tap [source] on the back with your card.")) + source.visible_message(span_danger("[source] starts flickering in an array of colors!")) + handle_emag(source) + addtimer(CALLBACK(src, PROC_REF(stop_emag), source), 2 MINUTES) //Disco mode for 2 minutes! This doesn't affect the ethereal at all besides either annoying some players, or making someone look badass. return TRUE /// Special handling for getting hit with a light eater @@ -177,23 +181,22 @@ source.emp_act(EMP_LIGHT) return COMPONENT_BLOCK_LIGHT_EATER -/datum/species/ethereal/proc/stop_emp(mob/living/carbon/human/H) +/datum/species/ethereal/proc/stop_emp(mob/living/carbon/human/ethereal) EMPeffect = FALSE - spec_updatehealth(H) - to_chat(H, span_notice("You feel more energized as your shine comes back.")) - + refresh_light_color(ethereal) + to_chat(ethereal, span_notice("You feel more energized as your shine comes back.")) -/datum/species/ethereal/proc/handle_emag(mob/living/carbon/human/H) +/datum/species/ethereal/proc/handle_emag(mob/living/carbon/human/ethereal) if(!emageffect) return current_color = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)] - spec_updatehealth(H) - addtimer(CALLBACK(src, PROC_REF(handle_emag), H), 5) //Call ourselves every 0.5 seconds to change color + refresh_light_color(ethereal) + addtimer(CALLBACK(src, PROC_REF(handle_emag), ethereal), 0.5 SECONDS) -/datum/species/ethereal/proc/stop_emag(mob/living/carbon/human/H) +/datum/species/ethereal/proc/stop_emag(mob/living/carbon/human/ethereal) emageffect = FALSE - spec_updatehealth(H) - H.visible_message(span_danger("[H] stops flickering and goes back to their normal state!")) + refresh_light_color(ethereal) + ethereal.visible_message(span_danger("[ethereal] stops flickering and goes back to their normal state!")) /datum/species/ethereal/get_features() var/list/features = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index 4773cf769ad..e22940db2ad 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -48,8 +48,9 @@ return ..() /datum/species/human/felinid/randomize_features(mob/living/carbon/human/human_mob) - randomize_external_organs(human_mob) - return ..() + var/list/features = ..() + features["ears"] = pick("None", "Cat") + return features /proc/mass_purrbation() for(var/mob in GLOB.human_list) diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 91ec9dfe0c5..01451a8db36 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -3,19 +3,21 @@ name = "Golem" id = SPECIES_GOLEM inherent_traits = list( - TRAIT_NO_UNDERWEAR, TRAIT_GENELESS, TRAIT_LAVA_IMMUNE, - TRAIT_NOBREATH, + TRAIT_NEVER_WOUNDED, TRAIT_NOBLOOD, + TRAIT_NOBREATH, + TRAIT_NODISMEMBER, TRAIT_NOFIRE, + TRAIT_NO_AUGMENTS, + TRAIT_NO_DNA_COPY, + TRAIT_NO_PLASMA_TRANSFORM, + TRAIT_NO_UNDERWEAR, TRAIT_PIERCEIMMUNE, TRAIT_RADIMMUNE, - TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, - TRAIT_NO_AUGMENTS, - TRAIT_NODISMEMBER, - TRAIT_NEVER_WOUNDED + TRAIT_SNOWSTORM_IMMUNE, // Shared with plasma river... but I guess if you can survive a plasma river a blizzard isn't a big deal + TRAIT_UNHUSKABLE, ) mutantheart = null mutantlungs = null diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index b169beba940..c7a181027e6 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -13,9 +13,6 @@ human.set_haircolor("#bb9966", update = FALSE) // brown human.set_hairstyle("Business Hair", update = TRUE) -/datum/species/human/randomize_features(mob/living/carbon/human/human_mob) - human_mob.skin_tone = random_skin_tone() - /datum/species/human/get_scream_sound(mob/living/carbon/human/human) if(human.physique == MALE) if(prob(1)) @@ -82,4 +79,3 @@ )) return to_add - diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 5f91cbb2830..45e34d96bfd 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -75,8 +75,9 @@ //SKYRAT EDIT REMOVAL BEGIN /* /datum/species/lizard/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["body_markings"] = pick(GLOB.body_markings_list) - randomize_external_organs(human_mob) + var/list/features = ..() + features["body_markings"] = pick(GLOB.body_markings_list) + return features */ //SKYRAT EDIT REMOVAL END diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm index df289c514dc..8fb36e7c4e2 100644 --- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm +++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm @@ -12,13 +12,13 @@ meat = /obj/item/food/meat/slab/monkey knife_butcher_results = list(/obj/item/food/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1) inherent_traits = list( - TRAIT_NO_UNDERWEAR, - TRAIT_NO_BLOOD_OVERLAY, TRAIT_GUN_NATURAL, + TRAIT_NO_AUGMENTS, + TRAIT_NO_BLOOD_OVERLAY, + TRAIT_NO_DNA_COPY, + TRAIT_NO_UNDERWEAR, TRAIT_VENTCRAWLER_NUDE, TRAIT_WEAK_SOUL, - TRAIT_NO_TRANSFORMATION_STING, - TRAIT_NO_AUGMENTS, ) no_equip_flags = ITEM_SLOT_OCLOTHING | ITEM_SLOT_GLOVES | ITEM_SLOT_FEET | ITEM_SLOT_SUITSTORE changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | ERT_SPAWN | SLIME_EXTRACT diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index df816fbca35..8f3cd84e1e5 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -59,9 +59,10 @@ if(istype(attacking_item, /obj/item/melee/flyswatter)) damage_mods += 10 // Yes, a 10x damage modifier -/datum/species/moth/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["moth_markings"] = pick(GLOB.moth_wings_list) - randomize_external_organs(human_mob) +/datum/species/moth/randomize_features() + var/list/features = ..() + features["moth_markings"] = pick(GLOB.moth_wings_list) // SKYRAT EDIT CHANGE - ORIGINAL: features["moth_markings"] = pick(GLOB.moth_markings_list) + return features /datum/species/moth/get_scream_sound(mob/living/carbon/human/human) return 'sound/voice/moth/scream_moth.ogg' diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 67f57f75a5a..eaabee63485 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -8,13 +8,15 @@ inherent_traits = list( TRAIT_GENELESS, TRAIT_HARDLY_WOUNDED, - TRAIT_RADIMMUNE, - TRAIT_RESISTCOLD, TRAIT_NOBLOOD, TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, + TRAIT_NO_PLASMA_TRANSFORM, + TRAIT_RADIMMUNE, + TRAIT_RESISTCOLD, + TRAIT_UNHUSKABLE, ) + inherent_biotypes = MOB_HUMANOID|MOB_MINERAL inherent_respiration_type = RESPIRATION_PLASMA mutantlungs = /obj/item/organ/internal/lungs/plasmaman diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index 0b645fd120a..5cf2355c86c 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -105,6 +105,3 @@ )) return to_add - -/datum/species/pod/randomize_features(mob/living/carbon/human_mob) - randomize_external_organs(human_mob) diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index a63afeeea29..4120f939d51 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -10,19 +10,20 @@ TRAIT_FAKEDEATH, TRAIT_GENELESS, TRAIT_LIMBATTACHMENT, + TRAIT_NOBLOOD, TRAIT_NOBREATH, TRAIT_NOCLONELOSS, - TRAIT_RADIMMUNE, + TRAIT_NO_DNA_COPY, + TRAIT_NO_UNDERWEAR, TRAIT_PIERCEIMMUNE, + TRAIT_RADIMMUNE, TRAIT_RESISTCOLD, TRAIT_RESISTHEAT, TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTLOWPRESSURE, TRAIT_TOXIMMUNE, + TRAIT_UNHUSKABLE, TRAIT_XENO_IMMUNE, - TRAIT_NOBLOOD, - TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, ) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID mutanttongue = /obj/item/organ/internal/tongue/bone diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 14c4c4d1c15..e567b1a292b 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -7,22 +7,22 @@ mutanttongue = /obj/item/organ/internal/tongue/zombie inherent_traits = list( // SHARED WITH ALL ZOMBIES - TRAIT_NO_ZOMBIFY, TRAIT_EASILY_WOUNDED, TRAIT_EASYDISMEMBER, TRAIT_FAKEDEATH, TRAIT_LIMBATTACHMENT, + TRAIT_LIVERLESS_METABOLISM, TRAIT_NOBREATH, TRAIT_NOCLONELOSS, TRAIT_NODEATH, TRAIT_NOHUNGER, - TRAIT_LIVERLESS_METABOLISM, + TRAIT_NO_DNA_COPY, + TRAIT_NO_ZOMBIFY, TRAIT_RADIMMUNE, TRAIT_RESISTCOLD, TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTLOWPRESSURE, TRAIT_TOXIMMUNE, - TRAIT_NO_TRANSFORMATION_STING, // HIGH FUNCTIONING UNIQUE TRAIT_NOBLOOD, TRAIT_SUCCUMB_OVERRIDE, @@ -105,11 +105,12 @@ TRAIT_EASYDISMEMBER, TRAIT_FAKEDEATH, TRAIT_LIMBATTACHMENT, + TRAIT_LIVERLESS_METABOLISM, TRAIT_NOBREATH, TRAIT_NOCLONELOSS, TRAIT_NODEATH, TRAIT_NOHUNGER, - TRAIT_LIVERLESS_METABOLISM, + TRAIT_NO_DNA_COPY, TRAIT_RADIMMUNE, TRAIT_RESISTCOLD, TRAIT_RESISTHIGHPRESSURE, diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index 8f6dc8efeb9..6f4e8570099 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -30,11 +30,3 @@ . = ..() if(.) update_body_parts() - -/mob/living/carbon/human/become_husk(source) - if(istype(dna.species, /datum/species/skeleton)) //skeletons shouldn't be husks. - cure_husk() - return - . = ..() - if(.) - update_body_parts() diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index a6b766289c0..182eba52b71 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -13,7 +13,7 @@ damageoverlaytemp = 0 update_damage_hud() - if(IS_IN_STASIS(src)) + if(HAS_TRAIT(src, TRAIT_STASIS)) . = ..() reagents.handle_stasis_chems(src, seconds_per_tick, times_fired) else diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 446e92f09f0..356653745e8 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -40,7 +40,7 @@ if(isnull(loc) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) return - if(!IS_IN_STASIS(src)) + if(!HAS_TRAIT(src, TRAIT_STASIS)) if(stat != DEAD) //Mutations and radiation diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 6095638318d..8611bf85eb4 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -509,7 +509,7 @@ return TRUE if(!(flags & IGNORE_GRAB) && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE) return TRUE - if(!(flags & IGNORE_STASIS) && IS_IN_STASIS(src)) + if(!(flags & IGNORE_STASIS) && HAS_TRAIT(src, TRAIT_STASIS)) return TRUE return FALSE @@ -1163,7 +1163,8 @@ /mob/living/resist_grab(moving_resist) . = TRUE - if(pulledby.grab_state || body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) || has_movespeed_modifier(/datum/movespeed_modifier/shove) && getStaminaLoss() > STAMINA_THRESHOLD_HARD_RESIST) //SKYRAT EDIT CHANGE - ORIGINAL : if(pulledby.grab_state || body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) || has_movespeed_modifier(/datum/movespeed_modifier/shove) && getStaminaLoss() >= 30) + //If we're in an aggressive grab or higher, we're lying down, we're vulnerable to grabs, or we're staggered and we have some amount of stamina loss, we must resist + if(pulledby.grab_state || body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) || get_timed_status_effect_duration(/datum/status_effect/staggered) && getStaminaLoss() > STAMINA_THRESHOLD_HARD_RESIST) //SKYRAT EDIT CHANGE - ORIGINAL : if(pulledby.grab_state || body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) || get_timed_status_effect_duration(/datum/status_effect/staggered) && getStaminaLoss() >= 30) var/altered_grab_state = pulledby.grab_state if(body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) && pulledby.grab_state < GRAB_KILL) //If prone, resisting out of a grab is equivalent to 1 grab state higher. won't make the grab state exceed the normal max, however - SKYRAT EDIT CHANGE: if((resting || HAS_TRAIT(src, TRAIT_GRABWEAKNESS)) && pulledby.grab_state < GRAB_KILL) //If resting, resisting out of a grab is equivalent to 1 grab state higher. won't make the grab state exceed the normal max, however altered_grab_state++ diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index 50b4abf8035..de01642f0c6 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -283,7 +283,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( var/dist = get_dist(speaker, src) - message_range if(dist > 0 && dist <= EAVESDROP_EXTRA_RANGE && !HAS_TRAIT(src, TRAIT_GOOD_HEARING) && !isobserver(src)) // ghosts can hear all messages clearly raw_message = stars(raw_message) - if (dist > EAVESDROP_EXTRA_RANGE && !HAS_TRAIT(src, TRAIT_GOOD_HEARING) && !isobserver(src)) + if (message_range != INFINITY && dist > EAVESDROP_EXTRA_RANGE && !HAS_TRAIT(src, TRAIT_GOOD_HEARING) && !isobserver(src)) return FALSE // Too far away and don't have good hearing, you can't hear anything // we need to send this signal before compose_message() is used since other signals need to modify diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index b320f500701..31ead7ef718 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -349,7 +349,7 @@ eye_lights.icon = icon add_overlay(eye_lights) - if(opened && !(R_TRAIT_UNIQUEPANEL in model.model_features)) + if(opened && !(TRAIT_R_UNIQUEPANEL in model.model_features)) if(wiresexposed) add_overlay("ov-opencover +w") else if(cell) diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm index 2aeb97a89fe..80809bb5a40 100644 --- a/code/modules/mob/living/silicon/robot/robot_model.dm +++ b/code/modules/mob/living/silicon/robot/robot_model.dm @@ -248,7 +248,7 @@ reskin_icons[skin] = image(icon = details[SKIN_ICON] || 'icons/mob/silicon/robots.dmi', icon_state = details[SKIN_ICON_STATE]) //SKYRAT EDIT ADDITION BEGIN - ALTBORGS if (!isnull(details[SKIN_FEATURES])) - if (R_TRAIT_WIDE in details[SKIN_FEATURES]) + if (TRAIT_R_WIDE in details[SKIN_FEATURES]) var/image/reskin = reskin_icons[skin] reskin.pixel_x -= 16 //SKYRAT EDIT END @@ -257,7 +257,7 @@ return FALSE var/list/details = borg_skins[borg_skin] //SKYRAT EDIT START - if(cyborg.hasExpanded && (((R_TRAIT_WIDE in details[SKIN_FEATURES]) && (R_TRAIT_WIDE in model_features)) || ((R_TRAIT_TALL in details[SKIN_FEATURES]) && (R_TRAIT_TALL in model_features)))) + if(cyborg.hasExpanded && (((TRAIT_R_WIDE in details[SKIN_FEATURES]) && (TRAIT_R_WIDE in model_features)) || ((TRAIT_R_TALL in details[SKIN_FEATURES]) && (TRAIT_R_TALL in model_features)))) to_chat(cyborg, span_warning("You can't make yourself into a larger frame when you've already used an expander!")) return FALSE //SKYRAT EDIT END diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index bbc37911bb1..96beb024fe9 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -497,18 +497,28 @@ /mob/living/proc/cure_husk(source) REMOVE_TRAIT(src, TRAIT_HUSK, source) - if(!HAS_TRAIT(src, TRAIT_HUSK)) - REMOVE_TRAIT(src, TRAIT_DISFIGURED, "husk") - update_body() - return TRUE + if(HAS_TRAIT(src, TRAIT_HUSK)) + return FALSE + REMOVE_TRAIT(src, TRAIT_DISFIGURED, "husk") + update_body() + UnregisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_UNHUSKABLE)) + return TRUE /mob/living/proc/become_husk(source) - if(!HAS_TRAIT(src, TRAIT_HUSK)) - ADD_TRAIT(src, TRAIT_HUSK, source) - ADD_TRAIT(src, TRAIT_DISFIGURED, "husk") - update_body() - else - ADD_TRAIT(src, TRAIT_HUSK, source) + if(HAS_TRAIT(src, TRAIT_UNHUSKABLE)) + return + var/was_husk = HAS_TRAIT(src, TRAIT_HUSK) + ADD_TRAIT(src, TRAIT_HUSK, source) + if (was_husk) + return + ADD_TRAIT(src, TRAIT_DISFIGURED, "husk") + update_body() + RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_UNHUSKABLE), PROC_REF(became_unhuskable)) + +/// Called when we become unhuskable while already husked +/mob/living/proc/became_unhuskable() + SIGNAL_HANDLER + cure_husk() /mob/living/proc/cure_fakedeath(source) remove_traits(list(TRAIT_FAKEDEATH, TRAIT_DEATHCOMA), source) diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm index 49358223e35..b782f2fc959 100644 --- a/code/modules/movespeed/modifiers/mobs.dm +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -81,8 +81,8 @@ blacklisted_movetypes = FLOATING variable = TRUE -/datum/movespeed_modifier/shove - multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH +/datum/movespeed_modifier/staggered + multiplicative_slowdown = STAGGERED_SLOWDOWN_STRENGTH /datum/movespeed_modifier/human_carry multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 69af56d3419..40e99eefe6a 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -31,6 +31,38 @@ var/requires_gravity = TRUE // can you use this to write in zero-g embedding = list(embed_chance = 50) sharpness = SHARP_POINTY + var/dart_insert_icon = 'icons/obj/weapons/guns/toy.dmi' + var/dart_insert_casing_icon_state = "overlay_pen" + var/dart_insert_projectile_icon_state = "overlay_pen_proj" + +/obj/item/pen/Initialize(mapload) + . = ..() + AddComponent(/datum/component/dart_insert, \ + dart_insert_icon, \ + dart_insert_casing_icon_state, \ + dart_insert_icon, \ + dart_insert_projectile_icon_state, \ + CALLBACK(src, PROC_REF(get_dart_var_modifiers))\ + ) + RegisterSignal(src, COMSIG_DART_INSERT_ADDED, PROC_REF(on_inserted_into_dart)) + RegisterSignal(src, COMSIG_DART_INSERT_REMOVED, PROC_REF(on_removed_from_dart)) + +/obj/item/pen/proc/on_inserted_into_dart(datum/source, obj/projectile/dart, mob/user, embedded = FALSE) + SIGNAL_HANDLER + +/obj/item/pen/proc/get_dart_var_modifiers() + return list( + "damage" = max(5, throwforce), + "speed" = max(0, throw_speed - 3), + "embedding" = embedding, + "armour_penetration" = armour_penetration, + "wound_bonus" = wound_bonus, + "bare_wound_bonus" = bare_wound_bonus, + "demolition_mod" = demolition_mod, + ) + +/obj/item/pen/proc/on_removed_from_dart(datum/source, obj/projectile/dart, mob/user) + SIGNAL_HANDLER /obj/item/pen/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is scribbling numbers all over [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit sudoku...")) @@ -69,7 +101,7 @@ if("#FF0000") colour = "#00FF00" chosen_color = "green" - throw_speed = initial(throw_speed) + throw_speed-- if("#00FF00") colour = "#0000FF" chosen_color = "blue" @@ -84,6 +116,8 @@ icon_state = "pen-fountain" font = FOUNTAIN_PEN_FONT requires_gravity = FALSE // fancy spess pens + dart_insert_casing_icon_state = "overlay_fountainpen" + dart_insert_projectile_icon_state = "overlay_fountainpen_proj" /obj/item/pen/charcoal name = "charcoal stylus" @@ -113,13 +147,23 @@ custom_materials = list(/datum/material/gold = SMALL_MATERIAL_AMOUNT*7.5) sharpness = SHARP_EDGED resistance_flags = FIRE_PROOF - unique_reskin = list("Oak" = "pen-fountain-o", - "Gold" = "pen-fountain-g", - "Rosewood" = "pen-fountain-r", - "Black and Silver" = "pen-fountain-b", - "Command Blue" = "pen-fountain-cb" - ) + unique_reskin = list( + "Oak" = "pen-fountain-o", + "Gold" = "pen-fountain-g", + "Rosewood" = "pen-fountain-r", + "Black and Silver" = "pen-fountain-b", + "Command Blue" = "pen-fountain-cb" + ) embedding = list("embed_chance" = 75) + dart_insert_casing_icon_state = "overlay_fountainpen_gold" + dart_insert_projectile_icon_state = "overlay_fountainpen_gold_proj" + var/list/overlay_reskin = list( + "Oak" = "overlay_fountainpen_gold", + "Gold" = "overlay_fountainpen_gold", + "Rosewood" = "overlay_fountainpen_gold", + "Black and Silver" = "overlay_fountainpen", + "Command Blue" = "overlay_fountainpen_gold" + ) /obj/item/pen/fountain/captain/Initialize(mapload) . = ..() @@ -128,12 +172,19 @@ effectiveness = 115, \ ) //the pen is mightier than the sword + RegisterSignal(src, COMSIG_DART_INSERT_PARENT_RESKINNED, PROC_REF(reskin_dart_insert)) /obj/item/pen/fountain/captain/reskin_obj(mob/M) ..() if(current_skin) desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp." +/obj/item/pen/fountain/captain/proc/reskin_dart_insert(datum/component/dart_insert/insert_comp) + if(!istype(insert_comp)) //You really shouldn't be sending this signal from anything other than a dart_insert component + return + insert_comp.casing_overlay_icon_state = overlay_reskin[current_skin] + insert_comp.projectile_overlay_icon_state = "[overlay_reskin[current_skin]]_proj" + /obj/item/pen/attack_self(mob/living/carbon/user) . = ..() if(.) @@ -247,6 +298,23 @@ reagents.add_reagent(/datum/reagent/toxin/mutetoxin, 15) reagents.add_reagent(/datum/reagent/toxin/staminatoxin, 10) +/obj/item/pen/sleepy/on_inserted_into_dart(datum/source, obj/item/ammo_casing/dart, mob/user) + . = ..() + var/obj/projectile/proj = dart.loaded_projectile + RegisterSignal(proj, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(on_dart_hit)) + +/obj/item/pen/sleepy/on_removed_from_dart(datum/source, obj/item/ammo_casing/dart, obj/projectile/proj, mob/user) + . = ..() + if(istype(proj)) + UnregisterSignal(proj, COMSIG_PROJECTILE_SELF_ON_HIT) + +/obj/item/pen/sleepy/proc/on_dart_hit(datum/source, atom/movable/firer, atom/target, angle, hit_limb, blocked) + SIGNAL_HANDLER + var/mob/living/carbon/carbon_target = target + if(!istype(carbon_target) || blocked == 100) + return + if(carbon_target.can_inject(target_zone = hit_limb)) + reagents.trans_to(carbon_target, reagents.total_volume, transferred_by = firer, methods = INJECT) /* * (Alan) Edaggers */ @@ -262,6 +330,7 @@ light_power = 0.75 light_color = COLOR_SOFT_RED light_on = FALSE + dart_insert_projectile_icon_state = "overlay_edagger" /// The real name of our item when extended. var/hidden_name = "energy dagger" /// The real desc of our item when extended. @@ -287,6 +356,62 @@ RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) RegisterSignal(src, COMSIG_DETECTIVE_SCANNED, PROC_REF(on_scan)) +/obj/item/pen/edagger/on_inserted_into_dart(datum/source, obj/item/ammo_casing/dart, mob/user) + . = ..() + var/datum/component/transforming/transform_comp = GetComponent(/datum/component/transforming) + if(HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE)) + transform_comp.do_transform(src, user) + RegisterSignal(dart.loaded_projectile, COMSIG_PROJECTILE_FIRE, PROC_REF(on_containing_dart_fired)) + RegisterSignal(dart.loaded_projectile, COMSIG_PROJECTILE_ON_SPAWN_DROP, PROC_REF(on_containing_dart_drop)) + RegisterSignal(dart.loaded_projectile, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED, PROC_REF(on_containing_dart_embedded)) + +/obj/item/pen/edagger/on_removed_from_dart(datum/source, obj/item/ammo_casing/dart, obj/projectile/projectile, mob/user) + . = ..() + if(istype(dart)) + UnregisterSignal(dart, list(COMSIG_ITEM_UNEMBEDDED, COMSIG_ITEM_FAILED_EMBED)) + if(istype(projectile)) + UnregisterSignal(projectile, list(COMSIG_PROJECTILE_FIRE, COMSIG_PROJECTILE_ON_SPAWN_DROP, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED)) + +/obj/item/pen/edagger/get_dart_var_modifiers() + . = ..() + var/datum/component/transforming/transform_comp = GetComponent(/datum/component/transforming) + .["damage"] = max(5, transform_comp.throwforce_on) + .["speed"] = max(0, transform_comp.throw_speed_on - 3) + var/list/embed_params = .["embedding"] + embed_params["embed_chance"] = 100 + +/obj/item/pen/edagger/proc/on_containing_dart_fired(obj/projectile/source) + SIGNAL_HANDLER + playsound(source, 'sound/weapons/saberon.ogg', 5, TRUE) + var/datum/component/transforming/transform_comp = GetComponent(/datum/component/transforming) + source.hitsound = transform_comp.hitsound_on + source.set_light(light_range, light_power, light_color, l_on = TRUE) + +/obj/item/pen/edagger/proc/on_containing_dart_drop(datum/source, obj/item/ammo_casing/new_casing) + SIGNAL_HANDLER + playsound(new_casing, 'sound/weapons/saberoff.ogg', 5, TRUE) + +/obj/item/pen/edagger/proc/on_containing_dart_embedded(datum/source, obj/item/ammo_casing/new_casing) + SIGNAL_HANDLER + RegisterSignal(new_casing, COMSIG_ITEM_UNEMBEDDED, PROC_REF(on_embedded_removed)) + RegisterSignal(new_casing, COMSIG_ITEM_FAILED_EMBED, PROC_REF(on_containing_dart_failed_embed)) + +/obj/item/pen/edagger/proc/on_containing_dart_failed_embed(obj/item/ammo_casing/source) + SIGNAL_HANDLER + playsound(source, 'sound/weapons/saberoff.ogg', 5, TRUE) + UnregisterSignal(source, list(COMSIG_ITEM_UNEMBEDDED, COMSIG_ITEM_FAILED_EMBED)) + +/obj/item/pen/edagger/proc/on_embedded_removed(obj/item/ammo_casing/source, mob/living/carbon/victim) + SIGNAL_HANDLER + playsound(source, 'sound/weapons/saberoff.ogg', 5, TRUE) + UnregisterSignal(source, list(COMSIG_ITEM_UNEMBEDDED, COMSIG_ITEM_FAILED_EMBED)) + victim.visible_message( + message = span_warning("The blade of the [hidden_name] retracts as the [source.name] is removed from [victim]!"), + self_message = span_warning("The blade of the [hidden_name] retracts as the [source.name] is removed from you!"), + blind_message = span_warning("You hear an energy blade retract!"), + vision_distance = 1 + ) + /obj/item/pen/edagger/suicide_act(mob/living/user) if(HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE)) user.visible_message(span_suicide("[user] forcefully rams the pen into their mouth!")) @@ -348,6 +473,25 @@ toolspeed = 10 //You will never willingly choose to use one of these over a shovel. font = FOUNTAIN_PEN_FONT colour = "#0000FF" + dart_insert_casing_icon_state = "overlay_survivalpen" + dart_insert_projectile_icon_state = "overlay_survivalpen_proj" + +/obj/item/pen/survival/on_inserted_into_dart(datum/source, obj/item/ammo_casing/dart, mob/user) + . = ..() + RegisterSignal(dart.loaded_projectile, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(on_dart_hit)) + +/obj/item/pen/survival/on_removed_from_dart(datum/source, obj/item/ammo_casing/dart, obj/projectile/proj, mob/user) + . = ..() + if(istype(proj)) + UnregisterSignal(proj, COMSIG_PROJECTILE_SELF_ON_HIT) + +/obj/item/pen/survival/proc/on_dart_hit(obj/projectile/source, atom/movable/firer, atom/target) + var/turf/target_turf = get_turf(target) + if(!target_turf) + target_turf = get_turf(src) + if(ismineralturf(target_turf)) + var/turf/closed/mineral/mineral_turf = target_turf + mineral_turf.gets_drilled(firer, TRUE) /obj/item/pen/destroyer name = "Fine Tipped Pen" @@ -362,6 +506,7 @@ desc = "A pen with an extendable screwdriver tip. This one has a yellow cap." icon_state = "pendriver" toolspeed = 1.2 // gotta have some downside + dart_insert_projectile_icon_state = "overlay_pendriver" /obj/item/pen/screwdriver/get_all_tool_behaviours() return list(TOOL_SCREWDRIVER) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 580d2a66f96..c38036e6eab 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -243,8 +243,15 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/examine(mob/user) . = ..() var/immune = HAS_MIND_TRAIT(user, TRAIT_MADNESS_IMMUNE) - if(isliving(user) && !immune && (get_dist(user, src) < SM_HALLUCINATION_RANGE(internal_energy))) - . += span_danger("You get headaches just from looking at it.") + if(isliving(user)) + if (!immune && (get_dist(user, src) < SM_HALLUCINATION_RANGE(internal_energy))) + . += span_danger("You get headaches just from looking at it.") + var/mob/living/living_user = user + if (HAS_TRAIT(user, TRAIT_REMOTE_TASTING)) + to_chat(user, span_warning("The taste is overwhelming and indescribable!")) + living_user.electrocute_act(shock_damage = 15, source = src, flags = SHOCK_KNOCKDOWN | SHOCK_NOGLOVES) + . += span_notice("It could use a little more Sodium Chloride...") + . += delamination_strategy.examine(src) return . diff --git a/code/modules/projectiles/ammunition/_firing.dm b/code/modules/projectiles/ammunition/_firing.dm index dee2c087c68..009c52b227e 100644 --- a/code/modules/projectiles/ammunition/_firing.dm +++ b/code/modules/projectiles/ammunition/_firing.dm @@ -66,6 +66,7 @@ if(reagents && loaded_projectile.reagents) reagents.trans_to(loaded_projectile, reagents.total_volume, transferred_by = user) //For chemical darts/bullets qdel(reagents) + SEND_SIGNAL(src, COMSIG_CASING_READY_PROJECTILE, target, user, quiet, zone_override, fired_from) /obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread, atom/fired_from) var/turf/curloc = get_turf(fired_from) diff --git a/code/modules/projectiles/ammunition/ballistic/foam.dm b/code/modules/projectiles/ammunition/ballistic/foam.dm index 21ceeb6918b..2895d74555b 100644 --- a/code/modules/projectiles/ammunition/ballistic/foam.dm +++ b/code/modules/projectiles/ammunition/ballistic/foam.dm @@ -9,6 +9,7 @@ custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 0.1125) harmful = FALSE var/modified = FALSE + var/static/list/insertable_items_hint = list(/obj/item/pen) /obj/item/ammo_casing/foam_dart/Initialize(mapload) . = ..() @@ -18,47 +19,37 @@ . = ..() if(modified) icon_state = "[base_icon_state]_empty" - loaded_projectile?.icon_state = "[base_icon_state]_empty" + loaded_projectile?.icon_state = "[loaded_projectile.base_icon_state]_empty_proj" return icon_state = "[base_icon_state]" - loaded_projectile?.icon_state = "[loaded_projectile.base_icon_state]" + loaded_projectile?.icon_state = "[loaded_projectile.base_icon_state]_proj" /obj/item/ammo_casing/foam_dart/update_desc() . = ..() desc = "It's Donk or Don't! [modified ? "... Although, this one doesn't look too safe." : "Ages 8 and up."]" -/obj/item/ammo_casing/foam_dart/attackby(obj/item/A, mob/user, params) - var/obj/projectile/bullet/foam_dart/FD = loaded_projectile - if (A.tool_behaviour == TOOL_SCREWDRIVER && !modified) +/obj/item/ammo_casing/foam_dart/examine_more(mob/user) + . = ..() + if(!HAS_TRAIT(src, TRAIT_DART_HAS_INSERT)) + var/list/type_initial_names = list() + for(var/type in insertable_items_hint) + var/obj/item/type_item = type + type_initial_names += "\a [initial(type_item.name)]" + . += span_notice("[modified ? "You can" : "If you removed the safety cap with a screwdriver, you could"] insert a small item\ + [length(type_initial_names) ? ", such as [english_list(type_initial_names, and_text = "or ", final_comma_text = ", ")]" : ""].") + + +/obj/item/ammo_casing/foam_dart/attackby(obj/item/attacking_item, mob/user, params) + var/obj/projectile/bullet/foam_dart/dart = loaded_projectile + if (attacking_item.tool_behaviour == TOOL_SCREWDRIVER && !modified) modified = TRUE - FD.modified = TRUE - FD.damage_type = BRUTE + dart.modified = TRUE + dart.damage_type = BRUTE to_chat(user, span_notice("You pop the safety cap off [src].")) update_appearance() - else if (istype(A, /obj/item/pen)) - if(modified) - if(!FD.pen) - harmful = TRUE - if(!user.transferItemToLoc(A, FD)) - return - FD.pen = A - FD.damage = 5 - to_chat(user, span_notice("You insert [A] into [src].")) - else - to_chat(user, span_warning("There's already something in [src].")) - else - to_chat(user, span_warning("The safety cap prevents you from inserting [A] into [src].")) else return ..() -/obj/item/ammo_casing/foam_dart/attack_self(mob/living/user) - var/obj/projectile/bullet/foam_dart/FD = loaded_projectile - if(FD.pen) - FD.damage = initial(FD.damage) - user.put_in_hands(FD.pen) - to_chat(user, span_notice("You remove [FD.pen] from [src].")) - FD.pen = null - /obj/item/ammo_casing/foam_dart/riot name = "riot foam dart" desc = "Whose smart idea was it to use toys as crowd control? Ages 18 and up." diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm index a3bb54a07e0..713790049b5 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm @@ -32,6 +32,7 @@ damage = 50 speed = 1 range = 25 + shrapnel_type = null embedding = list( embed_chance = 90, fall_chance = 2, @@ -42,7 +43,6 @@ jostle_pain_mult = 3, rip_time = 1 SECONDS ) - shrapnel_type = /obj/item/ammo_casing/arrow /// holy arrows /obj/item/ammo_casing/arrow/holy @@ -59,7 +59,6 @@ desc = "Here it comes, cultist scum!" icon_state = "holy_arrow_projectile" damage = 20 //still a lot but this is roundstart gear so far less - shrapnel_type =/obj/item/ammo_casing/arrow/holy embedding = list( embed_chance = 50, fall_chance = 2, diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 18c0b557f88..a7beb1a7102 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -282,8 +282,8 @@ var/mob/living/L = target hit_limb_zone = L.check_hit_limb_zone_name(def_zone) if(fired_from) - SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle, hit_limb_zone) - SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb_zone) + SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle, hit_limb_zone, blocked) + SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb_zone, blocked) if(QDELETED(src)) // in case one of the above signals deleted the projectile for whatever reason return BULLET_ACT_BLOCK diff --git a/code/modules/projectiles/projectile/bullets/foam_dart.dm b/code/modules/projectiles/projectile/bullets/foam_dart.dm index 6d4cffd4524..3f086166e6a 100644 --- a/code/modules/projectiles/projectile/bullets/foam_dart.dm +++ b/code/modules/projectiles/projectile/bullets/foam_dart.dm @@ -5,27 +5,24 @@ damage_type = OXY icon = 'icons/obj/weapons/guns/toy.dmi' icon_state = "foamdart_proj" - base_icon_state = "foamdart_proj" + base_icon_state = "foamdart" range = 10 + shrapnel_type = null embedding = null var/modified = FALSE var/obj/item/pen/pen = null /obj/projectile/bullet/foam_dart/Initialize(mapload) . = ..() - RegisterSignal(src, COMSIG_PROJECTILE_ON_SPAWN_DROP, PROC_REF(handle_drop)) + RegisterSignals(src, list(COMSIG_PROJECTILE_ON_SPAWN_DROP, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED), PROC_REF(handle_drop)) /obj/projectile/bullet/foam_dart/proc/handle_drop(datum/source, obj/item/ammo_casing/foam_dart/newcasing) SIGNAL_HANDLER newcasing.modified = modified + newcasing.update_appearance() var/obj/projectile/bullet/foam_dart/newdart = newcasing.loaded_projectile newdart.modified = modified newdart.damage_type = damage_type - if(pen) - newdart.pen = pen - pen.forceMove(newdart) - pen = null - newdart.damage = 5 newdart.update_appearance() /obj/projectile/bullet/foam_dart/Destroy() @@ -35,5 +32,5 @@ /obj/projectile/bullet/foam_dart/riot name = "riot foam dart" icon_state = "foamdart_riot_proj" - base_icon_state = "foamdart_riot_proj" + base_icon_state = "foamdart_riot" stamina = 25 diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm index de7e59facc3..d76b2de9d6a 100644 --- a/code/modules/projectiles/projectile/bullets/rifle.dm +++ b/code/modules/projectiles/projectile/bullets/rifle.dm @@ -46,7 +46,7 @@ bare_wound_bonus = 80 embedding = list(embed_chance=100, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) wound_falloff_tile = -5 - shrapnel_type = /obj/item/ammo_casing/harpoon + shrapnel_type = null // Rebar (Rebar Crossbow) /obj/projectile/bullet/rebar @@ -75,4 +75,3 @@ embedding = list(embed_chance=80, fall_chance=1, jostle_chance=3, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=3, jostle_pain_mult=2, rip_time=14) embed_falloff_tile = -3 shrapnel_type = /obj/item/stack/rods - diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 20d4da62f2b..5f9d7f81995 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -765,7 +765,7 @@ if(!reagent.metabolizing) reagent.metabolizing = TRUE reagent.on_mob_metabolize(owner) - if(can_overdose) + if(can_overdose && !HAS_TRAIT(owner, TRAIT_OVERDOSEIMMUNE)) if(reagent.overdose_threshold) if(reagent.volume >= reagent.overdose_threshold && !reagent.overdosed) reagent.overdosed = TRUE diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index a4d31849cda..bc5b14614c6 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -136,7 +136,6 @@ //SKYRAT EDIT CHANGE END /obj/machinery/chem_dispenser/Initialize(mapload) - . = ..() if(dispensable_reagents != null && !dispensable_reagents.len) dispensable_reagents = default_dispensable_reagents if(dispensable_reagents) @@ -162,6 +161,8 @@ if(emagged_reagents) emagged_reagents = sort_list(emagged_reagents, GLOBAL_PROC_REF(cmp_reagents_asc)) + . = ..() // So that we call RefreshParts() after adjusting the lists + if(is_operational) begin_processing() update_appearance() diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 5234018bbd9..d58df6a1d6b 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -61,13 +61,16 @@ reagents.add_reagent(/datum/reagent/blood, disease_amount, data) add_initial_reagents() -/obj/item/reagent_containers/examine() +/obj/item/reagent_containers/examine(mob/user) . = ..() if(has_variable_transfer_amount) if(possible_transfer_amounts.len > 1) . += span_notice("Left-click or right-click in-hand to increase or decrease its transfer amount.") else if(possible_transfer_amounts.len) . += span_notice("Left-click or right-click in-hand to view its transfer amount.") + if(isliving(user) && HAS_TRAIT(user, TRAIT_REMOTE_TASTING)) + var/mob/living/living_user = user + living_user.taste(reagents) /obj/item/reagent_containers/create_reagents(max_vol, flags) . = ..() diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 6a86bcbaae1..8c1bfa246a7 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1581,6 +1581,17 @@ RND_CATEGORY_MECHFAB_CYBORG_MODULES + RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_ENGINEERING ) +/datum/design/borg_upgrade_inducer + name = "Cyborg inducer" + id = "borg_upgrade_inducer" + build_type = MECHFAB + build_path = /obj/item/borg/upgrade/inducer + materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5, /datum/material/glass = SHEET_MATERIAL_AMOUNT * 2.5, /datum/material/silver = SHEET_MATERIAL_AMOUNT * 2) + construction_time = 120 + category = list( + RND_CATEGORY_MECHFAB_CYBORG_MODULES + RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_ENGINEERING + ) + /datum/design/borg_upgrade_circuit_app name = "Circuit Manipulator" id = "borg_upgrade_circuitapp" diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index 86b9f2dfafe..6638f56c1b4 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -197,12 +197,18 @@ If you create T5+ please take a pass at mech_fabricator.dm. The parts being good /obj/item/storage/part_replacer/cyborg //SKYRAT EDIT - ICON OVERRIDEN BY AESTHETICS - SEE MODULE name = "rapid part exchange device" - desc = "Special mechanical module made to store, sort, and apply standard machine parts." + desc = "Special mechanical module made to store, sort, and apply standard machine parts. This one has an extra large compartment for more parts." icon_state = "borgrped" inhand_icon_state = "RPED" lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' +/obj/item/storage/part_replacer/cyborg/Initialize(mapload) + . = ..() + atom_storage.max_slots = 400 + atom_storage.max_total_storage = 800 + atom_storage.max_specific_storage = WEIGHT_CLASS_GIGANTIC + /obj/item/storage/part_replacer/proc/get_sorted_parts(ignore_stacks = FALSE) var/list/part_list = list() //Assemble a list of current parts, then sort them by their rating! diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index d46bb35d8c3..28710bbfb8d 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -1017,6 +1017,7 @@ "borg_upgrade_lavaproof", "borg_upgrade_rped", "borg_upgrade_hypermod", + "borg_upgrade_inducer", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 00f66b370be..a9dab01c918 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -901,7 +901,7 @@ SHOULD_CALL_PARENT(TRUE) if(IS_ORGANIC_LIMB(src)) - if(owner && HAS_TRAIT(owner, TRAIT_HUSK)) + if(!(bodypart_flags & BODYPART_UNHUSKABLE) && owner && HAS_TRAIT(owner, TRAIT_HUSK)) dmg_overlay_type = "" //no damage overlay shown when husked is_husked = TRUE else if(owner && HAS_TRAIT(owner, TRAIT_INVISIBLE_MAN)) @@ -1267,12 +1267,12 @@ if(BLEED_OVERLAY_LOW to BLEED_OVERLAY_MED) new_bleed_icon = "[body_zone]_1" if(BLEED_OVERLAY_MED to BLEED_OVERLAY_GUSH) - if(owner.body_position == LYING_DOWN || IS_IN_STASIS(owner) || owner.stat == DEAD) + if(owner.body_position == LYING_DOWN || HAS_TRAIT(owner, TRAIT_STASIS) || owner.stat == DEAD) new_bleed_icon = "[body_zone]_2s" else new_bleed_icon = "[body_zone]_2" if(BLEED_OVERLAY_GUSH to INFINITY) - if(IS_IN_STASIS(owner) || owner.stat == DEAD) + if(HAS_TRAIT(owner, TRAIT_STASIS) || owner.stat == DEAD) new_bleed_icon = "[body_zone]_2s" else new_bleed_icon = "[body_zone]_3" diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm index f10393dd653..10195c6d98e 100644 --- a/code/modules/surgery/bodyparts/robot_bodyparts.dm +++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm @@ -42,6 +42,7 @@ damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT) disabling_threshold_percentage = 1 + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/arm/right/robot name = "cyborg right arm" @@ -75,6 +76,7 @@ biological_state = (BIO_ROBOTIC|BIO_JOINTED) damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT) + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/leg/left/robot name = "cyborg left leg" @@ -108,6 +110,7 @@ biological_state = (BIO_ROBOTIC|BIO_JOINTED) damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT) + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/leg/left/robot/emp_act(severity) . = ..() @@ -154,6 +157,7 @@ biological_state = (BIO_ROBOTIC|BIO_JOINTED) damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT) + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/leg/right/robot/emp_act(severity) . = ..() @@ -197,14 +201,15 @@ biological_state = (BIO_ROBOTIC) damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT) - - var/wired = FALSE - var/obj/item/stock_parts/cell/cell = null + bodypart_flags = BODYPART_UNHUSKABLE robotic_emp_paralyze_damage_percent_threshold = 0.6 wing_types = list(/obj/item/organ/external/wings/functional/robotic) + var/wired = FALSE + var/obj/item/stock_parts/cell/cell = null + /obj/item/bodypart/chest/robot/emp_act(severity) . = ..() if(!. || isnull(owner)) @@ -376,6 +381,7 @@ damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT) head_flags = HEAD_EYESPRITES + bodypart_flags = BODYPART_UNHUSKABLE var/obj/item/assembly/flash/handheld/flash1 = null var/obj/item/assembly/flash/handheld/flash2 = null diff --git a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm index ad3c9ce213c..f4be2fd340f 100644 --- a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm @@ -331,6 +331,7 @@ should_draw_greyscale = FALSE dmg_overlay_type = null head_flags = NONE + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/chest/skeleton biological_state = BIO_BONE @@ -338,6 +339,7 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE dmg_overlay_type = null + bodypart_flags = BODYPART_UNHUSKABLE wing_types = list(/obj/item/organ/external/wings/functional/skeleton) /obj/item/bodypart/arm/left/skeleton @@ -345,24 +347,28 @@ limb_id = SPECIES_SKELETON should_draw_greyscale = FALSE dmg_overlay_type = null + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/arm/right/skeleton biological_state = (BIO_BONE|BIO_JOINTED) limb_id = SPECIES_SKELETON should_draw_greyscale = FALSE dmg_overlay_type = null + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/leg/left/skeleton biological_state = (BIO_BONE|BIO_JOINTED) limb_id = SPECIES_SKELETON should_draw_greyscale = FALSE dmg_overlay_type = null + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/leg/right/skeleton biological_state = (BIO_BONE|BIO_JOINTED) limb_id = SPECIES_SKELETON should_draw_greyscale = FALSE dmg_overlay_type = null + bodypart_flags = BODYPART_UNHUSKABLE ///MUSHROOM /obj/item/bodypart/head/mushroom diff --git a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm index 8070072521f..8ba27c2cdf9 100644 --- a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm @@ -10,6 +10,7 @@ brute_modifier = 1.5 //Plasmemes are weak burn_modifier = 1.5 //Plasmemes are weak head_flags = HEAD_EYESPRITES + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/chest/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' @@ -22,6 +23,7 @@ dmg_overlay_type = null brute_modifier = 1.5 //Plasmemes are weak burn_modifier = 1.5 //Plasmemes are weak + bodypart_flags = BODYPART_UNHUSKABLE wing_types = NONE /obj/item/bodypart/arm/left/plasmaman @@ -34,6 +36,7 @@ dmg_overlay_type = null brute_modifier = 1.5 //Plasmemes are weak burn_modifier = 1.5 //Plasmemes are weak + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/arm/right/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' @@ -45,6 +48,7 @@ dmg_overlay_type = null brute_modifier = 1.5 //Plasmemes are weak burn_modifier = 1.5 //Plasmemes are weak + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/leg/left/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' @@ -56,6 +60,7 @@ dmg_overlay_type = null brute_modifier = 1.5 //Plasmemes are weak burn_modifier = 1.5 //Plasmemes are weak + bodypart_flags = BODYPART_UNHUSKABLE /obj/item/bodypart/leg/right/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' @@ -67,3 +72,4 @@ dmg_overlay_type = null brute_modifier = 1.5 //Plasmemes are weak burn_modifier = 1.5 //Plasmemes are weak + bodypart_flags = BODYPART_UNHUSKABLE diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index e21f277ecf6..bfeb128eb7a 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -7,11 +7,12 @@ zone = BODY_ZONE_PRECISE_GROIN slot = ORGAN_SLOT_EXTERNAL_TAIL - bodypart_overlay = /datum/bodypart_overlay/mutant/tail - //dna_block = DNA_TAIL_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA. restyle_flags = EXTERNAL_RESTYLE_FLESH + // defaults to cat, but the parent type shouldn't be created regardless + bodypart_overlay = /datum/bodypart_overlay/mutant/tail/cat + ///Does this tail have a wagging sprite, and is it currently wagging? var/wag_flags = NONE ///The original owner of this tail @@ -83,7 +84,7 @@ organ_owner.update_body_parts() UnregisterSignal(organ_owner, COMSIG_LIVING_DEATH) -///Tail parent type (which is MONKEEEEEEEEEEE by default), with wagging functionality +///Tail parent type, with wagging functionality /datum/bodypart_overlay/mutant/tail layers = EXTERNAL_FRONT|EXTERNAL_BEHIND feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = "tail_monkey" @@ -92,8 +93,10 @@ /datum/bodypart_overlay/mutant/tail/get_base_icon_state() return (wagging ? "wagging_" : "") + sprite_datum.icon_state //add the wagging tag if we be wagging +// SKYRAT EDIT ADDITION - CUSTOMIZATION /datum/bodypart_overlay/mutant/tail/get_global_feature_list() - return GLOB.sprite_accessories["tail"] // SKYRAT EDIT - Customization - ORIGINAL: return GLOB.tails_list + return GLOB.sprite_accessories["tail"] +// SKYRAT EDIT ADDITION END /datum/bodypart_overlay/mutant/tail/can_draw_on_bodypart(mob/living/carbon/human/human) if(human.wear_suit && (human.wear_suit.flags_inv & HIDEJUMPSUIT)) @@ -124,6 +127,9 @@ color_source = NONE feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = "tail_monkey" +/datum/bodypart_overlay/mutant/tail/monkey/get_global_feature_list() + return GLOB.sprite_accessories["tail"] // SKYRAT EDIT CHANGE - ORIGINAL: return GLOB.tails_list_monkey + /obj/item/organ/external/tail/lizard name = "lizard tail" desc = "A severed lizard tail. Somewhere, no doubt, a lizard hater is very pleased with themselves." diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index d9d163b8702..56c10327441 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -109,6 +109,7 @@ #include "card_mismatch.dm" #include "cardboard_cutouts.dm" #include "chain_pull_through_space.dm" +#include "changeling.dm" #include "chat_filter.dm" #include "circuit_component_category.dm" #include "client_colours.dm" diff --git a/code/modules/unit_tests/changeling.dm b/code/modules/unit_tests/changeling.dm new file mode 100644 index 00000000000..449188a75fd --- /dev/null +++ b/code/modules/unit_tests/changeling.dm @@ -0,0 +1,99 @@ +/// Tests transformation sting goes back and forth correctly +/datum/unit_test/transformation_sting + var/ling_name = "Is-A-Changeling" + var/base_victim_name + var/last_frame = 1 + var/icon/final_icon + +/datum/unit_test/transformation_sting/Run() + var/mob/living/carbon/human/ling = setup_ling() + var/mob/living/carbon/human/victim = setup_victim() + var/datum/antagonist/changeling/ling_datum = ling.mind.has_antag_datum(/datum/antagonist/changeling) + + // Get the ability we're testing + ling_datum.give_power(/datum/action/changeling/sting/transformation) // SKYRAT EDIT CHANGE - Transformation sting not purchasable here - ORIGINAL : ling_datum.purchase_power(/datum/action/changeling/sting/transformation) + var/datum/action/changeling/sting/transformation/sting_action = locate() in ling.actions + sting_action.selected_dna = ling_datum.current_profile + sting_action.sting_duration = 0.5 SECONDS // just makes sure everything settles. + + // Check that they look different before stinging + add_to_screenshot(ling, victim, both_species = TRUE) + + // Do the sting, make the transformation + sting_action.sting_action(ling, victim) + // Check their name and species align + TEST_ASSERT(victim.has_status_effect(/datum/status_effect/temporary_transformation), "Victim did not get temporary transformation status effect on being transformation stung.") + TEST_ASSERT_EQUAL(victim.real_name, ling_name, "Victim real name did not change on being transformation stung.") + TEST_ASSERT_EQUAL(victim.name, ling_name, "Victim name did not change on being transformation stung.") + TEST_ASSERT_EQUAL(victim.dna.species.type, ling.dna.species.type, "Victim species did not change on being transformation stung.") + TEST_ASSERT_EQUAL(victim.dna.features["mcolor"], ling.dna.features["mcolor"], "Victim mcolor did not change on being transformation stung.") + // Check they actually look the same + add_to_screenshot(ling, victim) + + // Make sure we give it enough time such that the status effect process ticks over and finishes + sleep(sting_action.sting_duration + 0.5 SECONDS) + + // Check their name and species reset correctly + TEST_ASSERT_EQUAL(victim.name, base_victim_name, "Victim name did not change back after transformation sting expired.") + TEST_ASSERT_EQUAL(victim.real_name, base_victim_name, "Victim real name did not change back after transformation sting expired.") + TEST_ASSERT_NOTEQUAL(victim.dna.species.type, ling.dna.species.type, "Victim species did not change back after transformation sting expired.") + TEST_ASSERT_NOTEQUAL(victim.dna.features["mcolor"], ling.dna.features["mcolor"], "Victim mcolor did not reset after transformation sting expired.") + // Check they actually look different again + add_to_screenshot(ling, victim, both_species = TRUE) + + test_screenshot("appearances", final_icon) + +/// Adds both mobs to the screenshot test, if both_species is TRUE, it also adds the victim in lizard form +/datum/unit_test/transformation_sting/proc/add_to_screenshot(mob/living/carbon/human/ling, mob/living/carbon/human/victim, both_species = FALSE) + if(isnull(final_icon)) + final_icon = icon('icons/effects/effects.dmi', "nothing") + + // If we have a lot of dna features with a lot of parts (icons) + // This'll eventually runtime into a bad icon operation + // So we're recaching the icons here to prevent it from failing + final_icon = icon(final_icon) + final_icon.Insert(getFlatIcon(ling, no_anim = TRUE), dir = SOUTH, frame = last_frame) + final_icon.Insert(getFlatIcon(victim, no_anim = TRUE), dir = NORTH, frame = last_frame) + + if(both_species) + var/prior_species = victim.dna.species.type + victim.set_species(/datum/species/lizard) + final_icon.Insert(getFlatIcon(victim, no_anim = TRUE), dir = EAST, frame = last_frame) + victim.set_species(prior_species) + + last_frame += 1 + +/datum/unit_test/transformation_sting/proc/setup_victim() + var/mob/living/carbon/human/victim = allocate(/mob/living/carbon/human/consistent) + base_victim_name = victim.real_name + victim.mind_initialize() + return victim + +/datum/unit_test/transformation_sting/proc/setup_ling() + var/mob/living/carbon/human/ling = allocate(/mob/living/carbon/human/consistent) + // Because we use two consistent humans, we need to change some of the features to know they're actually updating to new values. + // The more DNA features and random things we change, the more likely we are to catch something not updating correctly. + // Yeah guess who/what this is, I dare you. + ling.dna.features["mcolor"] = "#886600" + ling.dna.mutant_bodyparts["tail"] = list(MUTANT_INDEX_NAME = "Smooth", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["tail_lizard"] = "Smooth" + ling.dna.mutant_bodyparts["snout"] = list(MUTANT_INDEX_NAME = "Sharp + Light", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["snout"] = "Sharp + Light" + ling.dna.mutant_bodyparts["horns"] = list(MUTANT_INDEX_NAME = "Curled", MUTANT_INDEX_COLOR_LIST = list("#292826", "#292826", "#8292826")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["horns"] = "Curved" + ling.dna.mutant_bodyparts["frills"] = list(MUTANT_INDEX_NAME = "Short", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["frills"] = "Sort" + ling.dna.mutant_bodyparts["spines"] = list(MUTANT_INDEX_NAME = "Long + Membrane", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["spines"] = "Long + Membrane" + ling.dna.body_markings["chest"] = list("Light Belly" = list("#886600", 0)) // SKYRAT EDIT CHANGE - ORIGINAL : ling.dna.features[body_markings] = list("Light Belly") + ling.dna.features["legs"] = DIGITIGRADE_LEGS + ling.eye_color_left = "#FFFFFF" + ling.eye_color_right = "#FFFFFF" + ling.dna.update_ui_block(DNA_EYE_COLOR_LEFT_BLOCK) + ling.dna.update_ui_block(DNA_EYE_COLOR_RIGHT_BLOCK) + ling.set_species(/datum/species/lizard) + + ling.real_name = ling_name + ling.dna.real_name = ling_name + ling.name = ling_name + ling.dna.initialize_dna(create_mutation_blocks = FALSE, randomize_features = FALSE) + + ling.mind_initialize() + ling.mind.add_antag_datum(/datum/antagonist/changeling) + + return ling diff --git a/code/modules/unit_tests/monkey_business.dm b/code/modules/unit_tests/monkey_business.dm index 20bfffe6a48..80044a0486d 100644 --- a/code/modules/unit_tests/monkey_business.dm +++ b/code/modules/unit_tests/monkey_business.dm @@ -14,7 +14,8 @@ /datum/unit_test/monkey_business/Run() for(var/monkey_id in 1 to length(GLOB.the_station_areas)) - var/mob/living/carbon/human/monkey = allocate(/mob/living/carbon/human/consistent, get_first_open_turf_in_area(GLOB.the_station_areas[monkey_id])) + var/area/monkey_zone = GLOB.areas_by_type[GLOB.the_station_areas[monkey_id]] + var/mob/living/carbon/human/monkey = allocate(/mob/living/carbon/human/consistent, get_first_open_turf_in_area(monkey_zone)) monkey.set_species(/datum/species/monkey) monkey.set_name("Monkey [monkey_id]") if(monkey_id % monkey_angry_nth == 0) // BLOOD FOR THE BLOOD GODS diff --git a/code/modules/unit_tests/say.dm b/code/modules/unit_tests/say.dm index 3ae55a12e37..ec58dcedc88 100644 --- a/code/modules/unit_tests/say.dm +++ b/code/modules/unit_tests/say.dm @@ -58,12 +58,15 @@ /// This runs some simple speech tests on a speaker and listener and determines if a person can hear whispering or speaking as they are moved a distance away /datum/unit_test/speech - var/list/handle_speech_result = null - var/list/handle_hearing_result = null var/mob/living/carbon/human/speaker var/mob/living/carbon/human/listener + var/list/handle_speech_result = null + var/list/handle_hearing_result = null + var/obj/item/radio/speaker_radio var/obj/item/radio/listener_radio + var/speaker_radio_heard_message = FALSE + var/listener_radio_received_message = FALSE /datum/unit_test/speech/proc/handle_speech(datum/source, list/speech_args) SIGNAL_HANDLER @@ -99,6 +102,16 @@ handle_hearing_result = list() handle_hearing_result += hearing_args +/datum/unit_test/speech/proc/handle_radio_hearing(datum/source, mob/living/user, message, channel) + SIGNAL_HANDLER + + speaker_radio_heard_message = TRUE + +/datum/unit_test/speech/proc/handle_radio_speech(datum/source, list/data) + SIGNAL_HANDLER + + listener_radio_received_message = TRUE + /datum/unit_test/speech/Run() speaker = allocate(/mob/living/carbon/human/consistent) // Name changes to make understanding breakpoints easier @@ -114,7 +127,10 @@ listener.mock_client = mock_client RegisterSignal(speaker, COMSIG_MOB_SAY, PROC_REF(handle_speech)) + RegisterSignal(speaker_radio, COMSIG_RADIO_NEW_MESSAGE, PROC_REF(handle_radio_hearing)) + RegisterSignal(listener, COMSIG_MOVABLE_HEAR, PROC_REF(handle_hearing)) + RegisterSignal(listener_radio, COMSIG_RADIO_RECEIVE_MESSAGE, PROC_REF(handle_radio_speech)) // speaking and whispering should be hearable conversation(distance = 1) @@ -169,6 +185,9 @@ handle_hearing_result = null /datum/unit_test/speech/proc/radio_test() + speaker_radio_heard_message = FALSE + listener_radio_received_message = FALSE + speaker.forceMove(run_loc_floor_bottom_left) listener.forceMove(locate((run_loc_floor_bottom_left.x + 10), run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) @@ -186,11 +205,15 @@ speaker.say(pangram_quote) TEST_ASSERT(handle_speech_result, "Handle speech signal was not fired (radio test)") - TEST_ASSERT(islist(handle_hearing_result), "Listener failed to hear radio message (radio test)") + TEST_ASSERT(speaker_radio_heard_message, "Speaker's radio did not hear them speak (radio test)") TEST_ASSERT_EQUAL(speaker_radio.get_frequency(), listener_radio.get_frequency(), "Radio frequencies were not equal (radio test)") + TEST_ASSERT(listener_radio_received_message, "Listener's radio did not receive the broadcast (radio test)") + TEST_ASSERT(islist(handle_hearing_result), "Listener failed to hear radio message (radio test)") handle_speech_result = null handle_hearing_result = null + speaker_radio_heard_message = FALSE + listener_radio_received_message = FALSE speaker_radio.set_frequency(FREQ_CTF_RED) speaker.say(pangram_quote) @@ -200,6 +223,8 @@ handle_speech_result = null handle_hearing_result = null + speaker_radio_heard_message = FALSE + listener_radio_received_message = FALSE speaker_radio.set_broadcasting(FALSE) #undef NORMAL_HEARING_RANGE diff --git a/code/modules/unit_tests/screenshots/transformation_sting_appearances.png b/code/modules/unit_tests/screenshots/transformation_sting_appearances.png new file mode 100644 index 00000000000..ce0545d1b56 Binary files /dev/null and b/code/modules/unit_tests/screenshots/transformation_sting_appearances.png differ diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index e51205c00e4..5e3d9d3b055 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -52,11 +52,12 @@ /obj/item/skillchip/appraiser = 2, /obj/item/skillchip/basketweaving = 2, /obj/item/skillchip/bonsai = 2, + /obj/item/skillchip/intj = 2, /obj/item/skillchip/light_remover = 2, + /obj/item/skillchip/master_angler = 2, /obj/item/skillchip/sabrage = 2, /obj/item/skillchip/useless_adapter = 5, /obj/item/skillchip/wine_taster = 2, - /obj/item/skillchip/master_angler = 2, ), ), list( diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index b54edffe4c0..feae0499655 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -16,6 +16,7 @@ /obj/item/storage/box/evidence = 6, /obj/item/flashlight/seclite = 4, /obj/item/restraints/legcuffs/bola/energy = 7, + /obj/item/clothing/gloves/tackler = 5, ) contraband = list( /obj/item/clothing/glasses/sunglasses = 2, @@ -26,7 +27,6 @@ /obj/item/coin/antagtoken = 1, /obj/item/clothing/head/helmet/blueshirt = 1, /obj/item/clothing/suit/armor/vest/blueshirt = 1, - /obj/item/clothing/gloves/tackler = 5, /obj/item/grenade/stingbang = 1, /obj/item/watertank/pepperspray = 2, /obj/item/storage/belt/holster/energy = 4, diff --git a/html/changelogs/AutoChangeLog-pr-774.yml b/html/changelogs/AutoChangeLog-pr-774.yml deleted file mode 100644 index eb01bc4609b..00000000000 --- a/html/changelogs/AutoChangeLog-pr-774.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "san7890" -delete-after: True -changes: - - code_imp: "The currently operating rust-g version on a live server is posted to places like the runtime.log, in the same place where the revision information and any applicable test merges already were. /:cl:" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-780.yml b/html/changelogs/AutoChangeLog-pr-780.yml deleted file mode 100644 index d94f0207782..00000000000 --- a/html/changelogs/AutoChangeLog-pr-780.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Nerev4r" -delete-after: True -changes: - - rscadd: "NanoTrasen, after extensive testing in a variety of stars' light wavelengths, have deemed their PDAs ready enough to actually use the onboard cameras they already had." \ No newline at end of file diff --git a/html/changelogs/archive/2023-11.yml b/html/changelogs/archive/2023-11.yml index 2462f64f68e..239c9a20bce 100644 --- a/html/changelogs/archive/2023-11.yml +++ b/html/changelogs/archive/2023-11.yml @@ -1146,3 +1146,121 @@ this in poor ways may displease the Gods. Woe upon your lineage. - rscadd: A single pack of glowshroom mycelium has been added to the Hearth's starting seed stores for the benefit of creative healers, shamans, and radiation enthusiasts. +2023-11-23: + Autisem: + - rscadd: Cyborg inducer for engineering borgs + - balance: The borg RPED can hold as many part as the BSRPED now + - balance: Cyborg chargers now draw from the power net as cell chargers do + Iajret: + - bugfix: borers can once again fill their hosts with various wonders of chemistry + Nerev4r: + - rscadd: NanoTrasen, after extensive testing in a variety of stars' light wavelengths, + have deemed their PDAs ready enough to actually use the onboard cameras they + already had. + OrionTheFox: + - qol: Allergy Dogtags (and any other dogtags, really) are now actually whitelisted + to fit into wallets. + san7890: + - code_imp: 'The currently operating rust-g version on a live server is posted to + places like the runtime.log, in the same place where the revision information + and any applicable test merges already were. /:cl:' +2023-11-24: + Jacquerel: + - bugfix: The plasma river is about as deadly for animals as it is for humans. + - bugfix: Golems can now wade in the plasma river unscathed. + - bugfix: Undismemberable limbs will no longer be dismembered by the plasma river. + - balance: Golems and plasmamen cannot become husked. + - image: Robotic and Skeletal parts will remain distinct while the rest of the body + is husked. + - rscadd: A new skill chip can be found in maintenance or purchased from the vendor, + allowing you to experience food in new and exciting ways. + - rscadd: Abductors also have access to this incredible power, simply using their + genius level brains. + JohnFulpWillard: + - qol: Mafia panel no longer shows vote buttons if you're on stand, shows the roles + of revealed players, and list out who is on the stand, if any. + LovliestPlant: + - rscadd: Adds links to any special rules or metaprotections to antag's objective + panels. + Melbert: + - balance: Transformation sting now lasts 8 minutes, down from permanent. However, + the effect is paused for dead and stasis mobs, making it permanent SO LONG AS + they stay dead or in stasis. The effect is also permanent if used on a monkey. + - balance: Transformation sting now costs 33 chemicals, down from 50. + - balance: Transformation sting now costs 2 dna points, down from 3. + - bugfix: Transformation sting works on monkeys again. + - refactor: Refactored a bit of human randomization. + - refactor: Refactors how ethereals update their color when damaged. + Nerev4r: + - bugfix: Chameleon mutation is toggleable again. + - rscadd: Certain firmware updates rolled out, finally, in Sector 13 have allowed + machines to emulate personal computers within their brains. + RatFromTheJungle: + - bugfix: fixes punches doing like triple stamina damage, by removing a 2.6x multiplier. + Smol42: + - rscadd: Added four acrador snouts. + Steals-The-PRs: + - bugfix: Androids cannot have overdose effect by any chems. + SyncIt21: + - bugfix: autolathe does not diminish materials from custom material items like + toolboxes when printing them in bulk. Also does not gray out that item in the + UI + - bugfix: autloathe correctly updates UI after inserting items into it + - bugfix: RCD can build directional windows on top of existing grills & without + them. + The Sharkening: + - refactor: Removes unused Kilostation Automapper templates + TwistedSilicon: + - bugfix: Window damage overlays have been fixed. + Xander3359: + - admin: Remove "Make AI" from VV dropdown + Y0SH1M4S73R: + - rscadd: Certain types of pens now function like you expect they would when inserted + into a foam dart + - qol: Examining a foam dart closely will show you how to modify it, or what it + is modified with + aaaa1023: + - qol: adds pixel perfect 4x, 4.5x, and 5x + dieamond13: + - qol: gives roundstart prisoners a key memory of what their crime is + jjpark-kb: + - bugfix: gutlunches now produce miner salve instead of milk, as well as the other + reagents if fed the correct ore + - rscadd: you can craft the gutlunch trough + - qol: you can fill the gutlunch trough with a mining bag + - rscadd: you can hammer glass shards to get back sand + lizardqueenlexi: + - bugfix: Skillsoft's skillchip stations are now ADA-compliant (Astronauts with + Disabilities Act). Paraplegic characters can now implant themselves with skillchips, + the same as anyone else. + necromanceranne: + - balance: Judo Joe, archnemesis of Maint Khan, has begun re-airing his midnight + infomercials shilling his extremely expensive Tackle Supreme Judo Karate Training + video tapes. Unable to pass up a 'bargain', Nanotrasen has purchased these tapes + en masse. Tackling techniques have started to improve, as well as Nanotrasen's + tackling instructional algorithms within tackle gloves. + - balance: The outcomes for tackling are more equalized. It isn't as feast or famine, + and should be somewhat more controllable without becoming too severe. + - rscadd: Blocking successfully against a tackle will force the tackle to be a neutral + outcome. + - rscadd: Unarmed effectiveness from arms now contributes to attacking with and + defending from tackles. + - rscadd: Those who refuse to use firearms (like Sleeping Carp users and insane + unholy berzerkers) are better at tackling others. + - rscadd: Riot specialized armor, and not just riot armor, now contributes meaningfully + to tackling effectiveness. + - balance: MK.1 Swat Suits, the ones that come in SWAT crates, now functions similarly + to riot armor. + - rscadd: Settlers from the outer rims have noticed they aren't very good at protecting + themselves against Judo Joe's clearly discriminatory tackling techniques. + - rscadd: Security lockers come with gripper gloves, security vendors now sell them + as standard items, and the HoS' garment bag now has a pair of gorilla gloves. + Gripper gloves have a positive skill bonus to tackling. + - rscadd: Being insane also makes you INSANELY good at tackling but also INSANELY + likely to eat shit on a whiff. DO OR DIE, BITCH. + - refactor: Shoving slowdown and all its implementations now use a status effect, + Staggered. + vinylspiders: + - bugfix: fullupgrade chem dispensers will now spawn with all their chems + vvvv-vvvv: + - bugfix: Fix refresh button in log viewer diff --git a/icons/obj/weapons/guns/toy.dmi b/icons/obj/weapons/guns/toy.dmi index 83a85e7e447..3f7e509b699 100644 Binary files a/icons/obj/weapons/guns/toy.dmi and b/icons/obj/weapons/guns/toy.dmi differ diff --git a/modular_skyrat/master_files/code/datums/components/tippable.dm b/modular_skyrat/master_files/code/datums/components/tippable.dm index 09013130f1e..e911914c1ce 100644 --- a/modular_skyrat/master_files/code/datums/components/tippable.dm +++ b/modular_skyrat/master_files/code/datums/components/tippable.dm @@ -8,14 +8,14 @@ var/mob/living/silicon/robot/robot = tipped_mob if(is_tipped) ADD_TRAIT(robot, TRAIT_IMMOBILIZED, TIPPED_OVER) - if(R_TRAIT_UNIQUETIP in robot.model.model_features) + if(TRAIT_R_UNIQUETIP in robot.model.model_features) robot.icon_state = "[robot.model.cyborg_base_icon]-tipped" robot.cut_overlays() // Cut eye-lights return robot.transform = turn(robot.transform, 180) else REMOVE_TRAIT(robot, TRAIT_IMMOBILIZED, TIPPED_OVER) - if(R_TRAIT_UNIQUETIP in robot.model.model_features) + if(TRAIT_R_UNIQUETIP in robot.model.model_features) robot.icon_state = "[robot.model.cyborg_base_icon]" robot.regenerate_icons() // Return eye-lights return diff --git a/modular_skyrat/master_files/code/datums/mutations/chameleon.dm b/modular_skyrat/master_files/code/datums/mutations/chameleon.dm new file mode 100644 index 00000000000..7bd88ed3eb2 --- /dev/null +++ b/modular_skyrat/master_files/code/datums/mutations/chameleon.dm @@ -0,0 +1,28 @@ +// toggleable chameleon skin +/datum/mutation/human/chameleon + power_path = /datum/action/cooldown/spell/chameleon_skin_activate + +/datum/action/cooldown/spell/chameleon_skin_activate + name = "Activate Chameleon Skin" + desc = "The chromatophores in your skin adjust to your surroundings, as long as you stay still." + spell_requirements = NONE + button_icon = 'icons/mob/actions/actions_minor_antag.dmi' + button_icon_state = "ninja_cloak" + +/datum/action/cooldown/spell/chameleon_skin_activate/cast(list/targets, mob/user = usr) + . = ..() + + if(HAS_TRAIT(user,TRAIT_CHAMELEON_SKIN)) + chameleon_skin_deactivate(user) + return + + ADD_TRAIT(user, TRAIT_CHAMELEON_SKIN, GENETIC_MUTATION) + to_chat(user, "The pigmentation of your skin shifts and starts to take on the colors of your surroundings.") + +/datum/action/cooldown/spell/chameleon_skin_activate/proc/chameleon_skin_deactivate(mob/user = usr) + if(!HAS_TRAIT_FROM(user,TRAIT_CHAMELEON_SKIN, GENETIC_MUTATION)) + return + + REMOVE_TRAIT(user, TRAIT_CHAMELEON_SKIN, GENETIC_MUTATION) + user.alpha = 255 + to_chat(user, text("Your skin shifts as it shimmers back into its original colors.")) diff --git a/modular_skyrat/master_files/code/datums/traits/good.dm b/modular_skyrat/master_files/code/datums/traits/good.dm index 08f265145a9..1a5a6d9d26e 100644 --- a/modular_skyrat/master_files/code/datums/traits/good.dm +++ b/modular_skyrat/master_files/code/datums/traits/good.dm @@ -14,7 +14,7 @@ name = "Linguist" desc = "You're a student of numerous languages and come with an additional language point." value = 4 - mob_trait = QUIRK_LINGUIST + mob_trait = TRAIT_LINGUIST gain_text = span_notice("Your brain seems more equipped to handle different modes of conversation.") lose_text = span_danger("Your grasp of the finer points of Draconic idioms fades away.") medical_record_text = "Patient demonstrates a high brain plasticity in regards to language learning." diff --git a/modular_skyrat/master_files/code/datums/traits/neutral.dm b/modular_skyrat/master_files/code/datums/traits/neutral.dm index 5f3fe059464..432fa728f03 100644 --- a/modular_skyrat/master_files/code/datums/traits/neutral.dm +++ b/modular_skyrat/master_files/code/datums/traits/neutral.dm @@ -1,5 +1,3 @@ -#define TRAIT_HYDRA_HEADS "hydrahead" // We still dont have a centralised trait file - GLOBAL_VAR_INIT(DNR_trait_overlay, generate_DNR_trait_overlay()) /// Instantiates GLOB.DNR_trait_overlay by creating a new mutable_appearance instance of the overlay. diff --git a/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm b/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm index d68f78c5d46..3a59d18fc52 100644 --- a/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/modular_skyrat/master_files/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -78,6 +78,7 @@ GLOBAL_LIST_INIT(skyrat_wood_recipes, list( new/datum/stack_recipe("produce bin", /obj/machinery/smartfridge/producebin, 10, time = 2 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_STRUCTURE), new/datum/stack_recipe("storage barrel", /obj/structure/closet/crate/wooden/storage_barrel, 4, time = 2 SECONDS, one_per_turf = TRUE, on_solid_ground = FALSE, category = CAT_STRUCTURE), new/datum/stack_recipe("worm barrel", /obj/structure/wormfarm, 5, time = 2 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_TOOLS), + new/datum/stack_recipe("gutlunch trough", /obj/structure/ore_container/gutlunch_trough, 5, time = 2 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_STRUCTURE), new/datum/stack_recipe("sturdy wooden fence", /obj/structure/railing/wooden_fencing, 5, time = 2 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_TOOLS), new/datum/stack_recipe("sturdy wooden fence gate", /obj/structure/railing/wooden_fencing/gate, 5, time = 2 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_TOOLS), )) diff --git a/modular_skyrat/master_files/code/modules/antagonists/changeling/powers/tiny_prick.dm b/modular_skyrat/master_files/code/modules/antagonists/changeling/powers/tiny_prick.dm new file mode 100644 index 00000000000..0eaf7f50f9f --- /dev/null +++ b/modular_skyrat/master_files/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -0,0 +1,3 @@ +// Transformation sting is not able to be purchased +/datum/action/changeling/sting/transformation + dna_cost = CHANGELING_POWER_UNOBTAINABLE diff --git a/modular_skyrat/master_files/code/modules/client/preferences.dm b/modular_skyrat/master_files/code/modules/client/preferences.dm index bc97b467cd9..52a70bd907c 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences.dm @@ -111,28 +111,29 @@ return language /datum/preferences/proc/validate_species_parts() - var/list/target_bodyparts = pref_species.default_mutant_bodyparts.Copy() + var/list/default_bodyparts = GLOB.default_mutant_bodyparts[pref_species.name] + var/list/target_bodyparts = default_bodyparts.Copy() // Remove all "extra" accessories for(var/key in mutant_bodyparts) if(!GLOB.sprite_accessories[key]) // That accessory no longer exists, remove it mutant_bodyparts -= key continue - if(!pref_species.default_mutant_bodyparts[key]) + if(!GLOB.default_mutant_bodyparts[pref_species.name][key]) mutant_bodyparts -= key continue if(!GLOB.sprite_accessories[key][mutant_bodyparts[key][MUTANT_INDEX_NAME]]) // The individual accessory no longer exists - mutant_bodyparts[key][MUTANT_INDEX_NAME] = pref_species.default_mutant_bodyparts[key] + mutant_bodyparts[key][MUTANT_INDEX_NAME] = GLOB.default_mutant_bodyparts[pref_species.name[key][MUTANTPART_NAME]] validate_color_keys_for_part(key) // Validate the color count of each accessory that wasnt removed // Add any missing accessories for(var/key in target_bodyparts) if(!mutant_bodyparts[key]) var/datum/sprite_accessory/SA - if(target_bodyparts[key] == ACC_RANDOM) + if(target_bodyparts[key][MUTANTPART_CAN_RANDOMIZE]) SA = random_accessory_of_key_for_species(key, pref_species) else - SA = GLOB.sprite_accessories[key][target_bodyparts[key]] + SA = GLOB.sprite_accessories[key][target_bodyparts[key][MUTANTPART_NAME]] var/final_list = list() final_list[MUTANT_INDEX_NAME] = SA.name final_list[MUTANT_INDEX_COLOR_LIST] = SA.get_default_color(features, pref_species) diff --git a/modular_skyrat/master_files/code/modules/client/preferences/middleware/languages.dm b/modular_skyrat/master_files/code/modules/client/preferences/middleware/languages.dm index 22a0854e88d..d9412fd8066 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences/middleware/languages.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences/middleware/languages.dm @@ -65,7 +65,7 @@ var/list/data = list() - var/max_languages = preferences.all_quirks.Find(QUIRK_LINGUIST) ? MAX_LANGUAGES_LINGUIST : MAX_LANGUAGES_NORMAL + var/max_languages = preferences.all_quirks.Find(TRAIT_LINGUIST) ? MAX_LANGUAGES_LINGUIST : MAX_LANGUAGES_NORMAL var/species_type = preferences.read_preference(/datum/preference/choiced/species) var/datum/species/species = new species_type() var/datum/language_holder/lang_holder = preferences.get_adjusted_language_holder() @@ -125,7 +125,7 @@ */ /datum/preference_middleware/languages/proc/give_language(list/params) var/language_name = params["language_name"] - var/max_languages = preferences.all_quirks.Find(QUIRK_LINGUIST) ? MAX_LANGUAGES_LINGUIST : MAX_LANGUAGES_NORMAL + var/max_languages = preferences.all_quirks.Find(TRAIT_LINGUIST) ? MAX_LANGUAGES_LINGUIST : MAX_LANGUAGES_NORMAL if(preferences.languages && preferences.languages.len == max_languages) // too many languages return TRUE diff --git a/modular_skyrat/master_files/code/modules/client/preferences/mutant_parts.dm b/modular_skyrat/master_files/code/modules/client/preferences/mutant_parts.dm index fd11a6bd3b5..57c26e4dd37 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences/mutant_parts.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences/mutant_parts.dm @@ -164,6 +164,9 @@ . = ..() var/obj/item/bodypart/head/our_head = target.get_bodypart(BODY_ZONE_HEAD) + if(isnull(our_head)) // dullahans. + return + if(.) our_head.bodytype |= BODYTYPE_SNOUTED else diff --git a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm index 30df82a7f11..1bb68a1f10f 100644 --- a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm +++ b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm @@ -14,7 +14,7 @@ var/datum/preference/preference = GLOB.preference_entries[preference_type] if ( \ - (preference.relevant_mutant_bodypart in default_mutant_bodyparts) \ + (preference.relevant_mutant_bodypart in GLOB.default_mutant_bodyparts[name]) \ || (preference.relevant_inherent_trait in inherent_traits) \ || (preference.relevant_head_flag && check_head_flags(preference.relevant_head_flag)) \ ) diff --git a/modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi b/modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi index 86f4c783e20..fa2fc8b89aa 100644 Binary files a/modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi and b/modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi differ diff --git a/modular_skyrat/modules/ashwalkers/code/buildings/gutluncher_foodtrough.dm b/modular_skyrat/modules/ashwalkers/code/buildings/gutluncher_foodtrough.dm new file mode 100644 index 00000000000..fec1b4c1715 --- /dev/null +++ b/modular_skyrat/modules/ashwalkers/code/buildings/gutluncher_foodtrough.dm @@ -0,0 +1,6 @@ +/obj/structure/ore_container/gutlunch_trough/attackby(obj/item/attacking_item, mob/living/carbon/human/user, list/modifiers) + if(!istype(attacking_item, /obj/item/storage/bag/ore)) + return ..() + + for(var/obj/item/stack/ore/stored_ore in attacking_item.contents) + attacking_item.atom_storage?.attempt_remove(stored_ore, src) diff --git a/modular_skyrat/modules/ashwalkers/code/items/ash_seedmesh.dm b/modular_skyrat/modules/ashwalkers/code/items/ash_seedmesh.dm index a0882c288a1..205e357313e 100644 --- a/modular_skyrat/modules/ashwalkers/code/items/ash_seedmesh.dm +++ b/modular_skyrat/modules/ashwalkers/code/items/ash_seedmesh.dm @@ -9,23 +9,26 @@ /obj/item/seed_mesh/attackby(obj/item/attacking_item, mob/user, params) if(istype(attacking_item, /obj/item/stack/ore/glass)) - var/obj/item/stack/stack_item = attacking_item + var/obj/item/stack/ore/ore_item = attacking_item + if(ore_item.points == 0) + user.balloon_alert(user, "[ore_item] is worthless!") + return - while(stack_item.amount >= 5) + while(ore_item.amount >= 5) if(!do_after(user, 5 SECONDS, src)) user.balloon_alert(user, "have to stand still!") return - if(!stack_item.use(5)) - user.balloon_alert(user, "unable to use five of [stack_item]!") + if(!ore_item.use(5)) + user.balloon_alert(user, "unable to use five of [ore_item]!") return if(prob(70)) - user.balloon_alert(user, "[stack_item] reveals nothing!") + user.balloon_alert(user, "[ore_item] reveals nothing!") continue var/spawn_seed = pick(subtypesof(/obj/item/seeds) - seeds_blacklist) new spawn_seed(get_turf(src)) - user.balloon_alert(user, "[stack_item] revealed something!") + user.balloon_alert(user, "[ore_item] revealed something!") return ..() diff --git a/modular_skyrat/modules/better_vox/code/vox_species.dm b/modular_skyrat/modules/better_vox/code/vox_species.dm index 4d3f1b237c9..a8c2d4c0e2e 100644 --- a/modular_skyrat/modules/better_vox/code/vox_species.dm +++ b/modular_skyrat/modules/better_vox/code/vox_species.dm @@ -17,9 +17,6 @@ breathid = "n2" mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/vox - default_mutant_bodyparts = list( - "tail" = "Vox Primalis Tail", - ) payday_modifier = 1.0 outfit_important_for_life = /datum/outfit/vox species_language_holder = /datum/language_holder/vox @@ -50,6 +47,10 @@ LOADOUT_ITEM_EARS = VOX_PRIMALIS_EARS_ICON, ) +/datum/species/vox_primalis/get_default_mutant_bodyparts() + return list( + "tail" = list("Vox Primalis Tail", FALSE), + ) /datum/species/vox_primalis/pre_equip_species_outfit(datum/job/job, mob/living/carbon/human/equipping, visuals_only) . = ..() diff --git a/modular_skyrat/modules/borgs/code/robot.dm b/modular_skyrat/modules/borgs/code/robot.dm index 3de94b08d8c..8bddf039f4d 100644 --- a/modular_skyrat/modules/borgs/code/robot.dm +++ b/modular_skyrat/modules/borgs/code/robot.dm @@ -13,7 +13,7 @@ layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs density = FALSE // We lose density and stop bumping passable dense things. - if(model && model.model_features && (R_TRAIT_TALL in model.model_features)) + if(model && model.model_features && (TRAIT_R_TALL in model.model_features)) maptext_height = 32 //Offset base chat-height value // Resting effects @@ -44,7 +44,7 @@ if(layer == LYING_MOB_LAYER) layer = initial(layer) density = initial(density) // We were prone before, so we become dense and things can bump into us again. - if(model && model.model_features && (R_TRAIT_TALL in model.model_features)) + if(model && model.model_features && (TRAIT_R_TALL in model.model_features)) maptext_height = 48 //Offset value of tallborgs /mob/living/silicon/robot/proc/rest_style() @@ -103,7 +103,7 @@ * model_features is defined in modular_skyrat\modules\altborgs\code\modules\mob\living\silicon\robot\robot_model.dm. */ /mob/living/silicon/robot/proc/can_rest() - if(model && model.model_features && ((R_TRAIT_WIDE in model.model_features) || (R_TRAIT_TALL in model.model_features))) + if(model && model.model_features && ((TRAIT_R_WIDE in model.model_features) || (TRAIT_R_TALL in model.model_features))) if(TRAIT_IMMOBILIZED in _status_traits) return FALSE return TRUE diff --git a/modular_skyrat/modules/borgs/code/robot_items.dm b/modular_skyrat/modules/borgs/code/robot_items.dm index 96a03b2e38d..1e04b3103ad 100644 --- a/modular_skyrat/modules/borgs/code/robot_items.dm +++ b/modular_skyrat/modules/borgs/code/robot_items.dm @@ -681,7 +681,7 @@ var/list/details = disguise_model.borg_skins[skin] var/image/reskin = image(icon = details[SKIN_ICON] || 'icons/mob/silicon/robots.dmi', icon_state = details[SKIN_ICON_STATE]) if (!isnull(details[SKIN_FEATURES])) - if (R_TRAIT_WIDE in details[SKIN_FEATURES]) + if (TRAIT_R_WIDE in details[SKIN_FEATURES]) reskin.pixel_x -= 16 reskin_icons[skin] = reskin var/borg_skin = show_radial_menu(cyborg, cyborg, reskin_icons, custom_check = CALLBACK(src, PROC_REF(check_menu), cyborg), radius = 38, require_near = TRUE) diff --git a/modular_skyrat/modules/borgs/code/robot_model.dm b/modular_skyrat/modules/borgs/code/robot_model.dm index ffdd2d5e684..8c94520ad0d 100644 --- a/modular_skyrat/modules/borgs/code/robot_model.dm +++ b/modular_skyrat/modules/borgs/code/robot_model.dm @@ -11,7 +11,7 @@ var/mob/living/silicon/robot/cyborg = robot || loc if (!istype(robot)) return - if (model_features && (R_TRAIT_TALL in model_features)) + if (model_features && (TRAIT_R_TALL in model_features)) cyborg.maptext_height = 48 //Runechat blabla cyborg.AddElement(/datum/element/footstep, FOOTSTEP_MOB_SHOE, 2, -6, sound_vary = TRUE) add_verb(cyborg, /mob/living/silicon/robot/proc/robot_lay_down) @@ -33,7 +33,7 @@ var/mob/living/silicon/robot/cyborg = robot || loc if (!istype(robot)) return - if (model_features && (R_TRAIT_WIDE in model_features)) + if (model_features && (TRAIT_R_WIDE in model_features)) hat_offset = INFINITY cyborg.set_base_pixel_x(-16) add_verb(cyborg, /mob/living/silicon/robot/proc/robot_lay_down) @@ -47,16 +47,16 @@ /obj/item/robot_model/standard name = "Standard" borg_skins = list( - "Default" = list(SKIN_ICON_STATE = "robot", SKIN_FEATURES = list(R_TRAIT_SMALL)), - "Marina" = list(SKIN_ICON_STATE = "marinasd", SKIN_ICON = CYBORG_ICON_STANDARD, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK)), - "Heavy" = list(SKIN_ICON_STATE = "heavysd", SKIN_ICON = CYBORG_ICON_STANDARD, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK)), - "Eyebot" = list(SKIN_ICON_STATE = "eyebotsd", SKIN_ICON = CYBORG_ICON_STANDARD, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL)), - "Robot" = list(SKIN_ICON_STATE = "robot_old", SKIN_ICON = CYBORG_ICON_STANDARD, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK)), + "Default" = list(SKIN_ICON_STATE = "robot", SKIN_FEATURES = list(TRAIT_R_SMALL)), + "Marina" = list(SKIN_ICON_STATE = "marinasd", SKIN_ICON = CYBORG_ICON_STANDARD, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK)), + "Heavy" = list(SKIN_ICON_STATE = "heavysd", SKIN_ICON = CYBORG_ICON_STANDARD, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK)), + "Eyebot" = list(SKIN_ICON_STATE = "eyebotsd", SKIN_ICON = CYBORG_ICON_STANDARD, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL)), + "Robot" = list(SKIN_ICON_STATE = "robot_old", SKIN_ICON = CYBORG_ICON_STANDARD, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK)), "Bootyborg" = list(SKIN_ICON_STATE = "bootysd", SKIN_ICON = CYBORG_ICON_STANDARD), "Male Bootyborg" = list(SKIN_ICON_STATE = "male_bootysd", SKIN_ICON = CYBORG_ICON_STANDARD), "Protectron" = list(SKIN_ICON_STATE = "protectron_standard", SKIN_ICON = CYBORG_ICON_STANDARD), "Miss M" = list(SKIN_ICON_STATE = "missm_sd", SKIN_ICON = CYBORG_ICON_STANDARD), - "Partyhound" = list(SKIN_ICON_STATE = "k69", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)) + "Partyhound" = list(SKIN_ICON_STATE = "k69", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)) ) //SERVICE @@ -72,7 +72,7 @@ "Heavy" = list(SKIN_ICON_STATE = "heavyserv", SKIN_ICON = CYBORG_ICON_SERVICE), "Kent" = list(SKIN_ICON_STATE = "kent", SKIN_LIGHT_KEY = "medical", SKIN_HAT_OFFSET = 3), "Can" = list(SKIN_ICON_STATE = "kent", SKIN_LIGHT_KEY = "medical", SKIN_HAT_OFFSET = 3), - "Zoomba" = list(SKIN_ICON_STATE = "zoomba_green", SKIN_ICON = CYBORG_ICON_SERVICE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL), SKIN_HAT_OFFSET = -13), + "Zoomba" = list(SKIN_ICON_STATE = "zoomba_green", SKIN_ICON = CYBORG_ICON_SERVICE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL), SKIN_HAT_OFFSET = -13), "ARACHNE" = list(SKIN_ICON_STATE = "arachne_service", SKIN_ICON = CYBORG_ICON_SERVICE), "Slipper" = list(SKIN_ICON_STATE = "slipper_service", SKIN_ICON = CYBORG_ICON_SERVICE), "Bootyborg" = list(SKIN_ICON_STATE = "bootyservice", SKIN_ICON = CYBORG_ICON_SERVICE), @@ -83,20 +83,20 @@ "Mech" = list(SKIN_ICON_STATE = "lloyd", SKIN_ICON = CYBORG_ICON_SERVICE), "Handy" = list(SKIN_ICON_STATE = "handy-service", SKIN_ICON = CYBORG_ICON_SERVICE), /// 64x32 skins - "Borgi" = list(SKIN_ICON_STATE = "borgi-serv", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE, R_TRAIT_SMALL)), - "Drake" = list(SKIN_ICON_STATE = "drakeserv", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Vale" = list(SKIN_ICON_STATE = "valeserv", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "ValeDark" = list(SKIN_ICON_STATE = "valeservdark", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Darkhound" = list(SKIN_ICON_STATE = "k50", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Partyhound" = list(SKIN_ICON_STATE = "k69", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), + "Borgi" = list(SKIN_ICON_STATE = "borgi-serv", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE, TRAIT_R_SMALL)), + "Drake" = list(SKIN_ICON_STATE = "drakeserv", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Vale" = list(SKIN_ICON_STATE = "valeserv", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "ValeDark" = list(SKIN_ICON_STATE = "valeservdark", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Darkhound" = list(SKIN_ICON_STATE = "k50", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Partyhound" = list(SKIN_ICON_STATE = "k69", SKIN_ICON = CYBORG_ICON_SERVICE_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), /// 32x64 skins - "Meka" = list(SKIN_ICON_STATE = "mekaserve", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "Meka (Alt)" = list(SKIN_ICON_STATE = "mekaserve_alt", SKIN_LIGHT_KEY = "mekaserve", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekaserv", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekaserv", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Barista)" = list(SKIN_ICON_STATE = "k4tserve", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (80s)" = list(SKIN_ICON_STATE = "k4tserve_alt1", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Dispenser)" = list(SKIN_ICON_STATE = "k4tserve_alt2", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekaserve", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "Meka (Alt)" = list(SKIN_ICON_STATE = "mekaserve_alt", SKIN_LIGHT_KEY = "mekaserve", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekaserv", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekaserv", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Barista)" = list(SKIN_ICON_STATE = "k4tserve", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (80s)" = list(SKIN_ICON_STATE = "k4tserve_alt1", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Dispenser)" = list(SKIN_ICON_STATE = "k4tserve_alt2", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) //MINING @@ -106,8 +106,8 @@ /// 32x32 Skins "Lavaland" = list(SKIN_ICON_STATE = "miner", SKIN_LIGHT_KEY = "miner"), "Asteroid" = list(SKIN_ICON_STATE = "minerOLD", SKIN_LIGHT_KEY = "miner"), - "Drone" = list(SKIN_ICON_STATE = "miningdrone", SKIN_ICON = CYBORG_ICON_MINING, SKIN_FEATURES = list(R_TRAIT_SMALL)), - "Zoomba" = list(SKIN_ICON_STATE = "zoomba_miner", SKIN_ICON = CYBORG_ICON_MINING, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL), SKIN_HAT_OFFSET = -13), + "Drone" = list(SKIN_ICON_STATE = "miningdrone", SKIN_ICON = CYBORG_ICON_MINING, SKIN_FEATURES = list(TRAIT_R_SMALL)), + "Zoomba" = list(SKIN_ICON_STATE = "zoomba_miner", SKIN_ICON = CYBORG_ICON_MINING, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL), SKIN_HAT_OFFSET = -13), "Slipper" = list(SKIN_ICON_STATE = "slipper_mine", SKIN_ICON = CYBORG_ICON_MINING), "Spider Miner" = list(SKIN_ICON_STATE = "spidermin", SKIN_LIGHT_KEY = "miner"), "Droid" = list(SKIN_ICON_STATE = "miner", SKIN_ICON = CYBORG_ICON_MINING, SKIN_HAT_OFFSET = 4), @@ -123,18 +123,18 @@ "Miss M" = list(SKIN_ICON_STATE = "missm_miner", SKIN_ICON = CYBORG_ICON_MINING), "Mech" = list(SKIN_ICON_STATE = "ishimura", SKIN_ICON = CYBORG_ICON_MINING), /// 64x32 skins - "Blade" = list(SKIN_ICON_STATE = "blade", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Vale" = list(SKIN_ICON_STATE = "valemine", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Drake" = list(SKIN_ICON_STATE = "drakemine", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Hound" = list(SKIN_ICON_STATE = "cargohound", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Darkhound" = list(SKIN_ICON_STATE = "cargohounddark", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Otie" = list(SKIN_ICON_STATE = "otiec", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), + "Blade" = list(SKIN_ICON_STATE = "blade", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Vale" = list(SKIN_ICON_STATE = "valemine", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Drake" = list(SKIN_ICON_STATE = "drakemine", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Hound" = list(SKIN_ICON_STATE = "cargohound", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Darkhound" = list(SKIN_ICON_STATE = "cargohounddark", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Otie" = list(SKIN_ICON_STATE = "otiec", SKIN_ICON = CYBORG_ICON_MINING_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), /// 32x64 skins - "Meka" = list(SKIN_ICON_STATE = "mekamine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Rookie)" = list(SKIN_ICON_STATE = "k4tmine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Veteran)" = list(SKIN_ICON_STATE = "k4tmine_alt1", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekamine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekamine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekamine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Rookie)" = list(SKIN_ICON_STATE = "k4tmine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Veteran)" = list(SKIN_ICON_STATE = "k4tmine_alt1", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekamine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekamine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) //CLOWN @@ -145,22 +145,22 @@ "Male Bootyborg" = list(SKIN_ICON_STATE = "male_bootyclown", SKIN_ICON = 'modular_skyrat/modules/borgs/icons/robots_clown.dmi'), "ARACHNE" = list(SKIN_ICON_STATE = "arachne_clown", SKIN_ICON = 'modular_skyrat/modules/borgs/icons/robots_clown.dmi'), "Slipper" = list(SKIN_ICON_STATE = "slipper_clown", SKIN_ICON = 'modular_skyrat/modules/borgs/icons/robots_clown.dmi'), - "Marina" = list(SKIN_ICON_STATE = "marina_mommy", SKIN_ICON = 'modular_skyrat/modules/borgs/icons/robots_clown.dmi', SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK)), + "Marina" = list(SKIN_ICON_STATE = "marina_mommy", SKIN_ICON = 'modular_skyrat/modules/borgs/icons/robots_clown.dmi', SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK)), "Garish" = list(SKIN_ICON_STATE = "garish", SKIN_ICON = 'modular_skyrat/modules/borgs/icons/robots_clown.dmi'), "Robot" = list(SKIN_ICON_STATE = "clownbot", SKIN_ICON = 'modular_skyrat/modules/borgs/icons/robots_clown.dmi'), - "Sleek" = list(SKIN_ICON_STATE = "clownman", SKIN_ICON = 'modular_skyrat/modules/borgs/icons/robots_clown.dmi', SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK)), + "Sleek" = list(SKIN_ICON_STATE = "clownman", SKIN_ICON = 'modular_skyrat/modules/borgs/icons/robots_clown.dmi', SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK)), /// 32x64 skins - "K4T" = list(SKIN_ICON_STATE = "k4tclown", SKIN_ICON = CYBORG_ICON_CLOWN_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "K4T" = list(SKIN_ICON_STATE = "k4tclown", SKIN_ICON = CYBORG_ICON_CLOWN_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) //ENGINEERING /obj/item/robot_model/engineering borg_skins = list( /// 32x32 Skins - "Default" = list(SKIN_ICON_STATE = "engineer", SKIN_FEATURES = list(R_TRAIT_SMALL)), - "Zoomba" = list(SKIN_ICON_STATE = "zoomba_engi", SKIN_ICON = CYBORG_ICON_ENG, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL), SKIN_HAT_OFFSET = -13), + "Default" = list(SKIN_ICON_STATE = "engineer", SKIN_FEATURES = list(TRAIT_R_SMALL)), + "Zoomba" = list(SKIN_ICON_STATE = "zoomba_engi", SKIN_ICON = CYBORG_ICON_ENG, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL), SKIN_HAT_OFFSET = -13), "Default - Treads" = list(SKIN_ICON_STATE = "engi-tread", SKIN_LIGHT_KEY = "engineer", SKIN_ICON = CYBORG_ICON_ENG), - "Loader" = list(SKIN_ICON_STATE = "loaderborg", SKIN_ICON = CYBORG_ICON_ENG, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK)), + "Loader" = list(SKIN_ICON_STATE = "loaderborg", SKIN_ICON = CYBORG_ICON_ENG, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK)), "Handy" = list(SKIN_ICON_STATE = "handyeng", SKIN_ICON = CYBORG_ICON_ENG), "Sleek" = list(SKIN_ICON_STATE = "sleekeng", SKIN_ICON = CYBORG_ICON_ENG), "Can" = list(SKIN_ICON_STATE = "caneng", SKIN_ICON = CYBORG_ICON_ENG), @@ -176,22 +176,22 @@ "Wide" = list(SKIN_ICON_STATE = "wide-engi", SKIN_ICON = CYBORG_ICON_ENG), "ARACHNE" = list(SKIN_ICON_STATE = "arachne_engi", SKIN_ICON = CYBORG_ICON_ENG), "Slipper" = list(SKIN_ICON_STATE = "slipper_engi", SKIN_ICON = CYBORG_ICON_ENG), - "Alina" = list(SKIN_ICON_STATE = "alina-eng", SKIN_LIGHT_KEY = "alina", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Eyebot" = list(SKIN_ICON_STATE = "eyeboteng", SKIN_ICON = CYBORG_ICON_ENG, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL)), + "Alina" = list(SKIN_ICON_STATE = "alina-eng", SKIN_LIGHT_KEY = "alina", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Eyebot" = list(SKIN_ICON_STATE = "eyeboteng", SKIN_ICON = CYBORG_ICON_ENG, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL)), /// 64x32 Skins - "Borgi" = list(SKIN_ICON_STATE = "borgi-eng", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE, R_TRAIT_SMALL)), - "Otie" = list(SKIN_ICON_STATE = "otiee", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Pup Dozer" = list(SKIN_ICON_STATE = "pupdozer", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Vale" = list(SKIN_ICON_STATE = "valeeng", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Hound" = list(SKIN_ICON_STATE = "engihound", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Darkhound" = list(SKIN_ICON_STATE = "engihounddark", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Drake" = list(SKIN_ICON_STATE = "drakeeng", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), + "Borgi" = list(SKIN_ICON_STATE = "borgi-eng", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE, TRAIT_R_SMALL)), + "Otie" = list(SKIN_ICON_STATE = "otiee", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Pup Dozer" = list(SKIN_ICON_STATE = "pupdozer", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Vale" = list(SKIN_ICON_STATE = "valeeng", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Hound" = list(SKIN_ICON_STATE = "engihound", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Darkhound" = list(SKIN_ICON_STATE = "engihounddark", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Drake" = list(SKIN_ICON_STATE = "drakeeng", SKIN_ICON = CYBORG_ICON_ENG_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), /// 32x64 Skins - "Meka" = list(SKIN_ICON_STATE = "mekaengi", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Technician)" = list(SKIN_ICON_STATE = "k4tengi", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Hazard)" = list(SKIN_ICON_STATE = "k4tengi_alt1", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekaeng", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekaeng", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekaengi", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Technician)" = list(SKIN_ICON_STATE = "k4tengi", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Hazard)" = list(SKIN_ICON_STATE = "k4tengi_alt1", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekaeng", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekaeng", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) /obj/item/robot_model/janitor @@ -200,7 +200,7 @@ "Default" = list(SKIN_ICON_STATE = "janitor"), "ARACHNE" = list(SKIN_ICON_STATE = "arachne_jani", SKIN_ICON = CYBORG_ICON_JANI), "Slipper" = list(SKIN_ICON_STATE = "slipper_janitor", SKIN_ICON = CYBORG_ICON_JANI), - "Zoomba" = list(SKIN_ICON_STATE = "zoomba_jani", SKIN_ICON = CYBORG_ICON_JANI, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL), SKIN_HAT_OFFSET = -13), + "Zoomba" = list(SKIN_ICON_STATE = "zoomba_jani", SKIN_ICON = CYBORG_ICON_JANI, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL), SKIN_HAT_OFFSET = -13), "Marina" = list(SKIN_ICON_STATE = "marinajan", SKIN_ICON = CYBORG_ICON_JANI), "Sleek" = list(SKIN_ICON_STATE = "sleekjan", SKIN_ICON = CYBORG_ICON_JANI), "Can" = list(SKIN_ICON_STATE = "canjan", SKIN_ICON = CYBORG_ICON_JANI), @@ -211,37 +211,37 @@ "Protectron" = list(SKIN_ICON_STATE = "protectron_janitor", SKIN_ICON = CYBORG_ICON_JANI), "Miss M" = list(SKIN_ICON_STATE = "missm_janitor", SKIN_ICON = CYBORG_ICON_JANI), "Mech" = list(SKIN_ICON_STATE = "flynn", SKIN_ICON = CYBORG_ICON_JANI), - "Eyebot" = list(SKIN_ICON_STATE = "eyebotjani", SKIN_ICON = CYBORG_ICON_JANI, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL)), + "Eyebot" = list(SKIN_ICON_STATE = "eyebotjani", SKIN_ICON = CYBORG_ICON_JANI, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL)), "Insekt" = list(SKIN_ICON_STATE = "insekt-Sci", SKIN_ICON = CYBORG_ICON_JANI), "Wide" = list(SKIN_ICON_STATE = "wide-jani", SKIN_ICON = CYBORG_ICON_JANI), "Spider" = list(SKIN_ICON_STATE = "spidersci", SKIN_ICON = CYBORG_ICON_JANI), /// 64x32 Skins - "Borgi" = list(SKIN_ICON_STATE = "borgi-jani", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE, R_TRAIT_SMALL)), - "Scrubpuppy" = list(SKIN_ICON_STATE = "scrubpup", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Drake" = list(SKIN_ICON_STATE = "drakejanit", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Vale" = list(SKIN_ICON_STATE = "J9", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Otie" = list(SKIN_ICON_STATE = "otiej", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), + "Borgi" = list(SKIN_ICON_STATE = "borgi-jani", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE, TRAIT_R_SMALL)), + "Scrubpuppy" = list(SKIN_ICON_STATE = "scrubpup", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Drake" = list(SKIN_ICON_STATE = "drakejanit", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Vale" = list(SKIN_ICON_STATE = "J9", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Otie" = list(SKIN_ICON_STATE = "otiej", SKIN_ICON = CYBORG_ICON_JANI_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), /// 32x64 Skins - "Meka" = list(SKIN_ICON_STATE = "mekajani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Viscera)" = list(SKIN_ICON_STATE = "k4tjani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Domestic)" = list(SKIN_ICON_STATE = "k4tjani_alt1", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekajani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekajani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekajani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Viscera)" = list(SKIN_ICON_STATE = "k4tjani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Domestic)" = list(SKIN_ICON_STATE = "k4tjani_alt1", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekajani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekajani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) //MEDICAL /obj/item/robot_model/medical borg_skins = list( /// 32x32 Skins - "Machinified Doctor" = list(SKIN_ICON_STATE = "medical", SKIN_TRAITS = list(R_TRAIT_SMALL)), + "Machinified Doctor" = list(SKIN_ICON_STATE = "medical", SKIN_TRAITS = list(TRAIT_R_SMALL)), "Qualified Doctor" = list(SKIN_ICON_STATE = "qualified_doctor"), "ARACHNE" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "arachne_med"), "Slipper" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "slipper_med"), - "Zoomba" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "zoomba_med", SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL), SKIN_HAT_OFFSET = -13), + "Zoomba" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "zoomba_med", SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL), SKIN_HAT_OFFSET = -13), "Droid" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "medical", SKIN_HAT_OFFSET = 4), "Sleek" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "sleekmed"), "Marina" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "marinamed"), - "Eyebot" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "eyebotmed", SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL)), + "Eyebot" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "eyebotmed", SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL)), "Heavy" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "heavymed"), "Bootyborg" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "bootymedical"), "Birdborg" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "bird_med"), @@ -251,18 +251,18 @@ "Insekt" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "insekt-Med"), "Mech" = list(SKIN_ICON = CYBORG_ICON_MED, SKIN_ICON_STATE = "gibbs"), /// 64x32 Skins - "Borgi" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "borgi-medi", SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Drake" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "drakemed", SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Hound" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "medihound", SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "DarkHound" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "medihounddark", SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Vale" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "valemed", SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Alina" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "alina-med", SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), + "Borgi" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "borgi-medi", SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Drake" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "drakemed", SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Hound" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "medihound", SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "DarkHound" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "medihounddark", SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Vale" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "valemed", SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Alina" = list(SKIN_ICON = CYBORG_ICON_MED_WIDE, SKIN_ICON_STATE = "alina-med", SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), /// 32x64 Skins - "Meka" = list(SKIN_ICON_STATE = "mekamed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Doc)" = list(SKIN_ICON_STATE = "k4tmed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Field Medic)" = list(SKIN_ICON_STATE = "k4tmed_alt1", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekamed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekamed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekamed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Doc)" = list(SKIN_ICON_STATE = "k4tmed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Field Medic)" = list(SKIN_ICON_STATE = "k4tmed_alt1", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekamed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekamed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) //PEACEKEEPER @@ -270,33 +270,33 @@ borg_skins = list( /// 32x32 Skins "Default" = list(SKIN_ICON_STATE = "peace"), - "Zoomba" = list(SKIN_ICON_STATE = "zoomba_peace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL), SKIN_HAT_OFFSET = -13), + "Zoomba" = list(SKIN_ICON_STATE = "zoomba_peace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL), SKIN_HAT_OFFSET = -13), "ARACHNE" = list(SKIN_ICON_STATE = "arachne_peacekeeper", SKIN_ICON = CYBORG_ICON_PEACEKEEPER), - "Sleek" = list(SKIN_ICON_STATE = "sleekpeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK)), - "Spider" = list(SKIN_ICON_STATE = "whitespider", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(R_TRAIT_SMALL)), - "Marina" = list(SKIN_ICON_STATE = "marinapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK)), + "Sleek" = list(SKIN_ICON_STATE = "sleekpeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK)), + "Spider" = list(SKIN_ICON_STATE = "whitespider", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(TRAIT_R_SMALL)), + "Marina" = list(SKIN_ICON_STATE = "marinapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK)), "Bootyborg" = list(SKIN_ICON_STATE = "bootypeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER), "Male Bootyborg" = list(SKIN_ICON_STATE = "male_bootypeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER), "Birdborg" = list(SKIN_ICON_STATE = "bird_pk", SKIN_ICON = CYBORG_ICON_PEACEKEEPER), "Protectron" = list(SKIN_ICON_STATE = "protectron_peacekeeper", SKIN_ICON = CYBORG_ICON_PEACEKEEPER), "Insekt" = list(SKIN_ICON_STATE = "insekt-Default", SKIN_ICON = CYBORG_ICON_PEACEKEEPER), - "Omni" = list(SKIN_ICON_STATE = "omoikane", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(R_TRAIT_SMALL)), + "Omni" = list(SKIN_ICON_STATE = "omoikane", SKIN_ICON = CYBORG_ICON_PEACEKEEPER, SKIN_FEATURES = list(TRAIT_R_SMALL)), /// 64x32 Skins - "Drake" = list(SKIN_ICON_STATE = "drakepeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Borgi" = list(SKIN_ICON_STATE = "borgi", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE, R_TRAIT_SMALL)), - "Vale" = list(SKIN_ICON_STATE = "valepeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), + "Drake" = list(SKIN_ICON_STATE = "drakepeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Borgi" = list(SKIN_ICON_STATE = "borgi", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE, TRAIT_R_SMALL)), + "Vale" = list(SKIN_ICON_STATE = "valepeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), /// 32x64 Skins - "Meka" = list(SKIN_ICON_STATE = "mekapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T" = list(SKIN_ICON_STATE = "k4tpeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T" = list(SKIN_ICON_STATE = "k4tpeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) /obj/item/robot_model/security borg_skins = list( /// 32x32 Skins "Default" = list(SKIN_ICON_STATE = "sec"), - "Zoomba" = list(SKIN_ICON_STATE = "zoomba_sec", SKIN_ICON = CYBORG_ICON_SEC, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL), SKIN_HAT_OFFSET = -13), + "Zoomba" = list(SKIN_ICON_STATE = "zoomba_sec", SKIN_ICON = CYBORG_ICON_SEC, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL), SKIN_HAT_OFFSET = -13), "Default - Treads" = list(SKIN_ICON_STATE = "sec-tread", SKIN_LIGHT_KEY = "sec", SKIN_ICON = CYBORG_ICON_SEC), "Sleek" = list(SKIN_ICON_STATE = "sleeksec", SKIN_ICON = CYBORG_ICON_SEC), "Marina" = list(SKIN_ICON_STATE = "marinasec", SKIN_ICON = CYBORG_ICON_SEC), @@ -307,22 +307,22 @@ "Male Bootyborg" = list(SKIN_ICON_STATE = "male_bootysecurity", SKIN_ICON = CYBORG_ICON_SEC), "Protectron" = list(SKIN_ICON_STATE = "protectron_security", SKIN_ICON = CYBORG_ICON_SEC), "Miss M" = list(SKIN_ICON_STATE = "missm_security", SKIN_ICON = CYBORG_ICON_SEC), - "Eyebot" = list(SKIN_ICON_STATE = "eyebotsec", SKIN_ICON = CYBORG_ICON_SEC, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL)), + "Eyebot" = list(SKIN_ICON_STATE = "eyebotsec", SKIN_ICON = CYBORG_ICON_SEC, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL)), "Insekt" = list(SKIN_ICON_STATE = "insekt-Sec", SKIN_ICON = CYBORG_ICON_SEC), "Mech" = list(SKIN_ICON_STATE = "woody", SKIN_ICON = CYBORG_ICON_SEC), /// 64x32 Skins - "Borgi" = list(SKIN_ICON_STATE = "borgi-sec", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE, R_TRAIT_SMALL)), - "Hound" = list(SKIN_ICON_STATE = "k9", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Darkhound" = list(SKIN_ICON_STATE = "k9dark", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Drake" = list(SKIN_ICON_STATE = "drakesec", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Otie" = list(SKIN_ICON_STATE = "oties", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Alina" = list(SKIN_ICON_STATE = "alina-sec", SKIN_LIGHT_KEY = "alina", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Vale" = list(SKIN_ICON_STATE = "valesec", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), + "Borgi" = list(SKIN_ICON_STATE = "borgi-sec", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE, TRAIT_R_SMALL)), + "Hound" = list(SKIN_ICON_STATE = "k9", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Darkhound" = list(SKIN_ICON_STATE = "k9dark", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Drake" = list(SKIN_ICON_STATE = "drakesec", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Otie" = list(SKIN_ICON_STATE = "oties", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Alina" = list(SKIN_ICON_STATE = "alina-sec", SKIN_LIGHT_KEY = "alina", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Vale" = list(SKIN_ICON_STATE = "valesec", SKIN_ICON = CYBORG_ICON_SEC_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), /// 32x64 Skins - "Meka" = list(SKIN_ICON_STATE = "mekasec", SKIN_ICON = CYBORG_ICON_SEC_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T" = list(SKIN_ICON_STATE = "k4tsec", SKIN_ICON = CYBORG_ICON_SEC_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekasec", SKIN_ICON = CYBORG_ICON_SEC_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekasec", SKIN_ICON = CYBORG_ICON_SEC_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekasec", SKIN_ICON = CYBORG_ICON_SEC_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T" = list(SKIN_ICON_STATE = "k4tsec", SKIN_ICON = CYBORG_ICON_SEC_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekasec", SKIN_ICON = CYBORG_ICON_SEC_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekasec", SKIN_ICON = CYBORG_ICON_SEC_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) // CARGO @@ -358,20 +358,20 @@ /// 32x32 Skins "Technician" = list(SKIN_ICON_STATE = "cargoborg", SKIN_ICON = CYBORG_ICON_CARGO), "Miss M" = list(SKIN_ICON_STATE = "missm_cargo", SKIN_ICON = CYBORG_ICON_CARGO), - "Zoomba" = list(SKIN_ICON_STATE = "zoomba_cargo", SKIN_ICON = CYBORG_ICON_CARGO, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_SMALL), SKIN_HAT_OFFSET = -13), + "Zoomba" = list(SKIN_ICON_STATE = "zoomba_cargo", SKIN_ICON = CYBORG_ICON_CARGO, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_SMALL), SKIN_HAT_OFFSET = -13), "Birdborg" = list(SKIN_ICON_STATE = "bird_cargo", SKIN_ICON = CYBORG_ICON_CARGO), /// 64x32 Skins - "Borgi" = list(SKIN_ICON_STATE = "borgi-cargo", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE, R_TRAIT_SMALL)), - "Drake" = list(SKIN_ICON_STATE = "drakecargo", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Hound" = list(SKIN_ICON_STATE = "cargohound", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Darkhound" = list(SKIN_ICON_STATE = "cargohounddark", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), - "Vale" = list(SKIN_ICON_STATE = "valecargo", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_WIDE)), + "Borgi" = list(SKIN_ICON_STATE = "borgi-cargo", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE, TRAIT_R_SMALL)), + "Drake" = list(SKIN_ICON_STATE = "drakecargo", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Hound" = list(SKIN_ICON_STATE = "cargohound", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Darkhound" = list(SKIN_ICON_STATE = "cargohounddark", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), + "Vale" = list(SKIN_ICON_STATE = "valecargo", SKIN_ICON = CYBORG_ICON_CARGO_WIDE, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_WIDE)), /// 32x64 Skins - "Meka" = list(SKIN_ICON_STATE = "mekacargo", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Loader)" = list(SKIN_ICON_STATE = "k4tcargo", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T (Turtleneck)" = list(SKIN_ICON_STATE = "k4tcargo_alt1", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekacargo", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekacargo", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekacargo", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Loader)" = list(SKIN_ICON_STATE = "k4tcargo", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T (Turtleneck)" = list(SKIN_ICON_STATE = "k4tcargo_alt1", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekacargo", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekacargo", SKIN_ICON = CYBORG_ICON_CARGO_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) @@ -430,10 +430,10 @@ "Male Booty Syndicate" = list(SKIN_ICON_STATE = "male_bootysyndie", SKIN_ICON = CYBORG_ICON_SYNDIE), "Mech" = list(SKIN_ICON_STATE = "chesty", SKIN_ICON = CYBORG_ICON_SYNDIE), /// 32x64 Skins - "Meka" = list(SKIN_ICON_STATE = "mekasyndi", SKIN_ICON = CYBORG_ICON_SYNDIE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T" = list(SKIN_ICON_STATE = "k4tsyndi", SKIN_ICON = CYBORG_ICON_SYNDIE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekasyndi", SKIN_ICON = CYBORG_ICON_SYNDIE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekasyndi", SKIN_ICON = CYBORG_ICON_SYNDIE_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekasyndi", SKIN_ICON = CYBORG_ICON_SYNDIE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T" = list(SKIN_ICON_STATE = "k4tsyndi", SKIN_ICON = CYBORG_ICON_SYNDIE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekasyndi", SKIN_ICON = CYBORG_ICON_SYNDIE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekasyndi", SKIN_ICON = CYBORG_ICON_SYNDIE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) /obj/item/robot_model/syndicatejack/rebuild_modules() @@ -475,10 +475,10 @@ "BootyBorg" = list(SKIN_ICON_STATE = "bootyninja", SKIN_ICON = CYBORG_ICON_NINJA), "Male Bootyborg" = list(SKIN_ICON_STATE = "male_bootyninja", SKIN_ICON = CYBORG_ICON_NINJA), /// 32x64 Skins - "Meka" = list(SKIN_ICON_STATE = "mekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T" = list(SKIN_ICON_STATE = "k4tninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T" = list(SKIN_ICON_STATE = "k4tninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) /obj/item/robot_model/ninja/rebuild_modules() @@ -559,10 +559,10 @@ "BootyBorg" = list(SKIN_ICON_STATE = "bootyninja", SKIN_ICON = CYBORG_ICON_NINJA), "Male Bootyborg" = list(SKIN_ICON_STATE = "male_bootyninja", SKIN_ICON = CYBORG_ICON_NINJA), /// 32x64 Skins - "Meka" = list(SKIN_ICON_STATE = "mekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "K4T" = list(SKIN_ICON_STATE = "k4tninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKA" = list(SKIN_ICON_STATE = "fmekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15), - "NiKO" = list(SKIN_ICON_STATE = "mmekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(R_TRAIT_UNIQUEWRECK, R_TRAIT_UNIQUETIP, R_TRAIT_TALL), SKIN_HAT_OFFSET = 15) + "Meka" = list(SKIN_ICON_STATE = "mekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "K4T" = list(SKIN_ICON_STATE = "k4tninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekaninja", SKIN_ICON = CYBORG_ICON_NINJA_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) ) /obj/item/robot_model/ninja_saboteur/do_transform_animation() diff --git a/modular_skyrat/modules/borgs/code/robot_upgrade.dm b/modular_skyrat/modules/borgs/code/robot_upgrade.dm index 358ca96d73f..5dfc12325f2 100644 --- a/modular_skyrat/modules/borgs/code/robot_upgrade.dm +++ b/modular_skyrat/modules/borgs/code/robot_upgrade.dm @@ -315,7 +315,7 @@ if(borg.hasAffection) to_chat(usr, span_warning("This unit already has a affection module installed!")) return FALSE - if(!(R_TRAIT_WIDE in borg.model.model_features)) + if(!(TRAIT_R_WIDE in borg.model.model_features)) to_chat(usr, span_warning("This unit's chassis does not support this module.")) return FALSE @@ -403,7 +403,7 @@ if(borg.hasShrunk) to_chat(usr, span_warning("This unit already has a shrink module installed!")) return FALSE - if(R_TRAIT_SMALL in borg.model.model_features) + if(TRAIT_R_SMALL in borg.model.model_features) to_chat(usr, span_warning("This unit's chassis cannot be shrunk any further.")) return FALSE diff --git a/modular_skyrat/modules/borgs/code/update_icons.dm b/modular_skyrat/modules/borgs/code/update_icons.dm index a9c3ffefb04..dc982cbdabe 100644 --- a/modular_skyrat/modules/borgs/code/update_icons.dm +++ b/modular_skyrat/modules/borgs/code/update_icons.dm @@ -2,7 +2,7 @@ icon = (model.cyborg_icon_override ? model.cyborg_icon_override : initial(icon)) . = ..() /// Let's give custom borgs the ability to have flavor panels for their model - if(opened && (R_TRAIT_UNIQUEPANEL in model.model_features)) + if(opened && (TRAIT_R_UNIQUEPANEL in model.model_features)) if(wiresexposed) add_overlay("[model.cyborg_base_icon]_w") else if(cell) @@ -52,13 +52,13 @@ else icon_state = "[model.cyborg_base_icon]" - if((R_TRAIT_UNIQUETIP in model.model_features) && (TRAIT_IMMOBILIZED in _status_traits)) + if((TRAIT_R_UNIQUETIP in model.model_features) && (TRAIT_IMMOBILIZED in _status_traits)) icon_state = "[model.cyborg_base_icon]-tipped" if(particles) dissipate() cut_overlays() - if(stat == DEAD && (R_TRAIT_UNIQUEWRECK in model.model_features)) + if(stat == DEAD && (TRAIT_R_UNIQUEWRECK in model.model_features)) icon_state = "[model.cyborg_base_icon]-wreck" diff --git a/modular_skyrat/modules/customization/__DEFINES/lists.dm b/modular_skyrat/modules/customization/__DEFINES/lists.dm index b0877b91b76..6c5d6bf496b 100644 --- a/modular_skyrat/modules/customization/__DEFINES/lists.dm +++ b/modular_skyrat/modules/customization/__DEFINES/lists.dm @@ -2,6 +2,17 @@ GLOBAL_LIST_EMPTY(sprite_accessories) GLOBAL_LIST_EMPTY(generic_accessories) GLOBAL_LIST_EMPTY(genetic_accessories) +/// What accessories can a species have as well as their default accessory of such type e.g. "frills" = "Aquatic". Default accessory colors is dictated by the accessory properties and mutcolors of the specie +GLOBAL_LIST_EMPTY(default_mutant_bodyparts) +GLOBAL_LIST_INIT(possible_genitals, list( + ORGAN_SLOT_VAGINA, + ORGAN_SLOT_WOMB, + ORGAN_SLOT_TESTICLES, + ORGAN_SLOT_BREASTS, + ORGAN_SLOT_ANUS, + ORGAN_SLOT_PENIS +)) + GLOBAL_LIST_EMPTY(body_markings) GLOBAL_LIST_EMPTY_TYPED(body_markings_per_limb, /list) GLOBAL_LIST_EMPTY(body_marking_sets) diff --git a/modular_skyrat/modules/customization/__HELPERS/global_lists.dm b/modular_skyrat/modules/customization/__HELPERS/global_lists.dm index a2dca2e39be..d203c1ea805 100644 --- a/modular_skyrat/modules/customization/__HELPERS/global_lists.dm +++ b/modular_skyrat/modules/customization/__HELPERS/global_lists.dm @@ -1,5 +1,6 @@ /proc/make_skyrat_datum_references() make_sprite_accessory_references() + make_default_mutant_bodypart_references() make_body_marking_references() make_body_marking_set_references() make_body_marking_dna_block_references() @@ -30,6 +31,18 @@ if(P.generic && !GLOB.generic_accessories[P.key]) GLOB.generic_accessories[P.key] = P.generic +/proc/make_default_mutant_bodypart_references() + // Build the global list for default species' mutant_bodyparts + for(var/path in subtypesof(/datum/species)) + var/datum/species/species_type = path + var/datum/species/species_instance = new species_type + if(!isnull(species_instance.name)) + GLOB.default_mutant_bodyparts[species_instance.name] = species_instance.get_default_mutant_bodyparts() + if(species_instance.can_have_genitals) + for(var/genital in GLOB.possible_genitals) + GLOB.default_mutant_bodyparts[species_instance.name] += list((genital) = list("None", FALSE)) + qdel(species_instance) + /proc/make_body_marking_references() // Here we build the global list for all body markings for(var/path in subtypesof(/datum/body_marking)) diff --git a/modular_skyrat/modules/customization/datums/dna.dm b/modular_skyrat/modules/customization/datums/dna.dm index 7e0fb14838c..e29e403e97b 100644 --- a/modular_skyrat/modules/customization/datums/dna.dm +++ b/modular_skyrat/modules/customization/datums/dna.dm @@ -57,16 +57,6 @@ GLOBAL_LIST_EMPTY(total_uf_len_by_block) ///Current body size, used for proper re-sizing and keeping track of that var/current_body_size = BODY_SIZE_NORMAL -/datum/dna/proc/initialize_dna(newblood_type, skip_index = FALSE) - if(newblood_type) - blood_type = newblood_type - unique_enzymes = generate_unique_enzymes() - unique_identity = generate_unique_identity() - if(!skip_index) //I hate this - generate_dna_blocks() - mutant_bodyparts = species.get_random_mutant_bodyparts(features) - unique_features = generate_unique_features() - /datum/dna/proc/generate_unique_features() var/list/data = list() @@ -186,59 +176,6 @@ GLOBAL_LIST_EMPTY(total_uf_len_by_block) holder.maptext_height = 32 * features["body_size"] // Adjust runechat height current_body_size = features["body_size"] -/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE, list/override_features, list/override_mutantparts, list/override_markings, retain_features = FALSE, retain_mutantparts = FALSE) - if(QDELETED(src)) - CRASH("You're trying to change your species post deletion, this is a recipe for madness") - if(isnull(mrace)) - CRASH("set_species called without a species to set to") - if(!has_dna()) - return - - var/datum/species/new_race - if(ispath(mrace)) - new_race = new mrace - else if(istype(mrace)) - if(QDELING(mrace)) - CRASH("someone is calling set_species() and is passing it a qdeling species datum, this is VERY bad, stop it") - new_race = mrace - else - CRASH("set_species called with an invalid mrace [mrace]") - - death_sound = new_race.death_sound - - var/datum/species/old_species = dna.species - dna.species = new_race - - if (old_species.properly_gained) - old_species.on_species_loss(src, new_race, pref_load) - - //BODYPARTS AND FEATURES - We need to instantiate the list with compatible mutant parts so we don't break things - - if(override_mutantparts && override_mutantparts.len) - for(var/feature in dna.mutant_bodyparts) - override_mutantparts[feature] = dna.mutant_bodyparts[feature] - dna.mutant_bodyparts = override_mutantparts - - if(override_markings && override_markings.len) - for(var/feature in dna.body_markings) - override_markings[feature] = dna.body_markings[feature] - dna.body_markings = override_markings - - if(override_features && override_features.len) - for(var/feature in dna.features) - override_features[feature] = dna.features[feature] - dna.features = override_features - //END OF BODYPARTS AND FEATURES - - apply_customizable_dna_features_to_species() - dna.unique_features = dna.generate_unique_features() - - dna.update_body_size() - - dna.species.on_species_gain(src, old_species, pref_load) - log_mob_tag("TAG: [tag] SPECIES: [key_name(src)] \[[mrace]\]") - - /mob/living/carbon/proc/apply_customizable_dna_features_to_species() if(!has_dna()) CRASH("[src] does not have DNA") diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/preferences_setup.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/preferences_setup.dm index 543a0c15cc1..c2bfd6c7d49 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/preferences_setup.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/preferences_setup.dm @@ -162,7 +162,7 @@ var/list/new_features = pref_species.get_random_features() //We do this to keep flavor text, genital sizes etc. for(var/key in new_features) features[key] = new_features[key] - mutant_bodyparts = pref_species.get_random_mutant_bodyparts(features) + mutant_bodyparts = pref_species.get_mutant_bodyparts(features) body_markings = pref_species.get_random_body_markings(features) if(pref_species.use_skintones) features["uses_skintones"] = TRUE diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm index b27d27bae0a..e4f05a3b205 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm @@ -34,7 +34,6 @@ /datum/sprite_accessory/ears/fox color_src = USE_ONE_COLOR - /datum/sprite_accessory/ears/mutant icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/ears.dmi' organ_type = /obj/item/organ/external/ears // SET BACK TO THIS AS SOON AS WE GET EARS AS EXTERNAL ORGANS: organ_type = /obj/item/organ/internal/ears/mutant @@ -289,7 +288,7 @@ icon_state = "deerear" /datum/sprite_accessory/ears/mutant/teshari - recommended_species = list(SPECIES_TESHARI) + recommended_species = list(SPECIES_TESHARI, SPECIES_TESHARI_ALT) //FLUFFY FRONTIER EDIT - TESHARI_REBORN /datum/sprite_accessory/ears/mutant/teshari/regular name = "Teshari Regular" diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm index 8ab45ecf430..ce8dc17424b 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/snout.dm @@ -433,3 +433,27 @@ color_src = USE_MATRIXED_COLORS name = "Acrador (Short)" icon_state = "acrador_short" + +/datum/sprite_accessory/snouts/acrador_1 + icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi' + color_src = USE_MATRIXED_COLORS + name = "Acrador 1 (Normal)" + icon_state = "acrador_1" + +/datum/sprite_accessory/snouts/acrador_2 + icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi' + color_src = USE_MATRIXED_COLORS + name = "Acrador 2 (Normal)" + icon_state = "acrador_2" + +/datum/sprite_accessory/snouts/acrador_3 + icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi' + color_src = USE_MATRIXED_COLORS + name = "Acrador 3 (Normal)" + icon_state = "acrador_3" + +/datum/sprite_accessory/snouts/acrador_4 + icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/snouts.dmi' + color_src = USE_MATRIXED_COLORS + name = "Acrador 4 (Normal)" + icon_state = "acrador_4" diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm index 4831414ca85..ef9212cb509 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm @@ -78,7 +78,7 @@ recommended_species = list(SPECIES_MAMMAL, SPECIES_HUMAN, SPECIES_SYNTH, SPECIES_TAJARAN, SPECIES_HUMANOID, SPECIES_GHOUL) /datum/sprite_accessory/tails/mammal/teshari - recommended_species = list(SPECIES_TESHARI) + recommended_species = list(SPECIES_TESHARI, SPECIES_TESHARI_ALT) //FLUFFY FRONTIER EDIT - TESHARI_REBORN /datum/sprite_accessory/tails/mammal/wagging/vulpkanin recommended_species = list(SPECIES_MAMMAL, SPECIES_HUMAN, SPECIES_SYNTH, SPECIES_VULP, SPECIES_HUMANOID, SPECIES_GHOUL) 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 c21b8859d21..03a68cb6925 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 @@ -313,7 +313,7 @@ icon_state = "brown" /datum/sprite_accessory/wings/moth/burnt - name = "Moth (Burnt)" + name = "Burnt Off" icon_state = "burnt_off" locked = TRUE diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm index 78c597e7864..a8499e2fcdb 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm @@ -1,9 +1,6 @@ // This DMI holds our radial icons for the 'hide mutant parts' verb #define HIDING_RADIAL_DMI 'modular_skyrat/modules/customization/modules/mob/living/carbon/human/MOD_sprite_accessories/icons/radial.dmi' -/mob/living/carbon/human - var/static/list/possible_genitals = list(ORGAN_SLOT_PENIS, ORGAN_SLOT_TESTICLES, ORGAN_SLOT_VAGINA, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS) - /mob/living/carbon/human/Topic(href, href_list) . = ..() @@ -11,7 +8,7 @@ switch(href_list["lookup_info"]) if("genitals") var/list/line = list() - for(var/genital in possible_genitals) + for(var/genital in GLOB.possible_genitals) if(!dna.species.mutant_bodyparts[genital]) continue var/datum/sprite_accessory/genital/G = GLOB.sprite_accessories[genital][dna.species.mutant_bodyparts[genital][MUTANT_INDEX_NAME]] diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm index 357e827e744..9568aec0bd0 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm @@ -27,32 +27,37 @@ GLOBAL_LIST_EMPTY(customizable_races) var/list/custom_worn_icons = list() ///Is this species restricted from changing their body_size in character creation? var/body_size_restricted = FALSE - ///What accessories can a species have aswell as their default accessory of such type e.g. "frills" = "Aquatic". Default accessory colors is dictated by the accessory properties and mutcolors of the specie - var/list/default_mutant_bodyparts = list() - /// A static list of all genital slot possibilities. - var/static/list/genitals_list = list(ORGAN_SLOT_VAGINA, ORGAN_SLOT_WOMB, ORGAN_SLOT_TESTICLES, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS, ORGAN_SLOT_PENIS) /// Are we lore protected? This prevents people from changing the species lore or species name. var/lore_protected = FALSE +/// Returns a list of the default mutant bodyparts, and whether or not they can be randomized or not +/datum/species/proc/get_default_mutant_bodyparts() + return list() + /datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/owner, forced_colour, force_update = FALSE) return -/datum/species/New() - . = ..() - if(can_have_genitals) - for(var/genital in genitals_list) - default_mutant_bodyparts[genital] = "None" - /datum/species/dullahan mutant_bodyparts = list() /datum/species/human/felinid mutant_bodyparts = list() - default_mutant_bodyparts = list("tail" = "Cat", "ears" = "Cat") + +/datum/species/human/felinid/get_default_mutant_bodyparts() + return list( + "tail" = list("Cat", FALSE), + "ears" = list("Cat", FALSE), + ) /datum/species/human mutant_bodyparts = list() - default_mutant_bodyparts = list("ears" = "None", "tail" = "None", "wings" = "None") + +/datum/species/human/get_default_mutant_bodyparts() + return list( + "ears" = list("None", FALSE), + "tail" = list("None", FALSE), + "wings" = list("None", FALSE), + ) /datum/species/mush mutant_bodyparts = list() @@ -75,20 +80,35 @@ GLOBAL_LIST_EMPTY(customizable_races) always_customizable = TRUE /datum/species/randomize_features(mob/living/carbon/human/human_mob) - return + var/list/features = ..() + return features -/datum/species/proc/get_random_mutant_bodyparts(list/features) //Needs features to base the colour off of +/** + * Returns a list of mutant_bodyparts + * + * Gets the default species mutant_bodyparts list for the given species datum and sets up its sprite accessories. + * + * Arguments: + * * features - Features are needed for the part color + * * existing_mutant_bodyparts - When passed a list of existing mutant bodyparts, the existing ones will not get overwritten + */ +/datum/species/proc/get_mutant_bodyparts(list/features, list/existing_mutant_bodyparts) //Needs features to base the colour off of var/list/mutantpart_list = list() - var/list/bodyparts_to_add = default_mutant_bodyparts.Copy() + if(LAZYLEN(existing_mutant_bodyparts)) + mutantpart_list = existing_mutant_bodyparts.Copy() + var/list/default_bodypart_data = GLOB.default_mutant_bodyparts[name] + var/list/bodyparts_to_add = default_bodypart_data.Copy() if(CONFIG_GET(flag/disable_erp_preferences)) - for(var/genital in genitals_list) + for(var/genital in GLOB.possible_genitals) bodyparts_to_add.Remove(genital) for(var/key in bodyparts_to_add) + if(LAZYLEN(existing_mutant_bodyparts) && existing_mutant_bodyparts[key]) + continue var/datum/sprite_accessory/SP - if(bodyparts_to_add[key] == ACC_RANDOM) + if(default_bodypart_data[key][MUTANTPART_CAN_RANDOMIZE]) SP = random_accessory_of_key_for_species(key, src) else - SP = GLOB.sprite_accessories[key][bodyparts_to_add[key]] + SP = GLOB.sprite_accessories[key][bodyparts_to_add[key][MUTANTPART_NAME]] if(!SP) CRASH("Cant find accessory of [key] key, [bodyparts_to_add[key]] name, for species [id]") var/list/color_list = SP.get_default_color(features, src) diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/akula.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/akula.dm index 19492ef4456..7a9181b75a9 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/akula.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/akula.dm @@ -29,10 +29,6 @@ ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "legs" = "Normal Legs" - ) outfit_important_for_life = /datum/outfit/akula payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -47,6 +43,12 @@ /// This variable stores the timer datum which appears if the mob becomes wet var/dry_up_timer = TIMER_ID_NULL +/datum/species/akula/get_default_mutant_bodyparts() + return list( + "tail" = list("Akula", TRUE), + "legs" = list("Normal Legs", FALSE), + ) + /datum/species/akula/get_species_description() return placeholder_description @@ -60,7 +62,8 @@ "Yet, despite their differences, all Agurkrral citizens swim freely in their kingdom's waters. Even the most controlling border princes, even those in the Old Principalities working the slave trade, know better than to openly erode a citizen's right to life, property, and speech. Any alien species can become an Agurkrral citizen, and even non-citizens enjoy the right to life, with executions outright banned. The aristocracy remains well-educated, even the edgerunner warlords of the New Principalities, and the Kingdom as a whole enjoys its status as a nation that's now a true rival to Sol. Larger, more populated, and better developed; though, having to 'integrate' Solarian technologies, goods, and peoples to fully succeed. The Azuleans are even known as an environmentally-focused people; although they hold no care for lands they cannot make use of, modern nobles are still in charge of maintaining the biosphere of lands they control, to allow their strangely engineered flora and fauna to thrive, and for the people to have healthy and clean waters to live in.", ) -/datum/species/akula/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/akula/randomize_features() + var/list/features = ..() var/main_color var/secondary_color var/tertiary_color @@ -82,9 +85,10 @@ main_color = "#DB35DE" secondary_color = "#BE3AFE" tertiary_color = "#F5E2EE" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = secondary_color - human_mob.dna.features["mcolor3"] = tertiary_color + features["mcolor"] = main_color + features["mcolor2"] = secondary_color + features["mcolor3"] = tertiary_color + return features /datum/species/akula/prepare_human_for_preview(mob/living/carbon/human/akula) var/main_color = "#1CD3E5" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/aquatic.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/aquatic.dm index 80aa57ca8ca..29df861b8bf 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/aquatic.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/aquatic.dm @@ -11,14 +11,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/aquatic - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "horns" = "None", - "ears" = ACC_RANDOM, - "legs" = "Normal Legs", - "wings" = "None" - ) payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT examine_limb_id = SPECIES_AKULA @@ -31,6 +23,16 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant/aquatic, ) +/datum/species/aquatic/get_default_mutant_bodyparts() + return list( + "tail" = list("Shark", TRUE), + "snout" = list("Shark", TRUE), + "horns" = list("None", FALSE), + "ears" = list("Hammerhead", TRUE), + "legs" = list("Normal Legs", FALSE), + "wings" = list("None", FALSE), + ) + /obj/item/organ/internal/tongue/aquatic liked_foodtypes = SEAFOOD | MEAT | FRUIT | GORE disliked_foodtypes = CLOTH | GROSS @@ -38,6 +40,7 @@ /datum/species/aquatic/randomize_features(mob/living/carbon/human/human_mob) + var/list/features = ..() var/main_color var/second_color var/random = rand(1,5) @@ -58,9 +61,10 @@ if(5) main_color = "#444444" second_color = "#DDDDEE" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/aquatic/get_random_body_markings(list/passed_features) var/name = "Shark" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ghoul.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ghoul.dm index 0b615d6bfc1..a1574f895a4 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ghoul.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ghoul.dm @@ -4,11 +4,6 @@ examine_limb_id = SPECIES_GHOUL can_have_genitals = FALSE //WHY WOULD YOU WANT TO FUCK ONE OF THESE THINGS? mutant_bodyparts = list("ghoulcolor" = "Tan Necrotic") - default_mutant_bodyparts = list( - "tail" = "None", - "ears" = "None", - "legs" = "Normal Legs" - ) mutanttongue = /obj/item/organ/internal/tongue/ghoul inherent_traits = list( TRAIT_ADVANCEDTOOLUSER, @@ -36,6 +31,13 @@ //i dont have to worry about sprites due to limbs_icon, thank god //also the head needs to be normal for hair to work +/datum/species/ghoul/get_default_mutant_bodyparts() + return list( + "tail" = list("None", FALSE), + "ears" = list("None", FALSE), + "legs" = list("Normal Legs", FALSE), + ) + /proc/proof_ghoul_features(list/inFeatures) // Missing Defaults in DNA? Randomize! if(inFeatures["ghoulcolor"] == null || inFeatures["ghoulcolor"] == "") diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_species.dm index 6f721354cd5..35ad767efab 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_species.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_species.dm @@ -17,9 +17,6 @@ TRAIT_USES_SKINTONES, ) inherent_biotypes = MOB_HUMANOID | MOB_ORGANIC - default_mutant_bodyparts = list( - "legs" = "Normal Legs" - ) exotic_bloodtype = "U" mutantheart = /obj/item/organ/internal/heart/hemophage mutantliver = /obj/item/organ/internal/liver/hemophage @@ -31,6 +28,10 @@ skinned_type = /obj/item/stack/sheet/animalhide/human veteran_only = TRUE +/datum/species/hemophage/get_default_mutant_bodyparts() + return list( + "legs" = list("Normal Legs", FALSE), + ) /datum/species/hemophage/check_roundstart_eligible() if(check_holidays(HALLOWEEN)) @@ -38,7 +39,6 @@ return ..() - /datum/species/hemophage/on_species_gain(mob/living/carbon/human/new_hemophage, datum/species/old_species, pref_load) . = ..() to_chat(new_hemophage, HEMOPHAGE_SPAWN_TEXT) diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/humanoid.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/humanoid.dm index 41f3715e8ca..0bdecf35227 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/humanoid.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/humanoid.dm @@ -9,19 +9,21 @@ ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "None", - "snout" = "None", - "ears" = "None", - "legs" = "Normal Legs", - "wings" = "None", - "taur" = "None", - "horns" = "None" - ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT payday_modifier = 1.0 examine_limb_id = SPECIES_HUMAN +/datum/species/humanoid/get_default_mutant_bodyparts() + return list( + "tail" = list("None", FALSE), + "snout" = list("None", FALSE), + "ears" = list("None", FALSE), + "legs" = list("Normal Legs", FALSE), + "wings" = list("None", FALSE), + "taur" = list("None", FALSE), + "horns" = list("None", FALSE), + ) + /datum/species/humanoid/get_species_description() return "This is a template species for your own creations!" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/insect.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/insect.dm index 50f2cbec142..97b21607c27 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/insect.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/insect.dm @@ -9,17 +9,6 @@ ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "None", - "snout" = "None", - "horns" = "None", - "ears" = "None", - "legs" = "Normal Legs", - "taur" = "None", - "fluff" = "None", - "wings" = "Bee", - "moth_antennae" = "None" - ) mutanttongue = /obj/item/organ/internal/tongue/insect payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -34,6 +23,19 @@ ) eyes_icon = 'modular_skyrat/modules/organs/icons/insect_eyes.dmi' +/datum/species/insect/get_default_mutant_bodyparts() + return list( + "tail" = list("None", FALSE), + "snout" = list("None", FALSE), + "horns" = list("None", FALSE), + "ears" = list("None", FALSE), + "legs" = list("Normal Legs", FALSE), + "taur" = list("None", FALSE), + "fluff" = list("None", FALSE), + "wings" = list("Bee", FALSE), + "moth_antennae" = list("None", FALSE), + ) + /datum/species/insect/get_species_description() return placeholder_description diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm index dd938a43e21..55f20d16e6b 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm @@ -1,20 +1,23 @@ /datum/species/lizard mutant_bodyparts = list() external_organs = list() - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "spines" = ACC_RANDOM, - "frills" = ACC_RANDOM, - "horns" = ACC_RANDOM, - "body_markings" = ACC_RANDOM, - "legs" = DIGITIGRADE_LEGS, - "taur" = "None", - "wings" = "None", - ) payday_modifier = 1.0 -/datum/species/lizard/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/lizard/get_default_mutant_bodyparts() + return list( + "tail" = list("Smooth", TRUE), + "snout" = list("Sharp + Light", TRUE), + "spines" = list("Long + Membrane", TRUE), + "frills" = list("Short", TRUE), + "horns" = list("Curled", TRUE), + "body_markings" = list("Light Belly", TRUE), + "legs" = list(DIGITIGRADE_LEGS,FALSE), + "taur" = list("None", FALSE), + "wings" = list("None", FALSE), + ) + +/datum/species/lizard/randomize_features() + var/list/features = ..() var/main_color = "#[random_color()]" var/second_color var/third_color @@ -29,9 +32,10 @@ if(3) //Third case, more randomisation second_color = "#[random_color()]" third_color = "#[random_color()]" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = third_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = third_color + return features /datum/species/lizard/prepare_human_for_preview(mob/living/carbon/human/lizard, lizard_color = "#009999") lizard.dna.features["mcolor"] = lizard_color diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/mammal.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/mammal.dm index 801695b4274..d450093819b 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/mammal.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/mammal.dm @@ -10,18 +10,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/mammal - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "horns" = "None", - "ears" = ACC_RANDOM, - "legs" = ACC_RANDOM, - "taur" = "None", - "fluff" = "None", - "wings" = "None", - "head_acc" = "None", - "neck_acc" = "None" - ) payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT bodypart_overrides = list( @@ -33,6 +21,19 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant, ) +/datum/species/mammal/get_default_mutant_bodyparts() + return list( + "tail" = list("Husky", TRUE), + "snout" = list("Husky", TRUE), + "horns" = list("None", FALSE), + "ears" = list("Husky", TRUE), + "legs" = list("Normal Legs", TRUE), + "taur" = list("None", FALSE), + "fluff" = list("None", FALSE), + "wings" = list("None", FALSE), + "head_acc" = list("None", FALSE), + "neck_acc" = list("None", FALSE), + ) /obj/item/organ/internal/tongue/mammal liked_foodtypes = GRAIN | MEAT @@ -40,7 +41,8 @@ toxic_foodtypes = TOXIC -/datum/species/mammal/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/mammal/randomize_features() + var/list/features = ..() var/main_color var/second_color var/third_color @@ -74,9 +76,10 @@ main_color = "#[random_color()]" second_color = "#[random_color()]" third_color = "#[random_color()]" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = third_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = third_color + return features /datum/species/mammal/get_random_body_markings(list/passed_features) var/name = "None" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/monkey.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/monkey.dm index 2b46cb02c21..76126e02192 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/monkey.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/monkey.dm @@ -1,5 +1,7 @@ -/datum/species/monkey - default_mutant_bodyparts = list("tail" = "Monkey") +/datum/species/monkey/get_default_mutant_bodyparts() + return list( + "tail" = list("Monkey", FALSE), + ) /datum/species/monkey/prepare_human_for_preview(mob/living/carbon/human/monke) regenerate_organs(monke, src, visual_only = TRUE) diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/moth.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/moth.dm index 6628060ee92..562ba54398d 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/moth.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/moth.dm @@ -1,10 +1,5 @@ /datum/species/moth mutant_bodyparts = list() - default_mutant_bodyparts = list( - "fluff" = "None", - "wings" = ACC_RANDOM, - "moth_antennae" = ACC_RANDOM, - ) inherent_traits = list( TRAIT_HAS_MARKINGS, TRAIT_TACKLING_WINGED_ATTACKER, @@ -12,8 +7,17 @@ TRAIT_MUTANT_COLORS, ) -/datum/species/moth/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["mcolor"] = "#E5CD99" +/datum/species/moth/get_default_mutant_bodyparts() + return list( + "fluff" = list("Plain", FALSE), + "wings" = list("Moth (Plain)", TRUE), + "moth_antennae" = list("Plain", TRUE), + ) + +/datum/species/moth/randomize_features() + var/list/features = ..() + features["mcolor"] = "#E5CD99" + return features /datum/species/moth/get_random_body_markings(list/passed_features) var/name = "None" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/podweak.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/podweak.dm index 90a4e4298a7..6e4615f99a5 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/podweak.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/podweak.dm @@ -7,12 +7,14 @@ TRAIT_LITERATE, ) mutant_bodyparts = list() - default_mutant_bodyparts = list( - "pod_hair" = ACC_RANDOM, - "legs" = "Normal Legs" - ) payday_modifier = 1.0 +/datum/species/pod/get_default_mutant_bodyparts() + return list( + "pod_hair" = list("Ivy", TRUE), + "legs" = list("Normal Legs", FALSE), + ) + /datum/species/pod/podweak name = "Podperson" id = SPECIES_PODPERSON_WEAK diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/roundstartslime.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/roundstartslime.dm index 422c1fd12cd..5490654ef96 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/roundstartslime.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/roundstartslime.dm @@ -1,20 +1,22 @@ /datum/species/jelly - default_mutant_bodyparts = list( - "tail" = "None", - "snout" = "None", - "ears" = "None", - "taur" = "None", - "wings" = "None", - "legs" = "Normal Legs", - "horns" = "None", - "spines" = "None", - "frills" = "None", - ) mutant_bodyparts = list() hair_color = "mutcolor" hair_alpha = 160 //a notch brighter so it blends better. facial_hair_alpha = 160 +/datum/species/jelly/get_default_mutant_bodyparts() + return list( + "tail" = list("None", FALSE), + "snout" = list("None", FALSE), + "ears" = list("None", FALSE), + "legs" = list("Normal Legs", FALSE), + "taur" = list("None", FALSE), + "wings" = list("None", FALSE), + "horns" = list("None", FALSE), + "spines" = list("None", FALSE), + "frills" = list("None", FALSE), + ) + /datum/species/jelly/get_species_description() return placeholder_description diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/skrell.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/skrell.dm index 47cd5be08c0..c92c46a1406 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/skrell.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/skrell.dm @@ -16,7 +16,6 @@ mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/skrell payday_modifier = 1.0 - default_mutant_bodyparts = list("skrell_hair" = ACC_RANDOM) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT eyes_icon = 'modular_skyrat/modules/organs/icons/skrell_eyes.dmi' mutantbrain = /obj/item/organ/internal/brain/skrell @@ -34,13 +33,19 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant/skrell, ) +/datum/species/skrell/get_default_mutant_bodyparts() + return list( + "skrell_hair" = list("Male", TRUE), + ) + /datum/species/skrell/get_species_description() return placeholder_description /datum/species/skrell/get_species_lore() return list(placeholder_lore) -/datum/species/skrell/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/skrell/randomize_features() + var/list/features = ..() var/main_color var/random = rand(1,6) //Choose from a range of green-blue colors @@ -57,9 +62,10 @@ main_color = "#22BBFF" if(6) main_color = "#2266FF" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = main_color - human_mob.dna.features["mcolor3"] = main_color + features["mcolor"] = main_color + features["mcolor2"] = main_color + features["mcolor3"] = main_color + return features /datum/species/skrell/prepare_human_for_preview(mob/living/carbon/human/skrell) var/skrell_color = "#22BBFF" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/tajaran.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/tajaran.dm index e5739b23624..7f9cfb7664b 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/tajaran.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/tajaran.dm @@ -11,12 +11,6 @@ mutanttongue = /obj/item/organ/internal/tongue/cat/tajaran inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "ears" = ACC_RANDOM, - "legs" = "Normal Legs" - ) payday_modifier = 1.0 species_language_holder = /datum/language_holder/tajaran changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -30,13 +24,21 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant, ) +/datum/species/tajaran/get_default_mutant_bodyparts() + return list( + "tail" = list("Cat (Big)", TRUE), + "snout" = list("Cat, normal", TRUE), + "ears" = list("Cat, normal", TRUE), + "legs" = list("Normal Legs", FALSE), + ) /obj/item/organ/internal/tongue/cat/tajaran liked_foodtypes = GRAIN | MEAT disliked_foodtypes = CLOTH -/datum/species/tajaran/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/tajaran/randomize_features() + var/list/features = ..() var/main_color var/second_color var/random = rand(1,5) @@ -57,9 +59,10 @@ if(5) main_color = "#DDCC99" second_color = "#DDCCAA" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/tajaran/get_random_body_markings(list/passed_features) var/name = pick("Tajaran", "Floof", "Floofer") diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/unathi.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/unathi.dm index c744097639a..ccbb0dd1416 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/unathi.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/unathi.dm @@ -10,15 +10,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/unathi - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "spines" = "None", - "frills" = "None", - "horns" = ACC_RANDOM, - "body_markings" = ACC_RANDOM, - "legs" = "Normal Legs" - ) payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT examine_limb_id = SPECIES_LIZARD @@ -33,6 +24,16 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/lizard, ) +/datum/species/unathi/get_default_mutant_bodyparts() + return list( + "tail" = list("Smooth", TRUE), + "snout" = list("Sharp + Light", TRUE), + "spines" = list("None", FALSE), + "frills" = list("None", FALSE), + "horns" = list("Curled", TRUE), + "body_markings" = list("Smooth Belly", TRUE), + "legs" = list("Normal Legs", FALSE), + ) /obj/item/organ/internal/tongue/unathi liked_foodtypes = GORE | MEAT | SEAFOOD | NUTS @@ -40,7 +41,8 @@ toxic_foodtypes = TOXIC -/datum/species/unathi/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/unathi/randomize_features() + var/list/features = ..() var/main_color var/second_color var/random = rand(1,5) @@ -61,9 +63,10 @@ if(5) main_color = "#33BB11" second_color = "#339911" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/unathi/get_species_description() return placeholder_description diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm index 059019f249e..60c0eee37cd 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm @@ -16,12 +16,6 @@ mutantbrain = /obj/item/organ/internal/brain/vox breathid = "n2" mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "Vox Tail", - "legs" = DIGITIGRADE_LEGS, - "snout" = "Vox Snout", - "spines" = ACC_RANDOM - ) payday_modifier = 1.0 outfit_important_for_life = /datum/outfit/vox species_language_holder = /datum/language_holder/vox @@ -51,6 +45,14 @@ LOADOUT_ITEM_EARS = VOX_EARS_ICON ) +/datum/species/vox/get_default_mutant_bodyparts() + return list( + "tail" = list("Vox Tail", FALSE), + "legs" = list(DIGITIGRADE_LEGS,FALSE), + "snout" = list("Vox Snout", FALSE), + "spines" = list("Vox Bands", TRUE), + ) + /datum/species/vox/pre_equip_species_outfit(datum/job/job, mob/living/carbon/human/equipping, visuals_only) . = ..() if(job?.vox_outfit) @@ -69,10 +71,12 @@ return randname -/datum/species/vox/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["mcolor"] = pick("#77DD88", "#77DDAA", "#77CCDD", "#77DDCC") - human_mob.dna.features["mcolor2"] = pick("#EEDD88", "#EECC88") - human_mob.dna.features["mcolor3"] = pick("#222222", "#44EEFF", "#44FFBB", "#8844FF", "#332233") +/datum/species/vox/randomize_features() + var/list/features = ..() + features["mcolor"] = pick("#77DD88", "#77DDAA", "#77CCDD", "#77DDCC") + features["mcolor2"] = pick("#EEDD88", "#EECC88") + features["mcolor3"] = pick("#222222", "#44EEFF", "#44FFBB", "#8844FF", "#332233") + return features /datum/species/vox/get_random_body_markings(list/passed_features) var/name = pick(list("Vox", "Vox Hive", "Vox Nightling", "Vox Heart", "Vox Tiger")) diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vulpkanin.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vulpkanin.dm index 62e001c5f74..48b2b3d327b 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vulpkanin.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vulpkanin.dm @@ -10,12 +10,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/vulpkanin - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "ears" = ACC_RANDOM, - "legs" = "Normal Legs" - ) species_language_holder = /datum/language_holder/vulpkanin payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -29,6 +23,13 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant, ) +/datum/species/vulpkanin/get_default_mutant_bodyparts() + return list( + "tail" = list("Fox", TRUE), + "snout" = list("Mammal, Long", TRUE), + "ears" = list("Fox", TRUE), + "legs" = list("Normal Legs", FALSE), + ) /obj/item/organ/internal/tongue/vulpkanin liked_foodtypes = RAW | MEAT @@ -36,7 +37,8 @@ toxic_foodtypes = TOXIC -/datum/species/vulpkanin/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/vulpkanin/randomize_features() + var/list/features = ..() var/main_color var/second_color var/random = rand(1,5) @@ -57,9 +59,10 @@ if(5) main_color = "#999999" second_color = "#EEEEEE" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/vulpkanin/get_random_body_markings(list/passed_features) var/name = pick("Fox", "Floof", "Floofer") diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/xeno.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/xeno.dm index b4dbe252503..4b2052bd083 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/xeno.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/xeno.dm @@ -12,13 +12,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutanttongue = /obj/item/organ/internal/tongue/xeno_hybrid mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "Xenomorph Tail", - "xenodorsal" = ACC_RANDOM, - "xenohead" = ACC_RANDOM, - "legs" = DIGITIGRADE_LEGS, - "taur" = "None" - ) external_organs = list() payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -34,6 +27,15 @@ meat = /obj/item/food/meat/slab/xeno skinned_type = /obj/item/stack/sheet/animalhide/xeno +/datum/species/xeno/get_default_mutant_bodyparts() + return list( + "tail" = list("Xenomorph Tail", FALSE), + "xenodorsal" = list("Standard", TRUE), + "xenohead" = list("Standard", TRUE), + "legs" = list(DIGITIGRADE_LEGS,FALSE), + "taur" = list("None", FALSE), + ) + /datum/species/xeno/get_species_description() return placeholder_description diff --git a/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm b/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm index 33896dd331f..74cde1544a3 100644 --- a/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm +++ b/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm @@ -30,8 +30,8 @@ new_spawn.AddElement(/datum/element/dusts_on_catatonia) new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type, /area/misc/hilbertshotel, /area/centcom/holding/cafe, /area/centcom/holding/cafewar, /area/centcom/holding/cafebotany, /area/centcom/holding/cafebuild, /area/centcom/holding/cafevox, /area/centcom/holding/cafedorms, /area/centcom/holding/cafepark, /area/centcom/holding/cafeplumbing)) - ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT) - ADD_TRAIT(new_spawn, TRAIT_FREE_GHOST, GHOSTROLE_TRAIT) + ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, TRAIT_GHOSTROLE) + ADD_TRAIT(new_spawn, TRAIT_FREE_GHOST, TRAIT_GHOSTROLE) to_chat(new_spawn,span_warning("Ghosting is free!")) var/datum/action/toggle_dead_chat_mob/D = new(new_spawn) D.Grant(new_spawn) @@ -58,8 +58,8 @@ new_spawn.AddElement(/datum/element/dusts_on_catatonia) new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type, /area/misc/hilbertshotel, /area/centcom/holding/cafe, /area/centcom/holding/cafewar, /area/centcom/holding/cafebotany, /area/centcom/holding/cafebuild, /area/centcom/holding/cafevox, /area/centcom/holding/cafedorms, /area/centcom/holding/cafepark, /area/centcom/holding/cafeplumbing)) - ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT) - ADD_TRAIT(new_spawn, TRAIT_FREE_GHOST, GHOSTROLE_TRAIT) + ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, TRAIT_GHOSTROLE) + ADD_TRAIT(new_spawn, TRAIT_FREE_GHOST, TRAIT_GHOSTROLE) to_chat(new_spawn,span_warning("Ghosting is free!")) var/datum/action/toggle_dead_chat_mob/D = new(new_spawn) SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn) @@ -83,11 +83,11 @@ if(!..()) return 0 var/mob/M = target - if(HAS_TRAIT_FROM(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT)) - REMOVE_TRAIT(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT) + if(HAS_TRAIT_FROM(M,TRAIT_SIXTHSENSE,TRAIT_GHOSTROLE)) + REMOVE_TRAIT(M,TRAIT_SIXTHSENSE,TRAIT_GHOSTROLE) to_chat(M,span_notice("You're no longer hearing deadchat.")) else - ADD_TRAIT(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT) + ADD_TRAIT(M,TRAIT_SIXTHSENSE,TRAIT_GHOSTROLE) to_chat(M,span_notice("You're once again hearing deadchat.")) /obj/item/storage/box/syndie_kit/chameleon/ghostcafe diff --git a/modular_skyrat/modules/ghostcafe/code/ghostcafeturf.dm b/modular_skyrat/modules/ghostcafe/code/ghostcafeturf.dm index 68a03c5f6d1..0af43268ca5 100644 --- a/modular_skyrat/modules/ghostcafe/code/ghostcafeturf.dm +++ b/modular_skyrat/modules/ghostcafe/code/ghostcafeturf.dm @@ -6,6 +6,6 @@ lava_damage = 0 lava_firestacks = 0 temperature_damage = 0 - immunity_trait = GHOSTROLE_TRAIT + immunity_trait = TRAIT_GHOSTROLE immunity_resistance_flags = LAVA_PROOF diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm index 52995365b01..66cbbb510b2 100644 --- a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm @@ -140,7 +140,7 @@ /datum/wound/blunt/robotic/handle_process(seconds_per_tick, times_fired) . = ..() - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return if (limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle) diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm index e9e9ce3cb68..d4483dafb0b 100644 --- a/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm @@ -20,7 +20,7 @@ /datum/wound/blunt/robotic/secures_internals/handle_process(seconds_per_tick, times_fired) . = ..() - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return if (gelled) diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm index 24ac18eeab6..16540ac9f36 100644 --- a/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm @@ -126,7 +126,7 @@ if (outgoing_bodytemp_coeff <= 0) return var/statis_mult = 1 - if (IS_IN_STASIS(victim)) // stasis heavily reduces the ingoing and outgoing transfer of heat + if (HAS_TRAIT(victim, TRAIT_STASIS)) // stasis heavily reduces the ingoing and outgoing transfer of heat statis_mult *= OVERHEAT_ON_STASIS_HEAT_MULT var/difference_from_average = max((BODYTEMP_NORMAL - victim.bodytemperature), 0) diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm index 1a0c730c68c..2d20b0edbb2 100644 --- a/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm @@ -194,7 +194,7 @@ var/base_mult = 1 if (victim) - if (IS_IN_STASIS(victim)) + if (HAS_TRAIT(victim, TRAIT_STASIS)) base_mult *= ELECTRICAL_DAMAGE_ON_STASIS_MULT if (victim.body_position == LYING_DOWN) base_mult *= ELECTRICAL_DAMAGE_LYING_DOWN_MULT diff --git a/modular_skyrat/modules/modular_implants/code/nif_persistence.dm b/modular_skyrat/modules/modular_implants/code/nif_persistence.dm index fd24fd3b579..ce4d865f7cf 100644 --- a/modular_skyrat/modules/modular_implants/code/nif_persistence.dm +++ b/modular_skyrat/modules/modular_implants/code/nif_persistence.dm @@ -22,7 +22,7 @@ /mob/living/carbon/human/proc/save_nif_data(datum/modular_persistence/persistence, remove_nif = FALSE) var/obj/item/organ/internal/cyberimp/brain/nif/installed_nif = get_organ_by_type(/obj/item/organ/internal/cyberimp/brain/nif) - if(HAS_TRAIT(src, GHOSTROLE_TRAIT)) //Nothing is lost from playing a ghost role + if(HAS_TRAIT(src, TRAIT_GHOSTROLE)) //Nothing is lost from playing a ghost role return FALSE if(remove_nif) @@ -69,7 +69,7 @@ /// Loads the NIF data for an individual user. /mob/living/carbon/human/proc/load_nif_data(datum/modular_persistence/persistence) - if(HAS_TRAIT(src, GHOSTROLE_TRAIT)) + if(HAS_TRAIT(src, TRAIT_GHOSTROLE)) return FALSE if(!persistence.nif_path) diff --git a/modular_skyrat/modules/modular_implants/code/nifs.dm b/modular_skyrat/modules/modular_implants/code/nifs.dm index 12d9c67ad81..5d2b1aabd4a 100644 --- a/modular_skyrat/modules/modular_implants/code/nifs.dm +++ b/modular_skyrat/modules/modular_implants/code/nifs.dm @@ -185,7 +185,7 @@ /obj/item/organ/internal/cyberimp/brain/nif/process(seconds_per_tick) . = ..() - if(!linked_mob || broken || IS_IN_STASIS(linked_mob)) + if(!linked_mob || broken || HAS_TRAIT(linked_mob, TRAIT_STASIS)) return FALSE if(calibrating) diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/huds.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/huds.dm index 77353910752..dead3ffa066 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts/huds.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/huds.dm @@ -24,7 +24,7 @@ ADD_TRAIT(linked_mob, hud_trait, GLASSES_TRAIT) for(var/trait as anything in added_eyewear_traits) - ADD_TRAIT(linked_mob, trait, NIFSOFT_TRAIT) + ADD_TRAIT(linked_mob, trait, TRAIT_NIFSOFT) linked_mob.update_sight() @@ -35,10 +35,10 @@ hud.hide_from(linked_mob) if(hud_trait) - REMOVE_TRAIT(linked_mob, hud_trait, NIFSOFT_TRAIT) + REMOVE_TRAIT(linked_mob, hud_trait, TRAIT_NIFSOFT) for(var/trait in added_eyewear_traits) - REMOVE_TRAIT(linked_mob, trait, NIFSOFT_TRAIT) + REMOVE_TRAIT(linked_mob, trait, TRAIT_NIFSOFT) linked_mob.update_sight() return TRUE diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/hexacrocin.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/hexacrocin.dm index 5323a8ddc86..c55deb402fa 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/hexacrocin.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/hexacrocin.dm @@ -43,7 +43,7 @@ to_chat(exposed_mob, span_purple("Your libido is going haywire! It feels like speaking is much harder...")) exposed_mob.gain_trauma(/datum/brain_trauma/very_special/bimbo, TRAUMA_RESILIENCE_BASIC) - ADD_TRAIT(exposed_mob, TRAIT_BIMBO, LEWDCHEM_TRAIT) + ADD_TRAIT(exposed_mob, TRAIT_BIMBO, TRAIT_LEWDCHEM) /datum/chemical_reaction/hexacrocin results = list(/datum/reagent/drug/aphrodisiac/crocin/hexacrocin = 1) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/pentacamphor.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/pentacamphor.dm index 2c2e6083c8c..88161435704 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/pentacamphor.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_chemistry/reagents/pentacamphor.dm @@ -23,11 +23,11 @@ if(HAS_TRAIT(exposed_mob, TRAIT_BIMBO)) exposed_mob.cure_trauma_type(/datum/brain_trauma/very_special/bimbo, TRAUMA_RESILIENCE_ABSOLUTE) to_chat(exposed_mob, span_notice("Your mind is free. Your thoughts are pure and innocent once more.")) - REMOVE_TRAIT(exposed_mob, TRAIT_BIMBO, LEWDCHEM_TRAIT) + REMOVE_TRAIT(exposed_mob, TRAIT_BIMBO, TRAIT_LEWDCHEM) return if(!HAS_TRAIT(exposed_mob, TRAIT_NEVERBONER)) to_chat(exposed_mob, span_notice("You feel like you'll never feel aroused again...")) - ADD_TRAIT(exposed_mob, TRAIT_NEVERBONER, LEWDCHEM_TRAIT) + ADD_TRAIT(exposed_mob, TRAIT_NEVERBONER, TRAIT_LEWDCHEM) /datum/chemical_reaction/pentacamphor results = list(/datum/reagent/drug/aphrodisiac/camphor/pentacamphor = 1) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/strapon.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/strapon.dm index f499d5ba973..ec2fc7c0d9b 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/strapon.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/strapon.dm @@ -182,7 +182,7 @@ . = ..() update_icon_state() update_icon() - ADD_TRAIT(src, TRAIT_NODROP, STRAPON_TRAIT) + ADD_TRAIT(src, TRAIT_NODROP, TRAIT_STRAPON) /obj/item/strapon_dildo/update_icon_state() . = ..() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/human.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/human.dm index c861b924d6f..d38656878af 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/human.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/human.dm @@ -371,7 +371,7 @@ return FALSE var/obj/item/clothing/sextoy/condom/condom = penis - return condom.condom_state == CONDOM_BROKEN + return condom.condom_state == TRAIT_CONDOM_BROKEN // For handling things that don't already have handcuff handlers. /mob/living/carbon/human/set_handcuffed(new_value) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/condom.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/condom.dm index c6ca46a83ab..21c2023f198 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/condom.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/condom.dm @@ -76,13 +76,13 @@ condom_state = "dirty" if(prob(10)) //chance of condom to break on first time. name = "broken condom" - condom_state = CONDOM_BROKEN + condom_state = TRAIT_CONDOM_BROKEN update_icon_state() update_icon() if("dirty") name = "broken condom" - condom_state = CONDOM_BROKEN + condom_state = TRAIT_CONDOM_BROKEN update_icon_state() update_icon() 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 a94c833cc9b..c7256be1610 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 @@ -430,7 +430,7 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors /obj/item/clothing/sextoy/dildo/double_dildo_end/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_NODROP, STRAPON_TRAIT) + ADD_TRAIT(src, TRAIT_NODROP, TRAIT_STRAPON) /obj/item/clothing/sextoy/dildo/double_dildo_end/update_icon_state() . = ..() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_quirks.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_quirks.dm index 3473ce277da..d85e0db56d7 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_quirks.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_quirks.dm @@ -155,19 +155,19 @@ /datum/brain_trauma/very_special/bimbo/on_gain() owner.add_mood_event("bimbo", /datum/mood_event/bimbo) - if(!HAS_TRAIT_FROM(owner, TRAIT_BIMBO, LEWDCHEM_TRAIT)) - ADD_TRAIT(owner, TRAIT_BIMBO, LEWDCHEM_TRAIT) + if(!HAS_TRAIT_FROM(owner, TRAIT_BIMBO, TRAIT_LEWDCHEM)) + ADD_TRAIT(owner, TRAIT_BIMBO, TRAIT_LEWDCHEM) RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech)) - if(!HAS_TRAIT_FROM(owner, TRAIT_MASOCHISM, APHRO_TRAIT)) - ADD_TRAIT(owner, TRAIT_MASOCHISM, APHRO_TRAIT) + if(!HAS_TRAIT_FROM(owner, TRAIT_MASOCHISM, TRAIT_APHRO)) + ADD_TRAIT(owner, TRAIT_MASOCHISM, TRAIT_APHRO) /datum/brain_trauma/very_special/bimbo/on_lose() owner.clear_mood_event("bimbo") - if(HAS_TRAIT_FROM(owner, TRAIT_BIMBO, LEWDCHEM_TRAIT)) - REMOVE_TRAIT(owner, TRAIT_BIMBO, LEWDCHEM_TRAIT) + if(HAS_TRAIT_FROM(owner, TRAIT_BIMBO, TRAIT_LEWDCHEM)) + REMOVE_TRAIT(owner, TRAIT_BIMBO, TRAIT_LEWDCHEM) UnregisterSignal(owner, COMSIG_MOB_SAY) - if(HAS_TRAIT_FROM(owner, TRAIT_MASOCHISM, APHRO_TRAIT)) - REMOVE_TRAIT(owner, TRAIT_MASOCHISM, APHRO_TRAIT) + if(HAS_TRAIT_FROM(owner, TRAIT_MASOCHISM, TRAIT_APHRO)) + REMOVE_TRAIT(owner, TRAIT_MASOCHISM, TRAIT_APHRO) //Mood boost /datum/mood_event/bimbo @@ -195,13 +195,13 @@ /datum/quirk/masochism/post_add() . = ..() var/mob/living/carbon/human/affected_human = quirk_holder - ADD_TRAIT(affected_human, TRAIT_MASOCHISM, LEWDQUIRK_TRAIT) + ADD_TRAIT(affected_human, TRAIT_MASOCHISM, TRAIT_LEWDQUIRK) affected_human.pain_limit = 60 /datum/quirk/masochism/remove() . = ..() var/mob/living/carbon/human/affected_human = quirk_holder - REMOVE_TRAIT(affected_human, TRAIT_MASOCHISM, LEWDQUIRK_TRAIT) + REMOVE_TRAIT(affected_human, TRAIT_MASOCHISM, TRAIT_LEWDQUIRK) affected_human.pain_limit = 0 /* @@ -219,11 +219,11 @@ /datum/brain_trauma/very_special/neverboner/on_gain() var/mob/living/carbon/human/affected_human = owner - ADD_TRAIT(affected_human, TRAIT_NEVERBONER, APHRO_TRAIT) + ADD_TRAIT(affected_human, TRAIT_NEVERBONER, TRAIT_APHRO) /datum/brain_trauma/very_special/neverboner/on_lose() var/mob/living/carbon/human/affected_human = owner - REMOVE_TRAIT(affected_human, TRAIT_NEVERBONER, APHRO_TRAIT) + REMOVE_TRAIT(affected_human, TRAIT_NEVERBONER, TRAIT_APHRO) /* * SADISM @@ -297,12 +297,12 @@ /datum/quirk/ropebunny/post_add() . = ..() var/mob/living/carbon/human/affected_mob = quirk_holder - ADD_TRAIT(affected_mob, TRAIT_ROPEBUNNY, LEWDQUIRK_TRAIT) + ADD_TRAIT(affected_mob, TRAIT_ROPEBUNNY, TRAIT_LEWDQUIRK) /datum/quirk/ropebunny/remove() . = ..() var/mob/living/carbon/human/affected_mob = quirk_holder - REMOVE_TRAIT(affected_mob, TRAIT_ROPEBUNNY, LEWDQUIRK_TRAIT) + REMOVE_TRAIT(affected_mob, TRAIT_ROPEBUNNY, TRAIT_LEWDQUIRK) //Rigger code /datum/quirk/rigger @@ -318,12 +318,12 @@ /datum/quirk/rigger/post_add() . = ..() var/mob/living/carbon/human/affected_mob = quirk_holder - ADD_TRAIT(affected_mob, TRAIT_RIGGER, LEWDQUIRK_TRAIT) + ADD_TRAIT(affected_mob, TRAIT_RIGGER, TRAIT_LEWDQUIRK) /datum/quirk/rigger/remove() . = ..() var/mob/living/carbon/human/affected_mob = quirk_holder - REMOVE_TRAIT(affected_mob, TRAIT_RIGGER, LEWDQUIRK_TRAIT) + REMOVE_TRAIT(affected_mob, TRAIT_RIGGER, TRAIT_LEWDQUIRK) /datum/mood_event/sadistic description = span_purple("Others' suffering makes me happier\n") diff --git a/modular_skyrat/modules/moretraitoritems/code/glue.dm b/modular_skyrat/modules/moretraitoritems/code/glue.dm index 75867bca825..01a1c9983c1 100644 --- a/modular_skyrat/modules/moretraitoritems/code/glue.dm +++ b/modular_skyrat/modules/moretraitoritems/code/glue.dm @@ -17,11 +17,11 @@ return if(istype(target, /obj/item)) var/obj/item/I = target - if(HAS_TRAIT_FROM(I, TRAIT_NODROP, GLUED_ITEM_TRAIT)) + if(HAS_TRAIT_FROM(I, TRAIT_NODROP, TRAIT_GLUED_ITEM)) to_chat(user, span_warning("[I] is already sticky!")) return uses -= 1 - ADD_TRAIT(I, TRAIT_NODROP, GLUED_ITEM_TRAIT) + ADD_TRAIT(I, TRAIT_NODROP, TRAIT_GLUED_ITEM) I.desc += " It looks sticky." to_chat(user, span_notice("You smear the [I] with glue, making it incredibly sticky!")) if(uses == 0) diff --git a/modular_skyrat/modules/primitive_production/code/glassblowing.dm b/modular_skyrat/modules/primitive_production/code/glassblowing.dm index a887b063dab..3898b4f25de 100644 --- a/modular_skyrat/modules/primitive_production/code/glassblowing.dm +++ b/modular_skyrat/modules/primitive_production/code/glassblowing.dm @@ -392,7 +392,7 @@ to_chat(user, span_notice("You begin to [step_id] [src].")) if(!do_after(user, actioning_speed, target = src)) fail_message("You interrupt an action!", user) - REMOVE_TRAIT(tool_to_use, TRAIT_CURRENTLY_GLASSBLOWING, GLASSBLOWING_TRAIT) + REMOVE_TRAIT(tool_to_use, TRAIT_CURRENTLY_GLASSBLOWING, TRAIT_GLASSBLOWING) return FALSE if(glass.steps_remaining) @@ -402,7 +402,7 @@ if(check_finished(glass)) glass.is_finished = TRUE - REMOVE_TRAIT(tool_to_use, TRAIT_CURRENTLY_GLASSBLOWING, GLASSBLOWING_TRAIT) + REMOVE_TRAIT(tool_to_use, TRAIT_CURRENTLY_GLASSBLOWING, TRAIT_GLASSBLOWING) in_use = FALSE to_chat(user, span_notice("You finish trying to [step_id] [src].")) @@ -447,7 +447,7 @@ balloon_alert(user, "already glassblowing!") return FALSE - ADD_TRAIT(user, TRAIT_CURRENTLY_GLASSBLOWING, GLASSBLOWING_TRAIT) + ADD_TRAIT(user, TRAIT_CURRENTLY_GLASSBLOWING, TRAIT_GLASSBLOWING) return user var/obj/item/glassblowing/used_tool @@ -467,7 +467,7 @@ balloon_alert(user, "already in use!") return FALSE - ADD_TRAIT(used_tool, TRAIT_CURRENTLY_GLASSBLOWING, GLASSBLOWING_TRAIT) + ADD_TRAIT(used_tool, TRAIT_CURRENTLY_GLASSBLOWING, TRAIT_GLASSBLOWING) return used_tool /** diff --git a/modular_skyrat/modules/primitive_production/code/misc.dm b/modular_skyrat/modules/primitive_production/code/misc.dm new file mode 100644 index 00000000000..18bcafa8664 --- /dev/null +++ b/modular_skyrat/modules/primitive_production/code/misc.dm @@ -0,0 +1,35 @@ +/obj/item/shard/attackby(obj/item/item, mob/user, params) + //xenoarch hammer, forging hammer, etc. + if(item.tool_behaviour == TOOL_HAMMER) + var/added_color + switch(src.type) + if(/obj/item/shard) + added_color = "#88cdf1" + + if(/obj/item/shard/plasma) + added_color = "#ff80f4" + + if(/obj/item/shard/plastitanium) + added_color = "#5d3369" + + if(/obj/item/shard/titanium) + added_color = "#cfbee0" + + var/obj/colored_item = new /obj/item/stack/ore/glass/zero_cost(get_turf(src)) + colored_item.add_atom_colour(added_color, FIXED_COLOUR_PRIORITY) + new /obj/effect/decal/cleanable/glass(get_turf(src)) + user.balloon_alert(user, "[src] shatters!") + playsound(src, SFX_SHATTER, 30, TRUE) + qdel(src) + return TRUE + + return ..() + +/obj/item/stack/ore/glass/zero_cost + points = 0 + merge_type = /obj/item/stack/ore/glass/zero_cost + +/obj/item/stack/ore/examine(mob/user) + . = ..() + if(points == 0) + . += span_warning("
[src] is worthless and will not reward any mining points!") diff --git a/modular_skyrat/modules/stasisrework/code/stasissleeper.dm b/modular_skyrat/modules/stasisrework/code/stasissleeper.dm index ffeb12dc56e..3510fa5c269 100644 --- a/modular_skyrat/modules/stasisrework/code/stasissleeper.dm +++ b/modular_skyrat/modules/stasisrework/code/stasissleeper.dm @@ -75,7 +75,7 @@ visible_message(span_notice("[occupant] emerges from [src]!"), span_notice("You climb out of [src]!")) open_machine() - if(IS_IN_STASIS(user)) + if(HAS_TRAIT(user, TRAIT_STASIS)) thaw_them(user) /obj/machinery/stasissleeper/proc/stasis_running() @@ -112,9 +112,9 @@ return var/mob/living/L_occupant = occupant if(stasis_running()) - if(!IS_IN_STASIS(L_occupant)) + if(!HAS_TRAIT(L_occupant, TRAIT_STASIS)) chill_out(L_occupant) - else if(IS_IN_STASIS(L_occupant)) + else if(HAS_TRAIT(L_occupant, TRAIT_STASIS)) thaw_them(L_occupant) /obj/machinery/stasissleeper/screwdriver_act(mob/living/user, obj/item/used_item) diff --git a/modular_skyrat/modules/synths/code/bodyparts/internal_computer/brain.dm b/modular_skyrat/modules/synths/code/bodyparts/internal_computer/brain.dm new file mode 100644 index 00000000000..9b65b3f6772 --- /dev/null +++ b/modular_skyrat/modules/synths/code/bodyparts/internal_computer/brain.dm @@ -0,0 +1,11 @@ +/obj/item/organ/internal/brain/synth + var/obj/item/modular_computer/pda/synth/internal_computer + actions_types = list(/datum/action/item_action/synth/open_internal_computer) + +/obj/item/organ/internal/brain/synth/Initialize(mapload) + . = ..() + internal_computer = new(src) + +/obj/item/organ/internal/brain/synth/Destroy() + QDEL_NULL(internal_computer) + return ..() diff --git a/modular_skyrat/modules/synths/code/bodyparts/internal_computer/internal_computer.dm b/modular_skyrat/modules/synths/code/bodyparts/internal_computer/internal_computer.dm new file mode 100644 index 00000000000..89f24cdcede --- /dev/null +++ b/modular_skyrat/modules/synths/code/bodyparts/internal_computer/internal_computer.dm @@ -0,0 +1,117 @@ +/// Custom computer for synth brains +/obj/item/modular_computer/pda/synth + name = "virtual persocom" + + base_active_power_usage = 0 + base_idle_power_usage = 0 + + long_ranged = TRUE //Synths have good antennae + + max_idle_programs = 3 + + max_capacity = 32 + +/obj/item/modular_computer/pda/synth/Initialize(mapload) + . = ..() + + // prevent these from being created outside of synth brains + if(!istype(loc, /obj/item/organ/internal/brain/synth)) + return INITIALIZE_HINT_QDEL + +/datum/action/item_action/synth/open_internal_computer + name = "Open persocom emulation" + desc = "Accesses your built-in virtual machine." + check_flags = AB_CHECK_CONSCIOUS + +/datum/action/item_action/synth/open_internal_computer/Trigger(trigger_flags) + . = ..() + var/obj/item/organ/internal/brain/synth/targetmachine = target + targetmachine.internal_computer.interact(owner) + +/obj/item/modular_computer/pda/synth/ui_state(mob/user) + return GLOB.default_state + +/obj/item/modular_computer/pda/synth/ui_status(mob/user) + var/obj/item/organ/internal/brain/synth/brain_loc = loc + if(!istype(brain_loc)) + return UI_CLOSE + + if(!QDELETED(brain_loc.owner)) + if(brain_loc.owner == user) + return min( + ui_status_user_is_abled(user, src), + ui_status_only_living(user), + ) + else return UI_CLOSE + return ..() + +/obj/item/modular_computer/pda/synth/RemoveID(mob/user) + var/obj/item/organ/internal/brain/synth/brain_loc = loc + if(!istype(brain_loc)) + return ..() + + if(!computer_id_slot) + return ..() + + if(crew_manifest_update) + GLOB.manifest.modify(computer_id_slot.registered_name, computer_id_slot.assignment, computer_id_slot.get_trim_assignment()) + + if(user && !issilicon(user) && in_range(brain_loc.owner || brain_loc, user)) + user.put_in_hands(computer_id_slot) + else + computer_id_slot.forceMove(brain_loc.owner ? brain_loc.owner.drop_location() : brain_loc.drop_location()) //We actually update the physical on brain removal/insert + + computer_id_slot = null + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + balloon_alert(user, "removed ID") + +/obj/item/modular_computer/pda/synth/get_ntnet_status() + . = NTNET_NO_SIGNAL + // NTNet is down and we are not connected via wired connection. The synth is no more + var/obj/item/organ/internal/brain/synth/brain_loc = loc + if(!istype(brain_loc)) + return + if(!find_functional_ntnet_relay() || isnull(brain_loc.owner)) + return + var/turf/current_turf = get_turf(brain_loc.owner || brain_loc) + if(is_station_level(current_turf.z)) + return NTNET_GOOD_SIGNAL + else if(long_ranged && !is_centcom_level(current_turf.z)) // Centcom is excluded because cafe + return NTNET_LOW_SIGNAL + +/* +So, I am not snowflaking more code.. except this +Attacking a synth with an id loads it into its slot.. pain and probably shitcode +*/ + +/obj/item/card/id/attack(mob/living/target_mob, mob/living/user, params) + var/mob/living/carbon/human/targetmachine = target_mob + if(!istype(targetmachine)) + return ..() + + var/obj/item/organ/internal/brain/synth/robotbrain = targetmachine.get_organ_slot(ORGAN_SLOT_BRAIN) + if(istype(robotbrain)) + if(user.zone_selected == BODY_ZONE_PRECISE_EYES) + balloon_alert(user, "Inserting ID into persocom slot...") + if(do_after(user, 5 SECONDS)) + balloon_alert(user, "ID slot interface registered!") + to_chat(targetmachine, span_notice("[user] inserts [src] into your persocom's card slot.")) + robotbrain.internal_computer.InsertID(src, user) + return + return ..() + +/obj/item/modular_computer/pda/attack(mob/living/target_mob, mob/living/user, params) + var/mob/living/carbon/human/targetmachine = target_mob + if(!istype(targetmachine)) + return ..() + + var/obj/item/organ/internal/brain/synth/robotbrain = targetmachine.get_organ_slot(ORGAN_SLOT_BRAIN) + if(istype(robotbrain)) + if(user.zone_selected == BODY_ZONE_PRECISE_EYES) + balloon_alert(user, "Establishing SSH login with persocom...") + if(do_after(user, 5 SECONDS)) + balloon_alert(user, "Connection established!") + to_chat(targetmachine, span_notice("[user] establishes an SSH connection between [src] and your persocom emulation.")) + robotbrain.internal_computer.interact(user) + return + return ..() diff --git a/modular_skyrat/modules/synths/code/reagents/reagents.dm b/modular_skyrat/modules/synths/code/reagents/reagents.dm index ef48f0bf947..54be7648ada 100644 --- a/modular_skyrat/modules/synths/code/reagents/reagents.dm +++ b/modular_skyrat/modules/synths/code/reagents/reagents.dm @@ -98,10 +98,10 @@ /datum/reagent/medicine/taste_suppressor/on_mob_metabolize(mob/living/affected_mob) . = ..() - ADD_TRAIT(affected_mob, TRAIT_AGEUSIA, REAGENT_TRAIT) + ADD_TRAIT(affected_mob, TRAIT_AGEUSIA, TRAIT_REAGENT) /datum/reagent/medicine/taste_suppressor/on_mob_end_metabolize(mob/living/affected_mob) . = ..() - REMOVE_TRAIT(affected_mob, TRAIT_AGEUSIA, REAGENT_TRAIT) + REMOVE_TRAIT(affected_mob, TRAIT_AGEUSIA, TRAIT_REAGENT) diff --git a/modular_skyrat/modules/synths/code/species/synthetic.dm b/modular_skyrat/modules/synths/code/species/synthetic.dm index 124985d73da..9a362621327 100644 --- a/modular_skyrat/modules/synths/code/species/synthetic.dm +++ b/modular_skyrat/modules/synths/code/species/synthetic.dm @@ -18,19 +18,8 @@ TRAIT_LITERATE, TRAIT_NOCRITDAMAGE, // We do our own handling of crit damage. TRAIT_ROBOTIC_DNA_ORGANS, - TRAIT_NO_TRANSFORMATION_STING, ) mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "None", - "ears" = "None", - "legs" = "Normal Legs", - "snout" = "None", - MUTANT_SYNTH_ANTENNA = "None", - MUTANT_SYNTH_SCREEN = "None", - MUTANT_SYNTH_CHASSIS = "Default Chassis", - MUTANT_SYNTH_HEAD = "Default Head", - ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT reagent_flags = PROCESS_SYNTHETIC payday_modifier = 1.0 // Matches the rest of the pay penalties the non-human crew have @@ -63,6 +52,18 @@ /// This is the screen that is given to the user after they get revived. On death, their screen is temporarily set to BSOD before it turns off, hence the need for this var. var/saved_screen = "Blank" +/datum/species/synthetic/get_default_mutant_bodyparts() + return list( + "tail" = list("None", FALSE), + "ears" = list("None", FALSE), + "legs" = list("Normal Legs", FALSE), + "snout" = list("None", FALSE), + MUTANT_SYNTH_ANTENNA = list("None", FALSE), + MUTANT_SYNTH_SCREEN = list("None", FALSE), + MUTANT_SYNTH_CHASSIS = list("Default Chassis", FALSE), + MUTANT_SYNTH_HEAD = list("Default Head", FALSE), + ) + /datum/species/synthetic/spec_life(mob/living/carbon/human/human) . = ..() diff --git a/modular_skyrat/modules/teshari/code/_teshari.dm b/modular_skyrat/modules/teshari/code/_teshari.dm index 84dc35e59c2..1b09214e5f7 100644 --- a/modular_skyrat/modules/teshari/code/_teshari.dm +++ b/modular_skyrat/modules/teshari/code/_teshari.dm @@ -14,11 +14,6 @@ TRAIT_NO_UNDERWEAR, TRAIT_HAS_MARKINGS, ) - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "ears" = ACC_RANDOM, - "legs" = "Normal Legs" - ) digitigrade_customization = DIGITIGRADE_NEVER changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT payday_modifier = 1.0 @@ -53,6 +48,13 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant/teshari, ) +/datum/species/teshari/get_default_mutant_bodyparts() + return list( + "tail" = list("Teshari (Default)", TRUE), + "ears" = list("Teshari Regular", TRUE), + "legs" = list("Normal Legs", FALSE), + ) + /obj/item/organ/internal/tongue/teshari liked_foodtypes = MEAT diff --git a/modular_skyrat/modules/xenoarch/code/modules/research/xenoarch/xenoarch_tool.dm b/modular_skyrat/modules/xenoarch/code/modules/research/xenoarch/xenoarch_tool.dm index 50f695c2011..5d58fa29b84 100644 --- a/modular_skyrat/modules/xenoarch/code/modules/research/xenoarch/xenoarch_tool.dm +++ b/modular_skyrat/modules/xenoarch/code/modules/research/xenoarch/xenoarch_tool.dm @@ -7,6 +7,7 @@ /obj/item/xenoarch/hammer name = "parent dev item" desc = "A hammer that can be used to remove dirt from strange rocks." + tool_behaviour = TOOL_HAMMER var/dig_amount = 1 var/dig_speed = 1 SECONDS var/advanced = FALSE diff --git a/tff_modular/modules/blooper/atoms_movable.dm b/tff_modular/modules/blooper/atoms_movable.dm index e73058c3e93..a7446f60efb 100644 --- a/tff_modular/modules/blooper/atoms_movable.dm +++ b/tff_modular/modules/blooper/atoms_movable.dm @@ -59,7 +59,7 @@ blooper_pitch_range = BLOOPER_VARIANCE_RAND blooper_speed = rand(BLOOPER_DEFAULT_MINSPEED, BLOOPER_DEFAULT_MAXSPEED) -/randomize_human(mob/living/carbon/human/human) +/randomize_human(mob/living/carbon/human/human, randomize_mutations = FALSE) . = ..() human.set_blooper(pick(GLOB.blooper_list)) human.blooper_pitch = BLOOPER_PITCH_RAND(human.gender) diff --git a/tff_modular/modules/nabbers/code/_nabbers.dm b/tff_modular/modules/nabbers/code/_nabbers.dm index b18982429cd..79c98824c84 100644 --- a/tff_modular/modules/nabbers/code/_nabbers.dm +++ b/tff_modular/modules/nabbers/code/_nabbers.dm @@ -87,6 +87,7 @@ H.apply_damage(NABBER_DAMAGE_ONBURNING, OXY) /datum/species/nabber/randomize_features(mob/living/carbon/human/human_mob) + var/list/features = ..() var/main_color var/random = rand(1,6) switch(random) @@ -102,9 +103,10 @@ main_color = "#c0ad00" if(6) main_color = "#e6ff03" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = main_color - human_mob.dna.features["mcolor3"] = main_color + features["mcolor"] = main_color + features["mcolor2"] = main_color + features["mcolor3"] = main_color + return features /datum/species/nabber/prepare_human_for_preview(mob/living/carbon/human/nabber) var/nabber_color = "#00ac1d" diff --git a/tff_modular/modules/teshari_reborn/code/teshari.dm b/tff_modular/modules/teshari_reborn/code/teshari.dm index e6317be4a4f..5c16af2ad85 100644 --- a/tff_modular/modules/teshari_reborn/code/teshari.dm +++ b/tff_modular/modules/teshari_reborn/code/teshari.dm @@ -41,9 +41,6 @@ LOADOUT_ITEM_ACCESSORY = TESHARI_ACCESSORIES_ICON, LOADOUT_ITEM_EARS = TESHARI_EARS_ICON ) - default_mutant_bodyparts = list( - "legs" = "Normal Legs" - ) coldmod = TESHARI_ALT_COLDMOD heatmod = TESHARI_ALT_HEATMOD bodytemp_normal = BODYTEMP_NORMAL + (TEHSARI_ALT_TEMP_OFFSET/2) @@ -76,15 +73,17 @@ . = ..() teshari_agility.Destroy() teshari_echolocation.Destroy() + qdel(C.GetComponent(/datum/component/weak_body)) C.mob_size = initial(C.mob_size) /datum/species/teshari/alt/randomize_features(mob/living/carbon/human/human_mob) - . = ..() + var/list/features = ..() var/main_color = pick(COLOR_GRAY, COLOR_DARK_BROWN, COLOR_ALMOST_BLACK, COLOR_DARK_RED, COLOR_DARK_CYAN) var/second_color = pick(COLOR_WHITE, COLOR_BLACK, COLOR_BLUE, COLOR_VIOLET) - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/teshari/alt/create_pref_unique_perks() var/list/perk_descriptions = list() diff --git a/tgstation.dme b/tgstation.dme index fe320badfde..15d9b0c59d3 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -154,6 +154,7 @@ #include "code\__DEFINES\movespeed_modification.dm" #include "code\__DEFINES\multiz.dm" #include "code\__DEFINES\nitrile.dm" +#include "code\__DEFINES\nozzle_define.dm" #include "code\__DEFINES\nuclear_bomb.dm" #include "code\__DEFINES\obj_flags.dm" #include "code\__DEFINES\observers.dm" @@ -470,6 +471,7 @@ #include "code\__DEFINES\~skyrat_defines\_HELPERS\atmos_mapping_helpers.dm" #include "code\__DEFINES\~skyrat_defines\_HELPERS\lighting.dm" #include "code\__DEFINES\~skyrat_defines\_HELPERS\offset_index.dm" +#include "code\__DEFINES\~skyrat_defines\traits\declarations.dm" #include "code\__HELPERS\_auxtools_api.dm" #include "code\__HELPERS\_lists.dm" #include "code\__HELPERS\_planes.dm" @@ -1116,6 +1118,7 @@ #include "code\datums\components\customizable_reagent_holder.dm" #include "code\datums\components\damage_aura.dm" #include "code\datums\components\damage_chain.dm" +#include "code\datums\components\dart_insert.dm" #include "code\datums\components\deadchat_control.dm" #include "code\datums\components\death_linked.dm" #include "code\datums\components\dejavu.dm" @@ -1833,6 +1836,7 @@ #include "code\datums\status_effects\debuffs\debuffs.dm" #include "code\datums\status_effects\debuffs\decloning.dm" #include "code\datums\status_effects\debuffs\dizziness.dm" +#include "code\datums\status_effects\debuffs\dna_transformation.dm" #include "code\datums\status_effects\debuffs\drowsiness.dm" #include "code\datums\status_effects\debuffs\drugginess.dm" #include "code\datums\status_effects\debuffs\drunk.dm" @@ -1847,6 +1851,7 @@ #include "code\datums\status_effects\debuffs\slimed.dm" #include "code\datums\status_effects\debuffs\spacer.dm" #include "code\datums\status_effects\debuffs\speech_debuffs.dm" +#include "code\datums\status_effects\debuffs\staggered.dm" #include "code\datums\status_effects\debuffs\static_vision.dm" #include "code\datums\status_effects\debuffs\strandling.dm" #include "code\datums\status_effects\debuffs\terrified.dm" @@ -6111,6 +6116,7 @@ #include "modular_skyrat\master_files\code\datums\mood_events\generic_negative_events.dm" #include "modular_skyrat\master_files\code\datums\mood_events\needs_events.dm" #include "modular_skyrat\master_files\code\datums\mutations\_mutations.dm" +#include "modular_skyrat\master_files\code\datums\mutations\chameleon.dm" #include "modular_skyrat\master_files\code\datums\mutations\hulk.dm" #include "modular_skyrat\master_files\code\datums\quirks\_quirk.dm" #include "modular_skyrat\master_files\code\datums\quirks\negative.dm" @@ -6172,6 +6178,7 @@ #include "modular_skyrat\master_files\code\modules\antagonists\_common\antag_datum.dm" #include "modular_skyrat\master_files\code\modules\antagonists\ashwalker\ashwalker.dm" #include "modular_skyrat\master_files\code\modules\antagonists\changeling\changeling.dm" +#include "modular_skyrat\master_files\code\modules\antagonists\changeling\powers\tiny_prick.dm" #include "modular_skyrat\master_files\code\modules\antagonists\cult\cult_items.dm" #include "modular_skyrat\master_files\code\modules\antagonists\ert\ert.dm" #include "modular_skyrat\master_files\code\modules\antagonists\pirate\pirate_outfits.dm" @@ -6487,6 +6494,7 @@ #include "modular_skyrat\modules\ashwalkers\code\buildings\ash_farming.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\ash_tendril.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\fuelwell.dm" +#include "modular_skyrat\modules\ashwalkers\code\buildings\gutluncher_foodtrough.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\railroad.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\tendril_cursing.dm" #include "modular_skyrat\modules\ashwalkers\code\buildings\wormfarm.dm" @@ -7743,6 +7751,7 @@ #include "modular_skyrat\modules\primitive_cooking_additions\code\stone_stove.dm" #include "modular_skyrat\modules\primitive_production\code\ceramics.dm" #include "modular_skyrat\modules\primitive_production\code\glassblowing.dm" +#include "modular_skyrat\modules\primitive_production\code\misc.dm" #include "modular_skyrat\modules\primitive_production\code\production_skill.dm" #include "modular_skyrat\modules\primitive_structures\code\fencing.dm" #include "modular_skyrat\modules\primitive_structures\code\storage_structures.dm" @@ -7861,6 +7870,8 @@ #include "modular_skyrat\modules\synths\code\bodyparts\silicon_alt_brains.dm" #include "modular_skyrat\modules\synths\code\bodyparts\stomach.dm" #include "modular_skyrat\modules\synths\code\bodyparts\tongue.dm" +#include "modular_skyrat\modules\synths\code\bodyparts\internal_computer\brain.dm" +#include "modular_skyrat\modules\synths\code\bodyparts\internal_computer\internal_computer.dm" #include "modular_skyrat\modules\synths\code\reagents\blood_pack.dm" #include "modular_skyrat\modules\synths\code\reagents\pill.dm" #include "modular_skyrat\modules\synths\code\reagents\pill_bottles.dm" diff --git a/tgui/packages/tgui-dev-server/dreamseeker.js b/tgui/packages/tgui-dev-server/dreamseeker.js index c81f51e35c5..2b25b155ae0 100644 --- a/tgui/packages/tgui-dev-server/dreamseeker.js +++ b/tgui/packages/tgui-dev-server/dreamseeker.js @@ -6,8 +6,8 @@ import { exec } from 'child_process'; import { promisify } from 'util'; -import { createLogger } from './logging'; -import { require } from './require'; +import { createLogger } from './logging.js'; +import { require } from './require.js'; const axios = require('axios'); const logger = createLogger('dreamseeker'); diff --git a/tgui/packages/tgui-dev-server/index.js b/tgui/packages/tgui-dev-server/index.js index 460b15d99ad..199e93d8363 100644 --- a/tgui/packages/tgui-dev-server/index.js +++ b/tgui/packages/tgui-dev-server/index.js @@ -4,8 +4,8 @@ * @license MIT */ -import { createCompiler } from './webpack'; -import { reloadByondCache } from './reloader'; +import { createCompiler } from './webpack.js'; +import { reloadByondCache } from './reloader.js'; const noHot = process.argv.includes('--no-hot'); const noTmp = process.argv.includes('--no-tmp'); diff --git a/tgui/packages/tgui-dev-server/link/retrace.js b/tgui/packages/tgui-dev-server/link/retrace.js index 949835c7002..842de228fdf 100644 --- a/tgui/packages/tgui-dev-server/link/retrace.js +++ b/tgui/packages/tgui-dev-server/link/retrace.js @@ -6,9 +6,9 @@ import fs from 'fs'; import { basename } from 'path'; -import { createLogger } from '../logging'; -import { require } from '../require'; -import { resolveGlob } from '../util'; +import { createLogger } from '../logging.js'; +import { require } from '../require.js'; +import { resolveGlob } from '../util.js'; const SourceMap = require('source-map'); const { parse: parseStackTrace } = require('stacktrace-parser'); diff --git a/tgui/packages/tgui-dev-server/link/server.js b/tgui/packages/tgui-dev-server/link/server.js index f0c0d153d3a..60cc78c1bd9 100644 --- a/tgui/packages/tgui-dev-server/link/server.js +++ b/tgui/packages/tgui-dev-server/link/server.js @@ -6,9 +6,9 @@ import http from 'http'; import { inspect } from 'util'; -import { createLogger, directLog } from '../logging'; -import { require } from '../require'; -import { loadSourceMaps, retrace } from './retrace'; +import { createLogger, directLog } from '../logging.js'; +import { require } from '../require.js'; +import { loadSourceMaps, retrace } from './retrace.js'; const WebSocket = require('ws'); diff --git a/tgui/packages/tgui-dev-server/reloader.js b/tgui/packages/tgui-dev-server/reloader.js index aed9a7dcd77..c13a8afdfcf 100644 --- a/tgui/packages/tgui-dev-server/reloader.js +++ b/tgui/packages/tgui-dev-server/reloader.js @@ -7,10 +7,10 @@ import fs from 'fs'; import os from 'os'; import { basename } from 'path'; -import { DreamSeeker } from './dreamseeker'; -import { createLogger } from './logging'; -import { resolveGlob, resolvePath } from './util'; -import { regQuery } from './winreg'; +import { DreamSeeker } from './dreamseeker.js'; +import { createLogger } from './logging.js'; +import { resolveGlob, resolvePath } from './util.js'; +import { regQuery } from './winreg.js'; const logger = createLogger('reloader'); diff --git a/tgui/packages/tgui-dev-server/util.js b/tgui/packages/tgui-dev-server/util.js index d60ebb212fa..9d07b96c71a 100644 --- a/tgui/packages/tgui-dev-server/util.js +++ b/tgui/packages/tgui-dev-server/util.js @@ -6,7 +6,7 @@ import fs from 'fs'; import path from 'path'; -import { require } from './require'; +import { require } from './require.js'; const globPkg = require('glob'); diff --git a/tgui/packages/tgui-dev-server/webpack.js b/tgui/packages/tgui-dev-server/webpack.js index 1c16345a892..139610b79ce 100644 --- a/tgui/packages/tgui-dev-server/webpack.js +++ b/tgui/packages/tgui-dev-server/webpack.js @@ -7,10 +7,10 @@ import fs from 'fs'; import { createRequire } from 'module'; import { dirname } from 'path'; -import { loadSourceMaps, setupLink } from './link/server'; -import { createLogger } from './logging'; -import { reloadByondCache } from './reloader'; -import { resolveGlob } from './util'; +import { loadSourceMaps, setupLink } from './link/server.js'; +import { createLogger } from './logging.js'; +import { reloadByondCache } from './reloader.js'; +import { resolveGlob } from './util.js'; const logger = createLogger('webpack'); diff --git a/tgui/packages/tgui-dev-server/winreg.js b/tgui/packages/tgui-dev-server/winreg.js index d7408b5c390..b61fddc1a25 100644 --- a/tgui/packages/tgui-dev-server/winreg.js +++ b/tgui/packages/tgui-dev-server/winreg.js @@ -8,7 +8,7 @@ import { exec } from 'child_process'; import { promisify } from 'util'; -import { createLogger } from './logging'; +import { createLogger } from './logging.js'; const logger = createLogger('winreg'); diff --git a/tgui/packages/tgui-panel/chat/renderer.js b/tgui/packages/tgui-panel/chat/renderer.jsx similarity index 99% rename from tgui/packages/tgui-panel/chat/renderer.js rename to tgui/packages/tgui-panel/chat/renderer.jsx index 7a528cd4fd7..5d6337148fb 100644 --- a/tgui/packages/tgui-panel/chat/renderer.js +++ b/tgui/packages/tgui-panel/chat/renderer.jsx @@ -11,7 +11,7 @@ import { COMBINE_MAX_MESSAGES, COMBINE_MAX_TIME_WINDOW, IMAGE_RETRY_DELAY, IMAGE import { render } from 'inferno'; import { canPageAcceptType, createMessage, isSameMessage } from './model'; import { highlightNode, linkifyNode } from './replaceInTextNode'; -import { Tooltip } from '../../tgui/components'; +import { Tooltip } from 'tgui/components'; const logger = createLogger('chatRenderer'); diff --git a/tgui/packages/tgui-panel/index.js b/tgui/packages/tgui-panel/index.jsx similarity index 100% rename from tgui/packages/tgui-panel/index.js rename to tgui/packages/tgui-panel/index.jsx diff --git a/tgui/packages/tgui/interfaces/AntagInfoAssaultops.tsx b/tgui/packages/tgui/interfaces/AntagInfoAssaultops.tsx index 46f5a07182f..332d11d63fb 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoAssaultops.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoAssaultops.tsx @@ -2,6 +2,9 @@ import { useBackend, useLocalState } from '../backend'; import { LabeledList, Stack, Button, Section, ProgressBar, Box, Tabs, Divider } from '../components'; import { BooleanLike } from 'common/react'; import { Window } from '../layouts'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END type Objectives = { count: number; @@ -117,6 +120,11 @@ export const AntagInfoAssaultops = (props, context) => { {tab === 1 && } {tab === 2 && } + {/* SKYRAT EDIT ADDITION START */} + + + + {/* SKYRAT EDIT ADDITION END */} diff --git a/tgui/packages/tgui/interfaces/AntagInfoBlob.tsx b/tgui/packages/tgui/interfaces/AntagInfoBlob.tsx index e8471a6a5ac..7000b324aa9 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoBlob.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoBlob.tsx @@ -1,6 +1,9 @@ import { useBackend } from '../backend'; import { Box, Collapsible, Divider, LabeledList, Section, Stack } from '../components'; import { Objective } from './common/Objectives'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END import { Window } from '../layouts'; @@ -25,6 +28,7 @@ export const AntagInfoBlob = (props, context) => { + diff --git a/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx b/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx index f3eda78c661..339c115e30c 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx @@ -4,6 +4,9 @@ import { useBackend, useSharedState } from '../backend'; import { Button, Dimmer, Dropdown, Section, Stack, NoticeBox } from '../components'; import { Window } from '../layouts'; import { ObjectivePrintout, Objective, ReplaceObjectivesButton } from './common/Objectives'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END const hivestyle = { fontWeight: 'bold', @@ -54,9 +57,10 @@ type Info = { can_change_objective: BooleanLike; }; +// SKYRAT EDIT change height from 750 to 900 export const AntagInfoChangeling = (props, context) => { return ( - + { + {/* SKYRAT EDIT ADDITION START */} + + + + {/* SKYRAT EDIT ADDITION END */} diff --git a/tgui/packages/tgui/interfaces/AntagInfoClock.tsx b/tgui/packages/tgui/interfaces/AntagInfoClock.tsx index 8912a666bc5..96b94c70339 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoClock.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoClock.tsx @@ -1,16 +1,20 @@ import { useBackend } from '../backend'; import { Icon, Section, Stack } from '../components'; import { Window } from '../layouts'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END type Info = { antag_name: string; }; +// SKYRAT EDIT change height from 250 to 350 export const AntagInfoClock = (props, context) => { const { data } = useBackend(context); const { antag_name } = data; return ( - +
@@ -19,6 +23,11 @@ export const AntagInfoClock = (props, context) => { {' You are the ' + antag_name + '! '} + {/* SKYRAT EDIT ADDITION START */} + + + + {/* SKYRAT EDIT ADDITION END */} diff --git a/tgui/packages/tgui/interfaces/AntagInfoGeneric.tsx b/tgui/packages/tgui/interfaces/AntagInfoGeneric.tsx index 33b7623c44f..7aa7b80eea0 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoGeneric.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoGeneric.tsx @@ -2,23 +2,32 @@ import { useBackend } from '../backend'; import { Section, Stack } from '../components'; import { Window } from '../layouts'; import { ObjectivePrintout, Objective } from './common/Objectives'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END type Info = { antag_name: string; objectives: Objective[]; }; +// SKYRAT EDIT increase height from 250 to 500 export const AntagInfoGeneric = (props, context) => { const { data } = useBackend(context); const { antag_name, objectives } = data; return ( - +
You are the {antag_name}! + {/* SKYRAT EDIT ADDITION START */} + + + + {/* SKYRAT EDIT ADDITION END */} diff --git a/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx b/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx index ff14419473c..367cc311403 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx @@ -3,6 +3,9 @@ import { Section, Stack, Box, Tabs, Button, BlockQuote } from '../components'; import { Window } from '../layouts'; import { BooleanLike } from 'common/react'; import { ObjectivePrintout, Objective, ReplaceObjectivesButton } from './common/Objectives'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END const hereticRed = { color: '#e03c3c', @@ -63,6 +66,12 @@ const IntroductionSection = (props, context) => { + {/* SKYRAT EDIT ADDITION START */} + + + + {/* SKYRAT EDIT ADDITION END */} + diff --git a/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx b/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx index 0344f11d2ee..76e7944cfd7 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx @@ -5,6 +5,9 @@ import { BlockQuote, Button, Section, Stack, Tabs } from '../components'; import { BooleanLike } from 'common/react'; import { Window } from '../layouts'; import { ObjectivePrintout, Objective, ReplaceObjectivesButton } from './common/Objectives'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END const allystyle = { fontWeight: 'bold', @@ -55,6 +58,7 @@ const IntroductionSection = (props, context) => { /> } /> +
diff --git a/tgui/packages/tgui/interfaces/AntagInfoMorph.tsx b/tgui/packages/tgui/interfaces/AntagInfoMorph.tsx index fb98e1aa35b..58c379ab522 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoMorph.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoMorph.tsx @@ -1,5 +1,8 @@ import { BlockQuote, Stack } from '../components'; import { Window } from '../layouts'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END const goodstyle = { color: 'lightgreen', @@ -48,6 +51,11 @@ export const AntagInfoMorph = (props, context) => { {' '} + {/* SKYRAT EDIT ADDITION START */} + + + + {/* SKYRAT EDIT ADDITION END */}
diff --git a/tgui/packages/tgui/interfaces/AntagInfoNightmare.tsx b/tgui/packages/tgui/interfaces/AntagInfoNightmare.tsx index 327e114e2fd..6d4b105c498 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoNightmare.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoNightmare.tsx @@ -1,5 +1,8 @@ import { BlockQuote, LabeledList, Section, Stack } from '../components'; import { Window } from '../layouts'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END const tipstyle = { color: 'white', @@ -68,6 +71,11 @@ export const AntagInfoNightmare = (props, context) => {
+ {/* SKYRAT EDIT ADDITION START */} + + + + {/* SKYRAT EDIT ADDITION END */}
diff --git a/tgui/packages/tgui/interfaces/AntagInfoNinja.tsx b/tgui/packages/tgui/interfaces/AntagInfoNinja.tsx index a537888af75..0615e46e05d 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoNinja.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoNinja.tsx @@ -3,6 +3,9 @@ import { useBackend } from '../backend'; import { Icon, Section, Stack } from '../components'; import { Window } from '../layouts'; import { ObjectivePrintout, Objective, ReplaceObjectivesButton } from './common/Objectives'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END const ninja_emphasis = { color: 'red', @@ -48,6 +51,11 @@ export const AntagInfoNinja = (props, context) => { what you can do! + {/* SKYRAT EDIT ADDITION START */} + + + + {/* SKYRAT EDIT ADDITION END */} { + const { data } = useBackend(context); + const { antag_name } = data; + switch (antag_name) { + case 'Abductor Agent' || 'Abductor Scientist' || 'Abductor Solo': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + case 'Drifting Contractor': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + case 'Cortical Borer': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + case 'Venus Human Trap': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + case 'Obsessed': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + case 'Revenant': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + case 'Space Dragon': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + case 'Space Pirate': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + case 'Blob': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + case 'Changeling': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + case 'ClockCult': + return ( + + Special Rules: + {Dont be an asshole.} + + ); + case 'AssaultOps': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + case 'Heretic': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + case 'Malf AI': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + case 'Morph': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + case 'Nightmare': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + case 'Ninja': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + case 'Wizard': + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + default: + return ( + + Special Rules: + + { + + Special Rules and Metaprotections! + + } + + + ); + break; + } +}; diff --git a/tgui/packages/tgui/interfaces/AntagInfoTraitor.tsx b/tgui/packages/tgui/interfaces/AntagInfoTraitor.tsx index cc62986c085..083e3b2372c 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoTraitor.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoTraitor.tsx @@ -4,6 +4,9 @@ import { BlockQuote, Button, Dimmer, Section, Stack } from '../components'; import { BooleanLike } from 'common/react'; import { Window } from '../layouts'; import { ObjectivePrintout, Objective } from './common/Objectives'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END const allystyle = { fontWeight: 'bold', @@ -48,6 +51,14 @@ const IntroductionSection = (props, context) => { + {/* SKYRAT EDIT ADDITION START */} + + {/* SKYRAT EDIT ADDITION START */} + + + + + {/* SKYRAT EDIT ADDITION END */} ); @@ -218,11 +229,12 @@ const CodewordsSection = (props, context) => { ); }; +// SKYRAT EDIT: change height from 580 to 650 export const AntagInfoTraitor = (props, context) => { const { data } = useBackend(context); const { theme } = data; return ( - + diff --git a/tgui/packages/tgui/interfaces/AntagInfoWizard.tsx b/tgui/packages/tgui/interfaces/AntagInfoWizard.tsx index e5de257851a..94d528513d0 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoWizard.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoWizard.tsx @@ -3,6 +3,9 @@ import { useBackend } from '../backend'; import { Box, Section, Stack } from '../components'; import { Window } from '../layouts'; import { ObjectivePrintout, Objective, ReplaceObjectivesButton } from './common/Objectives'; +// SKYRAT EDIT BEGIN +import { Rules } from './AntagInfoRules'; +// SKYRAT EDIT END const teleportstyle = { color: 'yellow', @@ -48,12 +51,13 @@ type Info = { can_change_objective: BooleanLike; }; +// SKYRAT CHANGE height from 630 to 700 export const AntagInfoWizard = (props, context) => { const { data, act } = useBackend(context); const { ritual, objectives, can_change_objective } = data; return ( - + @@ -78,6 +82,11 @@ export const AntagInfoWizard = (props, context) => { + {/* SKYRAT EDIT ADDITION START */} + + + + {/* SKYRAT EDIT ADDITION END */} diff --git a/tgui/packages/tgui/interfaces/Autolathe.tsx b/tgui/packages/tgui/interfaces/Autolathe.tsx index 1436d045256..e83554e7164 100644 --- a/tgui/packages/tgui/interfaces/Autolathe.tsx +++ b/tgui/packages/tgui/interfaces/Autolathe.tsx @@ -118,18 +118,20 @@ type PrintButtonProps = { quantity: number; availableMaterials: MaterialMap; SHEET_MATERIAL_AMOUNT: number; + maxmult: number; }; const PrintButton = (props: PrintButtonProps, context) => { const { act } = useBackend(context); - const { design, quantity, availableMaterials, SHEET_MATERIAL_AMOUNT } = props; - - const canPrint = !Object.entries(design.cost).some( - ([material, amount]) => - !availableMaterials[material] || - amount * quantity > (availableMaterials[material] ?? 0) - ); + const { + design, + quantity, + availableMaterials, + SHEET_MATERIAL_AMOUNT, + maxmult, + } = props; + const canPrint = maxmult >= quantity; return ( { !canPrint && 'FabricatorRecipe__Button--disabled', ])} color={'transparent'} - onClick={() => act('make', { id: design.id, multiplier: quantity })}> + onClick={() => + canPrint && act('make', { id: design.id, multiplier: quantity }) + }> ×{quantity} @@ -163,11 +167,8 @@ const AutolatheRecipe = (props: AutolatheRecipeProps, context) => { const { act } = useBackend(context); const { design, availableMaterials, SHEET_MATERIAL_AMOUNT } = props; - const canPrint = !Object.entries(design.cost).some( - ([material, amount]) => - !availableMaterials[material] || - amount > (availableMaterials[material] ?? 0) - ); + const maxmult = design.maxmult; + const canPrint = maxmult > 0; return (
@@ -195,7 +196,9 @@ const AutolatheRecipe = (props: AutolatheRecipeProps, context) => { 'FabricatorRecipe__Title', !canPrint && 'FabricatorRecipe__Title--disabled', ])} - onClick={() => act('make', { id: design.id, multiplier: 1 })}> + onClick={() => + canPrint && act('make', { id: design.id, multiplier: 1 }) + }>
{ quantity={5} SHEET_MATERIAL_AMOUNT={SHEET_MATERIAL_AMOUNT} availableMaterials={availableMaterials} + maxmult={maxmult} /> { quantity={10} SHEET_MATERIAL_AMOUNT={SHEET_MATERIAL_AMOUNT} availableMaterials={availableMaterials} + maxmult={maxmult} />
{ !canPrint && 'FabricatorRecipe__Button--disabled', ])}> act('make', { id: design.id, diff --git a/tgui/packages/tgui/interfaces/BorerChem.jsx b/tgui/packages/tgui/interfaces/BorerChem.jsx index 35eb63857fc..8f5210ed0fa 100644 --- a/tgui/packages/tgui/interfaces/BorerChem.jsx +++ b/tgui/packages/tgui/interfaces/BorerChem.jsx @@ -44,7 +44,7 @@ export const BorerChem = (props, context) => { disabled={data.onCooldown || data.notEnoughChemicals} onClick={() => act('inject', { - reagent: chemical.id, + reagent: chemical.title, }) } /> diff --git a/tgui/packages/tgui/interfaces/MafiaPanel.tsx b/tgui/packages/tgui/interfaces/MafiaPanel.tsx index ee63d105dd1..23b4b45a27a 100644 --- a/tgui/packages/tgui/interfaces/MafiaPanel.tsx +++ b/tgui/packages/tgui/interfaces/MafiaPanel.tsx @@ -16,6 +16,7 @@ type RoleInfo = { type PlayerInfo = { name: string; + role_revealed: string; is_you: BooleanLike; ref: string; alive: string; @@ -49,11 +50,13 @@ type MafiaData = { is_observer: boolean; all_roles: string[]; admin_controls: boolean; + person_voted_up_ref: string; + player_voted_up: BooleanLike; }; export const MafiaPanelData = (props, context) => { const { act, data } = useBackend(context); - const { phase, roleinfo, admin_controls, messages } = data; + const { phase, roleinfo, admin_controls, messages, player_voted_up } = data; const [mafia_tab, setMafiaMode] = useLocalState( context, 'mafia_tab', @@ -90,7 +93,7 @@ export const MafiaPanelData = (props, context) => { - {phase === 'Judgment' && ( + {phase === 'Judgment' && !player_voted_up && ( @@ -401,17 +404,20 @@ const MafiaJudgement = (props, context) => { const { act, data } = useBackend(context); return (
- + +