diff --git a/.vscode/settings.json b/.vscode/settings.json index bfce9bda7c..8edb013566 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,7 +13,7 @@ "source.fixAll.eslint": true }, "workbench.editorAssociations": { - "*.dmi": "imagePreview.previewEditor" + "*.dmi": "dmiEditor.dmiEditor" }, "files.eol": "\n", "gitlens.advanced.blame.customArguments": ["-w"], diff --git a/_maps/RandomZLevels/away_mission/SnowCabin.dmm b/_maps/RandomZLevels/away_mission/SnowCabin.dmm index e7f5341bea..7de2ed53f1 100644 --- a/_maps/RandomZLevels/away_mission/SnowCabin.dmm +++ b/_maps/RandomZLevels/away_mission/SnowCabin.dmm @@ -99,7 +99,9 @@ /obj/machinery/door/airlock/command{ name = "Manager's Office" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "as" = ( @@ -134,7 +136,9 @@ /area/awaymission/cabin) "aw" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plating, /area/awaymission/cabin) "ax" = ( @@ -185,17 +189,18 @@ /turf/open/floor/plasteel/freezer, /area/awaymission/cabin) "aD" = ( -/obj/machinery/power/smes/magical{ - desc = "A high-capacity superconducting magnetic energy storage (SMES) unit. It seems to be powered just fine without our intervention."; - name = "nanotrasen power storage unit" - }, /obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/smes/magical, /turf/open/floor/plating, /area/awaymission/cabin) "aE" = ( /obj/effect/decal/cleanable/cobweb/cobweb2, /obj/effect/baseturf_helper/asteroid/snow, /obj/effect/decal/cleanable/dirt, +/obj/machinery/power/port_gen/pacman, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -207,7 +212,12 @@ pixel_y = 23 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/open/floor/plating, /area/awaymission/cabin) "aG" = ( @@ -255,7 +265,9 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -281,15 +293,6 @@ /turf/open/floor/carpet, /area/awaymission/cabin) "aQ" = ( -/obj/structure{ - anchored = 1; - density = 1; - desc = "Generates power from lava!"; - dir = 1; - icon = 'icons/obj/atmospherics/pipes/simple.dmi'; - icon_state = "compressor"; - name = "geothermal generator" - }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating{ icon_state = "panelscorched" @@ -366,7 +369,9 @@ /turf/open/floor/wood, /area/awaymission/cabin) "bb" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/carpet, /area/awaymission/cabin) "bc" = ( @@ -431,7 +436,9 @@ id_tag = "snowdorm5"; name = "Cabin 5" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "bn" = ( @@ -463,7 +470,9 @@ /obj/machinery/newscaster{ pixel_y = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "bt" = ( @@ -492,7 +501,9 @@ "by" = ( /obj/structure/table, /obj/machinery/reagentgrinder, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plasteel/cafeteria, /area/awaymission/cabin) "bz" = ( @@ -611,7 +622,9 @@ /obj/machinery/door/airlock/maintenance{ name = "Garage" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "bW" = ( @@ -739,7 +752,9 @@ /obj/structure/sign/poster/official/soft_cap_pop_art{ pixel_y = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "cu" = ( @@ -838,14 +853,18 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "cM" = ( /obj/machinery/door/airlock/wood{ name = "Gateway" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "cN" = ( @@ -859,12 +878,16 @@ /turf/open/floor/carpet, /area/awaymission/cabin) "cP" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plasteel/white, /area/awaymission/cabin) "cQ" = ( /obj/effect/landmark/awaystart, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/carpet, /area/awaymission/cabin) "cR" = ( @@ -898,7 +921,9 @@ /area/awaymission/cabin) "cW" = ( /obj/item/shovel, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plating{ icon_state = "platingdmg3" }, @@ -957,7 +982,9 @@ /obj/structure/chair/wood{ dir = 4 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/carpet, /area/awaymission/cabin) "df" = ( @@ -1040,20 +1067,19 @@ /area/awaymission/cabin) "du" = ( /obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-4" + }, /turf/open/floor/plating{ icon_state = "panelscorched" }, /area/awaymission/cabin) "dv" = ( -/obj/structure{ - anchored = 1; - density = 1; - desc = "Generates power from lava!"; - icon = 'icons/obj/atmospherics/pipes/simple.dmi'; - icon_state = "turbine"; - name = "geothermal generator" - }, /obj/effect/decal/cleanable/dirt, +/obj/machinery/power/rtg, +/obj/structure/cable{ + icon_state = "0-8" + }, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -1269,7 +1295,9 @@ /turf/open/floor/wood/cold, /area/awaymission/cabin/snowforest) "eg" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "eh" = ( @@ -1279,7 +1307,9 @@ "ei" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "ej" = ( @@ -1350,7 +1380,9 @@ /area/awaymission/cabin/snowforest) "et" = ( /obj/effect/decal/cleanable/dirt/dust, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "eu" = ( @@ -2724,11 +2756,15 @@ /obj/structure/sign/poster/official/fruit_bowl{ pixel_y = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hi" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plasteel/freezer, /area/awaymission/cabin) "hj" = ( @@ -2736,7 +2772,9 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt/dust, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "hk" = ( @@ -2781,7 +2819,9 @@ /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/oil, /obj/effect/decal/cleanable/generic, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "hs" = ( @@ -2789,14 +2829,18 @@ /obj/structure/sign/poster/contraband/missing_gloves{ pixel_x = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "ht" = ( /obj/structure/window{ dir = 4 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hu" = ( @@ -2816,6 +2860,9 @@ pixel_y = 4 }, /obj/effect/decal/cleanable/dirt, +/obj/item/stack/sheet/mineral/plasma{ + amount = 26 + }, /turf/open/floor/plating, /area/awaymission/cabin) "hw" = ( @@ -2841,28 +2888,36 @@ /turf/open/floor/plating, /area/awaymission/cabin) "hz" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/cafeteria, /area/awaymission/cabin) "hA" = ( /obj/machinery/door/airlock/freezer{ name = "Freezer" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/freezer, /area/awaymission/cabin) "hB" = ( /obj/machinery/door/airlock{ name = "Backstage" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hC" = ( /obj/structure/chair/wood{ dir = 8 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "2-8" + }, /turf/open/floor/carpet, /area/awaymission/cabin) "hD" = ( @@ -2874,7 +2929,9 @@ /obj/machinery/door/airlock{ name = "Kitchen" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hF" = ( @@ -2889,7 +2946,9 @@ /obj/structure/chair/wood{ dir = 1 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hH" = ( @@ -3124,7 +3183,9 @@ /obj/structure/extinguisher_cabinet{ pixel_y = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "io" = ( @@ -3321,7 +3382,9 @@ id_tag = "snowdorm1"; name = "Cabin 1" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "iW" = ( @@ -3329,7 +3392,9 @@ id_tag = "snowdorm2"; name = "Cabin 2" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "iX" = ( @@ -3337,7 +3402,9 @@ id_tag = "snowdorm3"; name = "Cabin 3" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "iY" = ( @@ -3345,7 +3412,9 @@ id_tag = "snowdorm4"; name = "Cabin 4" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "iZ" = ( @@ -3518,7 +3587,9 @@ }, /obj/item/reagent_containers/glass/bottle/cryoxadone, /obj/item/reagent_containers/glass/bottle/cryoxadone, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/white, /area/awaymission/cabin) "jr" = ( @@ -3649,7 +3720,9 @@ name = "Generator Room" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "jD" = ( @@ -5450,7 +5523,9 @@ /turf/open/floor/wood, /area/awaymission/cabin) "nR" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-4" + }, /turf/open/floor/plating, /area/awaymission/cabin) "nS" = ( @@ -5477,13 +5552,152 @@ /obj/machinery/door/airlock/maintenance{ name = "Maintenance" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) +"nY" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/awaymission/cabin) +"rn" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/awaymission/cabin) +"rV" = ( +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"sn" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/awaymission/cabin) +"uk" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/freezer, +/area/awaymission/cabin) +"uD" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"ww" = ( +/obj/effect/landmark/awaystart, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"wx" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/freezer, +/area/awaymission/cabin) +"zF" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"BB" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/awaymission/cabin) +"Co" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/cafeteria, +/area/awaymission/cabin) +"DU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plating, +/area/awaymission/cabin) +"Fj" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"FH" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"Hb" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"He" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"IG" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/awaymission/cabin) +"JZ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"KS" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"MB" = ( +/obj/structure/chair/wood{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) "MS" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/oil, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plating, /area/awaymission/cabin) "TZ" = ( @@ -5495,6 +5709,37 @@ /obj/item/clothing/shoes/winterboots/ice_boots, /turf/open/floor/plating/ice/smooth, /area/awaymission/cabin/caves) +"UL" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/freezer, +/area/awaymission/cabin) +"WD" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"WX" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plating, +/area/awaymission/cabin) +"WY" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) (1,1,1) = {" ab @@ -25696,21 +25941,21 @@ iZ aN jl bb -bb -bb +JZ +JZ eg bm -eg +Fj nS an -eg +rV eg eg eg eg eg hB -eg +Fj aq an cT @@ -25957,7 +26202,7 @@ az az aq an -eg +He bh an cA @@ -25967,7 +26212,7 @@ an an hx an -eg +He aq an cU @@ -26214,7 +26459,7 @@ az az aq an -eg +He aq an aq @@ -26224,7 +26469,7 @@ aq aq aq an -eg +He aq an cV @@ -26481,11 +26726,11 @@ aq aq bh an -eg +He bh an aL -nR +BB aL ed an @@ -26728,17 +26973,17 @@ an an aR an -eg +He aq an aq aq -eg +FH aq aq aq an -eg +He aq an cU @@ -26985,21 +27230,21 @@ aH an an an -eg +He aq an cz aq -eg +He aq aq bh an -eg +He aq an ed -nR +BB aL kE an @@ -27242,7 +27487,7 @@ an an aS hg -eg +He bh an nT @@ -27252,11 +27497,11 @@ bo bo cB an -eg +WD eg bV -aw -aw +sn +DU gM an an @@ -27499,17 +27744,17 @@ aH an an an -eg +He aq an aO aO hC -hC -hC -bb -bb -eg +MB +MB +JZ +JZ +WY aq an eb @@ -27756,7 +28001,7 @@ an an aT an -eg +He aq an az @@ -27766,7 +28011,7 @@ az aq aq cO -eg +He bh an an @@ -28270,7 +28515,7 @@ az az aq an -eg +He aq an aP @@ -28280,7 +28525,7 @@ nB hd az aO -eg +He aq aq an @@ -28527,7 +28772,7 @@ az az aq an -eg +He bh an bq @@ -28537,7 +28782,7 @@ hc hd az az -eg +He aq aq aN @@ -28780,11 +29025,11 @@ ja bp jm bb -bb -bb +JZ +JZ eg iY -eg +WY aq an bt @@ -28794,7 +29039,7 @@ jx hd az cO -eg +He aq aq iR @@ -29041,7 +29286,7 @@ aI aA jj an -eg +He aq an cN @@ -29308,7 +29553,7 @@ az aq aq aO -eg +He aq aq an @@ -29555,17 +29800,17 @@ ju au ji an -eg +He aq an de -de -de -de -de -bb -bb -eg +uD +uD +uD +uD +JZ +JZ +WY bh an an @@ -29808,11 +30053,11 @@ jb aN jn bb -bb -bb +JZ +JZ eg iX -eg +WY bh an hb @@ -29822,7 +30067,7 @@ eu cK cD an -eg +He aq aq an @@ -30069,7 +30314,7 @@ az az aq an -eg +He aq an hn @@ -30079,7 +30324,7 @@ aq aq aq an -eg +He aq aq aN @@ -30326,7 +30571,7 @@ az az aq an -eg +He aq an bv @@ -30336,7 +30581,7 @@ aq ap aq an -eg +He aq aq iU @@ -30593,7 +30838,7 @@ bu an eo an -eg +He aq aq bp @@ -30840,7 +31085,7 @@ an an aU an -eg +He aq an bw @@ -30848,9 +31093,9 @@ bO bO bO bO -hz +Co hE -eg +WY aq aq an @@ -31097,7 +31342,7 @@ aH an an an -eg +He aq an bx @@ -31105,9 +31350,9 @@ bO cJ cF cJ -hz +nY an -eg +He bh an an @@ -31354,7 +31599,7 @@ an an hf hy -eg +He aq an by @@ -31362,9 +31607,9 @@ hz hz hz hz -hz +rn an -eg +He aq aq an @@ -31611,7 +31856,7 @@ aH an an an -eg +He bh an bz @@ -31619,9 +31864,9 @@ bO bW ck cj -hz +nY an -eg +He aq aq aN @@ -31868,7 +32113,7 @@ an an aW an -eg +He aq an an @@ -31878,7 +32123,7 @@ an an hA an -eg +He aq aq iS @@ -32133,9 +32378,9 @@ bB bX cl cl -hi +uk an -eg +He aq aq bp @@ -32382,15 +32627,15 @@ az az aq an -eg +He aq an hi -hi -hi -hi -hi -hi +UL +UL +UL +UL +wx an hh aq @@ -32639,7 +32884,7 @@ az az aq an -eg +He aq an bC @@ -32649,7 +32894,7 @@ is dt cG an -eg +He bh an an @@ -32892,11 +33137,11 @@ jc bp jo bb -bb -bb +JZ +JZ eg iW -eg +WY aq an an @@ -32906,7 +33151,7 @@ an an an an -eg +He aq aq an @@ -33153,7 +33398,7 @@ aI aA jg an -eg +He aq an aJ @@ -33163,7 +33408,7 @@ cv hq cv an -eg +He aq aq aN @@ -33420,7 +33665,7 @@ bE bE lz an -eg +He aq aq iT @@ -33667,7 +33912,7 @@ jw au jh an -eg +He aq an bD @@ -33677,7 +33922,7 @@ cI hD bE nM -eg +He aq aq bp @@ -33920,21 +34165,21 @@ jd aN jp bb -bb -bb +JZ +JZ eg iV -eg +WY aq an cP -cP -cP -cP +IG +IG +IG jq -cP -cP -eg +IG +IG +WY aq aq an @@ -34181,7 +34426,7 @@ az az aq an -eg +He aq an bF @@ -34191,7 +34436,7 @@ ho bE lz an -eg +He aq an an @@ -34438,7 +34683,7 @@ az az aq an -eg +He nS an bF @@ -34448,7 +34693,7 @@ hp js hp an -eg +He aq an dB @@ -34705,7 +34950,7 @@ an an an an -eg +He bh an dB @@ -34952,7 +35197,7 @@ an an aU an -eg +WD eg nV ei @@ -34962,7 +35207,7 @@ hr hs et nV -eg +zF aq an dB @@ -35466,7 +35711,7 @@ an an aX bf -bb +KS an bj bH @@ -35476,7 +35721,7 @@ aq aq aq io -bb +KS az an dB @@ -35719,11 +35964,11 @@ ax an aF cL -aw +sn jC -bb -bb -bb +JZ +JZ +Hb an bk bJ @@ -35987,10 +36232,10 @@ an an aq cp +rV eg eg -eg -cQ +ww hI an dB @@ -36230,8 +36475,8 @@ ac ac dB ax -ed -aw +WX +DU ed hv an diff --git a/_maps/RandomZLevels/away_mission/jungleresort.dmm b/_maps/RandomZLevels/away_mission/jungleresort.dmm index 4207080ac4..cb5334e855 100644 --- a/_maps/RandomZLevels/away_mission/jungleresort.dmm +++ b/_maps/RandomZLevels/away_mission/jungleresort.dmm @@ -1992,6 +1992,7 @@ dir = 8 }, /obj/effect/decal/cleanable/oil/streak, +/obj/machinery/power/port_gen/pacman, /turf/open/floor/plating, /area/awaymission/jungleresort) "BP" = ( @@ -2040,7 +2041,7 @@ /obj/structure/cable{ icon_state = "0-8" }, -/obj/machinery/power/port_gen/pacman/super, +/obj/machinery/power/rtg, /turf/open/floor/plating, /area/awaymission/jungleresort) "CA" = ( @@ -2811,12 +2812,7 @@ /obj/structure/cable{ icon_state = "0-8" }, -/obj/machinery/power/smes{ - charge = 1.5e+006; - input_level = 30000; - inputting = 0; - output_level = 7000 - }, +/obj/machinery/power/smes/magical, /turf/open/floor/plating, /area/awaymission/jungleresort) "LR" = ( @@ -3183,6 +3179,9 @@ /obj/item/stack/sheet/mineral/uranium, /obj/item/clothing/glasses/meson/engine, /obj/item/storage/belt/utility, +/obj/item/stack/sheet/mineral/plasma{ + amount = 26 + }, /turf/open/floor/plating, /area/awaymission/jungleresort) "Rm" = ( @@ -3720,7 +3719,7 @@ /obj/structure/cable{ icon_state = "2-4" }, -/obj/machinery/power/port_gen/pacman/super, +/obj/machinery/power/rtg, /turf/open/floor/plating, /area/awaymission/jungleresort) "Yb" = ( diff --git a/_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm b/_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm index de2105e9d4..6eee9e9d9f 100644 --- a/_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm +++ b/_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm @@ -815,16 +815,16 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 351.9 + initial_temperature = 351.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "bX" = ( /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 351.9 + initial_temperature = 351.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "bY" = ( @@ -2263,8 +2263,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "eK" = ( @@ -2634,8 +2634,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/central) "fo" = ( @@ -2870,8 +2870,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/central) "fK" = ( @@ -3049,8 +3049,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "gg" = ( @@ -3197,8 +3197,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/crew_quarters) "gC" = ( @@ -3411,8 +3411,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/research) "he" = ( @@ -3422,8 +3422,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/crew_quarters) "hf" = ( @@ -3454,8 +3454,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/crew_quarters) "hi" = ( @@ -4789,8 +4789,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/gateway) "jM" = ( @@ -4823,8 +4823,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/research) "jR" = ( @@ -6221,6 +6221,7 @@ c_tag = "Engineering Secure Storage"; network = list("uo45") }, +/obj/machinery/power/port_gen/pacman, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -6606,8 +6607,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/gateway) "mJ" = ( @@ -7751,12 +7752,7 @@ /area/awaymission/undergroundoutpost45/engineering) "ou" = ( /obj/structure/cable, -/obj/machinery/power/smes{ - charge = 1.5e+006; - input_level = 30000; - inputting = 0; - output_level = 7000 - }, +/obj/machinery/power/smes/magical, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -8072,12 +8068,10 @@ /obj/machinery/power/terminal{ dir = 1 }, -/obj/machinery/power/port_gen/pacman{ - name = "P.A.C.M.A.N.-type portable generator" - }, /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/power/rtg, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -8086,9 +8080,6 @@ /obj/machinery/power/terminal{ dir = 1 }, -/obj/machinery/power/port_gen/pacman/super{ - name = "S.U.P.E.R.P.A.C.M.A.N.-type portable generator" - }, /obj/item/wrench, /obj/structure/cable{ icon_state = "0-8" @@ -8096,6 +8087,7 @@ /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/power/rtg, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -8104,12 +8096,10 @@ /obj/machinery/power/terminal{ dir = 1 }, -/obj/machinery/power/port_gen/pacman{ - name = "P.A.C.M.A.N.-type portable generator" - }, /obj/structure/cable{ icon_state = "0-8" }, +/obj/machinery/power/rtg, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -8356,8 +8346,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "pv" = ( @@ -8367,8 +8357,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "pw" = ( @@ -8379,8 +8369,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/engineering) "px" = ( @@ -8670,8 +8660,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "qb" = ( @@ -8902,8 +8892,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "qA" = ( @@ -8913,8 +8903,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "qB" = ( @@ -8924,8 +8914,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "qC" = ( @@ -11106,8 +11096,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/crew_quarters) "uc" = ( @@ -11752,8 +11742,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "vm" = ( @@ -11978,8 +11968,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/research) "vI" = ( @@ -12264,8 +12254,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/mining) "wk" = ( @@ -13483,8 +13473,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/mining) "yh" = ( @@ -13492,8 +13482,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yi" = ( @@ -13501,8 +13491,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yj" = ( @@ -13512,8 +13502,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yk" = ( @@ -13522,8 +13512,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yl" = ( @@ -13533,8 +13523,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "ym" = ( @@ -13543,8 +13533,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yn" = ( @@ -13552,8 +13542,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yo" = ( @@ -13562,8 +13552,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yp" = ( @@ -13572,8 +13562,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yq" = ( @@ -13581,8 +13571,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yr" = ( @@ -13590,8 +13580,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yt" = ( @@ -13600,8 +13590,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yu" = ( @@ -13610,8 +13600,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yw" = ( @@ -13620,8 +13610,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yz" = ( @@ -13629,8 +13619,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yA" = ( @@ -13639,8 +13629,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yB" = ( @@ -13648,8 +13638,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yC" = ( @@ -13658,8 +13648,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yD" = ( @@ -13669,8 +13659,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yH" = ( @@ -13680,8 +13670,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "KE" = ( diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 8fbb97bbdd..f1c58be502 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -2088,6 +2088,9 @@ }, /obj/machinery/suit_storage_unit/hos, /obj/effect/turf_decal/delivery, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "aeE" = ( @@ -5400,6 +5403,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, /turf/open/floor/plasteel, /area/security/brig) "akp" = ( @@ -5684,6 +5690,9 @@ }, /obj/structure/table, /obj/item/storage/box/donkpockets, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, /turf/open/floor/plasteel, /area/security/office) "akS" = ( @@ -13391,6 +13400,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, /turf/open/floor/plasteel/cafeteria, /area/command/heads_quarters/cmo) "aFb" = ( @@ -19982,6 +19994,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, /turf/open/floor/plasteel, /area/command/bridge) "aWV" = ( @@ -20707,12 +20722,20 @@ /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai_upload) "aYy" = ( -/obj/machinery/status_display/ai, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/closed/wall/r_wall, -/area/ai_monitored/turret_protected/ai_upload) +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/commons/dorms) "aYz" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -22940,6 +22963,9 @@ "beG" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/tile/red, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "beH" = ( @@ -23223,12 +23249,11 @@ /turf/open/floor/plating, /area/maintenance/port) "bft" = ( -/obj/machinery/status_display/ai, -/obj/structure/cable{ - icon_state = "4-8" +/obj/machinery/status_display/ai{ + pixel_x = -32 }, -/turf/closed/wall/r_wall, -/area/ai_monitored/turret_protected/ai_upload) +/turf/open/floor/plasteel, +/area/commons/locker) "bfu" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 @@ -27013,6 +27038,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, /turf/open/floor/plasteel/white, /area/science/research) "boB" = ( @@ -28442,6 +28470,9 @@ icon_state = "2-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, /turf/open/floor/plasteel, /area/command/heads_quarters/hop) "bsa" = ( @@ -31824,6 +31855,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, /turf/open/floor/plasteel/white, /area/command/heads_quarters/rd) "bzO" = ( @@ -32989,6 +33023,9 @@ pixel_x = 1; pixel_y = 9 }, +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, /turf/open/floor/plasteel, /area/cargo/miningdock) "bCp" = ( @@ -42889,7 +42926,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "cbr" = ( @@ -46784,6 +46821,9 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, /turf/open/floor/plasteel, /area/engineering/main) "clN" = ( @@ -47569,7 +47609,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/air_sensor{ +/obj/machinery/air_sensor/atmos/incinerator_tank{ pixel_x = -32; pixel_y = -32 }, @@ -52812,6 +52852,14 @@ icon_state = "platingdmg3" }, /area/commons/arcade) +"dGh" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/delivery, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/medical/medbay/central) "dIu" = ( /obj/structure/chair/sofa{ dir = 8 @@ -53793,6 +53841,12 @@ }, /turf/open/floor/plasteel, /area/cargo/miningdock) +"eVW" = ( +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) "eWL" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -54369,6 +54423,12 @@ /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/service/hydroponics) +"fzx" = ( +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/service/bar) "fAj" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -54656,6 +54716,7 @@ /obj/structure/sign/poster/contraband/robust_softdrinks{ pixel_y = 32 }, +/obj/machinery/vending/snack/orange, /turf/open/floor/wood, /area/service/bar) "fZm" = ( @@ -54952,6 +55013,12 @@ }, /turf/open/floor/plasteel/dark, /area/commons/fitness) +"grS" = ( +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai_upload) "gsM" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/maintenance, @@ -56182,6 +56249,19 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"iyK" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/plating, +/area/cargo/storage) "izg" = ( /obj/item/cigbutt/cigarbutt, /turf/open/floor/plating, @@ -57267,6 +57347,12 @@ }, /turf/open/floor/plasteel, /area/security/prison/upper) +"jYI" = ( +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) "jZT" = ( /obj/structure/cable{ icon_state = "4-8" @@ -57444,10 +57530,10 @@ /turf/open/floor/plasteel/dark, /area/security/prison/cells) "kgB" = ( -/obj/machinery/vending/snack/orange, /obj/machinery/light{ dir = 1 }, +/obj/machinery/jukebox, /turf/open/floor/wood, /area/service/bar) "khb" = ( @@ -58686,6 +58772,12 @@ }, /turf/open/floor/plasteel, /area/security/prison/upper) +"lOe" = ( +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/command/meeting_room) "lOr" = ( /obj/structure/table, /obj/machinery/light/floor, @@ -58881,6 +58973,9 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, /turf/open/floor/plasteel, /area/security/prison/cells) "maT" = ( @@ -84743,7 +84838,7 @@ aQN aTB aQN aWq -aQN +bft aWq aUt aQN @@ -87074,7 +87169,7 @@ bjr cBp bjr buB -bvV +iyK bxu bxu bxx @@ -93740,7 +93835,7 @@ aPR aWL aPR aZM -bbX +lOe bay bbM bcN @@ -95542,8 +95637,8 @@ aZR aZR aZR aZR -aZR -bft +grS +nVz wZI gDO aBW @@ -96565,7 +96660,7 @@ aSA aTX aVm aWU -aYy +aYB aZR aZR aZR @@ -97600,7 +97695,7 @@ bch bdi bbw bfy -bbw +eVW bik aZV aZV @@ -99885,7 +99980,7 @@ arf arf arf arf -ltK +aYy axP azb aAi @@ -103524,7 +103619,7 @@ btX bof bwG bxR -bxR +dGh bof bof bzW @@ -103762,7 +103857,7 @@ aSZ aQc qaY acN -aKR +fzx aJC aYV aYV @@ -111229,7 +111324,7 @@ blG biL cHV cIa -biL +jYI box buo bvc diff --git a/_maps/map_files/CogStation/CogStation.dmm b/_maps/map_files/CogStation/CogStation.dmm index 1dcb97a647..6f1ec5682b 100644 --- a/_maps/map_files/CogStation/CogStation.dmm +++ b/_maps/map_files/CogStation/CogStation.dmm @@ -57320,7 +57320,7 @@ name = "Chief Engineer's RC"; pixel_y = -32 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "csf" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index d64abed5dc..776e50e9a5 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -2619,9 +2619,8 @@ /turf/closed/wall/r_wall, /area/space/nearstation) "ajs" = ( -/obj/structure/table, -/obj/item/storage/briefcase, /obj/effect/turf_decal/delivery, +/obj/machinery/vending/kink, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "ajt" = ( @@ -2880,15 +2879,17 @@ "ajR" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/delivery, -/obj/item/kirbyplants{ - icon_state = "plant-21" - }, +/obj/structure/table, +/obj/item/storage/briefcase, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "ajS" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/kirbyplants{ + icon_state = "plant-21" + }, /turf/open/floor/plasteel/cafeteria, /area/hallway/secondary/entry) "ajT" = ( @@ -75787,7 +75788,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "fLq" = ( @@ -96886,7 +96887,7 @@ /obj/item/folder/red, /obj/item/toy/gun, /obj/item/clothing/head/beret/sec{ - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0); + armor = list("melee"=0,"bullet"=0,"laser"=0,"energy"=0,"bomb"=0,"bio"=0,"rad"=0); desc = "A replica beret resembling that of a special operations officer under Nanotrasen."; name = "replica officer's beret" }, @@ -98957,7 +98958,7 @@ name = "Replica CentCom officer's jumpsuit" }, /obj/item/clothing/head/centhat{ - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0); + armor = list("melee"=0,"bullet"=0,"laser"=0,"energy"=0,"bomb"=0,"bio"=0,"rad"=0); desc = "A replica hat of a Central Commander's attire. It has a small tag on it saying, 'It's good to be emperor.'"; name = "Replica CentCom hat" }, @@ -114141,6 +114142,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, +/obj/machinery/vending/kink, /turf/open/floor/plasteel, /area/commons/fitness/recreation) "sVM" = ( @@ -119427,7 +119429,7 @@ }, /obj/item/reagent_containers/food/drinks/beer{ desc = "Whatever it is, it reeks of foul, putrid froth."; - list_reagents = list("bacchus_blessing" = 15); + list_reagents = list("bacchus_blessing"=15); name = "Delta-Down"; pixel_x = 5; pixel_y = 5 diff --git a/_maps/map_files/FestiveBall/FestiveStation.dmm b/_maps/map_files/FestiveBall/FestiveStation.dmm index a559280263..353b298ceb 100644 --- a/_maps/map_files/FestiveBall/FestiveStation.dmm +++ b/_maps/map_files/FestiveBall/FestiveStation.dmm @@ -5069,7 +5069,7 @@ /area/command/heads_quarters/ce) "ane" = ( /obj/structure/filingcabinet/chestdrawer, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "anf" = ( diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index fa3c32a418..37a0292f45 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -13429,7 +13429,7 @@ /obj/item/radio/intercom{ pixel_x = 28 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "awq" = ( diff --git a/_maps/map_files/LambdaStation/dorms.dmm b/_maps/map_files/LambdaStation/dorms.dmm index d52c4e7870..99626ac667 100644 --- a/_maps/map_files/LambdaStation/dorms.dmm +++ b/_maps/map_files/LambdaStation/dorms.dmm @@ -5011,6 +5011,7 @@ dir = 1 }, /obj/machinery/light, +/obj/machinery/jukebox, /turf/open/floor/plasteel, /area/service/bar) "nb" = ( diff --git a/_maps/map_files/LambdaStation/lambda.dmm b/_maps/map_files/LambdaStation/lambda.dmm index 394f7fb7c1..97a17ff303 100644 --- a/_maps/map_files/LambdaStation/lambda.dmm +++ b/_maps/map_files/LambdaStation/lambda.dmm @@ -44859,7 +44859,7 @@ /obj/item/gps/engineering{ gpstag = "CE0" }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "bUH" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 3661b49684..52fe46984f 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -57489,7 +57489,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "ixH" = ( @@ -65631,6 +65631,14 @@ }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) +"mWS" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/jukebox, +/turf/open/floor/plasteel, +/area/service/bar) "mXi" = ( /turf/open/floor/wood, /area/command/heads_quarters/captain/private) @@ -119802,7 +119810,7 @@ teZ teZ wbZ hCA -msI +mWS pzY kPZ upO diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 68dfbe5bcf..8b4e4c38e6 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -6363,7 +6363,7 @@ c_tag = "Chief Engineer's Office"; network = list("ss13","engine") }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 10 }, @@ -13604,14 +13604,7 @@ /turf/open/floor/plasteel, /area/service/bar/atrium) "ayN" = ( -/obj/item/storage/fancy/cigarettes/cigars{ - pixel_y = 6 - }, -/obj/item/storage/fancy/cigarettes/cigars/cohiba{ - pixel_y = 3 - }, -/obj/item/storage/fancy/cigarettes/cigars/havana, -/obj/structure/table/reinforced, +/obj/machinery/jukebox, /turf/open/floor/plasteel/dark/corner{ dir = 4 }, @@ -13622,6 +13615,13 @@ pixel_x = 32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/item/storage/fancy/cigarettes/cigars/havana, +/obj/item/storage/fancy/cigarettes/cigars/cohiba{ + pixel_y = 3 + }, +/obj/item/storage/fancy/cigarettes/cigars{ + pixel_y = 6 + }, /turf/open/floor/plasteel/dark/side{ dir = 1 }, @@ -16379,9 +16379,8 @@ /area/hallway/secondary/exit) "aEg" = ( /obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped/inverse{ - dir = 4; - name = "air mixer" +/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped{ + dir = 4 }, /obj/structure/cable{ icon_state = "4-8" @@ -23915,7 +23914,7 @@ c_tag = "Library 2"; dir = 4 }, -/obj/structure/sign/painting{ +/obj/structure/sign/painting/library{ pixel_y = 32 }, /turf/open/floor/plasteel/dark/side{ @@ -23926,6 +23925,9 @@ /obj/structure/table/wood, /obj/item/folder, /obj/item/pen, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, /turf/open/floor/plasteel/dark, /area/service/library) "aRV" = ( @@ -23997,6 +23999,9 @@ /obj/machinery/newscaster{ pixel_x = 32 }, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, /turf/open/floor/plasteel/dark/side{ dir = 10 }, @@ -24956,6 +24961,9 @@ /area/maintenance/port/aft) "aUj" = ( /obj/machinery/photocopier, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, /turf/open/floor/plasteel/dark/side{ dir = 10 }, @@ -26435,7 +26443,7 @@ /turf/closed/wall, /area/service/library) "aXg" = ( -/obj/structure/sign/painting{ +/obj/structure/sign/painting/library{ pixel_y = -32 }, /turf/open/floor/plasteel/dark/side{ @@ -26444,6 +26452,9 @@ /area/service/library) "aXh" = ( /obj/machinery/light, +/obj/structure/sign/painting/library{ + pixel_y = -32 + }, /turf/open/floor/plasteel/dark, /area/service/library) "aXi" = ( @@ -26461,7 +26472,7 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "aXj" = ( -/obj/structure/sign/painting{ +/obj/structure/sign/painting/library{ pixel_y = -32 }, /turf/open/floor/plasteel/dark, @@ -26474,6 +26485,9 @@ c_tag = "Library 1"; dir = 8 }, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, /turf/open/floor/plasteel/dark/side{ dir = 10 }, @@ -35444,7 +35458,7 @@ /obj/structure/table/wood, /obj/item/folder, /obj/item/pen, -/obj/structure/sign/painting{ +/obj/structure/sign/painting/library{ pixel_x = -32 }, /turf/open/floor/plasteel/dark, @@ -84771,7 +84785,7 @@ awp awX axR ayN -aue +asg blj aCb aCe diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 2c01f48150..d8d18c4407 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -42909,7 +42909,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "bVE" = ( diff --git a/_maps/map_files/Snaxi/Snaxi.dmm b/_maps/map_files/Snaxi/Snaxi.dmm index 4def794b4f..1e3c094cf6 100644 --- a/_maps/map_files/Snaxi/Snaxi.dmm +++ b/_maps/map_files/Snaxi/Snaxi.dmm @@ -85,7 +85,7 @@ /obj/machinery/keycard_auth{ pixel_y = -28 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "aai" = ( diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index a147773cd1..cb32e435ca 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -2280,7 +2280,7 @@ /turf/open/floor/plasteel, /area/tdome/arena_source) "fX" = ( -/turf/closed/indestructible/riveted, +/turf/closed/indestructible/start_area, /area/start) "fY" = ( /obj/effect/landmark/start/new_player, diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 5695995713..9cae56645f 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -80,7 +80,7 @@ //DNA - Because fuck you and your magic numbers being all over the codebase. #define DNA_BLOCK_SIZE 3 -#define DNA_UNI_IDENTITY_BLOCKS 15 +#define DNA_UNI_IDENTITY_BLOCKS 19 #define DNA_HAIR_COLOR_BLOCK 1 #define DNA_FACIAL_HAIR_COLOR_BLOCK 2 #define DNA_SKIN_TONE_BLOCK 3 @@ -96,6 +96,10 @@ #define DNA_MUTANTEAR_BLOCK 13 #define DNA_MUTANTMARKING_BLOCK 14 #define DNA_TAUR_BLOCK 15 +#define DNA_BARK_SOUND_BLOCK 16 +#define DNA_BARK_SPEED_BLOCK 17 +#define DNA_BARK_PITCH_BLOCK 18 +#define DNA_BARK_VARIANCE_BLOCK 19 #define DNA_SEQUENCE_LENGTH 4 #define DNA_MUTATION_BLOCKS 8 diff --git a/code/__DEFINES/bitfields.dm b/code/__DEFINES/bitfields.dm new file mode 100644 index 0000000000..19a962fbff --- /dev/null +++ b/code/__DEFINES/bitfields.dm @@ -0,0 +1,4 @@ +#define DEFINE_BITFIELD(_variable, _flags) /datum/bitfield/##_variable { \ + flags = ##_flags; \ + variable = #_variable; \ +} diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 7ef6e8694d..2662caa63a 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -274,6 +274,8 @@ // #define HEARING_SPANS 6 #define HEARING_MESSAGE_MODE 7 // #define HEARING_SOURCE 8 +#define COMSIG_MOVABLE_BARK "movable_bark" //from base of atom/movable/proc/bark(): (list/hearers, distance, volume, pitch) +#define COMSIG_MOVABLE_QUEUE_BARK "movable_queue_bark" //from base of atom/movable/proc/send_speech(): (list/hearers, message, range, atom/movable/source, bubble_type, list/spans, datum/language/message_language, message_mode) #define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source) #define COMSIG_MOVABLE_TELEPORTED "movable_teleported" //from base of do_teleport(): (channel, turf/origin, turf/destination) #define COMSIG_MOVABLE_CHASM_DROP "movable_chasm_drop" //from base of /datum/component/chasm/drop() (/datum/component/chasm) @@ -417,7 +419,7 @@ #define COMPONENT_INTERRUPT_LIFE_PHYSICAL 2 // interrupt physical handling #define COMPONET_INTERRUPT_STATUS_EFFECTS 3 // interrupt status effects -#define COMSIG_LIVING_BIOLOGICAL_LIFE "biological_life" //from base of mob/living/BiologicalLife() (seconds, times_fired) +#define COMSIG_LIVING_BIOLOGICAL_LIFE "biological_life" //from base of mob/living/BiologicalLife() (delta_time, times_fired) #define COMSIG_LIVING_PHYSICAL_LIFE "physical_life" //from base of mob/living/PhysicalLife() (seconds, times_fired) @@ -569,7 +571,7 @@ #define COMSIG_MECHA_EQUIPMENT_CLICK "mecha_action_equipment_click" /// Prevents click from happening. #define COMPONENT_CANCEL_EQUIPMENT_CLICK (1<<0) - + // /mob/living/carbon/human signals #define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) #define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm new file mode 100644 index 0000000000..cc6e5bd49a --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm @@ -0,0 +1,3 @@ +/// Called from /mob/living/PushAM -- Called when this mob is about to push a movable, but before it moves +/// (aotm/movable/being_pushed) +#define COMSIG_LIVING_PUSHING_MOVABLE "living_pushing_movable" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm new file mode 100644 index 0000000000..5d2a471c0a --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -0,0 +1,2 @@ +///From base of mob/living/MobBump() (mob/living) +#define COMSIG_LIVING_MOB_BUMP "living_mob_bump" diff --git a/code/__DEFINES/dcs/signals/signals_subsystem.dm b/code/__DEFINES/dcs/signals/signals_subsystem.dm new file mode 100644 index 0000000000..c39b59262b --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_subsystem.dm @@ -0,0 +1,25 @@ +// Subsystem signals. Format: +// When the signal is called: (signal arguments) +// All signals send the source datum of the signal as the first argument + +///Subsystem signals +///From base of datum/controller/subsystem/Initialize: (start_timeofday) +#define COMSIG_SUBSYSTEM_POST_INITIALIZE "subsystem_post_initialize" + +///Called when the ticker enters the pre-game phase +#define COMSIG_TICKER_ENTER_PREGAME "comsig_ticker_enter_pregame" + +///Called when the ticker sets up the game for start +#define COMSIG_TICKER_ENTER_SETTING_UP "comsig_ticker_enter_setting_up" + +///Called when the ticker fails to set up the game for start +#define COMSIG_TICKER_ERROR_SETTING_UP "comsig_ticker_error_setting_up" + +/// Called when the round has started, but before GAME_STATE_PLAYING +#define COMSIG_TICKER_ROUND_STARTING "comsig_ticker_round_starting" + +// Point of interest signals +/// Sent from base of /datum/controller/subsystem/points_of_interest/proc/on_poi_element_added : (atom/new_poi) +#define COMSIG_ADDED_POINT_OF_INTEREST "added_point_of_interest" +/// Sent from base of /datum/controller/subsystem/points_of_interest/proc/on_poi_element_removed : (atom/old_poi) +#define COMSIG_REMOVED_POINT_OF_INTEREST "removed_point_of_interest" diff --git a/code/__DEFINES/layers_planes.dm b/code/__DEFINES/layers_planes.dm index 2550084207..fd841ba258 100644 --- a/code/__DEFINES/layers_planes.dm +++ b/code/__DEFINES/layers_planes.dm @@ -187,6 +187,9 @@ #define ABOVE_HUD_LAYER 30 #define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE" +#define LOBBY_BACKGROUND_LAYER 3 +#define LOBBY_BUTTON_LAYER 4 + #define SPLASHSCREEN_LAYER 90 #define SPLASHSCREEN_PLANE 90 #define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE" diff --git a/code/__DEFINES/loadout.dm b/code/__DEFINES/loadout.dm index f9b4c36c9c..792708b5bb 100644 --- a/code/__DEFINES/loadout.dm +++ b/code/__DEFINES/loadout.dm @@ -91,3 +91,8 @@ #define LOADOUT_TAB 4 #define CONTENT_PREFERENCES_TAB 5 #define KEYBINDINGS_TAB 6 + +//quirks +#define QUIRK_POSITIVE "Positive" +#define QUIRK_NEGATIVE "Negative" +#define QUIRK_NEUTRAL "Neutral" diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index 87e7fe3ce4..96201d71c2 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -42,6 +42,7 @@ #define LOG_MECHA (1 << 17) #define LOG_SHUTTLE (1 << 18) #define LOG_VICTIM (1 << 19) +#define LOG_ECON (1 << 20) //Individual logging panel pages #define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK | LOG_VICTIM) @@ -50,7 +51,7 @@ #define INDIVIDUAL_COMMS_LOG (LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS) #define INDIVIDUAL_OOC_LOG (LOG_OOC | LOG_ADMIN) #define INDIVIDUAL_OWNERSHIP_LOG (LOG_OWNERSHIP) -#define INDIVIDUAL_SHOW_ALL_LOG (LOG_ATTACK | LOG_SAY | LOG_WHISPER | LOG_EMOTE | LOG_DSAY | LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS | LOG_OOC | LOG_ADMIN | LOG_OWNERSHIP | LOG_GAME | LOG_VICTIM) +#define INDIVIDUAL_SHOW_ALL_LOG (LOG_ATTACK | LOG_SAY | LOG_WHISPER | LOG_EMOTE | LOG_DSAY | LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS | LOG_OOC | LOG_ADMIN | LOG_OWNERSHIP | LOG_GAME | LOG_VICTIM | LOG_ECON) #define LOGSRC_CLIENT "Client" #define LOGSRC_MOB "Mob" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index c8c084fc18..36f427a1bb 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -5,7 +5,6 @@ // Ready states at roundstart for mob/dead/new_player #define PLAYER_NOT_READY 0 #define PLAYER_READY_TO_PLAY 1 -#define PLAYER_READY_TO_OBSERVE 2 // movement intent defines for the m_intent var #define MOVE_INTENT_WALK "walk" diff --git a/code/__DEFINES/movement.dm b/code/__DEFINES/movement.dm index 5bf7de8647..bccbd425dd 100644 --- a/code/__DEFINES/movement.dm +++ b/code/__DEFINES/movement.dm @@ -13,7 +13,7 @@ GLOBAL_VAR_INIT(glide_size_multiplier, 1.0) /// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave. /// The whole result is then clamped to within the range above. /// Not very readable but it works -#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((32 / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE)) +#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((world.icon_size / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE)) /// Enables smooth movement // #define SMOOTH_MOVEMENT diff --git a/code/__DEFINES/pool.dm b/code/__DEFINES/pool.dm index 1bf39dcb1d..86088fbb79 100644 --- a/code/__DEFINES/pool.dm +++ b/code/__DEFINES/pool.dm @@ -8,5 +8,6 @@ GLOBAL_LIST_INIT(blacklisted_pool_reagents, list( /datum/reagent/toxin/plasma, /datum/reagent/oxygen, /datum/reagent/nitrous_oxide, /datum/reagent/nitrogen, //gases /datum/reagent/fermi, //blanket fermichem ban sorry. this also covers mkultra, genital enlargers, etc etc. - /datum/reagent/consumable/semen //NO. + /datum/reagent/consumable/semen, //NO. + /datum/reagent/consumable/milk )) diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index d2aa2f6a91..5581d71080 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -15,6 +15,7 @@ #define DISABLE_DEATHRATTLE (1<<12) #define DISABLE_ARRIVALRATTLE (1<<13) #define COMBOHUD_LIGHTING (1<<14) +#define SOUND_BARK (1<<15) #define DEADMIN_ALWAYS (1<<0) #define DEADMIN_ANTAGONIST (1<<1) @@ -22,7 +23,7 @@ #define DEADMIN_POSITION_SECURITY (1<<3) #define DEADMIN_POSITION_SILICON (1<<4) -#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS) +#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS|SOUND_BARK) //Chat toggles #define CHAT_OOC (1<<0) diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm index d1329060eb..061ac289d0 100644 --- a/code/__DEFINES/reactions.dm +++ b/code/__DEFINES/reactions.dm @@ -27,6 +27,7 @@ #define NOBLIUM_RESEARCH_AMOUNT 25 #define BZ_RESEARCH_SCALE 4 #define BZ_RESEARCH_MAX_AMOUNT 400 +#define QCD_RESEARCH_AMOUNT 0.2 // often made in absolutely massive quantities due to the simple nature of fusion #define MIASMA_RESEARCH_AMOUNT 6 #define STIMULUM_RESEARCH_AMOUNT 50 //Plasma fusion properties diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm index e27489380c..b8b9b78bf3 100644 --- a/code/__DEFINES/research.dm +++ b/code/__DEFINES/research.dm @@ -73,7 +73,9 @@ TECHWEB_POINT_TYPE_GENERIC = "General Research"\ ) +#define LARGEST_BOMB "bomb" + #define BOMB_TARGET_POINTS 50000 //Adjust as needed. Actual hard cap is double this, but will never be reached due to hyperbolic curve. -#define BOMB_TARGET_SIZE (world.system_type == MS_WINDOWS ? 240 : 50000) // The shockwave radius required for a bomb to get TECHWEB_BOMB_MIDPOINT points. +#define BOMB_TARGET_SIZE 300 // The shockwave radius required for a bomb to get TECHWEB_BOMB_MIDPOINT points. // Linux still has old trit fires, so #define BOMB_SUB_TARGET_EXPONENT 3 // The power of the points curve below the target size. Higher = less points for worse bombs, below target. diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index b711837232..a4d0b6427d 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -37,6 +37,7 @@ #define MODE_ALIEN "alientalk" #define MODE_HOLOPAD "holopad" +#define MODE_STATUSDISPLAY "statusdisplay" #define MODE_CHANGELING "changeling" #define MODE_KEY_CHANGELING "g" @@ -91,11 +92,32 @@ //ambition end #define MAX_MESSAGE_LEN 4096 //Citadel edit: What's the WORST that could happen? #define MAX_FLAVOR_LEN 4096 +#define MAX_FLAVOR_PREVIEW_LEN 40 #define MAX_TASTE_LEN 40 //lick... vore... ew... #define MAX_NAME_LEN 42 #define MAX_BROADCAST_LEN 512 #define MAX_CHARTER_LEN 80 +//Bark defines +#define BARK_DEFAULT_MINPITCH 0.6 +#define BARK_DEFAULT_MAXPITCH 1.4 +#define BARK_DEFAULT_MINVARY 0.1 +#define BARK_DEFAULT_MAXVARY 0.4 +#define BARK_DEFAULT_MINSPEED 2 +#define BARK_DEFAULT_MAXSPEED 8 + +#define BARK_SPEED_BASELINE 4 //Used to calculate delay between barks, any bark speeds below this feature higher bark density, any speeds above feature lower bark density. Keeps barking length consistent + +#define BARK_MAX_BARKS 128 +#define BARK_MAX_TIME (10 SECONDS) // More or less the amount of time the above takes to process through with a bark speed of 2. + +#define BARK_PITCH_RAND(gend) ((gend == MALE ? rand(60, 120) : (gend == FEMALE ? rand(80, 140) : rand(60,140))) / 100) //Macro for determining random pitch based off gender +#define BARK_VARIANCE_RAND (rand(BARK_DEFAULT_MINVARY * 100, BARK_DEFAULT_MAXVARY * 100) / 100) //Macro for randomizing bark variance to reduce the amount of copy-pasta necessary for that + +#define BARK_DO_VARY(pitch, variance) (rand(((pitch * 100) - (variance*50)), ((pitch*100) + (variance*50))) / 100) + +#define BARK_SOUND_FALLOFF_EXPONENT(distance) (distance/7) //At lower ranges, we want the exponent to be below 1 so that whispers don't sound too awkward. At higher ranges, we want the exponent fairly high to make yelling less obnoxious + // Is something in the IC chat filter? This is config dependent. #define CHAT_FILTER_CHECK(T) (config.ic_filter_regex && findtext(T, config.ic_filter_regex)) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 986b9821b3..222dc5cd39 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -233,6 +233,8 @@ #define TRAIT_TRASHCAN "trashcan" ///Used for fireman carry to have mobe not be dropped when passing by a prone individual. #define TRAIT_BEING_CARRIED "being_carried" +#define TRAIT_GLASS_BONES "glass_bones" +#define TRAIT_PAPER_SKIN "paper_skin" // mobility flag traits // IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it) diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 8a8ccd5023..58b7516be3 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -161,6 +161,10 @@ if (CONFIG_GET(flag/log_telecomms)) WRITE_LOG(GLOB.world_telecomms_log, "TCOMMS: [text]") +/proc/log_econ(text) + if (CONFIG_GET(flag/log_econ)) + WRITE_LOG(GLOB.world_econ_log, "MONEY: [text]") + /proc/log_chat(text) if (CONFIG_GET(flag/log_pda)) //same thing here diff --git a/code/__HELPERS/clients.dm b/code/__HELPERS/clients.dm new file mode 100644 index 0000000000..3b61cf1e1c --- /dev/null +++ b/code/__HELPERS/clients.dm @@ -0,0 +1,12 @@ +///Returns whether or not a player is a guest using their ckey as an input +/proc/is_guest_key(key) + if(findtext(key, "Guest-", 1, 7) != 1) //was findtextEx + return FALSE + + var/i, ch, len = length(key) + + for(i = 7, i <= len, ++i) //we know the first 6 chars are Guest- + ch = text2ascii(key, i) + if (ch < 48 || ch > 57) //0-9 + return FALSE + return TRUE diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 3e5658fa00..8b8c05063e 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -79,6 +79,12 @@ var/datum/emote/E = new path() E.emote_list[E.key] = E + for(var/path in subtypesof(/datum/bark)) + var/datum/bark/B = new path() + GLOB.bark_list[B.id] = path + if(B.allow_random) + GLOB.bark_random_list[B.id] = path + // Hair Gradients - Initialise all /datum/sprite_accessory/hair_gradient into an list indexed by gradient-style name for(var/path in subtypesof(/datum/sprite_accessory/hair_gradient)) var/datum/sprite_accessory/hair_gradient/H = new path() diff --git a/code/__HELPERS/matrices/color_matrix.dm b/code/__HELPERS/matrices/color_matrix.dm index e4a4a9bb48..bcc48b45f5 100644 --- a/code/__HELPERS/matrices/color_matrix.dm +++ b/code/__HELPERS/matrices/color_matrix.dm @@ -138,6 +138,25 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) return list(cosval,sinval,0,0, -sinval,cosval,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) +/** + * Builds a color matrix that transforms the hue, saturation, and value, all in one operation. + */ +/proc/color_matrix_hsv(hue, saturation, value) + hue = clamp(360 - hue, 0, 360) + + // This is very much a rough approximation of hueshifting. This carries some artifacting, such as negative values that simply shouldn't exist, but it does get the job done, and that's what matters. + var/cos_a = cos(hue) // These have to be inverted from 360, otherwise the hue's inverted + var/sin_a = sin(hue) + var/rot_x = cos_a + (1 - cos_a) / 3 + var/rot_y = (1 - cos_a) / 3 - 0.5774 * sin_a // 0.5774 is sqrt(1/3) + var/rot_z = (1 - cos_a) / 3 + 0.5774 * sin_a + + return list( + round((((1-saturation) * LUMA_R) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_z * saturation)) * value, 0.01), + round((((1-saturation) * LUMA_G) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_y * saturation)) * value, 0.01), + round((((1-saturation) * LUMA_B) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_x * saturation)) * value, 0.01), + 0, 0, 0 + ) //Returns a matrix addition of A with B /proc/color_matrix_add(list/A, list/B) diff --git a/code/__HELPERS/matrices/transform_matrix.dm b/code/__HELPERS/matrices/transform_matrix.dm index 251ef8151f..8f8a67535e 100644 --- a/code/__HELPERS/matrices/transform_matrix.dm +++ b/code/__HELPERS/matrices/transform_matrix.dm @@ -19,7 +19,7 @@ speed /= segments if(parallel) - animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL) + animate(src, transform = matrices[1], time = speed, loops, flags = ANIMATION_PARALLEL) else animate(src, transform = matrices[1], time = speed, loops) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 2f7dd7a64f..469f27926a 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -258,15 +258,24 @@ send2adminchat("Server", "A round of [mode.name] just ended[mode_result == "undefined" ? "." : " with a [mode_result]."] Survival rate: [survival_rate]") - if(LAZYLEN(GLOB.round_end_notifiees)) - world.TgsTargetedChatBroadcast("[GLOB.round_end_notifiees.Join(", ")] the round has ended.", FALSE) - if(length(CONFIG_GET(keyed_list/cross_server))) send_news_report() //tell the nice people on discord what went on before the salt cannon happens. - world.TgsTargetedChatBroadcast("The current round has ended. Please standby for your shift interlude Nanotrasen News Network's report!", FALSE) - world.TgsTargetedChatBroadcast(send_news_report(), FALSE) + if(CONFIG_GET(string/chat_roundend_notice_tag)) + var/broadcastmessage = "" + + if(LAZYLEN(GLOB.round_end_notifiees)) + broadcastmessage += "[GLOB.round_end_notifiees.Join(", ")], " + + + broadcastmessage += "[((broadcastmessage == "") ? "the" : "The")] current round has ended. Please standby for your shift interlude Nanotrasen News Network's report!\n" + broadcastmessage += "```\n[send_news_report()]\n```" + + if(CONFIG_GET(string/chat_reboot_role)) + broadcastmessage += "\n\n<@&[CONFIG_GET(string/chat_reboot_role)]>, the server will reboot shortly!" + + send2chat(broadcastmessage, CONFIG_GET(string/chat_roundend_notice_tag)) CHECK_TICK @@ -370,6 +379,8 @@ parts += "[FOURSPACES]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" parts += "[FOURSPACES]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[popcount["station_integrity"]]%"]" + if(mode.station_was_nuked && SSevents.holidays && SSevents.holidays[PRIDE_MONTH]) + parts += "[FOURSPACES]Gender revealed: [pick(500; "Male", 500; "Female", "Bigender", "Agender", "Demiboy", "Demigirl", "Genderfluid", "Pangender", "Xenogender", "Clown", 50; "What", 50; "Oh no.", 50; "Excuse me?")]" var/total_players = GLOB.joined_player_list.len if(total_players) parts+= "[FOURSPACES]Total Population: [total_players]" @@ -548,7 +559,7 @@ parts += "There were [station_vault] credits collected by crew this shift.
" if(total_players > 0) parts += "An average of [station_vault/total_players] credits were collected.
" - // log_econ("Roundend credit total: [station_vault] credits. Average Credits: [station_vault/total_players]") + log_econ("Roundend credit total: [station_vault] credits. Average Credits: [station_vault/total_players]") if(mr_moneybags) parts += "The most affluent crew member at shift end was [mr_moneybags.account_holder] with [mr_moneybags.account_balance] cr!" else diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index b415b4720f..428784e953 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1176,25 +1176,22 @@ GLOBAL_REAL_VAR(list/stack_trace_storage) var/initialpixely = pixel_y var/shiftx = rand(-pixelshiftx,pixelshiftx) var/shifty = rand(-pixelshifty,pixelshifty) - animate(src, pixel_x = pixel_x + shiftx, pixel_y = pixel_y + shifty, time = 0.2, loop = duration) - pixel_x = initialpixelx - pixel_y = initialpixely + animate(src, pixel_x = shiftx, pixel_y = shifty, time = 0.2, loop = duration, flags = ANIMATION_RELATIVE) + animate(pixel_x = initialpixelx, pixel_y = initialpixely, time = 0.2) -/atom/proc/do_jiggle(targetangle = 45, timer = 20) +/atom/proc/do_jiggle(targetangle = 25, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) - var/halftime = timer * 0.5 M.Turn(pick(-targetangle, targetangle)) - animate(src, transform = M, time = halftime, easing = ELASTIC_EASING) - animate(src, transform = OM, time = halftime, easing = ELASTIC_EASING) + animate(src, transform = M, time = timer * 0.1, easing = BACK_EASING | EASE_IN) + animate(transform = OM, time = timer * 0.4, easing = ELASTIC_EASING) /atom/proc/do_squish(squishx = 1.2, squishy = 0.6, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) - var/halftime = timer * 0.5 M.Scale(squishx, squishy) - animate(src, transform = M, time = halftime, easing = BOUNCE_EASING) - animate(src, transform = OM, time = halftime, easing = BOUNCE_EASING) + animate(src, transform = M, time = timer * 0.5, easing = ELASTIC_EASING) + animate(transform = OM, time = timer * 0.5, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) /proc/weightclass2text(var/w_class) switch(w_class) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index be1d95416b..8d06d9ecf3 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -1,329 +1,378 @@ -GLOBAL_LIST_INIT(bitfields, list( - "appearance_flags" = list( - "LONG_GLIDE" = LONG_GLIDE, - "RESET_COLOR" = RESET_COLOR, - "RESET_ALPHA" = RESET_ALPHA, - "RESET_TRANSFORM" = RESET_TRANSFORM, - "NO_CLIENT_COLOR" = NO_CLIENT_COLOR, - "KEEP_TOGETHER" = KEEP_TOGETHER, - "KEEP_APART" = KEEP_APART, - "PLANE_MASTER" = PLANE_MASTER, - "TILE_BOUND" = TILE_BOUND, - "PIXEL_SCALE" = PIXEL_SCALE - ), - "area_flags" = list( - "ABDUCTOR_PROOF" = ABDUCTOR_PROOF, - "BLOBS_ALLOWED" = BLOBS_ALLOWED, - "BLOCK_SUICIDE" = BLOCK_SUICIDE, - "CULT_PERMITTED" = CULT_PERMITTED, - "FLORA_ALLOWED" = FLORA_ALLOWED, - "HIDDEN_AREA" = HIDDEN_AREA, - "MEGAFAUNA_SPAWN_ALLOWED" = MEGAFAUNA_SPAWN_ALLOWED, - "MOB_SPAWN_ALLOWED" = MOB_SPAWN_ALLOWED, - "NO_ALERTS" = NO_ALERTS, - "NOTELEPORT" = NOTELEPORT, - "CAVES_ALLOWED" = CAVES_ALLOWED, - "UNIQUE_AREA" = UNIQUE_AREA, - "VALID_TERRITORY" = VALID_TERRITORY, - "XENOBIOLOGY_COMPATIBLE" = XENOBIOLOGY_COMPATIBLE, - "NO_ALERTS" = NO_ALERTS, - ) , - "sight" = list( - "SEE_INFRA" = SEE_INFRA, - "SEE_SELF" = SEE_SELF, - "SEE_MOBS" = SEE_MOBS, - "SEE_OBJS" = SEE_OBJS, - "SEE_TURFS" = SEE_TURFS, - "SEE_PIXELS" = SEE_PIXELS, - "SEE_THRU" = SEE_THRU, - "SEE_BLACKNESS" = SEE_BLACKNESS, - "BLIND" = BLIND - ), - "obj_flags" = list( - "EMAGGED" = EMAGGED, - "IN_USE" = IN_USE, - "CAN_BE_HIT" = CAN_BE_HIT, - "BEING_SHOCKED" = BEING_SHOCKED, - "DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION, - "ON_BLUEPRINTS" = ON_BLUEPRINTS, - "UNIQUE_RENAME" = UNIQUE_RENAME, - "USES_TGUI" = USES_TGUI, - "FROZEN" = FROZEN, - "SHOVABLE_ONTO" = SHOVABLE_ONTO, - "BLOCK_Z_OUT_DOWN" = BLOCK_Z_OUT_DOWN, - "BLOCK_Z_OUT_UP" = BLOCK_Z_OUT_UP, - "BLOCK_Z_IN_DOWN" = BLOCK_Z_IN_DOWN, - "BLOCK_Z_IN_UP" = BLOCK_Z_IN_UP, - "EXAMINE_SKIP" = EXAMINE_SKIP - ), - "datum_flags" = list( - "DF_USE_TAG" = DF_USE_TAG, - "DF_VAR_EDITED" = DF_VAR_EDITED, - "DF_ISPROCESSING" = DF_ISPROCESSING, - ), - "item_flags" = list( - "BEING_REMOVED" = BEING_REMOVED, - "IN_INVENTORY" = IN_INVENTORY, - "FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE, - "NEEDS_PERMIT" = NEEDS_PERMIT, - "SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND, - "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION, - "DROPDEL" = DROPDEL, - "NOBLUDGEON" = NOBLUDGEON, - "ABSTRACT" = ABSTRACT, - "IN_STORAGE" = IN_STORAGE, - "ITEM_CAN_BLOCK" = ITEM_CAN_BLOCK, - "ITEM_CAN_PARRY" = ITEM_CAN_PARRY - ), - "admin_flags" = list( - "BUILDMODE" = R_BUILDMODE, - "ADMIN" = R_ADMIN, - "BAN" = R_BAN, - "FUN" = R_FUN, - "SERVER" = R_SERVER, - "DEBUG" = R_DEBUG, - "POSSESS" = R_POSSESS, - "PERMISSIONS" = R_PERMISSIONS, - "STEALTH" = R_STEALTH, - "POLL" = R_POLL, - "VAREDIT" = R_VAREDIT, - "SOUNDS" = R_SOUNDS, - "SPAWN" = R_SPAWN, - "AUTOLOGIN" = R_AUTOLOGIN, - "DBRANKS" = R_DBRANKS, - "SENSITIVE" = R_SENSITIVE - ), - "interaction_flags_atom" = list( - "INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED, - "INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND, - "INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT, - "INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY, - "INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED, - "INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED, - "INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB, - "INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND, - "INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT - ), - "interaction_flags_machine" = list( - "INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN, - "INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE, - "INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN, - "INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON, - "INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON, - "INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON, - "INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE - ), - "interaction_flags_item" = list( - "INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP, - ), - "pass_flags" = list( - "PASSTABLE" = PASSTABLE, - "PASSGLASS" = PASSGLASS, - "PASSGRILLE" = PASSGRILLE, - "PASSBLOB" = PASSBLOB, - "PASSMOB" = PASSMOB, - "PASSCLOSEDTURF" = PASSCLOSEDTURF, - "LETPASSTHROW" = LETPASSTHROW - ), - "movement_type" = list( - "GROUND" = GROUND, - "FLYING" = FLYING, - "VENTCRAWLING" = VENTCRAWLING, - "FLOATING" = FLOATING, - "PHASING" = PHASING - ), - "resistance_flags" = list( - "LAVA_PROOF" = LAVA_PROOF, - "FIRE_PROOF" = FIRE_PROOF, - "FLAMMABLE" = FLAMMABLE, - "ON_FIRE" = ON_FIRE, - "UNACIDABLE" = UNACIDABLE, - "ACID_PROOF" = ACID_PROOF, - "INDESTRUCTIBLE" = INDESTRUCTIBLE, - "FREEZE_PROOF" = FREEZE_PROOF, - "GOLIATH_RESISTANCE" = GOLIATH_RESISTANCE, - "GOLIATH_WEAKNESS" = GOLIATH_WEAKNESS - ), - "flags_1" = list( - "NOJAUNT_1" = NOJAUNT_1, - "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1, - "CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1, - "HEAR_1" = HEAR_1, - "DEFAULT_RICOCHET_1" = DEFAULT_RICOCHET_1, - "CONDUCT_1" = CONDUCT_1, - "NO_LAVA_GEN_1" = NO_LAVA_GEN_1, - "NODECONSTRUCT_1" = NODECONSTRUCT_1, - "OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1, - "ON_BORDER_1" = ON_BORDER_1, - "NO_RUINS_1" = NO_RUINS_1, - "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1, - "HOLOGRAM_1" = HOLOGRAM_1, - "SHOCKED_1" = SHOCKED_1, - "INITIALIZED_1" = INITIALIZED_1, - "NO_SCREENTIPS_1" = NO_SCREENTIPS_1, - "ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1, - "BLOCK_FACE_ATOM_1" = BLOCK_FACE_ATOM_1, - "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1 - ), - "flags_ricochet" = list( - "RICOCHET_SHINY" = RICOCHET_SHINY, - "RICOCHET_HARD" = RICOCHET_HARD - ), - "clothing_flags" = list( - "LAVAPROTECT" = LAVAPROTECT, - "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE, - "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT, - "ALLOWINTERNALS" = ALLOWINTERNALS, - "NOSLIP" = NOSLIP, - "THICKMATERIAL" = THICKMATERIAL, - "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, - "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, - "IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS, - "SCAN_REAGENTS" = SCAN_REAGENTS - ), - "zap_flags" = list( - "ZAP_MOB_DAMAGE" = ZAP_MOB_DAMAGE, - "ZAP_OBJ_DAMAGE" = ZAP_OBJ_DAMAGE, - "ZAP_MOB_STUN" = ZAP_MOB_STUN, - "ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES, - "ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE, - ), - "smooth" = list( - "SMOOTH_TRUE" = SMOOTH_TRUE, - "SMOOTH_MORE" = SMOOTH_MORE, - "SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL, - "SMOOTH_BORDER" = SMOOTH_BORDER, - "SMOOTH_QUEUED" = SMOOTH_QUEUED, - ), - "reagents_holder_flags" = list( - "INJECTABLE" = INJECTABLE, - "DRAWABLE" = DRAWABLE, - "REFILLABLE" = REFILLABLE, - "DRAINABLE" = DRAINABLE, - "TRANSPARENT" = TRANSPARENT, - "AMOUNT_VISIBLE" = AMOUNT_VISIBLE, - "NO_REACT" = NO_REACT, - ), - "car_traits" = list( - "CAN_KIDNAP" = CAN_KIDNAP, - ), - "rad_flags" = list( - "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS, - "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE, - ), - "disease_flags" = list( - "CURABLE" = CURABLE, - "CAN_CARRY" = CAN_CARRY, - "CAN_RESIST" = CAN_RESIST - ), - "chemical_flags" = list( - "REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS, - "REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT, - "REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE, - "REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE, - "REAGENT_INVISIBLE" = REAGENT_INVISIBLE, - "REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW, - "REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME, - "REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL, - "REAGENT_ORGANIC_PROCESS" = REAGENT_ORGANIC_PROCESS, - "REAGENT_ROBOTIC_PROCESS" = REAGENT_ROBOTIC_PROCESS - ), - "clear_conversion" = list( - "REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE, - "REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE - ), - "organ_flags" = list( - "ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC, - "ORGAN_FROZEN" = ORGAN_FROZEN, - "ORGAN_FAILING" = ORGAN_FAILING, - "ORGAN_EXTERNAL" = ORGAN_EXTERNAL, - "ORGAN_VITAL" = ORGAN_VITAL, - "ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL - ), - "genital_flags" = list( - "GENITAL_BLACKLISTED" = GENITAL_BLACKLISTED, - "GENITAL_INTERNAL" = GENITAL_INTERNAL, - "GENITAL_HIDDEN" = GENITAL_HIDDEN, - "GENITAL_THROUGH_CLOTHES" = GENITAL_THROUGH_CLOTHES, - "GENITAL_FUID_PRODUCTION" = GENITAL_FUID_PRODUCTION, - "CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH, - "MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN, - "CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH +GLOBAL_LIST_INIT(bitfields, generate_bitfields()) - ), - "mob_biotypes" = list ( - "MOB_ORGANIC" = MOB_ORGANIC, - "MOB_MINERAL" = MOB_MINERAL, - "MOB_ROBOTIC" = MOB_ROBOTIC, - "MOB_UNDEAD" = MOB_UNDEAD, - "MOB_HUMANOID" = MOB_HUMANOID, - "MOB_BUG" = MOB_BUG, - "MOB_BEAST" = MOB_BEAST, - "MOB_EPIC" = MOB_EPIC, - "MOB_REPTILE" = MOB_REPTILE, - "MOB_SPIRIT" = MOB_SPIRIT - ), - "mobility_flags" = list( - "MOBILITY_MOVE" = MOBILITY_MOVE, - "MOBILITY_STAND" = MOBILITY_STAND, - "MOBILITY_PICKUP" = MOBILITY_PICKUP, - "MOBILITY_USE" = MOBILITY_USE, - "MOBILITY_UI" = MOBILITY_UI, - "MOBILITY_STORAGE" = MOBILITY_STORAGE, - "MOBILITY_PULL" = MOBILITY_PULL, - "MOBILITY_HOLD" = MOBILITY_HOLD, - "MOBILITY_RESIST" = MOBILITY_RESIST - ), - "combat_flags" = list( - "COMBAT_FLAG_SPRINT_TOGGLED" = COMBAT_FLAG_SPRINT_TOGGLED, - "COMBAT_FLAG_SPRINT_ACTIVE" = COMBAT_FLAG_SPRINT_ACTIVE, - "COMBAT_FLAG_ATTEMPTING_CRAWL" = COMBAT_FLAG_ATTEMPTING_CRAWL, - "COMBAT_FLAG_HARD_STAMCRIT" = COMBAT_FLAG_HARD_STAMCRIT, - "COMBAT_FLAG_INTENTIONALLY_RESTING" = COMBAT_FLAG_INTENTIONALLY_RESTING, - "COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST, - "COMBAT_FLAG_SPRINT_FORCED" = COMBAT_FLAG_SPRINT_FORCED - ), - "shield_flags" = list( - "SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT, - "SHIELD_ENERGY_WEAK" = SHIELD_ENERGY_WEAK, - "SHIELD_KINETIC_WEAK" = SHIELD_KINETIC_WEAK, - "SHIELD_KINETIC_STRONG" = SHIELD_KINETIC_STRONG, - "SHIELD_ENERGY_STRONG" = SHIELD_ENERGY_STRONG, - "SHIELD_DISABLER_DISRUPTED" = SHIELD_DISABLER_DISRUPTED, - "SHIELD_NO_RANGED" = SHIELD_NO_RANGED, - "SHIELD_NO_MELEE" = SHIELD_NO_MELEE, - "SHIELD_CAN_BASH" = SHIELD_CAN_BASH, - "SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN, - "SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN, - "SHIELD_BASH_WALL_DISARM" = SHIELD_BASH_WALL_DISARM, - "SHIELD_BASH_ALWAYS_DISARM" = SHIELD_BASH_ALWAYS_DISARM, - "SHIELD_BASH_GROUND_SLAM" = SHIELD_BASH_GROUND_SLAM, - "SHIELD_BASH_GROUND_SLAM_DISARM" = SHIELD_BASH_GROUND_SLAM_DISARM - ), - "storage_flags" = list( - "STORAGE_LIMIT_MAX_ITEMS" = STORAGE_LIMIT_MAX_ITEMS, - "STORAGE_LIMIT_MAX_W_CLASS" = STORAGE_LIMIT_MAX_W_CLASS, - "STORAGE_LIMIT_COMBINED_W_CLASS" = STORAGE_LIMIT_COMBINED_W_CLASS, - "STORAGE_LIMIT_VOLUME" = STORAGE_LIMIT_VOLUME - ), - "mutantrace_variation" = list( - "STYLE_DIGITIGRADE" = STYLE_DIGITIGRADE, - "STYLE_MUZZLE" = STYLE_MUZZLE, - "STYLE_SNEK_TAURIC" = STYLE_SNEK_TAURIC, - "STYLE_PAW_TAURIC" = STYLE_PAW_TAURIC, - "STYLE_HOOF_TAURIC" = STYLE_HOOF_TAURIC, - "STYLE_NO_ANTHRO_ICON" = STYLE_NO_ANTHRO_ICON, - "USE_SNEK_CLIP_MASK" = USE_SNEK_CLIP_MASK, - "USE_QUADRUPED_CLIP_MASK" = USE_QUADRUPED_CLIP_MASK - ), - "vis_flags" = list( - "VIS_INHERIT_ICON" = VIS_INHERIT_ICON, - "VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE, - "VIS_INHERIT_DIR" = VIS_INHERIT_DIR, - "VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER, - "VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE, - "VIS_INHERIT_ID" = VIS_INHERIT_ID, - "VIS_UNDERLAY" = VIS_UNDERLAY, - "VIS_HIDE" = VIS_HIDE - ) - )) +/// Specifies a bitfield for smarter debugging +/datum/bitfield + /// The variable name that contains the bitfield + var/variable + + /// An associative list of the readable flag and its true value + var/list/flags + +/// Turns /datum/bitfield subtypes into a list for use in debugging +/proc/generate_bitfields() + var/list/bitfields = list() + for (var/_bitfield in subtypesof(/datum/bitfield)) + var/datum/bitfield/bitfield = new _bitfield + bitfields[bitfield.variable] = bitfield.flags + return bitfields + +DEFINE_BITFIELD(admin_flags, list( + "ADMIN" = R_ADMIN, + "AUTOLOGIN" = R_AUTOLOGIN, + "BAN" = R_BAN, + "BUILDMODE" = R_BUILDMODE, + "DBRANKS" = R_DBRANKS, + "DEBUG" = R_DEBUG, + "FUN" = R_FUN, + "PERMISSIONS" = R_PERMISSIONS, + "POLL" = R_POLL, + "POSSESS" = R_POSSESS, + "SENSITIVE" = R_SENSITIVE, + "SERVER" = R_SERVER, + "SOUNDS" = R_SOUNDS, + "SPAWN" = R_SPAWN, + "STEALTH" = R_STEALTH, + "VAREDIT" = R_VAREDIT, +)) + +DEFINE_BITFIELD(appearance_flags, list( + "KEEP_APART" = KEEP_APART, + "KEEP_TOGETHER" = KEEP_TOGETHER, + "LONG_GLIDE" = LONG_GLIDE, + "NO_CLIENT_COLOR" = NO_CLIENT_COLOR, + "PASS_MOUSE" = PASS_MOUSE, + "PIXEL_SCALE" = PIXEL_SCALE, + "PLANE_MASTER" = PLANE_MASTER, + "RESET_ALPHA" = RESET_ALPHA, + "RESET_COLOR" = RESET_COLOR, + "RESET_TRANSFORM" = RESET_TRANSFORM, + "TILE_BOUND" = TILE_BOUND, + "TILE_MOVER" = TILE_MOVER, +)) + +DEFINE_BITFIELD(area_flags, list( + "ABDUCTOR_PROOF" = ABDUCTOR_PROOF, + "BLOBS_ALLOWED" = BLOBS_ALLOWED, + "BLOCK_SUICIDE" = BLOCK_SUICIDE, + "CULT_PERMITTED" = CULT_PERMITTED, + "FLORA_ALLOWED" = FLORA_ALLOWED, + "HIDDEN_AREA" = HIDDEN_AREA, + "MEGAFAUNA_SPAWN_ALLOWED" = MEGAFAUNA_SPAWN_ALLOWED, + "MOB_SPAWN_ALLOWED" = MOB_SPAWN_ALLOWED, + "NO_ALERTS" = NO_ALERTS, + "NOTELEPORT" = NOTELEPORT, + "CAVES_ALLOWED" = CAVES_ALLOWED, + "UNIQUE_AREA" = UNIQUE_AREA, + "VALID_TERRITORY" = VALID_TERRITORY, + "XENOBIOLOGY_COMPATIBLE" = XENOBIOLOGY_COMPATIBLE, + "NO_ALERTS" = NO_ALERTS, +)) + +DEFINE_BITFIELD(car_traits, list( + "CAN_KIDNAP" = CAN_KIDNAP, +)) + +DEFINE_BITFIELD(chemical_flags, list( + "REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS, + "REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT, + "REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW, + "REAGENT_INVISIBLE" = REAGENT_INVISIBLE, + "REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE, + "REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE, + "REAGENT_ORGANIC_PROCESS" = REAGENT_ORGANIC_PROCESS, + "REAGENT_ROBOTIC_PROCESS" = REAGENT_ROBOTIC_PROCESS, + "REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME, + "REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL, +)) + +DEFINE_BITFIELD(clear_conversion, list( + "REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE, + "REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE +)) + +DEFINE_BITFIELD(clothing_flags, list( + "ALLOWINTERNALS" = ALLOWINTERNALS, + "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT, + "IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS, + "LAVAPROTECT" = LAVAPROTECT, + "NOSLIP" = NOSLIP, + "SCAN_REAGENTS" = SCAN_REAGENTS, + "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE, + "THICKMATERIAL" = THICKMATERIAL, + "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, + "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, +)) + +DEFINE_BITFIELD(combat_flags, list( + "COMBAT_FLAG_ATTEMPTING_CRAWL" = COMBAT_FLAG_ATTEMPTING_CRAWL, + "COMBAT_FLAG_HARD_STAMCRIT" = COMBAT_FLAG_HARD_STAMCRIT, + "COMBAT_FLAG_INTENTIONALLY_RESTING" = COMBAT_FLAG_INTENTIONALLY_RESTING, + "COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST, + "COMBAT_FLAG_SPRINT_ACTIVE" = COMBAT_FLAG_SPRINT_ACTIVE, + "COMBAT_FLAG_SPRINT_FORCED" = COMBAT_FLAG_SPRINT_FORCED, + "COMBAT_FLAG_SPRINT_TOGGLED" = COMBAT_FLAG_SPRINT_TOGGLED, +)) + +DEFINE_BITFIELD(datum_flags, list( + "DF_USE_TAG" = DF_USE_TAG, + "DF_VAR_EDITED" = DF_VAR_EDITED, + "DF_ISPROCESSING" = DF_ISPROCESSING, +)) + +DEFINE_BITFIELD(disease_flags, list( + "CAN_CARRY" = CAN_CARRY, + "CAN_RESIST" = CAN_RESIST, + "CURABLE" = CURABLE, +)) + +DEFINE_BITFIELD(flags_1, list( + "ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1, + "BLOCK_FACE_ATOM_1" = BLOCK_FACE_ATOM_1, + "CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1, + "CONDUCT_1" = CONDUCT_1, + "DEFAULT_RICOCHET_1" = DEFAULT_RICOCHET_1, + "HEAR_1" = HEAR_1, + "HOLOGRAM_1" = HOLOGRAM_1, + "INITIALIZED_1" = INITIALIZED_1, + "NODECONSTRUCT_1" = NODECONSTRUCT_1, + "NOJAUNT_1" = NOJAUNT_1, + "NO_LAVA_GEN_1" = NO_LAVA_GEN_1, + "NO_RUINS_1" = NO_RUINS_1, + "NO_SCREENTIPS_1" = NO_SCREENTIPS_1, + "OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1, + "ON_BORDER_1" = ON_BORDER_1, + "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1, + "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1, + "SHOCKED_1" = SHOCKED_1, + "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1, +)) + +DEFINE_BITFIELD(flags_ricochet, list( + "RICOCHET_SHINY" = RICOCHET_SHINY, + "RICOCHET_HARD" = RICOCHET_HARD +)) + +DEFINE_BITFIELD(genital_flags, list( + "CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH, + "CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH, + "GENITAL_BLACKLISTED" = GENITAL_BLACKLISTED, + "GENITAL_FUID_PRODUCTION" = GENITAL_FUID_PRODUCTION, + "GENITAL_HIDDEN" = GENITAL_HIDDEN, + "GENITAL_INTERNAL" = GENITAL_INTERNAL, + "GENITAL_THROUGH_CLOTHES" = GENITAL_THROUGH_CLOTHES, + "MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN, +)) + +DEFINE_BITFIELD(interaction_flags_atom, list( + "INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND, + "INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB, + "INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED, + "INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED, + "INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND, + "INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT, + "INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED, + "INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY, + "INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT, +)) + +DEFINE_BITFIELD(interaction_flags_machine, list( + "INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON, + "INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE, + "INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN, + "INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON, + "INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON, + "INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE, + "INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN, +)) + +DEFINE_BITFIELD(interaction_flags_item, list( + "INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP, +)) + +DEFINE_BITFIELD(item_flags, list( + "ABSTRACT" = ABSTRACT, + "BEING_REMOVED" = BEING_REMOVED, + "DROPDEL" = DROPDEL, + "FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE, + "IN_INVENTORY" = IN_INVENTORY, + "IN_STORAGE" = IN_STORAGE, + "ITEM_CAN_BLOCK" = ITEM_CAN_BLOCK, + "ITEM_CAN_PARRY" = ITEM_CAN_PARRY, + "NEEDS_PERMIT" = NEEDS_PERMIT, + "NOBLUDGEON" = NOBLUDGEON, + "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION, + "SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND, +)) + +DEFINE_BITFIELD(mob_biotypes, list( + "MOB_BEAST" = MOB_BEAST, + "MOB_BUG" = MOB_BUG, + "MOB_EPIC" = MOB_EPIC, + "MOB_HUMANOID" = MOB_HUMANOID, + "MOB_MINERAL" = MOB_MINERAL, + "MOB_ORGANIC" = MOB_ORGANIC, + "MOB_REPTILE" = MOB_REPTILE, + "MOB_ROBOTIC" = MOB_ROBOTIC, + "MOB_SPIRIT" = MOB_SPIRIT, + "MOB_UNDEAD" = MOB_UNDEAD, +)) + +DEFINE_BITFIELD(mobility_flags, list( + "MOBILITY_HOLD" = MOBILITY_HOLD, + "MOBILITY_MOVE" = MOBILITY_MOVE, + "MOBILITY_PICKUP" = MOBILITY_PICKUP, + "MOBILITY_PULL" = MOBILITY_PULL, + "MOBILITY_RESIST" = MOBILITY_RESIST, + "MOBILITY_STAND" = MOBILITY_STAND, + "MOBILITY_STORAGE" = MOBILITY_STORAGE, + "MOBILITY_UI" = MOBILITY_UI, + "MOBILITY_USE" = MOBILITY_USE, +)) + +DEFINE_BITFIELD(movement_type, list( + "FLOATING" = FLOATING, + "FLYING" = FLYING, + "GROUND" = GROUND, + "PHASING" = PHASING, + "VENTCRAWLING" = VENTCRAWLING, +)) + +DEFINE_BITFIELD(mutantrace_variation, list( + "STYLE_DIGITIGRADE" = STYLE_DIGITIGRADE, + "STYLE_HOOF_TAURIC" = STYLE_HOOF_TAURIC, + "STYLE_MUZZLE" = STYLE_MUZZLE, + "STYLE_NO_ANTHRO_ICON" = STYLE_NO_ANTHRO_ICON, + "STYLE_PAW_TAURIC" = STYLE_PAW_TAURIC, + "STYLE_SNEK_TAURIC" = STYLE_SNEK_TAURIC, + "USE_SNEK_CLIP_MASK" = USE_SNEK_CLIP_MASK, + "USE_QUADRUPED_CLIP_MASK" = USE_QUADRUPED_CLIP_MASK, +)) + +DEFINE_BITFIELD(obj_flags, list( + "BEING_SHOCKED" = BEING_SHOCKED, + "BLOCK_Z_IN_DOWN" = BLOCK_Z_IN_DOWN, + "BLOCK_Z_IN_UP" = BLOCK_Z_IN_UP, + "BLOCK_Z_OUT_DOWN" = BLOCK_Z_OUT_DOWN, + "BLOCK_Z_OUT_UP" = BLOCK_Z_OUT_UP, + "CAN_BE_HIT" = CAN_BE_HIT, + "DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION, + "EMAGGED" = EMAGGED, + "EXAMINE_SKIP" = EXAMINE_SKIP, + "FROZEN" = FROZEN, + "IN_USE" = IN_USE, + "ON_BLUEPRINTS" = ON_BLUEPRINTS, + "SHOVABLE_ONTO" = SHOVABLE_ONTO, + "UNIQUE_RENAME" = UNIQUE_RENAME, + "USES_TGUI" = USES_TGUI, +)) + +DEFINE_BITFIELD(organ_flags, list( + "ORGAN_EXTERNAL" = ORGAN_EXTERNAL, + "ORGAN_FAILING" = ORGAN_FAILING, + "ORGAN_FROZEN" = ORGAN_FROZEN, + "ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL, + "ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC, + "ORGAN_VITAL" = ORGAN_VITAL, +)) + +DEFINE_BITFIELD(pass_flags, list( + "LETPASSTHROW" = LETPASSTHROW, + "PASSBLOB" = PASSBLOB, + "PASSCLOSEDTURF" = PASSCLOSEDTURF, + "PASSGLASS" = PASSGLASS, + "PASSGRILLE" = PASSGRILLE, + "PASSMOB" = PASSMOB, + "PASSTABLE" = PASSTABLE, +)) + +DEFINE_BITFIELD(rad_flags, list( + "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS, + "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE, +)) + +DEFINE_BITFIELD(reagents_holder_flags, list( + "AMOUNT_VISIBLE" = AMOUNT_VISIBLE, + "DRAINABLE" = DRAINABLE, + "DRAWABLE" = DRAWABLE, + "INJECTABLE" = INJECTABLE, + "NO_REACT" = NO_REACT, + "REFILLABLE" = REFILLABLE, + "TRANSPARENT" = TRANSPARENT, +)) + +DEFINE_BITFIELD(resistance_flags, list( + "ACID_PROOF" = ACID_PROOF, + "FIRE_PROOF" = FIRE_PROOF, + "FLAMMABLE" = FLAMMABLE, + "FREEZE_PROOF" = FREEZE_PROOF, + "GOLIATH_RESISTANCE" = GOLIATH_RESISTANCE, + "GOLIATH_WEAKNESS" = GOLIATH_WEAKNESS, + "INDESTRUCTIBLE" = INDESTRUCTIBLE, + "LAVA_PROOF" = LAVA_PROOF, + "ON_FIRE" = ON_FIRE, + "UNACIDABLE" = UNACIDABLE, +)) + +DEFINE_BITFIELD(shield_flags, list( + "SHIELD_BASH_ALWAYS_DISARM" = SHIELD_BASH_ALWAYS_DISARM, + "SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN, + "SHIELD_BASH_GROUND_SLAM" = SHIELD_BASH_GROUND_SLAM, + "SHIELD_BASH_GROUND_SLAM_DISARM" = SHIELD_BASH_GROUND_SLAM_DISARM, + "SHIELD_BASH_WALL_DISARM" = SHIELD_BASH_WALL_DISARM, + "SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN, + "SHIELD_CAN_BASH" = SHIELD_CAN_BASH, + "SHIELD_DISABLER_DISRUPTED" = SHIELD_DISABLER_DISRUPTED, + "SHIELD_ENERGY_STRONG" = SHIELD_ENERGY_STRONG, + "SHIELD_ENERGY_WEAK" = SHIELD_ENERGY_WEAK, + "SHIELD_KINETIC_STRONG" = SHIELD_KINETIC_STRONG, + "SHIELD_KINETIC_WEAK" = SHIELD_KINETIC_WEAK, + "SHIELD_NO_MELEE" = SHIELD_NO_MELEE, + "SHIELD_NO_RANGED" = SHIELD_NO_RANGED, + "SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT, +)) + +DEFINE_BITFIELD(sight, list( + "BLIND" = BLIND, + "SEE_BLACKNESS" = SEE_BLACKNESS, + "SEE_INFRA" = SEE_INFRA, + "SEE_MOBS" = SEE_MOBS, + "SEE_OBJS" = SEE_OBJS, + "SEE_PIXELS" = SEE_PIXELS, + "SEE_SELF" = SEE_SELF, + "SEE_THRU" = SEE_THRU, + "SEE_TURFS" = SEE_TURFS, +)) + +DEFINE_BITFIELD(smooth, list( + "SMOOTH_BORDER" = SMOOTH_BORDER, + "SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL, + "SMOOTH_MORE" = SMOOTH_MORE, + "SMOOTH_QUEUED" = SMOOTH_QUEUED, + "SMOOTH_TRUE" = SMOOTH_TRUE, +)) + +DEFINE_BITFIELD(storage_flags, list( + "STORAGE_LIMIT_COMBINED_W_CLASS" = STORAGE_LIMIT_COMBINED_W_CLASS, + "STORAGE_LIMIT_MAX_ITEMS" = STORAGE_LIMIT_MAX_ITEMS, + "STORAGE_LIMIT_MAX_W_CLASS" = STORAGE_LIMIT_MAX_W_CLASS, + "STORAGE_LIMIT_VOLUME" = STORAGE_LIMIT_VOLUME, +)) + +DEFINE_BITFIELD(vis_flags, list( + "VIS_HIDE" = VIS_HIDE, + "VIS_INHERIT_DIR" = VIS_INHERIT_DIR, + "VIS_INHERIT_ICON" = VIS_INHERIT_ICON, + "VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE, + "VIS_INHERIT_ID" = VIS_INHERIT_ID, + "VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER, + "VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE, + "VIS_UNDERLAY" = VIS_UNDERLAY, +)) + +DEFINE_BITFIELD(zap_flags, list( + "ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES, + "ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE, + "ZAP_MOB_DAMAGE" = ZAP_MOB_DAMAGE, + "ZAP_MOB_STUN" = ZAP_MOB_STUN, + "ZAP_OBJ_DAMAGE" = ZAP_OBJ_DAMAGE, +)) diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index da8b0ed3ee..ff5829ff73 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -43,6 +43,10 @@ GLOBAL_LIST_EMPTY(arachnid_spinneret_list) GLOBAL_LIST_EMPTY(arachnid_mandibles_list) GLOBAL_LIST_EMPTY(caps_list) + //Bark bits +GLOBAL_LIST_EMPTY(bark_list) +GLOBAL_LIST_EMPTY(bark_random_list) + //a way to index the right bodypart list given the type of bodypart GLOBAL_LIST_INIT(mutant_reference_list, list( "tail_lizard" = GLOB.tails_list_lizard, diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index 3f3d9c5e25..e9c38546a7 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -49,6 +49,8 @@ GLOBAL_VAR(tgui_log) GLOBAL_PROTECT(tgui_log) GLOBAL_VAR(world_shuttle_log) GLOBAL_PROTECT(world_shuttle_log) +GLOBAL_VAR(world_econ_log) +GLOBAL_PROTECT(world_econ_log) GLOBAL_VAR(perf_log) GLOBAL_PROTECT(perf_log) diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm index ae853a4e1a..58c182036d 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -101,14 +101,6 @@ ..() /client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params) - var/list/L = params2list(params) - if (L["middle"]) - if (src_object && src_location != over_location) - middragtime = world.time - middragatom = src_object - else - middragtime = 0 - middragatom = null mouseParams = params mouseLocation = over_location mouseObject = over_object @@ -121,9 +113,3 @@ /obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob) return - -/client/MouseDrop(src_object, over_object, src_location, over_location, src_control, over_control, params) - if (middragatom == src_object) - middragtime = 0 - middragatom = null - ..() diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 53ad775954..5029d51452 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -60,7 +60,7 @@ if(client && hud_used) hud_used.reorganize_alerts() thealert.transform = matrix(32, 6, MATRIX_TRANSLATE) - animate(thealert, transform = matrix(), time = 2.5, easing = CUBIC_EASING) + animate(thealert, transform = matrix(), time = 2.5, easing = BACK_EASING) if(thealert.timeout) addtimer(CALLBACK(src, .proc/alert_timeout, thealert, category), thealert.timeout) diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm new file mode 100644 index 0000000000..b426db1aac --- /dev/null +++ b/code/_onclick/hud/new_player.dm @@ -0,0 +1,333 @@ +/datum/hud/new_player + +/datum/hud/new_player/proc/populate_buttons(mob/dead/new_player/owner) + var/list/buttons = subtypesof(/atom/movable/screen/lobby) + for(var/button_type in buttons) + var/atom/movable/screen/lobby/lobbyscreen = new button_type() + lobbyscreen.SlowInit() + lobbyscreen.hud = src + static_inventory += lobbyscreen + if(istype(lobbyscreen, /atom/movable/screen/lobby/button)) + var/atom/movable/screen/lobby/button/lobby_button = lobbyscreen + lobby_button.owner = REF(owner) + show_hud(hud_version) + +/atom/movable/screen/lobby + plane = SPLASHSCREEN_PLANE + layer = LOBBY_BUTTON_LAYER + screen_loc = "TOP,CENTER" + +/// Run sleeping actions after initialize +/atom/movable/screen/lobby/proc/SlowInit() + return + +/atom/movable/screen/lobby/background + layer = LOBBY_BACKGROUND_LAYER + icon = 'icons/hud/lobby/background.dmi' + icon_state = "background" + screen_loc = "TOP,CENTER:-61" + +/atom/movable/screen/lobby/button + ///Is the button currently enabled? + var/enabled = TRUE + ///Is the button currently being hovered over with the mouse? + var/highlighted = FALSE + /// The ref of the mob that owns this button. Only the owner can click on it. + var/owner + +/atom/movable/screen/lobby/button/Click(location, control, params) + if(owner != REF(usr)) + return + + . = ..() + + if(!enabled) + return + flick("[base_icon_state]_pressed", src) + update_appearance(UPDATE_ICON) + return TRUE + +/atom/movable/screen/lobby/button/MouseEntered(location,control,params) + if(owner != REF(usr)) + return + + . = ..() + highlighted = TRUE + update_appearance(UPDATE_ICON) + +/atom/movable/screen/lobby/button/MouseExited() + if(owner != REF(usr)) + return + + . = ..() + highlighted = FALSE + update_appearance(UPDATE_ICON) + +/atom/movable/screen/lobby/button/update_icon(updates) + . = ..() + if(!enabled) + icon_state = "[base_icon_state]_disabled" + return + else if(highlighted) + icon_state = "[base_icon_state]_highlighted" + return + icon_state = base_icon_state + +/atom/movable/screen/lobby/button/proc/set_button_status(status) + if(status == enabled) + return FALSE + enabled = status + update_appearance(UPDATE_ICON) + return TRUE + +///Prefs menu +/atom/movable/screen/lobby/button/character_setup + screen_loc = "TOP:-70,CENTER:-54" + icon = 'icons/hud/lobby/character_setup.dmi' + icon_state = "character_setup" + base_icon_state = "character_setup" + +/atom/movable/screen/lobby/button/character_setup/Click(location, control, params) + . = ..() + if(!.) + return + hud.mymob.client.prefs.current_tab = SETTINGS_TAB + hud.mymob.client.prefs.ShowChoices(hud.mymob) + +///Button that appears before the game has started +/atom/movable/screen/lobby/button/ready + screen_loc = "TOP:-8,CENTER:-65" + icon = 'icons/hud/lobby/ready.dmi' + icon_state = "not_ready" + base_icon_state = "not_ready" + var/ready = FALSE + +/atom/movable/screen/lobby/button/ready/Initialize(mapload) + . = ..() + switch(SSticker.current_state) + if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/hide_ready_button) + if(GAME_STATE_SETTING_UP) + set_button_status(FALSE) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/show_ready_button) + else + set_button_status(FALSE) + +/atom/movable/screen/lobby/button/ready/proc/hide_ready_button() + SIGNAL_HANDLER + set_button_status(FALSE) + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/show_ready_button) + +/atom/movable/screen/lobby/button/ready/proc/show_ready_button() + SIGNAL_HANDLER + set_button_status(TRUE) + UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/hide_ready_button) + +/atom/movable/screen/lobby/button/ready/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + ready = !ready + if(ready) + new_player.ready = PLAYER_READY_TO_PLAY + base_icon_state = "ready" + else + new_player.ready = PLAYER_NOT_READY + base_icon_state = "not_ready" + update_appearance(UPDATE_ICON) + +///Shown when the game has started +/atom/movable/screen/lobby/button/join + screen_loc = "TOP:-13,CENTER:-58" + icon = 'icons/hud/lobby/join.dmi' + icon_state = "" //Default to not visible + base_icon_state = "join_game" + enabled = FALSE + +/atom/movable/screen/lobby/button/join/Initialize(mapload) + . = ..() + switch(SSticker.current_state) + if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/show_join_button) + if(GAME_STATE_SETTING_UP) + set_button_status(TRUE) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/hide_join_button) + else + set_button_status(TRUE) + +/atom/movable/screen/lobby/button/join/Click(location, control, params) + . = ..() + if(!.) + return + if(!SSticker?.IsRoundInProgress()) + to_chat(hud.mymob, span_boldwarning("The round is either not ready, or has already finished...")) + return + + //Determines Relevent Population Cap + var/relevant_cap + var/hpc = CONFIG_GET(number/hard_popcap) + var/epc = CONFIG_GET(number/extreme_popcap) + if(hpc && epc) + relevant_cap = min(hpc, epc) + else + relevant_cap = max(hpc, epc) + + var/mob/dead/new_player/new_player = hud.mymob + + if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(new_player.key) in GLOB.admin_datums))) + to_chat(new_player, span_danger("[CONFIG_GET(string/hard_popcap_message)]")) + + var/queue_position = SSticker.queued_players.Find(new_player) + if(queue_position == 1) + to_chat(new_player, span_notice("You are next in line to join the game. You will be notified when a slot opens up.")) + else if(queue_position) + to_chat(new_player, span_notice("There are [queue_position-1] players in front of you in the queue to join the game.")) + else + SSticker.queued_players += new_player + to_chat(new_player, span_notice("You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].")) + return + new_player.LateChoices() + +/atom/movable/screen/lobby/button/join/proc/show_join_button() + SIGNAL_HANDLER + set_button_status(TRUE) + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/hide_join_button) + +/atom/movable/screen/lobby/button/join/proc/hide_join_button() + SIGNAL_HANDLER + set_button_status(FALSE) + UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/show_join_button) + +/atom/movable/screen/lobby/button/observe + screen_loc = "TOP:-40,CENTER:-54" + icon = 'icons/hud/lobby/observe.dmi' + icon_state = "observe_disabled" + base_icon_state = "observe" + enabled = FALSE + +/atom/movable/screen/lobby/button/observe/Initialize(mapload) + . = ..() + if(SSticker.current_state > GAME_STATE_STARTUP) + set_button_status(TRUE) + else + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, .proc/enable_observing) + +/atom/movable/screen/lobby/button/observe/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + new_player.make_me_an_observer() + +/atom/movable/screen/lobby/button/observe/proc/enable_observing() + SIGNAL_HANDLER + flick("[base_icon_state]_enabled", src) + set_button_status(TRUE) + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, .proc/enable_observing) + +/atom/movable/screen/lobby/button/settings + icon = 'icons/hud/lobby/bottom_buttons.dmi' + icon_state = "settings" + base_icon_state = "settings" + screen_loc = "TOP:-122,CENTER:+30" + +/atom/movable/screen/lobby/button/settings/Click(location, control, params) + . = ..() + if(!.) + return + + hud.mymob.client.prefs.current_tab = GAME_PREFERENCES_TAB + hud.mymob.client.prefs.ShowChoices(hud.mymob) + +/atom/movable/screen/lobby/button/changelog_button + icon = 'icons/hud/lobby/bottom_buttons.dmi' + icon_state = "changelog" + base_icon_state = "changelog" + screen_loc ="TOP:-122,CENTER:+58" + + +/atom/movable/screen/lobby/button/crew_manifest + icon = 'icons/hud/lobby/bottom_buttons.dmi' + icon_state = "crew_manifest" + base_icon_state = "crew_manifest" + screen_loc = "TOP:-122,CENTER:+2" + +/atom/movable/screen/lobby/button/crew_manifest/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + new_player.ViewManifest() + +/atom/movable/screen/lobby/button/changelog_button/Click(location, control, params) + . = ..() + usr.client?.changelog() + +/atom/movable/screen/lobby/button/poll + icon = 'icons/hud/lobby/bottom_buttons.dmi' + icon_state = "poll" + base_icon_state = "poll" + screen_loc = "TOP:-122,CENTER:-26" + + var/new_poll = FALSE + +/atom/movable/screen/lobby/button/poll/SlowInit(mapload) + . = ..() + if(!usr) + return + var/mob/dead/new_player/new_player = usr + if(is_guest_key(new_player.key)) + set_button_status(FALSE) + return + if(!SSdbcore.Connect()) + set_button_status(FALSE) + return + var/isadmin = FALSE + if(new_player.client?.holder) + isadmin = TRUE + var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({" + SELECT id FROM [format_table_name("poll_question")] + WHERE (adminonly = 0 OR :isadmin = 1) + AND Now() BETWEEN starttime AND endtime + AND deleted = 0 + AND id NOT IN ( + SELECT pollid FROM [format_table_name("poll_vote")] + WHERE ckey = :ckey + AND deleted = 0 + ) + AND id NOT IN ( + SELECT pollid FROM [format_table_name("poll_textreply")] + WHERE ckey = :ckey + AND deleted = 0 + ) + "}, list("isadmin" = isadmin, "ckey" = new_player.ckey)) + if(!query_get_new_polls.Execute()) + qdel(query_get_new_polls) + set_button_status(FALSE) + return + if(query_get_new_polls.NextRow()) + new_poll = TRUE + else + new_poll = FALSE + update_appearance(UPDATE_OVERLAYS) + qdel(query_get_new_polls) + if(QDELETED(new_player)) + set_button_status(FALSE) + return + +/atom/movable/screen/lobby/button/poll/update_overlays() + . = ..() + if(new_poll) + . += mutable_appearance('icons/hud/lobby/poll_overlay.dmi', "new_poll") + +/atom/movable/screen/lobby/button/poll/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + new_player.handle_player_polling() diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 0070362f8b..935379b721 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -178,7 +178,7 @@ GLOBAL_LIST_EMPTY(radial_menus) starting.Scale(0.1,0.1) E.transform = starting var/matrix/TM = matrix() - animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing) + animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing, easing = SINE_EASING | EASE_OUT) else E.pixel_y = py E.pixel_x = px diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 8f3a7ef02c..23486cac29 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -126,6 +126,8 @@ return DISCARD_LAST_ACTION user.do_attack_animation(O) O.attacked_by(src, user) + if(force >= 20) + shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01)) /atom/movable/proc/attacked_by() return diff --git a/code/_rendering/atom_huds/atom_hud.dm b/code/_rendering/atom_huds/atom_hud.dm index 07b403284b..c89fe33db8 100644 --- a/code/_rendering/atom_huds/atom_hud.dm +++ b/code/_rendering/atom_huds/atom_hud.dm @@ -29,7 +29,9 @@ GLOBAL_LIST_INIT(huds, list( ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(), ANTAG_HUD_BLOODSUCKER = new/datum/atom_hud/antag/bloodsucker(), ANTAG_HUD_FUGITIVE = new/datum/atom_hud/antag(), - ANTAG_HUD_HERETIC = new/datum/atom_hud/antag/hidden() + ANTAG_HUD_HERETIC = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_SPACECOP = new/datum/atom_hud/antag(), + ANTAG_HUD_GANGSTER = new/datum/atom_hud/antag/hidden() )) /datum/atom_hud diff --git a/code/_rendering/parallax/parallax_holder.dm b/code/_rendering/parallax/parallax_holder.dm index cbe095c02b..1f7d84ae11 100644 --- a/code/_rendering/parallax/parallax_holder.dm +++ b/code/_rendering/parallax/parallax_holder.dm @@ -248,7 +248,7 @@ if(P.absolute) continue var/matrix/translate_matrix = matrix() - translate_matrix.Translate(cos(turn) * 480, sin(turn) * 480) + translate_matrix.Translate(sin(turn) * 480, cos(turn) * 480) var/matrix/target_matrix = matrix() var/move_speed = speed * P.speed // do the first segment by shifting down one screen @@ -282,7 +282,7 @@ continue P.CancelAnimation() var/matrix/translate_matrix = matrix() - translate_matrix.Translate(cos(turn) * 480, sin(turn) * 480) + translate_matrix.Translate(sin(turn) * 480, cos(turn) * 480) P.transform = translate_matrix animate(P, transform = matrix(), time = time, easing = QUAD_EASING | EASE_OUT) diff --git a/code/controllers/configuration/entries/bot.dm b/code/controllers/configuration/entries/bot.dm new file mode 100644 index 0000000000..071406ad65 --- /dev/null +++ b/code/controllers/configuration/entries/bot.dm @@ -0,0 +1,14 @@ +/datum/config_entry/flag/irc_announce_new_game + deprecated_by = /datum/config_entry/string/chat_announce_new_game + +/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value) + return "" //default broadcast + +/datum/config_entry/string/chat_announce_new_game + config_entry_value = null + +/datum/config_entry/string/chat_reboot_role + +/datum/config_entry/string/chat_roundend_notice_tag + +/datum/config_entry/string/chat_squawk_tag diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index 9966f90ce7..b7a92ee48f 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -39,16 +39,6 @@ /datum/config_entry/flag/show_irc_name -/datum/config_entry/flag/irc_announce_new_game - deprecated_by = /datum/config_entry/string/chat_announce_new_game - -/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value) - return "" //default broadcast - -/datum/config_entry/string/chat_announce_new_game - - config_entry_value = null - /datum/config_entry/string/default_view config_entry_value = "15x15" diff --git a/code/controllers/configuration/entries/logging.dm b/code/controllers/configuration/entries/logging.dm index 52e4743a22..81013d8030 100644 --- a/code/controllers/configuration/entries/logging.dm +++ b/code/controllers/configuration/entries/logging.dm @@ -79,6 +79,10 @@ /datum/config_entry/flag/log_telecomms config_entry_value = TRUE +/// log economy +/datum/config_entry/flag/log_econ + config_entry_value = TRUE + /// log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. /datum/config_entry/flag/log_twitter config_entry_value = TRUE diff --git a/code/controllers/subsystem/autotransfer.dm b/code/controllers/subsystem/autotransfer.dm index 0afa07939e..4b4405c8cf 100644 --- a/code/controllers/subsystem/autotransfer.dm +++ b/code/controllers/subsystem/autotransfer.dm @@ -31,7 +31,7 @@ SUBSYSTEM_DEF(autotransfer) if(world.time < targettime) return if(maxvotes == NO_MAXVOTES_CAP || maxvotes > curvotes) - SSvote.initiate_vote("transfer","server") + SSvote.initiate_vote("transfer","server", votesystem=APPROVAL_VOTING) targettime = targettime + voteinterval curvotes++ else diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 2153325940..643811368c 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -367,9 +367,14 @@ SUBSYSTEM_DEF(job) JobDebug("DO, Handling unrejectable unassigned") //Mop up people who can't leave. for(var/mob/dead/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?) - if(!GiveRandomJob(player)) - if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them an assistant - return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll + if(player.client.prefs.joblessrole == BERANDOMJOB) //Gives the player a random role if their preferences are set to it + if(!GiveRandomJob(player)) + if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them the overflow role + return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll + else //If the player prefers to return to lobby or be an assistant, give them assistant + if(!AssignRole(player, SSjob.overflow_role)) + if(!GiveRandomJob(player)) //The forced antagonist couldn't be assigned to overflow role (bans, client age) - give a random role + return FALSE //Somehow the forced antagonist couldn't be assigned to the overflow role or the a random role - reroll return validate_required_jobs(required_jobs) diff --git a/code/controllers/subsystem/jukeboxes.dm b/code/controllers/subsystem/jukeboxes.dm index 7be6d44a7f..1e457703c2 100644 --- a/code/controllers/subsystem/jukeboxes.dm +++ b/code/controllers/subsystem/jukeboxes.dm @@ -1,3 +1,19 @@ +//As a brief warning to all those who dare tread upon these grounds: +//The bulk of this code here was written years ago, back in the days of 512. +//We were incredibly drunk back then. And nowadays, we've found that being drunk is a hard requirement for working with this code. +//So if you're here to make changes? Brandish a glass. There are many sins here, but it's exactly as engineered as it needs to be. +//We physically won't be able to tell you what half of this code does. The only thing that'll help you here is the ballmer peak. +//Bottoms up, friend. And be sure to drink responsibly. Be sure to fetch some water, too; it eases the hangover. - Bhijn & Myr + + +// Jukelist indices +#define JUKE_TRACK 1 +#define JUKE_CHANNEL 2 +#define JUKE_BOX 3 +#define JUKE_FALLOFF 4 +#define JUKE_SOUND 5 + + SUBSYSTEM_DEF(jukeboxes) name = "Jukeboxes" wait = 5 @@ -25,27 +41,41 @@ SUBSYSTEM_DEF(jukeboxes) var/channeltoreserve = pick(freejukeboxchannels) if(!channeltoreserve) return FALSE + var/sound/song_to_init = sound(T.song_path) freejukeboxchannels -= channeltoreserve - var/list/youvegotafreejukebox = list(T, channeltoreserve, jukebox, jukefalloff) + var/list/youvegotafreejukebox = list(T, channeltoreserve, jukebox, jukefalloff, song_to_init) + + song_to_init.status = SOUND_MUTE + song_to_init.environment = 7 + song_to_init.channel = channeltoreserve + song_to_init.volume = 1 + song_to_init.falloff = jukefalloff + song_to_init.echo = list(0, null, -10000, null, null, null, null, null, null, null, null, null, null, 1, 1, 1, null, null) + activejukeboxes.len++ activejukeboxes[activejukeboxes.len] = youvegotafreejukebox - //Due to changes in later versions of 512, SOUND_UPDATE no longer properly plays audio when a file is defined in the sound datum. As such, we are now required to init the audio before we can actually do anything with it. - //Downsides to this? This means that you can *only* hear the jukebox audio if you were present on the server when it started playing, and it means that it's now impossible to add loops to the jukebox track list. - var/sound/song_to_init = sound(T.song_path) - song_to_init.status = SOUND_MUTE for(var/mob/M in GLOB.player_list) if(!M.client) continue if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS)) continue - M.playsound_local(M, null, 100, channel = youvegotafreejukebox[2], S = song_to_init) + SEND_SOUND(M, song_to_init) return activejukeboxes.len + +//Updates jukebox by transferring to different object or modifying falloff. +/datum/controller/subsystem/jukeboxes/proc/updatejukebox(IDtoupdate, obj/jukebox, jukefalloff) + if(islist(activejukeboxes[IDtoupdate])) + if(istype(jukebox)) + activejukeboxes[IDtoupdate][JUKE_BOX] = jukebox + if(!isnull(jukefalloff)) + activejukeboxes[IDtoupdate][JUKE_FALLOFF] = jukefalloff + /datum/controller/subsystem/jukeboxes/proc/removejukebox(IDtoremove) if(islist(activejukeboxes[IDtoremove])) - var/jukechannel = activejukeboxes[IDtoremove][2] + var/jukechannel = activejukeboxes[IDtoremove][JUKE_CHANNEL] for(var/mob/M in GLOB.player_list) if(!M.client) continue @@ -85,37 +115,74 @@ SUBSYSTEM_DEF(jukeboxes) if(!jukeinfo.len) stack_trace("Active jukebox without any associated metadata.") continue - var/datum/track/juketrack = jukeinfo[1] + var/datum/track/juketrack = jukeinfo[JUKE_TRACK] if(!istype(juketrack)) stack_trace("Invalid jukebox track datum.") continue - var/obj/jukebox = jukeinfo[3] + var/obj/jukebox = jukeinfo[JUKE_BOX] if(!istype(jukebox)) stack_trace("Nonexistant or invalid object associated with jukebox.") continue - var/sound/song_played = sound(juketrack.song_path) + + var/list/audible_zlevels = get_multiz_accessible_levels(jukebox.z) //TODO - for multiz refresh, this should use the cached zlevel connections var in SSMapping. For now this is fine! + + var/sound/song_played = jukeinfo[JUKE_SOUND] var/turf/currentturf = get_turf(jukebox) var/area/currentarea = get_area(jukebox) var/list/hearerscache = hearers(7, jukebox) + var/targetfalloff = jukeinfo[JUKE_FALLOFF] + var/mixes = ((targetfalloff*250)-750) + var/inrange + var/pressure_factor - song_played.falloff = jukeinfo[4] + + var/datum/gas_mixture/source_env = (istype(currentturf) ? currentturf.return_air() : null) + var/datum/gas_mixture/hearer_env //We init this var outside of the mob loop for the sake of performance + var/turf/hearerturf //ditto + + var/source_pressure = (istype(source_env) ? source_env.return_pressure() : 0) + + song_played.falloff = targetfalloff + song_played.volume = min((targetfalloff * 50), 100) for(var/mob/M in GLOB.player_list) if(!M.client) continue - if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS) || !M.can_hear()) - M.stop_sound_channel(jukeinfo[2]) + if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS)) + M.stop_sound_channel(jukeinfo[JUKE_CHANNEL]) continue - var/inrange = FALSE - if(jukebox.z == M.z) //todo - expand this to work with mining planet z-levels when robust jukebox audio gets merged to master - song_played.status = SOUND_UPDATE - if(get_area(M) == currentarea) - inrange = TRUE - else if(M in hearerscache) - inrange = TRUE - else - song_played.status = SOUND_MUTE | SOUND_UPDATE //Setting volume = 0 doesn't let the sound properties update at all, which is lame. - M.playsound_local(currentturf, null, 100, channel = jukeinfo[2], S = song_played, envwet = (inrange ? -250 : 0), envdry = (inrange ? 0 : -10000)) + inrange = FALSE + song_played.status = SOUND_MUTE | SOUND_UPDATE + + if(source_pressure) + hearerturf = get_turf(M) + hearer_env = (istype(hearerturf) ? hearerturf.return_air() : null) + if(istype(hearer_env)) + pressure_factor = min(source_pressure, hearer_env.return_pressure()) + + if(pressure_factor && targetfalloff && M.can_hear() && (hearerturf.z in audible_zlevels)) + if(get_area(hearerturf) == currentarea) + inrange = TRUE + else if(M in hearerscache) + inrange = TRUE + + song_played.x = (currentturf.x - hearerturf.x) * SOUND_DEFAULT_DISTANCE_MULTIPLIER + song_played.z = (currentturf.y - hearerturf.y) * SOUND_DEFAULT_DISTANCE_MULTIPLIER + song_played.y = (((currentturf.z - hearerturf.z) * 10 * SOUND_DEFAULT_DISTANCE_MULTIPLIER) + ((currentturf.z < hearerturf.z) ? -5 : 5)) + + if(pressure_factor < ONE_ATMOSPHERE) + song_played.volume = (min((targetfalloff * 50), 100) * max((pressure_factor - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 1)) + + song_played.echo[1] = (inrange ? 0 : -10000) + song_played.echo[3] = (inrange ? mixes : max(mixes, 0)) + song_played.status = SOUND_UPDATE + SEND_SOUND(M, song_played) CHECK_TICK return + +#undef JUKE_TRACK +#undef JUKE_CHANNEL +#undef JUKE_BOX +#undef JUKE_FALLOFF +#undef JUKE_SOUND diff --git a/code/controllers/subsystem/persistence/polly_parrot.dm b/code/controllers/subsystem/persistence/polly_parrot.dm new file mode 100644 index 0000000000..b0014c249a --- /dev/null +++ b/code/controllers/subsystem/persistence/polly_parrot.dm @@ -0,0 +1,11 @@ +/** + * Persists polly messages across rounds + */ +/datum/controller/subsystem/persistence/LoadGamePersistence() + . = ..() + LoadPolly() + +/datum/controller/subsystem/persistence/proc/LoadPolly() + for(var/mob/living/simple_animal/parrot/Polly/P in GLOB.alive_mob_list) + twitterize(P.speech_buffer, "polytalk") + break //Who's been duping the bird?! diff --git a/code/controllers/subsystem/persistence/poly_parrot.dm b/code/controllers/subsystem/persistence/poly_parrot.dm deleted file mode 100644 index 64743e9623..0000000000 --- a/code/controllers/subsystem/persistence/poly_parrot.dm +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Persists poly messages across rounds - */ -/datum/controller/subsystem/persistence/LoadGamePersistence() - . = ..() - LoadPoly() - -/datum/controller/subsystem/persistence/proc/LoadPoly() - for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.alive_mob_list) - twitterize(P.speech_buffer, "polytalk") - break //Who's been duping the bird?! diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index d1b3236050..d755003f3b 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -164,8 +164,8 @@ SUBSYSTEM_DEF(ticker) to_chat(world, "Welcome to [station_name()]!") send2chat("New round starting on [SSmapping.config.map_name]!", CONFIG_GET(string/chat_announce_new_game)) current_state = GAME_STATE_PREGAME - //Everyone who wants to be an observer is now spawned - create_observers() + SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME) + fire() if(GAME_STATE_PREGAME) //lobby stats for statpanels @@ -203,6 +203,7 @@ SUBSYSTEM_DEF(ticker) for(var/client/C in SSvote.voting) C << browse(null, "window=vote;can_close=0") SSvote.reset() + SEND_SIGNAL(src, COMSIG_TICKER_ENTER_SETTING_UP) current_state = GAME_STATE_SETTING_UP Master.SetRunLevel(RUNLEVEL_SETUP) if(start_immediately) @@ -215,6 +216,7 @@ SUBSYSTEM_DEF(ticker) start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) timeLeft = null Master.SetRunLevel(RUNLEVEL_LOBBY) + SEND_SIGNAL(src, COMSIG_TICKER_ERROR_SETTING_UP) if(GAME_STATE_PLAYING) mode.process(wait * 0.1) @@ -378,8 +380,6 @@ SUBSYSTEM_DEF(ticker) LAZYOR(player.client.prefs.characters_joined_as, player.new_character.real_name) else stack_trace("WARNING: Either a player did not have a new_character, did not have a client, or did not have preferences. This is VERY bad.") - else - player.new_player_panel() CHECK_TICK /datum/controller/subsystem/ticker/proc/collect_minds() @@ -612,7 +612,7 @@ SUBSYSTEM_DEF(ticker) var/list/ded = SSblackbox.first_death if(ded.len) var/last_words = ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : "" - news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]" + news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died.\nTheir name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]" else news_message += "\nNT Sanctioned Psykers proudly confirm reports that nobody died this shift!" @@ -633,13 +633,6 @@ SUBSYSTEM_DEF(ticker) else timeLeft = newtime -//Everyone who wanted to be an observer gets made one now -/datum/controller/subsystem/ticker/proc/create_observers() - for(var/mob/dead/new_player/player in GLOB.player_list) - if(player.ready == PLAYER_READY_TO_OBSERVE && player.mind) - //Break chain since this has a sleep input in it - addtimer(CALLBACK(player, /mob/dead/new_player.proc/make_me_an_observer), 1) - /datum/controller/subsystem/ticker/proc/load_mode() var/mode = trim(file2text("data/mode.txt")) if(mode) diff --git a/code/controllers/subsystem/title.dm b/code/controllers/subsystem/title.dm index 3cc3d9dd99..1dbfb1540c 100644 --- a/code/controllers/subsystem/title.dm +++ b/code/controllers/subsystem/title.dm @@ -10,7 +10,7 @@ SUBSYSTEM_DEF(title) /datum/controller/subsystem/title/Initialize() if(file_path && icon) - return ..() + return if(fexists("data/previous_title.dat")) var/previous_path = file2text("data/previous_title.dat") @@ -31,13 +31,16 @@ SUBSYSTEM_DEF(title) if(length(title_screens)) file_path = "[global.config.directory]/title_screens/images/[pick(title_screens)]" - if(!file_path || !fexists(file_path)) - file_path = "icons/default_title.dmi" + if(!file_path) + file_path = "icons/runtime/default_title.dmi" - if(fexists(file_path)) - icon = new(fcopy_rsc(file_path)) - if(splash_turf) - splash_turf.icon = icon + ASSERT(fexists(file_path)) + + icon = new(fcopy_rsc(file_path)) + + if(splash_turf) + splash_turf.icon = icon + splash_turf.handle_generic_titlescreen_sizes() return ..() diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index edf10f89c4..7f1ece6937 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -169,7 +169,7 @@ SUBSYSTEM_DEF(traumas) /obj/structure/fluff/empty_sleeper/syndicate, /obj/item/implant/radio/syndicate, /obj/item/clothing/head/helmet/space/syndicate, /obj/machinery/nuclearbomb/syndicate, /obj/item/grenade/syndieminibomb, /obj/item/storage/backpack/duffelbag/syndie, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/gun/ballistic/automatic/shotgun/bulldog, /obj/item/gun/ballistic/automatic/c20r, /obj/item/gun/ballistic/automatic/m90, /obj/item/gun/ballistic/automatic/l6_saw, /obj/item/storage/belt/grenade/full, /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate, /obj/item/gun/energy/kinetic_accelerator/crossbow, /obj/item/melee/transforming/energy/sword/saber, /obj/item/dualsaber, /obj/item/melee/powerfist, /obj/item/storage/box/syndie_kit, /obj/item/grenade/spawnergrenade/manhacks, /obj/item/grenade/chem_grenade/bioterrorfoam, /obj/item/reagent_containers/spray/chemsprayer/bioterror, /obj/item/ammo_box/magazine/m10mm, - /obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/vehicle/sealed/mecha/combat/gygax/dark, /obj/vehicle/sealed/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate, + /obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm712x82, /obj/item/antag_spawner/nuke_ops, /obj/vehicle/sealed/mecha/combat/gygax/dark, /obj/vehicle/sealed/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate, /obj/item/cartridge/virus/frame, /obj/item/chameleon, /obj/item/storage/box/syndie_kit/cutouts, /obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/card/emag, /obj/item/storage/toolbox/syndicate, /obj/item/storage/book/bible/syndicate, /obj/item/encryptionkey/binary, /obj/item/encryptionkey/syndicate, /obj/item/aiModule/syndicate, /obj/item/clothing/shoes/magboots/syndie, /obj/item/powersink, /obj/item/sbeacondrop, /obj/item/sbeacondrop/bomb, /obj/item/syndicatedetonator, /obj/item/shield/energy, /obj/item/assault_pod, /obj/item/slimepotion/slime/sentience/nuclear, /obj/item/stack/telecrystal, /obj/item/jammer, /obj/item/codespeak_manual/unlimited, /obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/fingerless/pugilist/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate, diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 772d7f7b8d..eb28d4b4f2 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -320,11 +320,11 @@ SUBSYSTEM_DEF(vote) admintext += "\nIt should be noted that this is not a raw tally of votes but rather the median score plus a tiebreaker!" for(var/i=1,i<=choices.len,i++) var/votes = choices[choices[i]] - admintext += "\n[choices[i]]: [votes]" + admintext += "\n[choices[i]]: [votes ? votes : "0"]" //This is raw data, but the raw data is null by default. If ya don't compensate for it, then it'll look weird! else for(var/i=1,i<=scores.len,i++) var/score = scores[scores[i]] - admintext += "\n[scores[i]]: [score]" + admintext += "\n[scores[i]]: [score ? score : "0"]" message_admins(admintext) return . diff --git a/code/datums/bark.dm b/code/datums/bark.dm new file mode 100644 index 0000000000..2bf3d7c69a --- /dev/null +++ b/code/datums/bark.dm @@ -0,0 +1,150 @@ +//Datums for barks and bark accessories + +/datum/bark + var/name = "Default" + var/id = "Default" + var/soundpath //Path for the actual sound file used for the bark + + // Pitch vars. The actual range for a bark is [(pitch - (maxvariance*0.5)) to (pitch + (maxvariance*0.5))] + // Make absolutely sure to take variance into account when curating a sound for bark purposes. + var/minpitch = BARK_DEFAULT_MINPITCH + var/maxpitch = BARK_DEFAULT_MAXPITCH + var/minvariance = BARK_DEFAULT_MINVARY + var/maxvariance = BARK_DEFAULT_MAXVARY + + // Speed vars. Speed determines the number of characters required for each bark, with lower speeds being faster with higher bark density + var/minspeed = BARK_DEFAULT_MINSPEED + var/maxspeed = BARK_DEFAULT_MAXSPEED + + // Visibility vars. Regardless of what's set below, these can still be obtained via adminbus and genetics. Rule of fun. + var/list/ckeys_allowed + var/ignore = FALSE //Controls whether or not this can be chosen in chargen + var/allow_random = FALSE //Allows chargen randomization to use this. This is mainly to restrict the pool to sounds that fit well for most characters + + +// So the basic jist of the sound design here: We make use primarily of shorter instrument samples for barks. We would've went with animalese instead, but doing so would've involved quite a bit of overhead to saycode. +// Short instrument samples tend to sound surprisingly nice for barks, being able to be played in rapid succession without being outright obnoxious. +// It isn't just instruments that work well here, however. Anything that works well as a stab? Short attack, no sustain, a decent amount of release? Also works extremely well for barks. + +/datum/bark/mutedc2 + name = "Muted String (Low)" + id = "mutedc2" + soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C2.ogg' + allow_random = TRUE + +/datum/bark/mutedc3 + name = "Muted String (Medium)" + id = "mutedc3" + soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C3.ogg' + allow_random = TRUE + +/datum/bark/mutedc4 + name = "Muted String (High)" + id = "mutedc4" + soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C4.ogg' + allow_random = TRUE + +/datum/bark/banjoc3 + name = "Banjo (Medium)" + id = "banjoc3" + soundpath = 'sound/instruments/banjo/Cn3.ogg' + allow_random = TRUE + +/datum/bark/banjoc4 + name = "Banjo (High)" + id = "banjoc4" + soundpath = 'sound/instruments/banjo/Cn4.ogg' + allow_random = TRUE + +/datum/bark/squeaky + name = "Squeaky" + id = "squeak" + soundpath = 'sound/items/toysqueak1.ogg' + maxspeed = 4 + +/datum/bark/beep + name = "Beepy" + id = "beep" + soundpath = 'sound/machines/terminal_select.ogg' + maxpitch = 1 //Bringing the pitch higher just hurts your ears :< + maxspeed = 4 //This soundbyte's too short for larger speeds to not sound awkward + +/datum/bark/chitter + name = "Chittery" + id = "chitter" + minspeed = 4 //Even with the sound being replaced with a unique, shorter sound, this is still a little too long for higher speeds + soundpath = 'sound/voice/barks/chitter.ogg' + +/datum/bark/synthetic_grunt + name = "Synthetic (Grunt)" + id = "synthgrunt" + soundpath = 'sound/misc/bloop.ogg' + +/datum/bark/synthetic + name = "Synthetic (Normal)" + id = "synth" + soundpath = 'sound/machines/uplinkerror.ogg' + +/datum/bark/bullet + name = "Windy" + id = "bullet" + maxpitch = 1.6 //This works well with higher pitches! + soundpath = 'sound/weapons/bulletflyby.ogg' //This works... Surprisingly well as a bark? It's neat! + +/datum/bark/coggers + name = "Brassy" + id = "coggers" + soundpath = 'sound/machines/clockcult/integration_cog_install.ogg' //Yet another unexpectedly good bark sound + + +// Genetics-only/admin-only sounds. These either clash hard with the audio design of the above sounds, or have some other form of audio design issue, but aren't *too* awful as a sometimes thing. +// Rule of fun very much applies to this section. Audio design is extremely important for the above section, but down here? No gods, no masters, pure anarchy. +// The min/max variables simply don't apply to these, as only chargen cares about them. As such, there's no need to define those. + +/datum/bark/bikehorn + name = "Bikehorn" + id = "horn" + soundpath = 'sound/instruments/bikehorn/Cn4.ogg' + ignore = TRUE // This is an unusually quiet sound. + +/datum/bark/bwoink + name = "Bwoink" + id = "bwoink" + soundpath = 'sound/effects/adminhelp.ogg' + ignore = TRUE // Emergent heart attack generation + +/datum/bark/merp + name = "Merp" + id = "merp" + soundpath = 'modular_citadel/sound/voice/merp.ogg' + ignore = TRUE + +/datum/bark/bark + name = "Bark" + id = "bark" + soundpath = 'modular_citadel/sound/voice/bark1.ogg' + ignore = TRUE + +/datum/bark/nya + name = "Nya" + id = "nya" + soundpath = 'modular_citadel/sound/voice/nya.ogg' + ignore = TRUE + +/datum/bark/moff + name = "Moff" + id = "moff" + soundpath = 'modular_citadel/sound/voice/mothsqueak.ogg' + ignore = TRUE + +/datum/bark/weh + name = "Weh" + id = "weh" + soundpath = 'modular_citadel/sound/voice/weh.ogg' + ignore = TRUE + +/datum/bark/honk + name = "Annoying Honk" + id = "honk" + soundpath = 'sound/creatures/goose1.ogg' + ignore = TRUE diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm index 6b84e1362d..44a1a76b08 100644 --- a/code/datums/brain_damage/split_personality.dm +++ b/code/datums/brain_damage/split_personality.dm @@ -123,7 +123,7 @@ trauma = _trauma return ..() -/mob/living/split_personality/BiologicalLife(seconds, times_fired) +/mob/living/split_personality/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(QDELETED(body)) diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index a3a9ed5898..e4648233de 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -164,6 +164,7 @@ message.maptext_height = mheight message.maptext_x = (CHAT_MESSAGE_WIDTH - owner.bound_width) * -0.5 message.maptext = MAPTEXT(complete_text) + message.pixel_x = -owner.pixel_x //Dogborgs and other wide boys have a pixel offset. This accounts for that // View the message LAZYADDASSOC(owned_by.seen_messages, message_loc, src) @@ -174,10 +175,6 @@ scheduled_destruction = world.time + (lifespan - CHAT_MESSAGE_EOL_FADE) enter_subsystem() - var/mob/living/silicon/robot/R = target - if(iscyborg(R)) - if((R.module.dogborg == TRUE || R.dogborg == TRUE) && isturf(R.loc)) //I hate whoever that thought that putting two types of dogborg that don't even sync up properly was good - message.pixel_x = 16 /** * Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion diff --git a/code/datums/components/bouncy.dm b/code/datums/components/bouncy.dm index fed603410e..3c4e228b59 100644 --- a/code/datums/components/bouncy.dm +++ b/code/datums/components/bouncy.dm @@ -32,7 +32,7 @@ var/atom/movable/A = parent switch(rand(1, 3)) if(1) - A.do_jiggle(45 + rand(-10, 10) * bouncy_mod, 14) + A.do_jiggle(25 + rand(-5, 5) * bouncy_mod, 14) if(2) var/min_b = 0.6/bouncy_mod var/max_b = 1.2 * bouncy_mod diff --git a/code/datums/components/crafting/glassware/glassware.dm b/code/datums/components/crafting/glassware/glassware.dm index 50137733ee..f37efedc8a 100644 --- a/code/datums/components/crafting/glassware/glassware.dm +++ b/code/datums/components/crafting/glassware/glassware.dm @@ -39,7 +39,7 @@ name = "tea cup" desc = "A glass cup made for sipping tea!" icon = 'icons/obj/glass_ware.dmi' - icon_state = "tea_plate" + icon_state = "tea_cup" //////////////////////Chem Disk///////////////////// //Two Steps // @@ -145,7 +145,7 @@ qdel(src) /obj/item/glasswork/glass_base/glass_lens_part5 - name = "unpolished glass lens" + name = "unpolished glass (lens)" desc = "An unpolished glass lens. It needs to be polished with some dry cloth." icon = 'icons/obj/glass_ware.dmi' icon_state = "glass_optics" @@ -159,7 +159,7 @@ qdel(src) /obj/item/glasswork/glass_base/glass_lens_part6 - name = "unrefined glass lens" + name = "unrefined glass (lens)" desc = "A polished glass lens. It needs to be refined with some sandstone." icon = 'icons/obj/glass_ware.dmi' icon_state = "glass_optics" @@ -179,7 +179,7 @@ /obj/item/glasswork/glass_base/spouty name = "Glass fodder sheet (spout)" - desc = "A set of glass sheets set aside for glass working. This one is ideal for a spouty flask. It needs to heated with something very hot." + desc = "A set of glass sheets set aside for glass working. This one is ideal for a spouty flask. It needs to be cut with some glassworking tools." next_step = /obj/item/glasswork/glass_base/spouty_part2 /obj/item/glasswork/glass_base/spouty/attackby(obj/item/I, mob/user, params) @@ -413,7 +413,7 @@ qdel(src) qdel(I) -/obj/item/glasswork/glass_base/tea_cupe2 +/obj/item/glasswork/glass_base/tea_cup2 name = "glassblowing rod (tea cup)" desc = "A hollow metal rod made for blowing glass. There is a blob of shapen glass at the end of it that needs to be cut off with some glassworking tools." icon_state = "blowing_rods_inuse" @@ -433,7 +433,7 @@ icon_state = "glass_base_half" next_step = /obj/item/glasswork/glass_base/tea_cup4 -/obj/item/glasswork/glass_base/cup3/attackby(obj/item/I, mob/user, params) +/obj/item/glasswork/glass_base/tea_cup3/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/stack/sheet/cloth)) if(do_after(user,10, target = src)) @@ -446,7 +446,7 @@ icon_state = "glass_base_half" next_step = /obj/item/tea_cup -/obj/item/glasswork/glass_base/cup4/attackby(obj/item/I, mob/user, params) +/obj/item/glasswork/glass_base/tea_cup4/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/stack/sheet/glass)) if(do_after(user,10, target = src)) diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index 1535c3f142..9bdb009962 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -346,9 +346,9 @@ /datum/component/embedded/proc/examineTurf(datum/source, mob/user, list/examine_list) if(harmful) - examine_list += "\t There is \a [weapon] embedded in [parent]!" + examine_list += "There is \a [weapon] embedded in [parent]!" else - examine_list += "\t There is \a [weapon] stuck to [parent]!" + examine_list += "There is \a [weapon] stuck to [parent]!" /// Someone is ripping out the item from the turf by hand diff --git a/code/datums/components/identification.dm b/code/datums/components/identification.dm index 59b98b57ac..cd47cfcbeb 100644 --- a/code/datums/components/identification.dm +++ b/code/datums/components/identification.dm @@ -61,7 +61,7 @@ if(identification_method_flags & ID_COMPONENT_EFFECT_NO_ACTIONS) return COMPONENT_NO_GRANT_ACTIONS -/datum/component/identification/proc/check_knowledge(mob/user) +/datum/component/identification/proc/check_knowledge(datum/source, mob/user) return ID_COMPONENT_KNOWLEDGE_NONE /datum/component/identification/proc/on_identify(mob/user) @@ -83,7 +83,7 @@ */ /datum/component/identification/syndicate -/datum/component/identification/syndicate/check_knowledge(mob/user) +/datum/component/identification/syndicate/check_knowledge(datum/source, mob/user) . = ..() if(user?.mind?.has_antag_datum(/datum/antagonist/traitor)) . = max(., ID_COMPONENT_KNOWLEDGE_FULL) diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index e100326f7b..d5b988d983 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -50,7 +50,7 @@ STOP_PROCESSING(SSobj, src) /datum/component/mood/proc/print_mood(mob/user) - var/msg = "*---------*\nYour current mood\n" + var/msg = "
Your current mood\n" msg += "My mental status: " //Long term switch(sanity) if(SANITY_GREAT to INFINITY) @@ -69,23 +69,23 @@ msg += "My current mood: " //Short term switch(mood_level) if(1) - msg += "I wish I was dead!\n" + msg += "I wish I was dead!\n" if(2) - msg += "I feel terrible...\n" + msg += "I feel terrible...\n" if(3) - msg += "I feel very upset.\n" + msg += "I feel very upset.\n" if(4) - msg += "I'm a bit sad.\n" + msg += "I'm a bit sad.\n" if(5) - msg += "I'm alright.\n" + msg += "I'm alright.\n" if(6) - msg += "I feel pretty okay.\n" + msg += "I feel pretty okay.\n" if(7) - msg += "I feel pretty good.\n" + msg += "I feel pretty good.\n" if(8) - msg += "I feel amazing!\n" + msg += "I feel amazing!\n" if(9) - msg += "I love life!\n" + msg += "I love life!\n" msg += "Moodlets:\n"//All moodlets if(mood_events.len) @@ -93,7 +93,8 @@ var/datum/mood_event/event = mood_events[i] msg += event.description else - msg += "I don't have much of a reaction to anything right now.\n" + msg += "I don't have much of a reaction to anything right now.\n" + msg += "
" to_chat(user || parent, msg) ///Called after moodevent/s have been added/removed. diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 00a58a75f8..c0101140d6 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -431,25 +431,26 @@ if(M.incapacitated() || !M.canUseStorage()) return var/atom/A = parent - A.add_fingerprint(M) // this must come before the screen objects only block, dunno why it wasn't before if(over_object == M) user_show_to_mob(M, trigger_on_found = TRUE) if(isrevenant(M)) INVOKE_ASYNC(GLOBAL_PROC, .proc/RevenantThrow, over_object, M, source) return + if(check_locked(null, M) || !M.CanReach(A) || (!M.CanReach(over_object) && !istype(over_object, /atom/movable/screen))) + return + playsound(A, "rustle", 50, TRUE, -5) + A.do_jiggle() + A.add_fingerprint(M) if(!istype(over_object, /atom/movable/screen)) INVOKE_ASYNC(src, .proc/dump_content_at, over_object, M) return if(A.loc != M) return - playsound(A, "rustle", 50, TRUE, -5) - A.do_jiggle() if(istype(over_object, /atom/movable/screen/inventory/hand)) var/atom/movable/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(A, H.held_index) return - A.add_fingerprint(M) /datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, trigger_on_found = FALSE) var/atom/A = parent diff --git a/code/datums/components/storage/ui.dm b/code/datums/components/storage/ui.dm index 820d7067d4..d41d82ae75 100644 --- a/code/datums/components/storage/ui.dm +++ b/code/datums/components/storage/ui.dm @@ -63,6 +63,8 @@ if(QDELETED(O)) continue var/atom/movable/screen/storage/item_holder/D = new(null, src, O) + // SNOWFLAKE: make O opaque too, pending storage rewrite + O.mouse_opacity = MOUSE_OPACITY_OPAQUE D.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" D.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]" O.maptext = "" @@ -138,6 +140,8 @@ I = i var/percent = percentage_by_item[I] var/atom/movable/screen/storage/volumetric_box/center/B = new /atom/movable/screen/storage/volumetric_box/center(null, src, I) + // SNOWFLAKE: force it to icon until we unfuck storage/click passing + I.mouse_opacity = MOUSE_OPACITY_ICON var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM) var/addrow = FALSE if(CEILING(pixels_to_use, 1) >= FLOOR(horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING, 1)) diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm index 56e06e3582..c0e6e9dba6 100644 --- a/code/datums/components/virtual_reality.dm +++ b/code/datums/components/virtual_reality.dm @@ -84,9 +84,9 @@ if(VR) VR.level_below = src level_above = VR - M.transfer_ckey(vr_M, FALSE) mastermind = M.mind mastermind.current.audiovisual_redirect = parent + M.transfer_ckey(vr_M, FALSE) RegisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER, .proc/switch_player) RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over) RegisterSignal(M, COMSIG_MOB_PRE_PLAYER_CHANGE, .proc/player_hijacked) diff --git a/code/datums/diseases/parrotpossession.dm b/code/datums/diseases/parrotpossession.dm index 1a3346d565..2fb3a36459 100644 --- a/code/datums/diseases/parrotpossession.dm +++ b/code/datums/diseases/parrotpossession.dm @@ -13,7 +13,7 @@ severity = DISEASE_SEVERITY_MEDIUM infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC|MOB_MINERAL bypasses_immunity = TRUE //2spook - var/mob/living/simple_animal/parrot/Poly/ghost/parrot + var/mob/living/simple_animal/parrot/Polly/ghost/parrot /datum/disease/parrot_possession/stage_act() ..() diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 43dad6cef8..5619a09f05 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -77,6 +77,7 @@ new_dna.species = new species.type new_dna.species.say_mod = species.say_mod new_dna.species.exotic_blood_color = species.exotic_blood_color //it can change from the default value + new_dna.species.exotic_blood_blend_mode = species.exotic_blood_blend_mode new_dna.species.eye_type = species.eye_type new_dna.species.limbs_id = species.limbs_id || species.id new_dna.real_name = real_name @@ -137,9 +138,9 @@ L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len) L[DNA_LEFT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.left_eye_color) L[DNA_RIGHT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.right_eye_color) - L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"], 6) - L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"], 6) - L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"], 6) + L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"]) + L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"]) + L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"]) if(!GLOB.mam_tails_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/mam_tails, GLOB.mam_tails_list) L[DNA_MUTANTTAIL_BLOCK] = construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) @@ -152,6 +153,10 @@ if(!GLOB.taur_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) L[DNA_TAUR_BLOCK] = construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) + L[DNA_BARK_SOUND_BLOCK] = construct_block(GLOB.bark_list.Find(H.vocal_bark_id), GLOB.bark_list.len) + L[DNA_BARK_SPEED_BLOCK] = construct_block(H.vocal_speed * 4, 16) + L[DNA_BARK_PITCH_BLOCK] = construct_block(H.vocal_pitch * 30, 48) + L[DNA_BARK_VARIANCE_BLOCK] = construct_block(H.vocal_pitch_range * 48, 48) for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) if(L[i]) @@ -247,19 +252,19 @@ if(DNA_HAIR_STYLE_BLOCK) setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len)) if(DNA_COLOR_ONE_BLOCK) - sanitize_hexcolor(features["mcolor"], 6) + setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor"])) if(DNA_COLOR_TWO_BLOCK) - sanitize_hexcolor(features["mcolor2"], 6) + setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor2"])) if(DNA_COLOR_THREE_BLOCK) - sanitize_hexcolor(features["mcolor3"], 6) + setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor3"])) if(DNA_MUTANTTAIL_BLOCK) - construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) + setblock(uni_identity, blocknumber, construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len)) if(DNA_MUTANTEAR_BLOCK) - construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len) + setblock(uni_identity, blocknumber, construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len)) if(DNA_MUTANTMARKING_BLOCK) - construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len) + setblock(uni_identity, blocknumber, construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len)) if(DNA_TAUR_BLOCK) - construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) + setblock(uni_identity, blocknumber, construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len)) if(species.mutant_bodyparts["taur"] && ishuman(holder)) var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]] switch(T?.taur_mode) @@ -271,6 +276,14 @@ H.physiology.footstep_type = FOOTSTEP_MOB_CRAWL else H.physiology.footstep_type = null + if(DNA_BARK_SOUND_BLOCK) + setblock(uni_identity, blocknumber, construct_block(GLOB.bark_list.Find(H.vocal_bark_id), GLOB.bark_list.len)) + if(DNA_BARK_SPEED_BLOCK) + setblock(uni_identity, blocknumber, construct_block(H.vocal_speed * 4, 16)) + if(DNA_BARK_PITCH_BLOCK) + setblock(uni_identity, blocknumber, construct_block(H.vocal_pitch * 30, 48)) + if(DNA_BARK_VARIANCE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(H.vocal_pitch_range * 48, 48)) //Please use add_mutation or activate_mutation instead /datum/dna/proc/force_give(datum/mutation/human/HM) @@ -490,6 +503,10 @@ update_body_parts() if(mutations_overlay_update) update_mutations_overlay() + set_bark(GLOB.bark_list[deconstruct_block(getblock(structure, DNA_BARK_SOUND_BLOCK), GLOB.bark_list.len)]) + vocal_speed = (deconstruct_block(getblock(structure, DNA_BARK_SPEED_BLOCK), 16) / 4) + vocal_pitch = (deconstruct_block(getblock(structure, DNA_BARK_PITCH_BLOCK), 48) / 30) + vocal_pitch_range = (deconstruct_block(getblock(structure, DNA_BARK_VARIANCE_BLOCK), 48) / 48) /mob/proc/domutcheck() diff --git a/code/datums/elements/flavor_text.dm b/code/datums/elements/flavor_text.dm index 6217665157..b61bacbd19 100644 --- a/code/datums/elements/flavor_text.dm +++ b/code/datums/elements/flavor_text.dm @@ -76,10 +76,10 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code if(examine_full_view) examine_list += "[msg]" return - if(length_char(msg) <= 40) + if(length_char(msg) <= MAX_FLAVOR_PREVIEW_LEN) examine_list += "[msg]" else - examine_list += "[copytext_char(msg, 1, 37)]... More..." + examine_list += "[copytext_char(msg, 1, (MAX_FLAVOR_PREVIEW_LEN - 3))]... More..." /datum/element/flavor_text/Topic(href, href_list) . = ..() @@ -199,7 +199,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code if(ismob(target)) add_verb(target, /mob/proc/set_pose) -/datum/element/flavor_Text/carbon/temporary/Detach(datum/source, force) +/datum/element/flavor_text/carbon/temporary/Detach(datum/source, force) . = ..() if(ismob(source)) remove_verb(source, /mob/proc/set_pose) diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm index e67120f254..85fea3533e 100644 --- a/code/datums/elements/strippable.dm +++ b/code/datums/elements/strippable.dm @@ -136,13 +136,19 @@ if (isnull(item)) return FALSE - source.visible_message( - span_warning("[user] tries to remove [source]'s [item.name]."), - span_userdanger("[user] tries to remove your [item.name]."), - ignored_mobs = user, - ) + var/strip_silence + var/obj/item/clothing/gloves/gloves = user.get_item_by_slot(ITEM_SLOT_GLOVES) + if(istype(gloves)) + strip_silence = gloves.strip_silence - to_chat(user, span_danger("You try to remove [source]'s [item]...")) + if(!strip_silence) + source.visible_message( + span_warning("[user] tries to remove [source]'s [item.name]."), + span_userdanger("[user] tries to remove your [item.name]."), + ignored_mobs = user, + ) + + to_chat(user, strip_silence ? span_danger("You try to remove [source]'s [item]...") : span_notice("You try to remove [source]'s [item]...")) user.log_message("[key_name(source)] is being stripped of [item] by [key_name(user)]", LOG_ATTACK, color="red") source.log_message("[key_name(source)] is being stripped of [item] by [key_name(user)]", LOG_VICTIM, color="red", log_globally=FALSE) item.add_fingerprint(source) @@ -284,7 +290,12 @@ /// A utility function for `/datum/strippable_item`s to start unequipping an item from a mob. /proc/start_unequip_mob(obj/item/item, mob/source, mob/user, strip_delay) - if (!do_mob(user, source, strip_delay || item.strip_delay, ignorehelditem = TRUE)) + var/strip_mod = 1 + var/obj/item/clothing/gloves/gloves = user.get_item_by_slot(ITEM_SLOT_GLOVES) + if(istype(gloves)) + strip_mod = gloves.strip_mod + + if (!do_mob(user, source, (strip_delay || item.strip_delay) / strip_mod, ignorehelditem = TRUE)) return FALSE return TRUE diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm index 968809747b..b04f55ef0e 100644 --- a/code/datums/mutable_appearance.dm +++ b/code/datums/mutable_appearance.dm @@ -10,7 +10,7 @@ // And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var // Helper similar to image() -/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, color = "#FFFFFF") +/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, color = "#FFFFFF", blend_mode = BLEND_DEFAULT) var/mutable_appearance/MA = new() MA.icon = icon MA.icon_state = icon_state @@ -19,5 +19,6 @@ MA.alpha = alpha MA.appearance_flags |= appearance_flags MA.color = color + MA.blend_mode = blend_mode return MA diff --git a/code/datums/saymode.dm b/code/datums/saymode.dm index 3b6fae5aee..bd0537bac7 100644 --- a/code/datums/saymode.dm +++ b/code/datums/saymode.dm @@ -120,6 +120,17 @@ return FALSE return TRUE +/datum/saymode/statusdisplay + key = "q" + mode = MODE_STATUSDISPLAY + +/datum/saymode/statusdisplay/handle_message(mob/living/user, message, datum/language/language) + if(isAI(user)) + var/mob/living/silicon/ai/AI = user + AI.statusdisplay_talk(message, language) + return FALSE + return TRUE + /datum/saymode/monkey key = "k" mode = MODE_MONKEY diff --git a/code/datums/traits/_quirk.dm b/code/datums/traits/_quirk.dm index 99fa6e73c5..ce1796346a 100644 --- a/code/datums/traits/_quirk.dm +++ b/code/datums/traits/_quirk.dm @@ -14,6 +14,7 @@ /// should we immediately call on_spawn or add a timer to trigger var/on_spawn_immediate = TRUE var/mob/living/quirk_holder + var/processing_quirk = FALSE /datum/quirk/New(mob/living/quirk_mob, spawn_effects) if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type)) @@ -25,7 +26,8 @@ quirk_holder.roundstart_quirks += src if(mob_trait) ADD_TRAIT(quirk_holder, mob_trait, ROUNDSTART_TRAIT) - START_PROCESSING(SSquirks, src) + if(processing_quirk) + START_PROCESSING(SSquirks, src) add() if(spawn_effects) if(on_spawn_immediate) @@ -35,7 +37,8 @@ addtimer(CALLBACK(src, .proc/post_add), 30) /datum/quirk/Destroy() - STOP_PROCESSING(SSquirks, src) + if(processing_quirk) + STOP_PROCESSING(SSquirks, src) remove() if(quirk_holder) to_chat(quirk_holder, lose_text) diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index a0f62a32b8..3bcca275a5 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -72,6 +72,7 @@ mob_trait = TRAIT_JOLLY mood_quirk = TRUE medical_record_text = "Patient demonstrates constant euthymia irregular for environment. It's a bit much, to be honest." + processing_quirk = TRUE /datum/quirk/jolly/on_process() if(prob(0.05)) diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index 8958226ff4..8d3acf0f6d 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -25,6 +25,7 @@ lose_text = "You no longer feel depressed." //if only it were that easy! medical_record_text = "Patient has a severe mood disorder, causing them to experience acute episodes of depression." mood_quirk = TRUE + processing_quirk = TRUE /datum/quirk/depression/on_process() if(prob(0.05)) @@ -38,6 +39,7 @@ medical_record_text = "Patient demonstrates an unnatural attachment to a family heirloom." var/obj/item/heirloom var/where + processing_quirk = TRUE GLOBAL_LIST_EMPTY(family_heirlooms) @@ -102,6 +104,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms) gain_text = "You feel smooth." lose_text = "You feel wrinkled again." medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death." + processing_quirk = TRUE /datum/quirk/brainproblems/on_process() quirk_holder.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2) @@ -129,25 +132,38 @@ GLOBAL_LIST_EMPTY(family_heirlooms) value = -1 medical_record_text = "Patient demonstrates a fear of the dark. (Seriously?)" -/datum/quirk/nyctophobia/on_process() - var/mob/living/carbon/human/H = quirk_holder - if(H.dna.species.id in list("shadow", "nightmare")) - return //we're tied with the dark, so we don't get scared of it; don't cleanse outright to avoid cheese - var/turf/T = get_turf(quirk_holder) - var/lums = T.get_lumcount() - if(lums <= 0.2) - if(quirk_holder.m_intent == MOVE_INTENT_RUN) - addtimer(CALLBACK(src, .proc/recheck),2) //0.2 seconds of being in the dark - SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia) - else - SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia") +/datum/quirk/nyctophobia/add() + RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved) -/datum/quirk/nyctophobia/proc/recheck() - var/turf/T = get_turf(quirk_holder) - var/lums = T.get_lumcount() - if(lums <= 0.2) //check again, did they remain in the dark for 0.2 seconds? - to_chat(quirk_holder, "Easy, easy, take it slow... you're in the dark...") +/datum/quirk/nyctophobia/remove() + UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED) + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia") + +/// Called when the quirk holder moves. Updates the quirk holder's mood. +/datum/quirk/nyctophobia/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced) + if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious()) + return + + var/mob/living/carbon/human/human_holder = quirk_holder + + if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE)) + return + + if((human_holder.sight & SEE_TURFS) == SEE_TURFS) + return + + var/turf/holder_turf = get_turf(quirk_holder) + + var/lums = holder_turf.get_lumcount() + + if(lums > 0.2) + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia") + return + + if(quirk_holder.m_intent == MOVE_INTENT_RUN) + to_chat(quirk_holder, span_warning("Easy, easy, take it slow... you're in the dark...")) quirk_holder.toggle_move_intent() + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia) /datum/quirk/lightless name = "Light Sensitivity" @@ -157,6 +173,36 @@ GLOBAL_LIST_EMPTY(family_heirlooms) lose_text = "Enlightening." medical_record_text = "Despite my warnings, the patient refuses turn on the lights, only to end up rolling down a full flight of stairs and into the cellar." +/datum/quirk/lightless/add() + RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved) + +/datum/quirk/lightless/remove() + UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED) + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "brightlight") + +/datum/quirk/lightless/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced) + if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious()) + return + + var/mob/living/carbon/human/human_holder = quirk_holder + + if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE)) + return + + if((human_holder.sight & SEE_TURFS) == SEE_TURFS) + return + + var/turf/holder_turf = get_turf(quirk_holder) + + var/lums = holder_turf.get_lumcount() + + if(lums < 0.8) + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "brightlight") + return + + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "brightlight", /datum/mood_event/brightlight) + + /datum/quirk/lightless/on_process() var/turf/T = get_turf(quirk_holder) var/lums = T.get_lumcount() @@ -236,6 +282,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms) gain_text = "..." lose_text = "You feel in tune with the world again." medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations." + processing_quirk = TRUE /datum/quirk/insanity/on_process() if(quirk_holder.reagents.has_reagent(/datum/reagent/toxin/mindbreaker)) @@ -261,6 +308,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms) lose_text = "You feel easier about talking again." //if only it were that easy! medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them." var/dumb_thing = TRUE + processing_quirk = TRUE /datum/quirk/social_anxiety/add() RegisterSignal(quirk_holder, COMSIG_MOB_EYECONTACT, .proc/eye_contact) @@ -425,3 +473,21 @@ GLOBAL_LIST_EMPTY(family_heirlooms) gain_text = "You can't smell anything!" lose_text = "You can smell again!" medical_record_text = "Patient suffers from anosmia and is incapable of smelling gases or particulates." + +/datum/quirk/paper_skin + name = "Paper Skin" + desc = "Your flesh is weaker, resulting in receiving cuts more easily." + value = -1 + mob_trait = TRAIT_PAPER_SKIN + gain_text = "Your flesh feels weak!" + lose_text = "Your flesh feels more durable!" + medical_record_text = "Patient suffers from weak flesh, resulting in them receiving cuts far more easily." + +/datum/quirk/glass_bones + name = "Glass Bones" + desc = "Your bones are far more brittle, and more vulnerable to breakage." + value = -1 + mob_trait = TRAIT_GLASS_BONES + gain_text = "Your bones feels weak!" + lose_text = "Your bones feels more durable!" + medical_record_text = "Patient suffers from brittle bones, resulting in them receiving breakages far more easily." diff --git a/code/datums/wounds/_scars.dm b/code/datums/wounds/_scars.dm index 3365fc359d..3fb6546edb 100644 --- a/code/datums/wounds/_scars.dm +++ b/code/datums/wounds/_scars.dm @@ -118,7 +118,7 @@ if(WOUND_SEVERITY_LOSS) msg = "[victim.p_their(TRUE)] [limb.name] [description]." // different format msg = "[msg]" - return "\t[msg]" + return "[msg]" /// Whether a scar can currently be seen by the viewer /datum/scar/proc/is_visible(mob/viewer) diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index f3e22807cf..c16be6005a 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -167,7 +167,7 @@ if(WOUND_INFECTION_SEPTIC to INFINITY) . += "Infection Level: LOSS IMMINENT\n" if(infestation > sanitization) - . += "\tSurgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n" + . += "Surgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n" if(flesh_damage > 0) . += "Flesh damage detected: Please apply ointment or regenerative mesh to allow recovery.\n" diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index a5b9dd2fc7..b09731ab62 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -212,6 +212,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED // airlock_wires = /datum/wires/airlock/maint sound_environment = SOUND_AREA_TUNNEL_ENCLOSED + minimap_color = "#454545" //Maintenance - Departmental @@ -435,6 +436,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway nightshift_public_area = NIGHTSHIFT_AREA_PUBLIC sound_environment = SOUND_AREA_STANDARD_STATION + minimap_color = "#aaaaaa" /area/hallway/primary name = "Primary Hallway" @@ -490,6 +492,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway/secondary/exit name = "Escape Shuttle Hallway" icon_state = "escape" + minimap_color = "#baa0a0" /area/hallway/secondary/exit/departure_lounge name = "Departure Lounge" @@ -498,6 +501,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway/secondary/entry name = "Arrival Shuttle Hallway" icon_state = "entry" + minimap_color = "#a0a0ba" /area/hallway/secondary/service name = "Service Hallway" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 44916cf1d2..24b49a3af7 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -124,6 +124,10 @@ /// Color on minimaps, if it's null (which is default) it makes one at random. var/minimap_color + var/minimap_color2 // if this isn't null, then this will show as a checkerboard pattern mixed in with the above. works even if the above is null (for better or worse) + + var/minimap_show_walls = TRUE + /** * These two vars allow for multiple unique areas to be linked to a master area * and share some functionalities such as APC powernet nodes, fire alarms etc, without sacrificing diff --git a/code/game/area/areas/ruins/_ruins.dm b/code/game/area/areas/ruins/_ruins.dm index 6699e94129..f9af5c8ce4 100644 --- a/code/game/area/areas/ruins/_ruins.dm +++ b/code/game/area/areas/ruins/_ruins.dm @@ -9,6 +9,9 @@ ambientsounds = RUINS sound_environment = SOUND_ENVIRONMENT_STONEROOM var/valid_territory = FALSE // hey so what if we did not allow things like cult summons to appear on ruins + minimap_color = "#775940" + minimap_color2 = "#6b5d48" + minimap_show_walls = FALSE /area/ruin/unpowered diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 242f3123e1..6bb6b444b0 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -518,7 +518,7 @@ . = list("[get_examine_string(user, TRUE)].") if(desc) - . += desc + . += "
[desc]" if(custom_materials) var/list/materials_list = list() @@ -702,7 +702,7 @@ var/blood_id = get_blood_id() if(!(blood_id in GLOB.blood_reagent_types)) return - return list("color" = BLOOD_COLOR_HUMAN, "ANIMAL DNA" = "Y-") + return list("color" = BLOOD_COLOR_HUMAN, "blendmode" = BLEND_MULTIPLY, "ANIMAL DNA" = "Y-") /mob/living/carbon/get_blood_dna_list() var/blood_id = get_blood_id() @@ -711,14 +711,16 @@ var/list/blood_dna = list() if(dna) blood_dna["color"] = dna.species.exotic_blood_color //so when combined, the list grows with the number of colors + blood_dna["blendmode"] = dna.species.exotic_blood_blend_mode blood_dna[dna.unique_enzymes] = dna.blood_type else blood_dna["color"] = BLOOD_COLOR_HUMAN + blood_dna["blendmode"] = BLEND_MULTIPLY blood_dna["UNKNOWN DNA"] = "X*" return blood_dna /mob/living/carbon/alien/get_blood_dna_list() - return list("color" = BLOOD_COLOR_XENO, "UNKNOWN DNA" = "X*") + return list("color" = BLOOD_COLOR_XENO, "blendmode" = BLEND_MULTIPLY, "UNKNOWN DNA" = "X*") //to add a mob's dna info into an object's blood_DNA list. /atom/proc/transfer_mob_blood_dna(mob/living/L) @@ -737,6 +739,7 @@ var/old = blood_DNA["color"] blood_DNA["color"] = BlendRGB(blood_DNA["color"], new_blood_dna["color"]) changed = old != blood_DNA["color"] + blood_DNA["blendmode"] = new_blood_dna["blendmode"] if(blood_DNA.len == old_length) return FALSE return changed @@ -756,6 +759,7 @@ blood_DNA["color"] = blood_dna["color"] else blood_DNA["color"] = BlendRGB(blood_DNA["color"], blood_dna["color"]) + blood_DNA["blendmode"] = blood_dna["blendmode"] //to add blood from a mob onto something, and transfer their dna info /atom/proc/add_mob_blood(mob/living/M) @@ -826,6 +830,11 @@ /atom/proc/blood_DNA_to_color() return (blood_DNA && blood_DNA["color"]) || BLOOD_COLOR_HUMAN +/atom/proc/blood_DNA_to_blend() + if(blood_DNA && !isnull(blood_DNA["blendmode"])) + return blood_DNA["blendmode"] + return BLEND_MULTIPLY + /atom/proc/clean_blood() . = blood_DNA? TRUE : FALSE blood_DNA = null @@ -1192,6 +1201,8 @@ log_mecha(log_text) if(LOG_SHUTTLE) log_shuttle(log_text) + if(LOG_ECON) + log_econ(log_text) else stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).") log_game(log_text) @@ -1295,7 +1306,7 @@ filters += filter(arglist(arguments)) UNSETEMPTY(filter_data) -/atom/proc/transition_filter(name, time, list/new_params, easing, loop) +/atom/proc/transition_filter(name, time, list/new_params, easing, loop, parallel = TRUE) var/filter = get_filter(name) if(!filter) return @@ -1306,7 +1317,7 @@ for(var/thing in new_params) params[thing] = new_params[thing] - animate(filter, new_params, time = time, easing = easing, loop = loop) + animate(filter, new_params, time = time, easing = easing, loop = loop, flags = (parallel ? ANIMATION_PARALLEL : 0)) for(var/param in params) filter_data[name][param] = params[param] diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 56c668a24b..bace332ef2 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -64,6 +64,16 @@ /// last time we yelled var/last_yell = 0 + // Text-to-bark sounds + var/sound/vocal_bark + var/vocal_bark_id + var/vocal_pitch = 1 + var/vocal_pitch_range = 0.2 //Actual pitch is (pitch - (vocal_pitch_range*0.5)) to (pitch + (vocal_pitch_range*0.5)) + var/vocal_volume = 70 //Baseline. This gets modified by yelling and other factors + var/vocal_speed = 4 //Lower values are faster, higher values are slower + + var/vocal_current_bark //When barks are queued, this gets passed to the bark proc. If vocal_current_bark doesn't match the args passed to the bark proc (if passed at all), then the bark simply doesn't play. Basic curtailing of spam~ + /atom/movable/Initialize(mapload) . = ..() switch(blocks_emissive) @@ -217,6 +227,10 @@ if(NAMEOF(src, glide_size)) set_glide_size(var_value) . = TRUE + if(NAMEOF(src, vocal_bark)) + if(isfile(var_value)) + vocal_bark = sound(var_value) //bark() expects vocal_bark to already be a sound datum, for performance reasons. adminbus QoL! + . = TRUE if(!isnull(.)) datum_flags |= DF_VAR_EDITED @@ -604,11 +618,11 @@ if(throwing && !throw_override) return if(on && !(movement_type & FLOATING)) - animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) - animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) setMovetype(movement_type | FLOATING) else if (!on && (movement_type & FLOATING)) - animate(src, pixel_y = initial(pixel_y), time = 10) + animate(src, pixel_z = initial(pixel_y), time = 10) setMovetype(movement_type & ~FLOATING) floating_need_update = FALSE // assume it's done @@ -696,6 +710,17 @@ var/datum/language_holder/LH = get_language_holder() return LH.update_atom_languages(src) +/// Sets the vocal bark for the atom, using the bark's ID +/atom/movable/proc/set_bark(id) + if(!id) + return FALSE + var/datum/bark/B = GLOB.bark_list[id] + if(!B) + return FALSE + vocal_bark = sound(initial(B.soundpath)) + vocal_bark_id = id + return vocal_bark + /* End language procs */ @@ -774,4 +799,4 @@ M.Turn(pick(-30, 30)) animate(I, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = M, easing = CUBIC_EASING) sleep(1) - animate(I, alpha = 0, transform = matrix(), time = 1) + animate(I, alpha = 0, transform = matrix(), time = 1, flags = ANIMATION_PARALLEL) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index e9a1fb61e0..62b2a6da8d 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -104,6 +104,10 @@ Class Procs: anchored = TRUE interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT + vocal_bark_id = "synth" + vocal_pitch = 0.6 + vocal_volume = 40 + var/stat = 0 var/use_power = IDLE_POWER_USE //0 = dont run the auto @@ -312,6 +316,36 @@ Class Procs: return TRUE // If we passed all of those checks, woohoo! We can interact with this machine. +/obj/machinery/proc/can_transact(obj/item/card/id/thecard, allowdepartment, silent) + if(!istype(thecard)) + if(!silent) + say("No card found.") + return FALSE + else if (!thecard.registered_account) + if(!silent) + say("No account found.") + return FALSE + else if(!allowdepartment && !thecard.registered_account.account_job) + if(!silent) + say("Departmental accounts have been blacklisted from personal expenses due to embezzlement.") + return FALSE + return TRUE + +/obj/machinery/proc/attempt_transact(obj/item/card/id/thecard, transaction_cost) + if(!istype(thecard)) + return FALSE + var/datum/bank_account/account = thecard.registered_account + if(!istype(account)) + return FALSE + + if(transaction_cost) + if(!account.adjust_money(-transaction_cost)) + return FALSE + var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department) + if(D) + D.adjust_money(transaction_cost) + return TRUE + /obj/machinery/proc/check_nap_violations() if(!SSeconomy.full_ancap) return TRUE diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 35f45818b6..4f876b97e1 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -62,14 +62,15 @@ if(!is_operational()) return - if(shocked && !(stat & NOPOWER)) - shock(user,50) - ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "Autolathe", capitalize(src.name)) ui.open() + if(shocked && !(stat & NOPOWER)) + if(shock(user,50)) + ui.close() //close the window if they got zapped successfully as to prevent them from getting zapped infinitely. + /obj/machinery/autolathe/ui_data(mob/user) var/list/data = list() data["materials"] = list() @@ -298,6 +299,16 @@ wires.interact(user) return STOP_ATTACK_PROC_CHAIN +/obj/machinery/autolathe/wirecutter_act(mob/living/user, obj/item/I) + . = ..() + if(busy) + balloon_alert(user, "it's busy!") + return STOP_ATTACK_PROC_CHAIN + + if(panel_open) + wires.interact(user) + return STOP_ATTACK_PROC_CHAIN + /obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted) if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal)) use_power(MINERAL_MATERIAL_AMOUNT / 10) diff --git a/code/game/machinery/colormate.dm b/code/game/machinery/colormate.dm index 1528142a3b..a208fc0bd2 100644 --- a/code/game/machinery/colormate.dm +++ b/code/game/machinery/colormate.dm @@ -1,6 +1,10 @@ +#define COLORMATE_TINT 1 +#define COLORMATE_HSV 2 +#define COLORMATE_MATRIX 3 + /obj/machinery/gear_painter name = "\improper Color Mate" - desc = "A machine to give your apparel a fresh new color! Recommended to use with white items for best results." + desc = "A machine to give your apparel a fresh new color!" icon = 'icons/obj/vending.dmi' icon_state = "colormate" // light_mask = "colormate-light-mask" @@ -10,7 +14,11 @@ var/atom/movable/inserted var/activecolor = "#FFFFFF" var/list/color_matrix_last - var/matrix_mode = FALSE + var/active_mode = COLORMATE_HSV + + var/build_hue = 0 + var/build_sat = 1 + var/build_val = 1 /// Allow holder'd mobs var/allow_mobs = TRUE /// Minimum lightness for normal mode @@ -71,8 +79,8 @@ return if(!QDELETED(H)) H.release() + insert_mob(victim, user) - temp = "[victim] has been inserted." SStgui.update_uis(src) if(is_type_in_list(I, allowed_types) && is_operational()) @@ -85,7 +93,6 @@ inserted = I update_icon() - temp = "[I] has been inserted." SStgui.update_uis(src) else @@ -134,7 +141,7 @@ /obj/machinery/gear_painter/ui_data(mob/user) . = list() - .["matrixactive"] = matrix_mode + .["activemode"] = active_mode .["matrixcolors"] = list( "rr" = color_matrix_last[1], "rg" = color_matrix_last[2], @@ -149,6 +156,9 @@ "cg" = color_matrix_last[11], "cb" = color_matrix_last[12] ) + .["buildhue"] = build_hue + .["buildsat"] = build_sat + .["buildval"] = build_val if(temp) .["temp"] = temp if(inserted) @@ -166,7 +176,7 @@ if(inserted) switch(action) if("switch_modes") - matrix_mode = text2num(params["mode"]) + active_mode = text2num(params["mode"]) return TRUE if("choose_color") var/chosen_color = input(usr, "Choose a color: ", "Colormate color picking", activecolor) as color|null @@ -174,14 +184,11 @@ activecolor = chosen_color return TRUE if("paint") - if(!check_valid_color(activecolor, usr)) - return TRUE - inserted.add_atom_colour(activecolor, FIXED_COLOUR_PRIORITY) - playsound(src, 'sound/effects/spray3.ogg', 50, 1) + do_paint(usr) temp = "Painted Successfully!" return TRUE if("drop") - temp = "Ejected \the [inserted]!" + temp = "" drop_item() return TRUE if("clear") @@ -192,76 +199,95 @@ if("set_matrix_color") color_matrix_last[params["color"]] = params["value"] return TRUE - if("matrix_paint") - var/list/cm = rgb_construct_color_matrix( - text2num(color_matrix_last[1]), - text2num(color_matrix_last[2]), - text2num(color_matrix_last[3]), - text2num(color_matrix_last[4]), - text2num(color_matrix_last[5]), - text2num(color_matrix_last[6]), - text2num(color_matrix_last[7]), - text2num(color_matrix_last[8]), - text2num(color_matrix_last[9]), - text2num(color_matrix_last[10]), - text2num(color_matrix_last[11]), - text2num(color_matrix_last[12]) - ) - if(!check_valid_color(cm, usr)) - return TRUE - inserted.add_atom_colour(cm, FIXED_COLOUR_PRIORITY) - playsound(src, 'sound/effects/spray3.ogg', 50, 1) - temp = "Matrix Painted Successfully!" + if("set_hue") + build_hue = clamp(text2num(params["buildhue"]), 0, 360) return TRUE + if("set_sat") + build_sat = clamp(text2num(params["buildsat"]), -10, 10) + return TRUE + if("set_val") + build_val = clamp(text2num(params["buildval"]), -10, 10) + return TRUE + + +/obj/machinery/gear_painter/proc/do_paint(mob/user) + var/color_to_use + switch(active_mode) + if(COLORMATE_TINT) + color_to_use = activecolor + if(COLORMATE_MATRIX) + color_to_use = rgb_construct_color_matrix( + text2num(color_matrix_last[1]), + text2num(color_matrix_last[2]), + text2num(color_matrix_last[3]), + text2num(color_matrix_last[4]), + text2num(color_matrix_last[5]), + text2num(color_matrix_last[6]), + text2num(color_matrix_last[7]), + text2num(color_matrix_last[8]), + text2num(color_matrix_last[9]), + text2num(color_matrix_last[10]), + text2num(color_matrix_last[11]), + text2num(color_matrix_last[12]) + ) + if(COLORMATE_HSV) + color_to_use = color_matrix_hsv(build_hue, build_sat, build_val) + color_matrix_last = color_to_use + if(!color_to_use || !check_valid_color(color_to_use, user)) + to_chat(user, "Invalid color.") + return FALSE + inserted.add_atom_colour(color_to_use, FIXED_COLOUR_PRIORITY) + playsound(src, 'sound/effects/spray3.ogg', 50, 1) + return TRUE + /// Produces the preview image of the item, used in the UI, the way the color is not stacking is a sin. /obj/machinery/gear_painter/proc/build_preview() if(inserted) //sanity - if(matrix_mode) - var/list/cm = rgb_construct_color_matrix( - text2num(color_matrix_last[1]), - text2num(color_matrix_last[2]), - text2num(color_matrix_last[3]), - text2num(color_matrix_last[4]), - text2num(color_matrix_last[5]), - text2num(color_matrix_last[6]), - text2num(color_matrix_last[7]), - text2num(color_matrix_last[8]), - text2num(color_matrix_last[9]), - text2num(color_matrix_last[10]), - text2num(color_matrix_last[11]), - text2num(color_matrix_last[12]) - ) - if(!check_valid_color(cm, usr)) - temp = "Failed to generate preview: Invalid color!" - return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) + var/list/cm + switch(active_mode) + if(COLORMATE_MATRIX) + cm = rgb_construct_color_matrix( + text2num(color_matrix_last[1]), + text2num(color_matrix_last[2]), + text2num(color_matrix_last[3]), + text2num(color_matrix_last[4]), + text2num(color_matrix_last[5]), + text2num(color_matrix_last[6]), + text2num(color_matrix_last[7]), + text2num(color_matrix_last[8]), + text2num(color_matrix_last[9]), + text2num(color_matrix_last[10]), + text2num(color_matrix_last[11]), + text2num(color_matrix_last[12]) + ) + if(!check_valid_color(cm, usr)) + return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - var/cur_color = inserted.color - inserted.color = null - inserted.color = cm - var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - inserted.color = cur_color + if(COLORMATE_TINT) + if(!check_valid_color(activecolor, usr)) + return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - . = preview + if(COLORMATE_HSV) + cm = color_matrix_hsv(build_hue, build_sat, build_val) + color_matrix_last = cm + if(!check_valid_color(cm, usr)) + return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - else - if(!check_valid_color(activecolor, usr)) - temp = "Failed to generate preview: Invalid color!" - return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) + var/cur_color = inserted.color + inserted.color = null + inserted.color = (active_mode == COLORMATE_TINT ? activecolor : cm) + var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) + inserted.color = cur_color + temp = "" - var/cur_color = inserted.color - inserted.color = null - inserted.color = activecolor - var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - inserted.color = cur_color - - . = preview + . = preview /obj/machinery/gear_painter/proc/check_valid_color(list/cm, mob/user) if(!islist(cm)) // normal var/list/HSV = ReadHSV(RGBtoHSV(cm)) if(HSV[3] < minimum_normal_lightness) - temp = "[cm] is far too dark (min lightness [minimum_normal_lightness]!" + temp = "[cm] is too dark (Minimum lightness: [minimum_normal_lightness])" return FALSE return TRUE else // matrix @@ -275,6 +301,6 @@ COLORTEST("FFFFFF", cm) #undef COLORTEST if(passed < minimum_matrix_tests) - temp = "[english_list(color)] is not allowed (passed [passed] out of 4, minimum [minimum_matrix_tests], minimum lightness [minimum_matrix_lightness])." + temp = "Matrix is too dark. (passed [passed] out of [minimum_matrix_tests] required tests. Minimum lightness: [minimum_matrix_lightness])." return FALSE return TRUE diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index 8b24a3804f..956b3e9c79 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -6,17 +6,22 @@ verb_say = "states" density = TRUE req_one_access = list(ACCESS_BAR, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_ENGINE, ACCESS_CARGO, ACCESS_THEATRE) + payment_department = ACCOUNT_SRV var/active = FALSE var/list/rangers = list() var/stop = 0 var/volume = 70 - var/datum/track/selection = null + var/queuecost = PRICE_CHEAP //Set to -1 to make this jukebox require access for queueing + var/datum/track/playing = null + var/datum/track/selectedtrack = null + var/list/queuedplaylist = list() + var/queuecooldown //This var exists solely to prevent accidental repeats of John Mulaney's 'What's New Pussycat?' incident. Intentional, however...... /obj/machinery/jukebox/disco name = "radiant dance machine mark IV" desc = "The first three prototypes were discontinued after mass casualty incidents." icon_state = "disco" - req_access = list(ACCESS_ENGINE) + req_one_access = list(ACCESS_ENGINE) anchored = FALSE var/list/spotlights = list() var/list/sparkles = list() @@ -24,7 +29,7 @@ /obj/machinery/jukebox/disco/indestructible name = "radiant dance machine mark V" desc = "Now redesigned with data gathered from the extensive disco and plasma research." - req_access = null + req_one_access = null anchored = TRUE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF flags_1 = NODECONSTRUCT_1 @@ -46,6 +51,16 @@ return return ..() +/obj/machinery/jukebox/emag_act(mob/user) + . = ..() + if(obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + queuecost = PRICE_FREE + req_one_access = null + to_chat(user, "You've bypassed [src]'s audio volume limiter, and enabled free play.") + return TRUE + /obj/machinery/jukebox/update_icon_state() if(active) icon_state = "[initial(icon_state)]-active" @@ -56,7 +71,7 @@ if(!anchored) to_chat(user,"This device must be anchored by a wrench!") return UI_CLOSE - if(!allowed(user) && !isobserver(user)) + if((queuecost < 0 && !allowed(user)) && !isobserver(user)) to_chat(user,"Error: Access Denied.") user.playsound_local(src, 'sound/misc/compiler-failure.ogg', 25, TRUE) return UI_CLOSE @@ -77,18 +92,21 @@ data["active"] = active data["songs"] = list() for(var/datum/track/S in SSjukeboxes.songs) - var/list/track_data = list( - name = S.song_name - ) + var/list/track_data = list(name = S.song_name) data["songs"] += list(track_data) + data["queued_tracks"] = list() + for(var/datum/track/S in queuedplaylist) + var/list/track_data = list(name = S.song_name) + data["queued_tracks"] += list(track_data) data["track_selected"] = null data["track_length"] = null - data["track_beat"] = null - if(selection) - data["track_selected"] = selection.song_name - data["track_length"] = DisplayTimeText(selection.song_length) - data["track_beat"] = selection.song_beat + if(playing) + data["track_selected"] = playing.song_name + data["track_length"] = DisplayTimeText(playing.song_length) data["volume"] = volume + data["is_emagged"] = (obj_flags & EMAGGED) + data["cost_for_play"] = queuecost + data["has_access"] = allowed(user) return data /obj/machinery/jukebox/ui_act(action, list/params) @@ -100,57 +118,91 @@ if("toggle") if(QDELETED(src)) return - if(!active) - if(stop > world.time) - to_chat(usr, "Error: The device is still resetting from the last activation, it will be ready again in [DisplayTimeText(stop-world.time)].") - playsound(src, 'sound/misc/compiler-failure.ogg', 50, TRUE) - return + if(!allowed(usr)) + return + if(!active && !playing) activate_music() - START_PROCESSING(SSobj, src) - return TRUE else stop = 0 - return TRUE - if("select_track") - if(active) - to_chat(usr, "Error: You cannot change the song until the current one is over.") + return TRUE + if("add_to_queue") + if(QDELETED(src)) return + if(world.time < queuecooldown) + return + if(!istype(selectedtrack, /datum/track)) + return + if(!allowed(usr) && queuecost) + var/obj/item/card/id/C + if(isliving(usr)) + var/mob/living/L = usr + C = L.get_idcard(TRUE) + if(!can_transact(C)) + queuecooldown = world.time + (1 SECONDS) + playsound(src, 'sound/misc/compiler-failure.ogg', 25, TRUE) + return + if(!attempt_transact(C, queuecost)) + say("Insufficient funds.") + queuecooldown = world.time + (1 SECONDS) + playsound(src, 'sound/misc/compiler-failure.ogg', 25, TRUE) + return + to_chat(usr, "You spend [queuecost] credits to queue [selectedtrack.song_name].") + log_econ("[queuecost] credits were inserted into [src] by [key_name(usr)] (ID: [C.registered_name]) to queue [selectedtrack.song_name].") + queuedplaylist += selectedtrack + if(active) + say("[selectedtrack.song_name] has been added to the queue.") + else if(!playing) + activate_music() + playsound(src, 'sound/machines/ping.ogg', 50, TRUE) + queuecooldown = world.time + (3 SECONDS) + return TRUE + if("select_track") var/list/available = list() for(var/datum/track/S in SSjukeboxes.songs) available[S.song_name] = S var/selected = params["track"] if(QDELETED(src) || !selected || !istype(available[selected], /datum/track)) return - selection = available[selected] + selectedtrack = available[selected] return TRUE if("set_volume") + if(!allowed(usr)) + return var/new_volume = params["volume"] if(new_volume == "reset") volume = initial(volume) - return TRUE else if(new_volume == "min") volume = 0 - return TRUE else if(new_volume == "max") - volume = 100 - return TRUE + volume = ((obj_flags & EMAGGED) ? 210 : 100) else if(text2num(new_volume) != null) - volume = text2num(new_volume) - return TRUE + volume = clamp(0, text2num(new_volume), ((obj_flags & EMAGGED) ? 210 : 100)) + var/wherejuke = SSjukeboxes.findjukeboxindex(src) + if(wherejuke) + SSjukeboxes.updatejukebox(wherejuke, jukefalloff = volume/35) + return TRUE /obj/machinery/jukebox/proc/activate_music() - var/jukeboxslottotake = SSjukeboxes.addjukebox(src, selection, 2) + if(playing || !queuedplaylist.len) + return FALSE + playing = queuedplaylist[1] + var/jukeboxslottotake = SSjukeboxes.addjukebox(src, playing, volume/35) if(jukeboxslottotake) active = TRUE update_icon() START_PROCESSING(SSobj, src) - stop = world.time + selection.song_length + stop = world.time + playing.song_length + queuedplaylist.Cut(1, 2) + say("Now playing: [playing.song_name]") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, TRUE) return TRUE else return FALSE /obj/machinery/jukebox/disco/activate_music() - ..() + . = ..() + if(!.) + return dance_setup() lights_spin() @@ -243,7 +295,7 @@ S.pixel_y = 7 S.forceMove(get_turf(src)) sleep(7) - if(selection.song_name == "Engineering's Ultimate High-Energy Hustle") + if(playing.song_name == "Engineering's Ultimate High-Energy Hustle") sleep(280) for(var/obj/reveal in sparkles) reveal.alpha = 255 @@ -299,7 +351,7 @@ continue if(prob(2)) // Unique effects for the dance floor that show up randomly to mix things up INVOKE_ASYNC(src, .proc/hierofunk) - sleep(selection.song_beat) + sleep(playing.song_beat) #undef DISCO_INFENO_RANGE @@ -431,6 +483,7 @@ return SSjukeboxes.removejukebox(position) STOP_PROCESSING(SSobj, src) + playing = null rangers = list() /obj/machinery/jukebox/disco/dance_over() @@ -439,12 +492,21 @@ QDEL_LIST(sparkles) /obj/machinery/jukebox/process() - if(active && world.time >= stop) - active = FALSE - dance_over() - playsound(src,'sound/machines/terminal_off.ogg',50,1) - update_icon() - stop = world.time + 100 + if(active) + if(world.time >= stop) + active = FALSE + dance_over() + if(stop && queuedplaylist.len) + activate_music() + else + playsound(src,'sound/machines/terminal_off.ogg',50,1) + update_icon() + playing = null + stop = 0 + else if(volume > 140) // BOOM BOOM BOOM BOOM + for(var/mob/living/carbon/C in hearers(round(volume/35), src)) // I WANT YOU IN MY ROOM + if(istype(C)) // LETS SPEND THE NIGHT TOGETHER + C.adjustEarDamage(max((((volume/35) - sqrt(get_dist(C, src) * 4)) - C.get_ear_protection())*0.1, 0)) // FROM NOW UNTIL FOREVER /obj/machinery/jukebox/disco/process() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index ed62019824..84e7b93e1b 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1356,6 +1356,7 @@ /obj/machinery/door/airlock/proc/remove_electrify() secondsElectrified = NOT_ELECTRIFIED unelectrify_timerid = null + diag_hud_set_electrified() /obj/machinery/door/airlock/proc/set_electrified(seconds, mob/user) secondsElectrified = seconds diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 18ed5205be..458f231f4b 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -203,9 +203,13 @@ GLOBAL_LIST_EMPTY(doppler_arrays) point_gain = (BOMB_TARGET_POINTS * 2 * orig_light) / (orig_light + BOMB_TARGET_SIZE) /*****The Point Capper*****/ - if(point_gain > linked_techweb.largest_bomb_value) - var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math - linked_techweb.largest_bomb_value = point_gain + + var/list/largest_values = linked_techweb.largest_values + if(!(LARGEST_BOMB in largest_values)) + largest_values[LARGEST_BOMB] = 0 + if(point_gain > largest_values[LARGEST_BOMB]) + var/old_tech_largest_bomb_value = largest_values[LARGEST_BOMB] //held so we can pull old before we do math + linked_techweb.largest_values[LARGEST_BOMB] = point_gain point_gain -= old_tech_largest_bomb_value var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_SCI) if(D) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index ff6f96a29f..12b2ba08e4 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -230,13 +230,13 @@ if(beaker) if(beaker.reagents && beaker.reagents.reagent_list.len) - . += "\tAttached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.\n" + . += "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.\n" else - . += "\tAttached is an empty [beaker.name].\n" + . += "Attached is an empty [beaker.name].\n" else - . += "\tNo chemicals are attached.\n" + . += "No chemicals are attached.\n" - . += "\t[attached ? attached : "No one"] is attached." + . += "[attached ? attached : "No one"] is attached." /obj/machinery/iv_drip/telescopic name = "telescopic IV drip" diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 4a05885b70..f4a82cb883 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -13,6 +13,17 @@ #define TURRET_FLAG_SHOOT_BORGS (1<<6) // checks if it can shoot cyborgs #define TURRET_FLAG_SHOOT_HEADS (1<<7) // checks if it can shoot at heads of staff +DEFINE_BITFIELD(turret_flags, list( + "TURRET_FLAG_AUTH_WEAPONS" = TURRET_FLAG_AUTH_WEAPONS, + "TURRET_FLAG_SHOOT_ALL" = TURRET_FLAG_SHOOT_ALL, + "TURRET_FLAG_SHOOT_ALL_REACT" = TURRET_FLAG_SHOOT_ALL_REACT, + "TURRET_FLAG_SHOOT_ANOMALOUS" = TURRET_FLAG_SHOOT_ANOMALOUS, + "TURRET_FLAG_SHOOT_BORGS" = TURRET_FLAG_SHOOT_BORGS, + "TURRET_FLAG_SHOOT_CRIMINALS" = TURRET_FLAG_SHOOT_CRIMINALS, + "TURRET_FLAG_SHOOT_HEADS" = TURRET_FLAG_SHOOT_HEADS, + "TURRET_FLAG_SHOOT_UNSHIELDED" = TURRET_FLAG_SHOOT_UNSHIELDED, +)) + /obj/machinery/porta_turret name = "turret" icon = 'icons/obj/turrets.dmi' diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 2438a6b66b..5aaed2a808 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -29,10 +29,12 @@ var/obj/effect/overlay/status_display_text/message1_overlay var/obj/effect/overlay/status_display_text/message2_overlay + var/mutable_appearance/ai_vtuber_overlay var/current_picture = "" var/current_mode = SD_BLANK var/message1 = "" var/message2 = "" + var/mob/living/silicon/ai/master /obj/item/wallframe/status_display name = "status display frame" @@ -122,6 +124,10 @@ if(overlay && message == overlay.message) return null + // if an AI is controlling, we don't update the overlay + if(master) + return + if(overlay) qdel(overlay) @@ -147,6 +153,10 @@ remove_messages() return + if(master) + remove_messages() + return + switch(current_mode) if(SD_BLANK) remove_messages() @@ -493,6 +503,42 @@ user.emote(initial(emote.key)) break +// ai vtuber moment +/obj/machinery/status_display/AICtrlClick(mob/living/silicon/ai/user) + if(!isAI(user) || master || (user.current && !istype(user.current, /obj/machinery/status_display))) // don't let two AIs control the same one, don't let AI control two things at once + return + + if(!user.client.prefs.custom_holoform_icon) + to_chat(user, span_notice("You have no custom holoform set!")) + return + + // move AI to the location, set master, update overlays (removes messages) + user.current = src + user.eyeobj.setLoc(get_turf(src)) + icon_state = initial(icon_state) + user.controlled_display = src + master = user + update_overlays() + update_appearance() + + // we set the avatar here + var/icon/I = icon(user.client.prefs.custom_holoform_icon) + I.Crop(1,16,32,32) + ai_vtuber_overlay = mutable_appearance(I) + ai_vtuber_overlay.blend_mode = BLEND_ADD + ai_vtuber_overlay.pixel_y = 8 + update_overlays() + add_overlay(ai_vtuber_overlay) + + // tell the user how to speak + to_chat(user, span_notice("Use :q to relay messages through the status display.")) + +// modified version of how holopads 'hear' and relay to AIs +/obj/machinery/status_display/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list()) + . = ..() + if(master && !radio_freq && master.controlled_display == src) + master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mods) + /obj/machinery/status_display/ai/process() if(stat & NOPOWER) update_appearance() diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm index 2762416949..f57daac309 100644 --- a/code/game/objects/effects/decals/cleanable/gibs.dm +++ b/code/game/objects/effects/decals/cleanable/gibs.dm @@ -3,6 +3,7 @@ desc = "They look bloody and gruesome." icon_state = "gibbl5" layer = LOW_OBJ_LAYER + blend_mode = BLEND_DEFAULT random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") mergeable_decal = FALSE bloodiness = 0 //This isn't supposed to be bloody. diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index 8aea7047b6..04942a1253 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -3,6 +3,7 @@ desc = "It's gooey. Perhaps it's the chef's cooking?" icon = 'icons/effects/blood.dmi' icon_state = "floor1" + blend_mode = BLEND_MULTIPLY random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7") blood_state = BLOOD_STATE_BLOOD bloodiness = BLOOD_AMOUNT_PER_DECAL @@ -33,16 +34,20 @@ . = ..() if(!fixed_color) add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY) + blend_mode = blood_DNA_to_blend() /obj/effect/decal/cleanable/blood/PersistenceSave(list/data) . = ..() data["color"] = color + data["blendmode"] = blend_mode /obj/effect/decal/cleanable/blood/PersistenceLoad(list/data) . = ..() if(data["color"]) fixed_color = TRUE add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY) + if(data["blendmode"]) + blend_mode = data["blendmode"] name = "dried blood" desc = "Looks like it's been here a while. Eew" bloodiness = 0 @@ -82,8 +87,8 @@ /obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose name = "blood" icon = 'icons/effects/blood.dmi' - icon_state = "ltrails_1" desc = "Your instincts say you shouldn't be following these." + blend_mode = BLEND_MULTIPLY random_icon_states = null beauty = -50 persistent = TRUE @@ -95,6 +100,7 @@ . = ..() data["dir"] = dir data["color"] = color + data["blendmode"] = blend_mode /obj/effect/decal/cleanable/trail_holder/PersistenceLoad(list/data) . = ..() @@ -103,11 +109,14 @@ if(data["color"]) fixed_color = TRUE add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY) + if(data["blendmode"]) + blend_mode = data["blendmode"] /obj/effect/decal/cleanable/trail_holder/update_icon() . = ..() if(!fixed_color) add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY) + blend_mode = blood_DNA_to_blend() /obj/effect/cleanable/trail_holder/Initialize(mapload) . = ..() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index be3f1709a9..0dcc23f3aa 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1,4 +1,5 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire")) +GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, ABOVE_LIGHTING_PLANE)) GLOBAL_VAR_INIT(rpg_loot_items, FALSE) // if true, everyone item when created will have its name changed to be diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index f66a1bea24..f680d0034b 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -601,11 +601,12 @@ H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, 0) else var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss() - var/mobhealth = H.health - H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0) - H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0) - H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0) - H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0) + if(overall_damage) + var/mobhealth = H.health + H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0) + H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0) + H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0) + H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0) H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually. user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.") playsound(src, 'sound/machines/defib_success.ogg', 50, 0) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 0ca2e40b45..69fc53c904 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -145,32 +145,29 @@ GENETICS SCANNER mob_status = "Deceased" oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss - var/msg = "*---------*\nAnalyzing results for [M]:\n\tOverall status: [mob_status]" + var/msg = "Analyzing results for [M]:\n
Overall status: [mob_status]" // Damage descriptions if(brute_loss > 10) - msg += "\n\t[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected." + msg += "\n[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected." if(fire_loss > 10) - msg += "\n\t[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected." + msg += "\n[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected." if(oxy_loss > 10) - msg += "\n\t[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected." + msg += "\n[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected." if(tox_loss > 10) - msg += "\n\t[tox_loss > 50 ? "Severe" : "Minor"] amount of [HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM) ? "system corruption" : "toxin damage"] detected." + msg += "\n[tox_loss > 50 ? "Severe" : "Minor"] amount of [HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM) ? "system corruption" : "toxin damage"] detected." if(M.getStaminaLoss()) - msg += "\n\tSubject appears to be suffering from fatigue." + msg += "\nSubject appears to be suffering from fatigue." if(advanced) - msg += "\n\tFatigue Level: [M.getStaminaLoss()]%." + msg += "\nFatigue Level: [M.getStaminaLoss()]%." if (M.getCloneLoss()) - msg += "\n\tSubject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage." + msg += "\nSubject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage." if(advanced) - msg += "\n\tCellular Damage Level: [M.getCloneLoss()]." + msg += "\nCellular Damage Level: [M.getCloneLoss()]." if(ishuman(M)) var/mob/living/carbon/human/H = M if(advanced && H.has_dna()) - msg += "\n\tGenetic Stability: [H.dna.stability]%." - - to_chat(user, msg) - msg = "" + msg += "\nGenetic Stability: [H.dna.stability]%." // Body part damage report var/list/dmgreport = list() @@ -178,7 +175,7 @@ GENETICS SCANNER var/mob/living/carbon/C = M var/list/damaged = C.get_damaged_bodyparts(1,1) if(length(damaged)>0 || oxy_loss>0 || tox_loss>0 || fire_loss>0) - dmgreport += "\ + dmgreport += "
\ \ \ \ @@ -196,7 +193,7 @@ GENETICS SCANNER \ " dmgreport += "
Damage:BruteBurn[(org.brute_dam > 0) ? "[org.brute_dam]" : "0"][(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]
" - to_chat(user, dmgreport.Join()) + msg += "\n[dmgreport.Join()]" //Organ damages report @@ -317,7 +314,7 @@ GENETICS SCANNER damage_message += " Minor [O.name] failure detected.
" if(temp_message || damage_message) - msg += "\t[uppertext(O.name)]:
[damage_message] [temp_message]\n" + msg += "\n[uppertext(O.name)]: [damage_message] [temp_message]\n" @@ -332,24 +329,24 @@ GENETICS SCANNER var/has_liver = C.dna && !(NOLIVER in C.dna.species.species_traits) var/has_stomach = C.dna && !(NOSTOMACH in C.dna.species.species_traits) if(!M.getorganslot(ORGAN_SLOT_EYES)) - msg += "\tSubject does not have eyes.\n" + msg += "Subject does not have eyes.\n" if(!M.getorganslot(ORGAN_SLOT_EARS)) - msg += "\tSubject does not have ears.\n" + msg += "Subject does not have ears.\n" if(!M.getorganslot(ORGAN_SLOT_BRAIN)) - msg += "\tSubject's brain function is non-existent!\n" + msg += "Subject's brain function is non-existent!\n" if(has_liver && !M.getorganslot(ORGAN_SLOT_LIVER)) - msg += "\tSubject's liver is missing!\n" + msg += "Subject's liver is missing!\n" if(blooded && !M.getorganslot(ORGAN_SLOT_HEART)) - msg += "\tSubject's heart is missing!\n" + msg += "Subject's heart is missing!\n" if(breathes && !M.getorganslot(ORGAN_SLOT_LUNGS)) - msg += "\tSubject's lungs have collapsed from trauma!\n" + msg += "Subject's lungs have collapsed from trauma!\n" if(has_stomach && !M.getorganslot(ORGAN_SLOT_STOMACH)) - msg += "\tSubject's stomach is missing!\n" + msg += "Subject's stomach is missing!\n" if(M.radiation) - msg += "\tSubject is irradiated.\n" - msg += "\tRadiation Level: [M.radiation] rad\n" + msg += "Subject is irradiated.\n" + msg += "Radiation Level: [M.radiation] rad\n" @@ -383,11 +380,11 @@ GENETICS SCANNER else if (S.flying_species != initial(S.flying_species)) mutant = TRUE - msg += "\tReported Species: [H.spec_trait_examine_font()][H.dna.custom_species ? H.dna.custom_species : S.name]\n" - msg += "\tBase Species: [H.spec_trait_examine_font()][S.name]\n" + msg += "\nReported Species: [H.spec_trait_examine_font()][H.dna.custom_species ? H.dna.custom_species : S.name]\n" + msg += "Base Species: [H.spec_trait_examine_font()][S.name]\n" if(mutant) - msg += "\tSubject has mutations present.\n" - msg += "\tBody temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)\n" + msg += "Subject has mutations present.\n" + msg += "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)\n" // Time of death if(M.tod && (M.stat == DEAD || ((HAS_TRAIT(M, TRAIT_FAKEDEATH)) && !advanced))) @@ -452,14 +449,14 @@ GENETICS SCANNER if(cyberimp_detect) msg += "Detected cybernetic modifications:\n" msg += "[cyberimp_detect]\n" - msg += "*---------*" + msg += "
" to_chat(user, msg) SEND_SIGNAL(M, COMSIG_NANITE_SCAN, user, FALSE) /proc/chemscan(mob/living/user, mob/living/M) if(istype(M)) if(M.reagents) - var/msg = "*---------*\n" + var/msg = "
" if(M.reagents.reagent_list.len) var/list/datum/reagent/reagents = list() for(var/datum/reagent/R in M.reagents.reagent_list) @@ -498,7 +495,7 @@ GENETICS SCANNER if(95 to INFINITY) msg += "Subject contains a extremely dangerous amount of toxic isomers.\n" - msg += "*---------*" + msg += "
" to_chat(user, msg) /obj/item/healthanalyzer/verb/toggle_mode() @@ -529,12 +526,14 @@ GENETICS SCANNER var/render_list = "" for(var/i in patient.get_wounded_bodyparts()) + if(render_list == "") + render_list += "
" var/obj/item/bodypart/wounded_part = i render_list += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]" for(var/k in wounded_part.wounds) var/datum/wound/W = k render_list += "
[W.get_scanner_description()]
\n" - render_list += "
" + render_list += "
" if(render_list == "") if(istype(scanner)) diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index 595b24d214..2b0b8da670 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -205,6 +205,10 @@ if(!throw_item(target, I, user)) break + if(user) + shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75)) + + /obj/item/pneumatic_cannon/proc/throw_item(turf/target, obj/item/I, mob/user) if(!istype(I)) return FALSE diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index ece4d6bae2..bea05f6ef1 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -22,8 +22,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ new/datum/stack_recipe("spout flask", /obj/item/glasswork/glass_base/spouty, 20), \ new/datum/stack_recipe("small bulb flask", /obj/item/glasswork/glass_base/flask_small, 5), \ new/datum/stack_recipe("large bottle flask", /obj/item/glasswork/glass_base/flask_large, 15), \ - new/datum/stack_recipe("tea cup", /obj/item/glasswork/glass_base/tea_plate, 5), \ - new/datum/stack_recipe("tea plate", /obj/item/glasswork/glass_base/tea_cup, 5), \ + new/datum/stack_recipe("tea cup", /obj/item/glasswork/glass_base/tea_cup, 5), \ + new/datum/stack_recipe("tea plate", /obj/item/glasswork/glass_base/tea_plate, 5), \ )), \ )) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 728e5fd726..588e066a41 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -561,4 +561,4 @@ singular_name = "catwalk floor tile" desc = "Flooring that shows its contents underneath. Engineers love it!" icon_state = "catwalk_tile" - turf_type = /turf/open/floor/plating/catwalk_floor + turf_type = /turf/open/floor/catwalk_floor diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index d93547e642..5bd7217484 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -119,6 +119,11 @@ dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder qdel(src) +/obj/item/weldingtool/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks, skill_gain_mult) + target.add_overlay(GLOB.welding_sparks) + . = ..() + target.cut_overlay(GLOB.welding_sparks) + /obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) if(!istype(H)) return ..() diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 46248c1ff8..4ea25bec96 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -7,6 +7,8 @@ var/obj_flags = CAN_BE_HIT var/set_obj_flags // ONLY FOR MAPPING: Sets flags from a string list, handled in Initialize. Usage: set_obj_flags = "EMAGGED;!CAN_BE_HIT" to set EMAGGED and clear CAN_BE_HIT. + var/minimap_override_color // allows this obj to set its own color on the minimap + var/damtype = BRUTE var/force = 0 diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 9887830364..4192a44150 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -65,7 +65,7 @@ /obj/structure/proc/do_climb(atom/movable/A) if(climbable) density = FALSE - . = step(A,get_dir(A,src.loc)) + . = step(A, (A.loc == loc ? dir : get_dir(A,src.loc))) density = TRUE /obj/structure/proc/climb_structure(mob/living/user) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 741b289d97..8e7f5a35f8 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -156,9 +156,10 @@ for(var/atom/movable/AM in L) if(AM != src && insert(AM) == -1) // limit reached break - // for(var/i in reverseRange(L.GetAllContents())) - // var/atom/movable/thing = i - // SEND_SIGNAL(thing, COMSIG_TRY_STORAGE_HIDE_ALL) + // todo: this should be unnecessary, storage should auto close on move wtf + for(var/i in reverseRange(L.GetAllContents())) + var/atom/movable/thing = i + SEND_SIGNAL(thing, COMSIG_TRY_STORAGE_HIDE_ALL) /obj/structure/closet/proc/open(mob/living/user, force = FALSE) if(!can_open(user, force)) 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 02ee466376..d96ad3b0d6 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -64,6 +64,7 @@ new /obj/item/clothing/under/rank/security/officer/blueshirt/seccorp/hoscorp(src) new /obj/item/clothing/suit/armor/vest/leather(src) new /obj/item/clothing/suit/armor/hos(src) + new /obj/item/clothing/suit/armor/hos/platecarrier(src) new /obj/item/clothing/under/rank/security/head_of_security/skirt(src) new /obj/item/clothing/under/rank/security/head_of_security/alt(src) new /obj/item/clothing/under/rank/security/head_of_security/alt/skirt(src) diff --git a/code/game/say.dm b/code/game/say.dm index b7bfe540d0..44f020e7c4 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -31,14 +31,42 @@ GLOBAL_LIST_INIT(freqtospan, list( /atom/movable/proc/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) +/atom/movable/proc/bark(list/hearers, distance, volume, pitch, queue_time) + if(queue_time && vocal_current_bark != queue_time) + return + if(SEND_SIGNAL(src, COMSIG_MOVABLE_BARK, hearers, distance, volume, pitch)) + return //bark interception. this probably counts as some flavor of BDSM + if(!vocal_bark) + if(!vocal_bark_id || !set_bark(vocal_bark_id)) //just-in-time bark generation + return + volume = min(volume, 100) + var/turf/T = get_turf(src) + for(var/mob/M in hearers) + M.playsound_local(T, vol = volume, vary = TRUE, frequency = pitch, max_distance = distance, falloff_distance = 0, falloff_exponent = BARK_SOUND_FALLOFF_EXPONENT(distance), S = vocal_bark, distance_multiplier = 1) + /atom/movable/proc/can_speak() return 1 /atom/movable/proc/send_speech(message, range = 7, atom/movable/source = src, bubble_type, list/spans, datum/language/message_language = null, message_mode) var/rendered = compose_message(src, message_language, message, , spans, message_mode, source) - for(var/_AM in get_hearers_in_view(range, source)) + var/list/hearers = get_hearers_in_view(range, source) + for(var/_AM in hearers) var/atom/movable/AM = _AM AM.Hear(rendered, src, message_language, message, , spans, message_mode, source) + if(SEND_SIGNAL(src, COMSIG_MOVABLE_QUEUE_BARK, hearers, args) || vocal_bark || vocal_bark_id) + for(var/mob/M in hearers) + if(!M.client) + continue + if(!(M.client.prefs.toggles & SOUND_BARK)) + hearers -= M + var/barks = min(round((LAZYLEN(message) / vocal_speed)) + 1, BARK_MAX_BARKS) + var/total_delay + vocal_current_bark = world.time //this is juuuuust random enough to reliably be unique every time send_speech() is called, in most scenarios + for(var/i in 1 to barks) + if(total_delay > BARK_MAX_TIME) + break + addtimer(CALLBACK(src, .proc/bark, hearers, range, vocal_volume, BARK_DO_VARY(vocal_pitch, vocal_pitch_range), vocal_current_bark), total_delay) + total_delay += rand(DS2TICKS(vocal_speed / BARK_SPEED_BASELINE), DS2TICKS(vocal_speed / BARK_SPEED_BASELINE) + DS2TICKS(vocal_speed / BARK_SPEED_BASELINE)) TICKS /atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, face_name = FALSE, atom/movable/source) if(!source) diff --git a/code/game/sound.dm b/code/game/sound.dm index edc3019f27..a99d9aeaa9 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -110,13 +110,20 @@ distance_multiplier - Can be used to multiply the distance at which the sound is */ /mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance, - falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0) - if(!client || !can_hear()) + falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0, virtual_hearer) + if(audiovisual_redirect) + virtual_hearer = get_turf(src) + audiovisual_redirect.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, max_distance, falloff_distance, distance_multiplier, max(0, envwet), -10000, virtual_hearer) + //No return here, as we want to deliberately support the possibility of shenanigans in which mobs with clients can have active AV redirects to completely different players + if(!client) return if(!S) S = sound(get_sfx(soundin)) + if(!can_hear() && !(S.status & SOUND_UPDATE)) //This is primarily to make sure sound updates still go through when a spaceman's deaf + return + S.wait = 0 //No queue S.channel = channel || SSsounds.random_available_channel() S.volume = vol @@ -131,7 +138,7 @@ distance_multiplier - Can be used to multiply the distance at which the sound is S.frequency = get_rand_frequency() if(isturf(turf_source)) - var/turf/T = get_turf(src) + var/turf/T = virtual_hearer || get_turf(src) //sound volume falloff with distance var/distance = get_dist(T, turf_source) @@ -173,7 +180,7 @@ distance_multiplier - Can be used to multiply the distance at which the sound is var/dz = turf_source.y - T.y // Hearing from infront/behind S.z = dz * distance_multiplier var/dy = (turf_source.z - T.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords. - S.y = dy + 1 + S.y = dy + distance_multiplier S.falloff = isnull(max_distance)? FALLOFF_SOUNDS : max_distance //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant. diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm index e57b0c9806..ef3c6a91d9 100644 --- a/code/game/turfs/closed.dm +++ b/code/game/turfs/closed.dm @@ -73,16 +73,26 @@ /turf/closed/indestructible/splashscreen name = "Space Station 13" - icon = 'icons/blank_title.png' + desc = null + icon = 'icons/blanks/blank_title.png' icon_state = "" - layer = FLY_LAYER + plane = SPLASHSCREEN_PLANE bullet_bounce_sound = null -/turf/closed/indestructible/splashscreen/New() +INITIALIZE_IMMEDIATE(/turf/closed/indestructible/splashscreen) + +/turf/closed/indestructible/splashscreen/Initialize(mapload) + . = ..() SStitle.splash_turf = src if(SStitle.icon) icon = SStitle.icon - ..() + handle_generic_titlescreen_sizes() + +///helper proc that will center the screen if the icon is changed to a generic width, to make admins have to fudge around with pixel_x less. returns null +/turf/closed/indestructible/splashscreen/proc/handle_generic_titlescreen_sizes() + var/icon/size_check = icon(SStitle.icon, icon_state) + var/width = size_check.Width() + pixel_x = (672 - width) * 0.5 //The title screen is mapped with the expectation that it's 672x480. Should probably turn the title screen size into a define some time! /turf/closed/indestructible/splashscreen/vv_edit_var(var_name, var_value) . = ..() @@ -90,7 +100,13 @@ switch(var_name) if(NAMEOF(src, icon)) SStitle.icon = icon + handle_generic_titlescreen_sizes() +/turf/closed/indestructible/start_area + name = null + desc = null + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + /turf/closed/indestructible/riveted icon = 'icons/turf/walls/riveted.dmi' icon_state = "riveted" diff --git a/code/game/turfs/open/floor/catwalk_plating.dm b/code/game/turfs/open/floor/catwalk_plating.dm index 76d22847c9..ac0f3b63de 100644 --- a/code/game/turfs/open/floor/catwalk_plating.dm +++ b/code/game/turfs/open/floor/catwalk_plating.dm @@ -5,7 +5,7 @@ * you can crowbar it to interact with the underneath stuff without destroying the tile... * unless you want to! */ -/turf/open/floor/plating/catwalk_floor +/turf/open/floor/catwalk_floor icon = 'icons/turf/floors/catwalk_plating.dmi' icon_state = "catwalk_below" floor_tile = /obj/item/stack/tile/catwalk @@ -16,29 +16,35 @@ barefootstep = FOOTSTEP_CATWALK clawfootstep = FOOTSTEP_CATWALK heavyfootstep = FOOTSTEP_CATWALK + intact = FALSE var/covered = TRUE -/turf/open/floor/plating/catwalk_floor/Initialize(mapload) +/turf/open/floor/catwalk_floor/Initialize(mapload) . = ..() layer = CATWALK_LAYER update_icon(UPDATE_OVERLAYS) -/turf/open/floor/plating/catwalk_floor/update_overlays() +/turf/open/floor/catwalk_floor/update_overlays() . = ..() - var/static/catwalk_overlay + var/static/image/catwalk_overlay if(isnull(catwalk_overlay)) - catwalk_overlay = iconstate2appearance(icon, "catwalk_above") + catwalk_overlay = new() + catwalk_overlay.icon = icon + catwalk_overlay.icon_state = "catwalk_above" + catwalk_overlay.plane = GAME_PLANE + catwalk_overlay.layer = CATWALK_LAYER + catwalk_overlay = catwalk_overlay.appearance if(covered) . += catwalk_overlay -/turf/open/floor/plating/catwalk_floor/screwdriver_act(mob/living/user, obj/item/tool) +/turf/open/floor/catwalk_floor/screwdriver_act(mob/living/user, obj/item/tool) . = ..() covered = !covered user.balloon_alert(user, "[!covered ? "cover removed" : "cover added"]") update_icon(UPDATE_OVERLAYS) -/turf/open/floor/plating/catwalk_floor/pry_tile(obj/item/crowbar, mob/user, silent) +/turf/open/floor/catwalk_floor/crowbar_act(mob/user, obj/item/I) if(covered) user.balloon_alert(user, "remove cover first!") return FALSE - . = ..() + return pry_tile(I, user) diff --git a/code/game/world.dm b/code/game/world.dm index 092422e822..a9eda444f0 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -117,6 +117,7 @@ GLOBAL_LIST(topic_status_cache) GLOB.world_asset_log = "[GLOB.log_directory]/asset.log" GLOB.world_attack_log = "[GLOB.log_directory]/attack.log" GLOB.world_victim_log = "[GLOB.log_directory]/victim.log" + GLOB.world_econ_log = "[GLOB.log_directory]/econ.log" GLOB.world_pda_log = "[GLOB.log_directory]/pda.log" GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log" GLOB.world_manifest_log = "[GLOB.log_directory]/manifest.log" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index bed3ee071f..dba4ec5b46 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -69,6 +69,7 @@ GLOBAL_PROTECT(admin_verbs_admin) /client/proc/cmd_admin_man_up, //CIT CHANGE - adds man up verb /client/proc/cmd_admin_man_up_global, //CIT CHANGE - ditto /client/proc/cmd_admin_create_centcom_report, + /client/proc/cmd_admin_make_priority_announcement, //CIT CHANGE /client/proc/cmd_change_command_name, /client/proc/cmd_admin_check_player_exp, /* shows players by playtime */ /client/proc/toggle_combo_hud, // toggle display of the combination pizza antag and taco sci/med/eng hud diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm index bab74300f5..0964f7aad3 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -150,7 +150,7 @@ GLOBAL_LIST(round_end_notifiees) /datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params) var/saltresult = "The wheel of salt [pick("clatters","screams","vibrates","clanks","resonates","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic"," demonic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog","laughing")] noise")] as it spins violently... And it seems the salt of the day is the " - var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin removal","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]" + var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin removal","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Polly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]" var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP","bikeshedding","crossdressing","sprites","semen keg","argument","theft","nerf","screeching","salt","creampie","lewding","murder","kissing","marriage","replacement","fucking","ship","netflix adaptation","dance","remaster","system","voyeur","decoration","pre-order","bukkake","seduction","worship","gangbang","handholding")]" if(prob(10)) saltresult += "@here for your salt, all day every day" @@ -174,12 +174,12 @@ GLOBAL_LIST(round_end_notifiees) /datum/tgs_chat_command/despacito/Run() return "https://www.youtube.com/watch?v=kJQP7kiw5Fk" -/datum/tgs_chat_command/poly - name = "poly" - help_text = "The Lewder, more applicable Poly speak for Citadel Station 13." +/datum/tgs_chat_command/polly + name = "polly" + help_text = "The Lewder, more applicable Polly speak for Citadel Station 13." var/list/speech_buffer -/datum/tgs_chat_command/poly/Run() +/datum/tgs_chat_command/polly/Run() LAZYINITLIST(speech_buffer) //I figure this is just safe to do for everything at this point if(length(speech_buffer)) //Let's not look up the whole json EVERY TIME, just the first time. return "[pick(speech_buffer)]" diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 9a74b63040..19201299c2 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -50,6 +50,10 @@ H.dna.features["flavor_text"] = "" //Oh no. H.dna.features["body_model"] = H.gender + H.set_bark(pick(GLOB.bark_random_list)) + H.vocal_pitch = BARK_PITCH_RAND(H.gender) + H.vocal_pitch_range = BARK_VARIANCE_RAND + SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE) H.update_body(TRUE) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index d134853494..18d880aa48 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -489,8 +489,8 @@ M.change_mob_type( /mob/living/simple_animal/crab/Coffee , null, null, delmob ) if("parrot") M.change_mob_type( /mob/living/simple_animal/parrot , null, null, delmob ) - if("polyparrot") - M.change_mob_type( /mob/living/simple_animal/parrot/Poly , null, null, delmob ) + if("pollyparrot") + M.change_mob_type( /mob/living/simple_animal/parrot/Polly , null, null, delmob ) if("constructarmored") M.change_mob_type( /mob/living/simple_animal/hostile/construct/armored , null, null, delmob ) if("constructbuilder") diff --git a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm index 8ecfc70a42..1c98060d9b 100644 --- a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm @@ -102,7 +102,7 @@ factory.spores += src . = ..() -/mob/living/simple_animal/hostile/blob/blobspore/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/blob/blobspore/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!is_zombie && isturf(src.loc)) @@ -233,7 +233,7 @@ return FALSE return ..() -/mob/living/simple_animal/hostile/blob/blobbernaut/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/blob/blobbernaut/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return var/list/blobs_in_area = range(2, src) diff --git a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm index efdd312c6e..25f50d7af4 100644 --- a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm +++ b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm @@ -2,7 +2,7 @@ // * MEZMERIZE // LOVE: Target falls in love with you. Being harmed directly causes them harm if they see it? // STAY: Target will do everything they can to stand in the same place. -// FOLLOW: Target follows you, spouting random phrases from their history (or maybe Poly's or NPC's vocab?) +// FOLLOW: Target follows you, spouting random phrases from their history (or maybe Polly's or NPC's vocab?) // ATTACK: Target finds a nearby non-Bloodsucker victim to attack. /datum/action/bloodsucker/targeted/mesmerize diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm index aa45c56892..6ea97b0595 100644 --- a/code/modules/antagonists/changeling/changeling_power.dm +++ b/code/modules/antagonists/changeling/changeling_power.dm @@ -16,7 +16,7 @@ var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD var/always_keep = 0 // important for abilities like revive that screw you if you lose them. var/ignores_fakedeath = FALSE // usable with the FAKEDEATH flag - var/loudness = 0 //Determines how much having this ability will affect changeling blood tests. At 4, the blood will react violently and turn to ash, creating a unique message in the process. At 10, the blood will explode when heated. + var/loudness = 0.5 //Determines how much having this ability will affect changeling blood tests. This is averaged with other purchased abilities. Above 1, the blood will react violently and turn to ash, creating a unique message in the process. Above 2, the blood will explode when heated. /obj/effect/proc_holder/changeling/proc/on_purchase(mob/user, is_respec) diff --git a/code/modules/antagonists/clockcult/clock_mobs.dm b/code/modules/antagonists/clockcult/clock_mobs.dm index b6fe18986a..a2263401aa 100644 --- a/code/modules/antagonists/clockcult/clock_mobs.dm +++ b/code/modules/antagonists/clockcult/clock_mobs.dm @@ -43,7 +43,7 @@ /mob/living/simple_animal/hostile/clockwork/examine(mob/user) var/t_He = p_they(TRUE) var/t_s = p_s() - var/msg = "*---------*\nThis is [icon2html(src, user)] \a [src]!\n" + var/msg = "This is [icon2html(src, user)] \a [src]!\n" msg += "[desc]\n" if(health < maxHealth) msg += "" @@ -55,7 +55,7 @@ var/addendum = examine_info() if(addendum) msg += "[addendum]\n" - msg += "*---------*" + msg += "" return list(msg) diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm index a1f9a7fa8d..c937b27f16 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm @@ -38,7 +38,7 @@ . = ..() true_name = pick(possible_true_names) -/mob/living/simple_animal/hostile/clockwork/guardian/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/clockwork/guardian/BiologicalLife(delta_time, times_fired) ..() if(is_in_host()) if(!is_servant_of_ratvar(host)) diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm index d58608652c..cab5aec636 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm @@ -39,7 +39,7 @@ if(!shield_health) return "Its shield has been destroyed!" -/mob/living/simple_animal/hostile/clockwork/marauder/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/clockwork/marauder/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return var/turf/T = get_turf(src) diff --git a/code/modules/antagonists/devil/imp/imp.dm b/code/modules/antagonists/devil/imp/imp.dm index c0abe504a5..4b2a41db71 100644 --- a/code/modules/antagonists/devil/imp/imp.dm +++ b/code/modules/antagonists/devil/imp/imp.dm @@ -48,7 +48,7 @@ ..() boost = world.time + 30 -/mob/living/simple_animal/imp/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/imp/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(boost*---------*\nThis is [icon2html(src, user)] [src]!") + . = list("This is [icon2html(src, user)] [src]!") //Left hand items for(var/obj/item/I in held_items) @@ -81,7 +81,7 @@ . += "You can see hellfire inside its gaping wounds." else if(health < (maxHealth/2)) . += "You can see hellfire inside its wounds." - . += "*---------*" + . += "" /mob/living/carbon/true_devil/IsAdvancedToolUser() return 1 diff --git a/code/modules/antagonists/gang/gang.dm b/code/modules/antagonists/gang/gang.dm index ea81c8b1af..050754a91e 100644 --- a/code/modules/antagonists/gang/gang.dm +++ b/code/modules/antagonists/gang/gang.dm @@ -67,6 +67,11 @@ if(handler) // if we have a handler, the handler should track this gang handler.gangs += my_gang my_gang.current_theme = handler.current_theme + else if(GLOB.families_override_theme) + my_gang.current_theme = new GLOB.families_override_theme + else + var/theme_to_use = pick(subtypesof(/datum/gang_theme)) + my_gang.current_theme = new theme_to_use my_gang.name = gang_name my_gang.gang_id = gang_id my_gang.acceptable_clothes = acceptable_clothes.Copy() diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index 1d8c205e11..a147263488 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -66,9 +66,21 @@ icon_state = "nuclearbomb_base" anchored = TRUE //stops it being moved +/obj/machinery/nuclearbomb/selfdestruct/Initialize(mapload) + . = ..() + if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(10)) + name = "station-wide gender-reveal terminal" + desc = "For when the whole sector deserves to know a gender. But of whom? Don't ask." + /obj/machinery/nuclearbomb/syndicate //ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb +/obj/machinery/nuclearbomb/syndicate/Initialize(mapload) + . = ..() + if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(50)) + name = "tactical gender-reveal device" + desc = "\"But whose gender is it revealing?\" you ponder. Don't worry. That comes later." + /obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station) var/datum/game_mode/nuclear/NM = SSticker.mode switch(off_station) diff --git a/code/modules/antagonists/slaughter/slaughterevent.dm b/code/modules/antagonists/slaughter/slaughterevent.dm index 3fd8f8b5e7..cdb1b32aad 100644 --- a/code/modules/antagonists/slaughter/slaughterevent.dm +++ b/code/modules/antagonists/slaughter/slaughterevent.dm @@ -20,6 +20,7 @@ if(!SSpersistence.IsValidDebrisLocation(C.loc, allowed_turf_typecache, allowed_z_cache, C.type, FALSE)) continue weight += 0.03 + CHECK_TICK return ..() /datum/round_event/ghost_role/slaughter diff --git a/code/modules/arousal/genitals.dm b/code/modules/arousal/genitals.dm index f4ecafa690..3e16a46526 100644 --- a/code/modules/arousal/genitals.dm +++ b/code/modules/arousal/genitals.dm @@ -33,6 +33,9 @@ linked_organ = null . = ..() +/obj/item/organ/genital/on_life() + return + /obj/item/organ/genital/proc/set_aroused_state(new_state,cause = "manual toggle") if(!(genital_flags & GENITAL_CAN_AROUSE)) return FALSE diff --git a/code/modules/arousal/organs/butt.dm b/code/modules/arousal/organs/butt.dm index 172b87f748..6cb32488a5 100644 --- a/code/modules/arousal/organs/butt.dm +++ b/code/modules/arousal/organs/butt.dm @@ -15,12 +15,6 @@ var/prev_size //former size value, to allow update_size() to early return should be there no significant changes. layer_index = BUTT_LAYER_INDEX -/obj/item/organ/genital/butt/on_life() - if(QDELETED(src)) - return - if(!owner) - return - /obj/item/organ/genital/butt/modify_size(modifier, min = -INFINITY, max = BUTT_SIZE_MAX) var/new_value = clamp(size_cached + modifier, min, max) if(new_value == size_cached) diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 113964d68e..f4f907ba2a 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -17,7 +17,6 @@ /obj/item/assembly_holder/IsAssemblyHolder() return TRUE - /obj/item/assembly_holder/proc/assemble(obj/item/assembly/A, obj/item/assembly/A2, mob/user) attach(A,user) attach(A2,user) @@ -32,6 +31,8 @@ else A.forceMove(src) A.holder = src + // bandaid: please don't try to be picked up while we're still in the assembly + A.interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP A.toggle_secure() if(!a_left) a_left = A @@ -103,9 +104,11 @@ to_chat(user, "You disassemble [src]!") if(a_left) a_left.on_detach() + a_left.interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP a_left = null if(a_right) a_right.on_detach() + a_right.interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP a_right = null qdel(src) return TRUE diff --git a/code/modules/atmospherics/auxgm/breathing_classes.dm b/code/modules/atmospherics/auxgm/breathing_classes.dm index 51a8e7bd40..6d5c4fde9b 100644 --- a/code/modules/atmospherics/auxgm/breathing_classes.dm +++ b/code/modules/atmospherics/auxgm/breathing_classes.dm @@ -46,7 +46,7 @@ gases = list( GAS_METHANE = 1, GAS_METHYL_BROMIDE = -0.7, - GAS_OXYGEN = -0.1, + GAS_O2 = -0.1, GAS_PLUOXIUM = -0.8 ) products = list( diff --git a/code/modules/atmospherics/auxgm/gas_types.dm b/code/modules/atmospherics/auxgm/gas_types.dm index f037e1bfab..828af0e8ea 100644 --- a/code/modules/atmospherics/auxgm/gas_types.dm +++ b/code/modules/atmospherics/auxgm/gas_types.dm @@ -69,6 +69,19 @@ fire_products = FIRE_PRODUCT_PLASMA enthalpy = FIRE_PLASMA_ENERGY_RELEASED // 3000000, 3 megajoules, 3000 kj +/datum/gas/nitrous_oxide + id = GAS_NITROUS + specific_heat = 40 + name = "Nitrous Oxide" + gas_overlay = "nitrous_oxide" + moles_visible = MOLES_GAS_VISIBLE * 2 + flags = GAS_FLAG_DANGEROUS + fire_products = list(GAS_N2 = 1) + oxidation_rate = 0.5 + oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100 + enthalpy = 81600 + heat_resistance = 6 + /datum/gas/water_vapor id = GAS_H2O specific_heat = 40 @@ -82,18 +95,23 @@ powermix = 1 breath_reagent = /datum/reagent/water -/datum/gas/nitrous_oxide - id = GAS_NITROUS - specific_heat = 40 - name = "Nitrous Oxide" - gas_overlay = "nitrous_oxide" - moles_visible = MOLES_GAS_VISIBLE * 2 - flags = GAS_FLAG_DANGEROUS - fire_products = list(GAS_N2 = 1) - oxidation_rate = 0.5 - oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100 - enthalpy = 81600 - heat_resistance = 6 + +/datum/gas/pluoxium + id = GAS_PLUOXIUM + specific_heat = 80 + name = "Pluoxium" + fusion_power = 10 + oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 25 // it is VERY stable + oxidation_rate = 8 // when it can oxidize, it can oxidize a LOT + enthalpy = -2000000 // but it reduces the heat output a great deal (plasma fires add 3000000 per mole) + powermix = -1 + heat_penalty = -1 + transmit_modifier = -5 + heat_resistance = 3 + price = 6 + +/datum/gas/pluoxium/generate_TLV() + return new/datum/tlv(-1, -1, 5, 6) /datum/gas/tritium id = GAS_TRITIUM @@ -111,17 +129,19 @@ fire_burn_rate = 2 fire_radiation_released = 50 // arbitrary number, basically 60 moles of trit burning will just barely start to harm you fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 + price = 7 /datum/gas/nitric_oxide id = GAS_NITRIC specific_heat = 20 name = "Nitric oxide" - flags = GAS_FLAG_DANGEROUS odor = "sharp sweetness" odor_strength = 1 fusion_power = 15 enthalpy = 91290 heat_resistance = 2 + powermix = -1 + heat_penalty = -1 /datum/gas/nitryl id = GAS_NITRYL @@ -134,6 +154,7 @@ fire_products = list(GAS_N2 = 0.5) enthalpy = 33200 oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 + price = 3 /datum/gas/hypernoblium id = GAS_HYPERNOB @@ -141,6 +162,7 @@ name = "Hyper-noblium" gas_overlay = "freon" moles_visible = MOLES_GAS_VISIBLE + price = 50 /datum/gas/hydrogen id = GAS_HYDROGEN @@ -168,6 +190,7 @@ enthalpy = FIRE_CARBON_ENERGY_RELEASED // it is a mystery transmit_modifier = -2 radioactivity_modifier = 5 + price = 3 /datum/gas/stimulum id = GAS_STIMULUM @@ -176,22 +199,7 @@ odor_strength = 10 name = "Stimulum" fusion_power = 7 - -/datum/gas/pluoxium - id = GAS_PLUOXIUM - specific_heat = 80 - name = "Pluoxium" - fusion_power = 10 - oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 25 // it is VERY stable - oxidation_rate = 8 // when it can oxidize, it can oxidize a LOT - enthalpy = -2000000 // but it reduces the heat output a great deal (plasma fires add 3000000 per mole) - powermix = -1 - heat_penalty = -1 - transmit_modifier = -5 - heat_resistance = 3 - -/datum/gas/pluoxium/generate_TLV() - return new/datum/tlv(-1, -1, 5, 6) + price = 25 /datum/gas/miasma id = GAS_MIASMA @@ -201,7 +209,9 @@ // snowflaked odor name = "Miasma" gas_overlay = "miasma" + color = "#963" moles_visible = MOLES_GAS_VISIBLE * 60 + price = 2 /datum/gas/methane id = GAS_METHANE @@ -227,6 +237,7 @@ ) enthalpy = -74600 fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + price = 1 /datum/gas/methyl_bromide id = GAS_METHYL_BROMIDE @@ -249,6 +260,7 @@ enthalpy = -35400 fire_burn_rate = 4 / 7 // oh no fire_temperature = 808 // its autoignition; it apparently doesn't spark readily, so i don't put it lower + price = 2 /datum/gas/bromine id = GAS_BROMINE @@ -285,3 +297,4 @@ powermix = -1 transmit_modifier = -10 heat_penalty = -10 + price = 5 // IT'S NOT ACTUALLY THAT HARD TO GET INTO A CANISTER LOL diff --git a/code/modules/atmospherics/gasmixtures/auxgm.dm b/code/modules/atmospherics/gasmixtures/auxgm.dm index d3de583f04..0c36457ea2 100644 --- a/code/modules/atmospherics/gasmixtures/auxgm.dm +++ b/code/modules/atmospherics/gasmixtures/auxgm.dm @@ -43,6 +43,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA var/list/TLVs = list() var/list/odors = list() var/list/odor_strengths = list() + var/list/prices = list() /datum/gas var/id = "" @@ -60,6 +61,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA var/datum/reagent/breath_reagent = null // what breathing this adds to your reagents var/datum/reagent/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something + var/price = 0 // How much this gas is worth when sold, per mole. var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material var/fire_temperature = null // temperature above which gas may catch fire; null for none @@ -135,6 +137,8 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA if(gas.odor) odor_strengths[g] = gas.odor_strength odors[g] = gas.odor + if(gas.price) + prices[g] = gas.price add_supermatter_properties(gas) _auxtools_register_gas(gas) if(done_initializing) diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 122d30f33e..b104c51fb7 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -729,11 +729,11 @@ /datum/gas_reaction/nitric_oxide/react(datum/gas_mixture/air, datum/holder) var/nitric = air.get_moles(GAS_NITRIC) var/oxygen = air.get_moles(GAS_O2) - var/max_amount = max(nitric / 10, MINIMUM_MOLE_COUNT) - var/enthalpy = air.return_temperature() * (air.heat_capacity() + R_IDEAL_GAS_EQUATION * air.total_moles()); + var/max_amount = max(nitric / 8, MINIMUM_MOLE_COUNT) + var/enthalpy = air.return_temperature() * (air.heat_capacity() + R_IDEAL_GAS_EQUATION * air.total_moles()) var/list/enthalpies = GLOB.gas_data.enthalpies if(oxygen > MINIMUM_MOLE_COUNT) - var/reaction_amount = min(max_amount, oxygen) + var/reaction_amount = min(max_amount, oxygen)/4 air.adjust_moles(GAS_NITRIC, -reaction_amount*2) air.adjust_moles(GAS_O2, -reaction_amount) air.adjust_moles(GAS_NITRYL, reaction_amount*2) @@ -759,7 +759,18 @@ var/initial_energy = air.thermal_energy() for(var/g in air.get_gases()) air.set_moles(g, 0) - air.set_moles(GAS_QCD, initial_energy / (air.return_temperature() * GLOB.gas_data.specific_heats[GAS_QCD])) + var/amount = initial_energy / (air.return_temperature() * GLOB.gas_data.specific_heats[GAS_QCD]) + air.set_moles(GAS_QCD, amount) + var/list/largest_values = SSresearch.science_tech.largest_values + if(!(GAS_QCD in largest_values)) + largest_values[GAS_QCD] = 0 + var/previous_largest = largest_values[GAS_QCD] + var/research_amount = amount * QCD_RESEARCH_AMOUNT + if(previous_largest < research_amount) + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, research_amount) + largest_values[GAS_QCD] = research_amount + else + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, research_amount / 100) /datum/gas_reaction/dehagedorn priority = 50 @@ -781,11 +792,10 @@ var/list/gases = GLOB.gas_data.specific_heats.Copy() gases -= GAS_QCD gases -= GAS_TRITIUM // no refusing sorry - for(var/g in gases) - gases[g] = 10000 / gases[g] + gases -= GAS_HYPERNOB // makes it waaay too easy to stabilize it while(energy_remaining > 0) var/G = pick(gases) air.adjust_moles(G, max(0.1, energy_remaining / (gases[G] * new_temp * 20))) energy_remaining = initial_energy - air.thermal_energy() - air.adjust_heat(-energy_remaining) + air.set_temperature(initial_energy / air.heat_capacity()) return REACTING diff --git a/code/modules/awaymissions/super_secret_room.dm b/code/modules/awaymissions/super_secret_room.dm index 2c01a66d43..a840180ea9 100644 --- a/code/modules/awaymissions/super_secret_room.dm +++ b/code/modules/awaymissions/super_secret_room.dm @@ -45,9 +45,9 @@ if(9) SpeakPeace(list("Alright maybe that's too boring.", "I can't keep manually typing these lines out though.", "It's hard to explain but the code structure I'm using is kind of terrible.")) if(10) - SpeakPeace(list("Oh I have an idea!", "Lets outsource this endless banter to Poly!", "Then you'll be able to keep listening to this without getting bored!")) + SpeakPeace(list("Oh I have an idea!", "Lets outsource this endless banter to Polly!", "Then you'll be able to keep listening to this without getting bored!")) if(isnull(shenanigans) || !shenanigans.len) - shenanigans = list("Except the poly file is missing...") + shenanigans = list("Except the polly file is missing...") if(11 to 14, 16 to 50, 52 to 99, 103 to 107, 109 to 203, 205 to 249, 252 to 665, 667 to 999, 1001 to 5642) SpeakPeace(list(pick(shenanigans),pick(shenanigans),pick(shenanigans))) if(times_spoken_to % 10 == 0) @@ -55,7 +55,7 @@ if(15) SpeakPeace(list("See? Isn't this fun?","Now you can mash this for hours without getting bored.","Anyway I'll leave you it.")) if(51) - SpeakPeace(list("The fun never ends around here.", "The Poly text files stores up to 500 statements.", "But you've probably heard a few repeats by now.")) + SpeakPeace(list("The fun never ends around here.", "The Polly text files stores up to 500 statements.", "But you've probably heard a few repeats by now.")) if(100) SpeakPeace(list("And that's a solid hundred.", "Good hustle I guess.", "You've probably heard a lot of repeats by now.")) if(101) diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index 6d965e2c5a..e464a056ab 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -169,13 +169,9 @@ /datum/export/large/gas_canister/get_cost(obj/O) var/obj/machinery/portable_atmospherics/canister/C = O var/worth = 10 - worth += C.air_contents.get_moles(GAS_BZ)*3 - worth += C.air_contents.get_moles(GAS_STIMULUM)*25 - worth += C.air_contents.get_moles(GAS_HYPERNOB)*20 - worth += C.air_contents.get_moles(GAS_MIASMA)*2 - worth += C.air_contents.get_moles(GAS_TRITIUM)*7 - worth += C.air_contents.get_moles(GAS_PLUOXIUM)*6 - worth += C.air_contents.get_moles(GAS_NITRYL)*10 + var/list/gas_prices = GLOB.gas_data.prices + for(var/gas in C.air_contents.get_gases()) + worth += C.air_contents.get_moles(gas)*gas_prices[gas] return worth diff --git a/code/modules/cargo/exports/weapons.dm b/code/modules/cargo/exports/weapons.dm index 42cd1dccea..5f2146200b 100644 --- a/code/modules/cargo/exports/weapons.dm +++ b/code/modules/cargo/exports/weapons.dm @@ -332,7 +332,7 @@ /datum/export/weapon/l6sawammo cost = 60 unit_name = "L6 SAW ammo box" - export_types = list(/obj/item/ammo_box/magazine/mm195x129) + export_types = list(/obj/item/ammo_box/magazine/mm712x82) include_subtypes = TRUE /datum/export/weapon/rocket diff --git a/code/modules/cargo/packs/engineering.dm b/code/modules/cargo/packs/engineering.dm index 9af18e13f6..4fc50e2385 100644 --- a/code/modules/cargo/packs/engineering.dm +++ b/code/modules/cargo/packs/engineering.dm @@ -49,7 +49,7 @@ /datum/supply_pack/engineering/engihardsuit name = "Engineering Hardsuit" - desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!" + desc = "Polly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!" cost = 2250 access = ACCESS_ENGINE contains = list(/obj/item/tank/internals/air, diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 41c4480c74..294fdcc30b 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -135,10 +135,6 @@ ///Used in MouseDrag to preserve the last mouse-entered object. var/mouseObject = null var/mouseControlObject = null - //Middle-mouse-button click dragtime control for aimbot exploit detection. - var/middragtime = 0 - //Middle-mouse-button clicked object control for aimbot exploit detection. - var/atom/middragatom /// Messages currently seen by this client var/list/seen_messages diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 4b93f42d4d..66bb714b99 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -422,10 +422,12 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if( (world.address == address || !address) && !GLOB.host ) GLOB.host = key world.update_status() - + if(holder) add_admin_verbs() - to_chat(src, get_message_output("memo")) + var/admin_memo_note = get_message_output("memo") + if(admin_memo_note) + to_chat(src, admin_memo_note) adminGreet() add_verbs_from_config() @@ -468,7 +470,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(CONFIG_GET(flag/autoconvert_notes)) convert_notes_sql(ckey) - to_chat(src, get_message_output("message", ckey)) + var/admin_message_note = get_message_output("message", ckey) + if(admin_message_note) + to_chat(src, admin_message_note) if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them. to_chat(src, "Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.") @@ -867,10 +871,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( return last_activity = world.time last_click = world.time - var/ab = FALSE var/list/L = params2list(params) - if (object && object == middragatom && L["left"]) - ab = max(0, 5 SECONDS-(world.time-middragtime)*0.1) + + if(L["drag"]) + return + var/mcl = CONFIG_GET(number/minute_click_limit) if (!holder && !ignore_spam && mcl) var/minute = round(world.time, 600) @@ -879,20 +884,14 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if (minute != clicklimiter[CURRENT_MINUTE]) clicklimiter[CURRENT_MINUTE] = minute clicklimiter[MINUTE_COUNT] = 0 - clicklimiter[MINUTE_COUNT] += 1+(ab) + clicklimiter[MINUTE_COUNT] += 1 if (clicklimiter[MINUTE_COUNT] > mcl) var/msg = "Your previous click was ignored because you've done too many in a minute." if (minute != clicklimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them) clicklimiter[ADMINSWARNED_AT] = minute msg += " Administrators have been informed." - if (ab) - log_game("[key_name(src)] is using the middle click aimbot exploit") - message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit
") - add_system_note("aimbot", "Is using the middle click aimbot exploit") - log_click(object, location, control, params, src, "lockout (spam - minute ab c [ab] s [middragtime])", TRUE) - else - log_click(object, location, control, params, src, "lockout (spam - minute)", TRUE) + log_click(object, location, control, params, src, "lockout (spam - minute)", TRUE) log_game("[key_name(src)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") to_chat(src, "[msg]") @@ -906,15 +905,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if (second != clicklimiter[CURRENT_SECOND]) clicklimiter[CURRENT_SECOND] = second clicklimiter[SECOND_COUNT] = 0 - clicklimiter[SECOND_COUNT] += 1+(!!ab) + clicklimiter[SECOND_COUNT] += 1 if (clicklimiter[SECOND_COUNT] > scl) to_chat(src, "Your previous click was ignored because you've done too many in a second") return - if(ab) //Citadel edit, things with stuff. - log_click(object, location, control, params, src, "dropped (ab c [ab] s [middragtime])", TRUE) - return - if(prefs.log_clicks) log_click(object, location, control, params, src, extra_info? "clicked ([extra_info])" : null) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index dcfb199837..e4056233c6 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -140,6 +140,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/modified_limbs = list() //prosthetic/amputated limbs var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded + // Vocal bark prefs + var/bark_id = "mutedc3" + var/bark_speed = 4 + var/bark_pitch = 1 + var/bark_variance = 0.2 + COOLDOWN_DECLARE(bark_previewing) + /// Security record note section var/security_records /// Medical record note section @@ -153,6 +160,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) //Quirk list var/list/all_quirks = list() + //Quirk category currently selected + var/quirk_category = QUIRK_POSITIVE // defaults to positive, the first tab! + //Job preferences 2.0 - indexed by job title , no key or value implies never var/list/job_preferences = list() @@ -223,6 +233,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/screenshake = 100 var/damagescreenshake = 2 + var/recoil_screenshake = 100 var/arousable = TRUE var/autostand = TRUE var/auto_ooc = FALSE @@ -401,7 +412,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
" dat += "

Flavor Text

" dat += "Set Examine Text
" - if(length(features["flavor_text"]) <= 40) + if(length(features["flavor_text"]) <= MAX_FLAVOR_PREVIEW_LEN) if(!length(features["flavor_text"])) dat += "\[...\]" else @@ -410,7 +421,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "[TextPreview(features["flavor_text"])]...
" dat += "

Silicon Flavor Text

" dat += "Set Silicon Examine Text
" - if(length(features["silicon_flavor_text"]) <= 40) + if(length(features["silicon_flavor_text"]) <= MAX_FLAVOR_PREVIEW_LEN) if(!length(features["silicon_flavor_text"])) dat += "\[...\]" else @@ -420,7 +431,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "

OOC notes

" dat += "Set OOC notes
" var/ooc_notes_len = length(features["ooc_notes"]) - if(ooc_notes_len <= 40) + if(ooc_notes_len <= MAX_FLAVOR_PREVIEW_LEN) if(!ooc_notes_len) dat += "\[...\]" else @@ -792,11 +803,21 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "" + dat += "" dat += "
" dat += "

Speech preferences

" dat += "Custom Speech Verb:
" - dat += "[custom_speech_verb]
" + dat += "[custom_speech_verb]
" dat += "Custom Tongue:
" - dat += "[custom_tongue]
" + dat += "[custom_tongue]
" dat += "Additional Language
" - dat += "[additional_language]
" + dat += "[additional_language]
" + dat += "
" + dat += "

Vocal Bark preferences

" + var/datum/bark/B = GLOB.bark_list[bark_id] + dat += "Vocal Bark Sound:
" + dat += "[B ? initial(B.name) : "INVALID"]
" + dat += "Vocal Bark Speed: [bark_speed]
" + dat += "Vocal Bark Pitch: [bark_pitch]
" + dat += "Vocal Bark Variance: [bark_variance]
" + dat += "
Preview Bark
" dat += "
" @@ -887,6 +908,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Screen Shake: [(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]
" if (user && user.client && !user.client.prefs.screenshake==0) dat += "Damage Screen Shake: [(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]
" + dat += "Recoil Screen Push: [(recoil_screenshake==100) ? "Full" : ((recoil_screenshake==0) ? "None" : "[screenshake]")]
" var/p_chaos if (!preferred_chaos) p_chaos = "No preference" @@ -1464,9 +1486,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
" dat += "
Current quirks: [all_quirks.len ? all_quirks.Join(", ") : "None"]
" dat += "
[GetPositiveQuirkCount()] / [MAX_QUIRKS] max positive quirks
\ - Quirk balance remaining: [GetQuirkBalance()]

" + Quirk balance remaining: [GetQuirkBalance()]
" + dat += " [QUIRK_POSITIVE] " + dat += " [QUIRK_NEUTRAL] " + dat += " [QUIRK_NEGATIVE] " + dat += "
" for(var/V in SSquirks.quirks) var/datum/quirk/T = SSquirks.quirks[V] + var/value = initial(T.value) + if((value > 0 && quirk_category != QUIRK_POSITIVE) || (value < 0 && quirk_category != QUIRK_NEGATIVE) || (value == 0 && quirk_category != QUIRK_NEUTRAL)) + continue + var/quirk_name = initial(T.name) var/has_quirk var/quirk_cost = initial(T.value) * -1 @@ -1488,7 +1518,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) quirk_cost = "+[quirk_cost]" var/font_color = "#AAAAFF" if(initial(T.value) != 0) - font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA" + font_color = value > 0 ? "#AAFFAA" : "#FFAAAA" if(quirk_conflict) dat += "[quirk_name] - [initial(T.desc)] \ LOCKED: [lock_reason]
" @@ -1618,6 +1648,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) SetQuirks(user) return TRUE + else if(href_list["quirk_category"]) + var/temp_quirk_category = href_list["quirk_category"] + if(temp_quirk_category == QUIRK_POSITIVE || temp_quirk_category == QUIRK_NEUTRAL || temp_quirk_category == QUIRK_NEGATIVE) + quirk_category = temp_quirk_category + SetQuirks(user) + switch(href_list["task"]) if("random") switch(href_list["preference"]) @@ -1697,7 +1733,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("name") var/new_name = input(user, "Choose your character's name:", "Character Preference") as text|null if(new_name) - new_name = reject_bad_name(new_name) + new_name = reject_bad_name(new_name, allow_numbers = TRUE) if(new_name) real_name = new_name else @@ -2538,6 +2574,43 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(selected_language) additional_language = selected_language + if("barksound") + var/list/woof_woof = list() + for(var/path in GLOB.bark_list) + var/datum/bark/B = GLOB.bark_list[path] + if(initial(B.ignore)) + continue + if(initial(B.ckeys_allowed)) + var/list/allowed = initial(B.ckeys_allowed) + if(!allowed.Find(user.client.ckey)) + continue + woof_woof[initial(B.name)] = initial(B.id) + var/new_bork = input(user, "Choose your desired vocal bark", "Character Preference") as null|anything in woof_woof + if(new_bork) + bark_id = woof_woof[new_bork] + var/datum/bark/B = GLOB.bark_list[bark_id] //Now we need sanitization to take into account bark-specific min/max values + bark_speed = round(clamp(bark_speed, initial(B.minspeed), initial(B.maxspeed)), 1) + bark_pitch = clamp(bark_pitch, initial(B.minpitch), initial(B.maxpitch)) + bark_variance = clamp(bark_variance, initial(B.minvariance), initial(B.maxvariance)) + + if("barkspeed") + var/datum/bark/B = GLOB.bark_list[bark_id] + var/borkset = input(user, "Choose your desired bark speed (Higher is slower, lower is faster). Min: [initial(B.minspeed)]. Max: [initial(B.maxspeed)]", "Character Preference") as null|num + if(borkset) + bark_speed = round(clamp(borkset, initial(B.minspeed), initial(B.maxspeed)), 1) + + if("barkpitch") + var/datum/bark/B = GLOB.bark_list[bark_id] + var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minpitch)]. Max: [initial(B.maxpitch)]", "Character Preference") as null|num + if(borkset) + bark_pitch = clamp(borkset, initial(B.minpitch), initial(B.maxpitch)) + + if("barkvary") + var/datum/bark/B = GLOB.bark_list[bark_id] + var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minvariance)]. Max: [initial(B.maxvariance)]", "Character Preference") as null|num + if(borkset) + bark_variance = clamp(borkset, initial(B.minvariance), initial(B.maxvariance)) + if("bodysprite") var/selected_body_sprite = input(user, "Choose your desired body sprite", "Character Preference") as null|anything in pref_species.allowed_limb_ids if(selected_body_sprite) @@ -2711,7 +2784,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("no_tetris_storage") no_tetris_storage = !no_tetris_storage if ("screenshake") - var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, 200 = maximum.)", "Character Preference", screenshake) as null|num + var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num if (!isnull(desiredshake)) screenshake = desiredshake if("damagescreenshake") @@ -2724,6 +2797,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) damagescreenshake = 0 else damagescreenshake = 1 + if ("recoil_screenshake") + var/desiredshake = input(user, "Set the amount of recoil screenshake/push you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num + if (!isnull(desiredshake)) + recoil_screenshake = desiredshake if("nameless") nameless = !nameless //END CITADEL EDIT @@ -2998,6 +3075,23 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("hud_toggle_flash") hud_toggle_flash = !hud_toggle_flash + if("barkpreview") + if(SSticker.current_state == GAME_STATE_STARTUP) //Timers don't tick at all during game startup, so let's just give an error message + to_chat(user, "Bark previews can't play during initialization!") + return + if(!COOLDOWN_FINISHED(src, bark_previewing)) + return + if(!parent || !parent.mob) + return + COOLDOWN_START(src, bark_previewing, (5 SECONDS)) + var/atom/movable/barkbox = new(get_turf(parent.mob)) + barkbox.set_bark(bark_id) + var/total_delay + for(var/i in 1 to (round((32 / bark_speed)) + 1)) + addtimer(CALLBACK(barkbox, /atom/movable/proc/bark, list(parent.mob), 7, 70, BARK_DO_VARY(bark_pitch, bark_variance)), total_delay) + total_delay += rand(DS2TICKS(bark_speed/4), DS2TICKS(bark_speed/4) + DS2TICKS(bark_speed/4)) TICKS + QDEL_IN(barkbox, total_delay) + if("save") save_preferences() save_character() @@ -3219,6 +3313,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.additional_language = language_entry character.grant_language(language_entry, TRUE, TRUE) + character.set_bark(bark_id) + character.vocal_speed = bark_speed + character.vocal_pitch = bark_pitch + character.vocal_pitch_range = bark_variance + //limb stuff, only done when initially spawning in if(initial_spawn) //delete any existing prosthetic limbs to make sure no remnant prosthetics are left over - But DO NOT delete those that are species-related diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index a4fadb9b41..249dbba45f 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -5,7 +5,7 @@ // You do not need to raise this if you are adding new values that have sane defaults. // Only raise this value when changing the meaning/format/name/layout of an existing value // where you would want the updater procs below to run -#define SAVEFILE_VERSION_MAX 53 +#define SAVEFILE_VERSION_MAX 55 /* SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn @@ -42,6 +42,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //if your savefile is 3 months out of date, then 'tough shit'. /datum/preferences/proc/update_preferences(current_version, savefile/S) + if(current_version < 55) //Bitflag toggles don't set their defaults when they're added, always defaulting to off instead. + toggles |= SOUND_BARK if(current_version < 46) //If you remove this, remove force_reset_keybindings() too. force_reset_keybindings_direct(TRUE) addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice. @@ -72,15 +74,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/job_engsec_med = 0 var/job_engsec_low = 0 - S["job_civilian_high"] >> job_civilian_high - S["job_civilian_med"] >> job_civilian_med - S["job_civilian_low"] >> job_civilian_low - S["job_medsci_high"] >> job_medsci_high - S["job_medsci_med"] >> job_medsci_med - S["job_medsci_low"] >> job_medsci_low - S["job_engsec_high"] >> job_engsec_high - S["job_engsec_med"] >> job_engsec_med - S["job_engsec_low"] >> job_engsec_low + S["job_civilian_high"] >> job_civilian_high + S["job_civilian_med"] >> job_civilian_med + S["job_civilian_low"] >> job_civilian_low + S["job_medsci_high"] >> job_medsci_high + S["job_medsci_med"] >> job_medsci_med + S["job_medsci_low"] >> job_medsci_low + S["job_engsec_high"] >> job_engsec_high + S["job_engsec_med"] >> job_engsec_med + S["job_engsec_low"] >> job_engsec_low //Can't use SSjob here since this happens right away on login for(var/job in subtypesof(/datum/job)) @@ -173,10 +175,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/devourable var/feeding var/lickable - S["digestable"] >> digestable - S["devourable"] >> devourable - S["feeding"] >> feeding - S["lickable"] >> lickable + S["digestable"] >> digestable + S["devourable"] >> devourable + S["feeding"] >> feeding + S["lickable"] >> lickable if(digestable) vore_flags |= DIGESTABLE if(devourable) @@ -196,8 +198,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car features["taur"] = "Cow (Spotted)" if(current_version < 31) - S["wing_color"] >> features["wings_color"] - S["horn_color"] >> features["horns_color"] + S["wing_color"] >> features["wings_color"] + S["horn_color"] >> features["horns_color"] if(current_version < 33) features["flavor_text"] = html_encode(features["flavor_text"]) @@ -346,6 +348,16 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(current_version < 53) parallax = PARALLAX_INSANE + // Some genius decided to make features update on the loading part, go figure. + if(current_version < 54) + var/old_silicon_flavor = S["silicon_feature_flavor_text"] + if(length(old_silicon_flavor)) + features["feature_silicon_flavor_text"] = old_silicon_flavor + var/old_flavor_text = S["flavor_text"] + // If they have the old flavor text but also have the new one, i suppose the new one is more important. + if(length(old_flavor_text) && !length(features["feature_flavor_text"])) + features["feature_flavor_text"] = old_flavor_text + /datum/preferences/proc/load_path(ckey,filename="preferences.sav") if(!ckey) return @@ -380,70 +392,70 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car . = TRUE //general preferences - S["ooccolor"] >> ooccolor - S["lastchangelog"] >> lastchangelog - S["UI_style"] >> UI_style - S["outline_color"] >> outline_color - S["outline_enabled"] >> outline_enabled - S["screentip_pref"] >> screentip_pref - S["screentip_color"] >> screentip_color - S["hotkeys"] >> hotkeys - S["chat_on_map"] >> chat_on_map - S["max_chat_length"] >> max_chat_length + S["ooccolor"] >> ooccolor + S["lastchangelog"] >> lastchangelog + S["UI_style"] >> UI_style + S["outline_color"] >> outline_color + S["outline_enabled"] >> outline_enabled + S["screentip_pref"] >> screentip_pref + S["screentip_color"] >> screentip_color + S["hotkeys"] >> hotkeys + S["chat_on_map"] >> chat_on_map + S["max_chat_length"] >> max_chat_length S["see_chat_non_mob"] >> see_chat_non_mob - S["tgui_fancy"] >> tgui_fancy - S["tgui_lock"] >> tgui_lock - S["buttons_locked"] >> buttons_locked - S["windowflash"] >> windowflashing + S["tgui_fancy"] >> tgui_fancy + S["tgui_lock"] >> tgui_lock + S["buttons_locked"] >> buttons_locked + S["windowflash"] >> windowflashing S["be_special"] >> be_special - S["default_slot"] >> default_slot - S["chat_toggles"] >> chat_toggles - S["toggles"] >> toggles - S["deadmin"] >> deadmin - S["ghost_form"] >> ghost_form - S["ghost_orbit"] >> ghost_orbit - S["ghost_accs"] >> ghost_accs - S["ghost_others"] >> ghost_others - S["preferred_map"] >> preferred_map - S["ignoring"] >> ignoring - S["ghost_hud"] >> ghost_hud - S["inquisitive_ghost"] >> inquisitive_ghost + S["default_slot"] >> default_slot + S["chat_toggles"] >> chat_toggles + S["toggles"] >> toggles + S["deadmin"] >> deadmin + S["ghost_form"] >> ghost_form + S["ghost_orbit"] >> ghost_orbit + S["ghost_accs"] >> ghost_accs + S["ghost_others"] >> ghost_others + S["preferred_map"] >> preferred_map + S["ignoring"] >> ignoring + S["ghost_hud"] >> ghost_hud + S["inquisitive_ghost"] >> inquisitive_ghost S["uses_glasses_colour"]>> uses_glasses_colour - S["clientfps"] >> clientfps - S["parallax"] >> parallax - S["ambientocclusion"] >> ambientocclusion - S["auto_fit_viewport"] >> auto_fit_viewport - S["widescreenpref"] >> widescreenpref - S["long_strip_menu"] >> long_strip_menu + S["clientfps"] >> clientfps + S["parallax"] >> parallax + S["ambientocclusion"] >> ambientocclusion + S["auto_fit_viewport"] >> auto_fit_viewport + S["widescreenpref"] >> widescreenpref + S["long_strip_menu"] >> long_strip_menu S["pixel_size"] >> pixel_size S["scaling_method"] >> scaling_method - S["hud_toggle_flash"] >> hud_toggle_flash - S["hud_toggle_color"] >> hud_toggle_color - S["menuoptions"] >> menuoptions - S["enable_tips"] >> enable_tips - S["tip_delay"] >> tip_delay - S["pda_style"] >> pda_style - S["pda_color"] >> pda_color - S["pda_skin"] >> pda_skin + S["hud_toggle_flash"] >> hud_toggle_flash + S["hud_toggle_color"] >> hud_toggle_color + S["menuoptions"] >> menuoptions + S["enable_tips"] >> enable_tips + S["tip_delay"] >> tip_delay + S["pda_style"] >> pda_style + S["pda_color"] >> pda_color + S["pda_skin"] >> pda_skin // Custom hotkeys - S["key_bindings"] >> key_bindings - S["modless_key_bindings"] >> modless_key_bindings + S["key_bindings"] >> key_bindings + S["modless_key_bindings"] >> modless_key_bindings //citadel code - S["arousable"] >> arousable - S["screenshake"] >> screenshake - S["damagescreenshake"] >> damagescreenshake - S["autostand"] >> autostand - S["cit_toggles"] >> cit_toggles - S["preferred_chaos"] >> preferred_chaos - S["auto_ooc"] >> auto_ooc - S["no_tetris_storage"] >> no_tetris_storage + S["arousable"] >> arousable + S["screenshake"] >> screenshake + S["damagescreenshake"] >> damagescreenshake + S["autostand"] >> autostand + S["cit_toggles"] >> cit_toggles + S["preferred_chaos"] >> preferred_chaos + S["auto_ooc"] >> auto_ooc + S["no_tetris_storage"] >> no_tetris_storage //favorite outfits - S["favorite_outfits"] >> favorite_outfits + S["favorite_outfits"] >> favorite_outfits var/list/parsed_favs = list() for(var/typetext in favorite_outfits) @@ -461,47 +473,47 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer) //Sanitize - ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor))) - lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog)) - UI_style = sanitize_inlist(UI_style, GLOB.available_ui_styles, GLOB.available_ui_styles[1]) - hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys)) - chat_on_map = sanitize_integer(chat_on_map, 0, 1, initial(chat_on_map)) + ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor))) + lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog)) + UI_style = sanitize_inlist(UI_style, GLOB.available_ui_styles, GLOB.available_ui_styles[1]) + hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys)) + chat_on_map = sanitize_integer(chat_on_map, 0, 1, initial(chat_on_map)) max_chat_length = sanitize_integer(max_chat_length, 1, CHAT_MESSAGE_MAX_LENGTH, initial(max_chat_length)) - see_chat_non_mob = sanitize_integer(see_chat_non_mob, 0, 1, initial(see_chat_non_mob)) - tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy)) - tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock)) - buttons_locked = sanitize_integer(buttons_locked, 0, 1, initial(buttons_locked)) - windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing)) - default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot)) - toggles = sanitize_integer(toggles, 0, 16777215, initial(toggles)) - deadmin = sanitize_integer(deadmin, 0, 16777215, initial(deadmin)) - clientfps = sanitize_integer(clientfps, 0, 1000, 0) - parallax = sanitize_integer(parallax, PARALLAX_DISABLE, PARALLAX_INSANE, null) - ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion)) - auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport)) - widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref)) - long_strip_menu = sanitize_integer(long_strip_menu, 0, 1, initial(long_strip_menu)) - pixel_size = sanitize_integer(pixel_size, PIXEL_SCALING_AUTO, PIXEL_SCALING_3X, initial(pixel_size)) - scaling_method = sanitize_text(scaling_method, initial(scaling_method)) + see_chat_non_mob = sanitize_integer(see_chat_non_mob, 0, 1, initial(see_chat_non_mob)) + tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy)) + tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock)) + buttons_locked = sanitize_integer(buttons_locked, 0, 1, initial(buttons_locked)) + windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing)) + default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot)) + toggles = sanitize_integer(toggles, 0, 16777215, initial(toggles)) + deadmin = sanitize_integer(deadmin, 0, 16777215, initial(deadmin)) + clientfps = sanitize_integer(clientfps, 0, 1000, 0) + parallax = sanitize_integer(parallax, PARALLAX_DISABLE, PARALLAX_INSANE, null) + ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion)) + auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport)) + widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref)) + long_strip_menu = sanitize_integer(long_strip_menu, 0, 1, initial(long_strip_menu)) + pixel_size = sanitize_integer(pixel_size, PIXEL_SCALING_AUTO, PIXEL_SCALING_3X, initial(pixel_size)) + scaling_method = sanitize_text(scaling_method, initial(scaling_method)) hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash)) hud_toggle_color = sanitize_hexcolor(hud_toggle_color, 6, 1, initial(hud_toggle_color)) - ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form)) - ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit)) - ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION) - ghost_others = sanitize_inlist(ghost_others, GLOB.ghost_others_options, GHOST_OTHERS_DEFAULT_OPTION) - menuoptions = SANITIZE_LIST(menuoptions) - be_special = SANITIZE_LIST(be_special) - pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style)) - pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color)) - pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT) - screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake)) - damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake)) - autostand = sanitize_integer(autostand, 0, 1, initial(autostand)) - cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles)) - auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc)) - no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage)) - key_bindings = sanitize_islist(key_bindings, list()) - modless_key_bindings = sanitize_islist(modless_key_bindings, list()) + ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form)) + ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit)) + ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION) + ghost_others = sanitize_inlist(ghost_others, GLOB.ghost_others_options, GHOST_OTHERS_DEFAULT_OPTION) + menuoptions = SANITIZE_LIST(menuoptions) + be_special = SANITIZE_LIST(be_special) + pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style)) + pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color)) + pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT) + screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake)) + damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake)) + autostand = sanitize_integer(autostand, 0, 1, initial(autostand)) + cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles)) + auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc)) + no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage)) + key_bindings = sanitize_islist(key_bindings, list()) + modless_key_bindings = sanitize_islist(modless_key_bindings, list()) favorite_outfits = SANITIZE_LIST(favorite_outfits) verify_keybindings_valid() // one of these days this will runtime and you'll be glad that i put it in a different proc so no one gets their saves wiped @@ -663,7 +675,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //Species var/species_id - S["species"] >> species_id + S["species"] >> species_id if(species_id) if(species_id == "avian" || species_id == "aquatic") species_id = "mammal" @@ -678,63 +690,63 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car scars_index = rand(1,5) // WHY //Character - S["real_name"] >> real_name - S["nameless"] >> nameless - S["custom_species"] >> custom_species - S["name_is_always_random"] >> be_random_name - S["body_is_always_random"] >> be_random_body - S["gender"] >> gender - S["body_model"] >> features["body_model"] - S["body_size"] >> features["body_size"] - S["age"] >> age - S["hair_color"] >> hair_color - S["facial_hair_color"] >> facial_hair_color - S["eye_type"] >> eye_type - S["left_eye_color"] >> left_eye_color - S["right_eye_color"] >> right_eye_color - S["use_custom_skin_tone"] >> use_custom_skin_tone - S["skin_tone"] >> skin_tone - S["hair_style_name"] >> hair_style - S["facial_style_name"] >> facial_hair_style - S["grad_style"] >> grad_style - S["grad_color"] >> grad_color - S["underwear"] >> underwear - S["undie_color"] >> undie_color - S["undershirt"] >> undershirt - S["shirt_color"] >> shirt_color - S["socks"] >> socks - S["socks_color"] >> socks_color - S["backbag"] >> backbag - S["jumpsuit_style"] >> jumpsuit_style - S["uplink_loc"] >> uplink_spawn_loc - S["custom_speech_verb"] >> custom_speech_verb - S["custom_tongue"] >> custom_tongue - S["additional_language"] >> additional_language - S["feature_mcolor"] >> features["mcolor"] - S["feature_lizard_tail"] >> features["tail_lizard"] - S["feature_lizard_snout"] >> features["snout"] - S["feature_lizard_horns"] >> features["horns"] - S["feature_lizard_frills"] >> features["frills"] - S["feature_lizard_spines"] >> features["spines"] - S["feature_lizard_legs"] >> features["legs"] - S["feature_human_tail"] >> features["tail_human"] - S["feature_human_ears"] >> features["ears"] - S["feature_deco_wings"] >> features["deco_wings"] - S["feature_insect_wings"] >> features["insect_wings"] - S["feature_insect_fluff"] >> features["insect_fluff"] - S["feature_insect_markings"] >> features["insect_markings"] - S["feature_arachnid_legs"] >> features["arachnid_legs"] - S["feature_arachnid_spinneret"] >> features["arachnid_spinneret"] - S["feature_arachnid_mandibles"] >> features["arachnid_mandibles"] - S["feature_horns_color"] >> features["horns_color"] - S["feature_wings_color"] >> features["wings_color"] - S["feature_color_scheme"] >> features["color_scheme"] + S["real_name"] >> real_name + S["nameless"] >> nameless + S["custom_species"] >> custom_species + S["name_is_always_random"] >> be_random_name + S["body_is_always_random"] >> be_random_body + S["gender"] >> gender + S["body_model"] >> features["body_model"] + S["body_size"] >> features["body_size"] + S["age"] >> age + S["hair_color"] >> hair_color + S["facial_hair_color"] >> facial_hair_color + S["eye_type"] >> eye_type + S["left_eye_color"] >> left_eye_color + S["right_eye_color"] >> right_eye_color + S["use_custom_skin_tone"] >> use_custom_skin_tone + S["skin_tone"] >> skin_tone + S["hair_style_name"] >> hair_style + S["facial_style_name"] >> facial_hair_style + S["grad_style"] >> grad_style + S["grad_color"] >> grad_color + S["underwear"] >> underwear + S["undie_color"] >> undie_color + S["undershirt"] >> undershirt + S["shirt_color"] >> shirt_color + S["socks"] >> socks + S["socks_color"] >> socks_color + S["backbag"] >> backbag + S["jumpsuit_style"] >> jumpsuit_style + S["uplink_loc"] >> uplink_spawn_loc + S["custom_speech_verb"] >> custom_speech_verb + S["custom_tongue"] >> custom_tongue + S["additional_language"] >> additional_language + S["feature_mcolor"] >> features["mcolor"] + S["feature_lizard_tail"] >> features["tail_lizard"] + S["feature_lizard_snout"] >> features["snout"] + S["feature_lizard_horns"] >> features["horns"] + S["feature_lizard_frills"] >> features["frills"] + S["feature_lizard_spines"] >> features["spines"] + S["feature_lizard_legs"] >> features["legs"] + S["feature_human_tail"] >> features["tail_human"] + S["feature_human_ears"] >> features["ears"] + S["feature_deco_wings"] >> features["deco_wings"] + S["feature_insect_wings"] >> features["insect_wings"] + S["feature_insect_fluff"] >> features["insect_fluff"] + S["feature_insect_markings"] >> features["insect_markings"] + S["feature_arachnid_legs"] >> features["arachnid_legs"] + S["feature_arachnid_spinneret"] >> features["arachnid_spinneret"] + S["feature_arachnid_mandibles"] >> features["arachnid_mandibles"] + S["feature_horns_color"] >> features["horns_color"] + S["feature_wings_color"] >> features["wings_color"] + S["feature_color_scheme"] >> features["color_scheme"] S["persistent_scars"] >> persistent_scars - S["scars1"] >> scars_list["1"] - S["scars2"] >> scars_list["2"] - S["scars3"] >> scars_list["3"] - S["scars4"] >> scars_list["4"] - S["scars5"] >> scars_list["5"] + S["scars1"] >> scars_list["1"] + S["scars2"] >> scars_list["2"] + S["scars3"] >> scars_list["3"] + S["scars4"] >> scars_list["4"] + S["scars5"] >> scars_list["5"] var/limbmodstr S["modified_limbs"] >> limbmodstr if(length(limbmodstr)) @@ -756,100 +768,94 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car else tcg_decks = list() - S["chosen_limb_id"] >> chosen_limb_id - S["hide_ckey"] >> hide_ckey //saved per-character + S["chosen_limb_id"] >> chosen_limb_id + S["hide_ckey"] >> hide_ckey //saved per-character //Custom names for(var/custom_name_id in GLOB.preferences_custom_names) var/savefile_slot_name = custom_name_id + "_name" //TODO remove this S[savefile_slot_name] >> custom_names[custom_name_id] - S["preferred_ai_core_display"] >> preferred_ai_core_display - S["prefered_security_department"] >> prefered_security_department + S["preferred_ai_core_display"] >> preferred_ai_core_display + S["prefered_security_department"] >> prefered_security_department //Jobs - S["joblessrole"] >> joblessrole + S["joblessrole"] >> joblessrole //Load prefs - S["job_preferences"] >> job_preferences + S["job_preferences"] >> job_preferences //Quirks - S["all_quirks"] >> all_quirks + S["all_quirks"] >> all_quirks //Records - S["security_records"] >> security_records - S["medical_records"] >> medical_records + S["security_records"] >> security_records + S["medical_records"] >> medical_records //Citadel code - S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"] - S["feature_mcolor2"] >> features["mcolor2"] - S["feature_mcolor3"] >> features["mcolor3"] + S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"] + S["feature_mcolor2"] >> features["mcolor2"] + S["feature_mcolor3"] >> features["mcolor3"] // note safe json decode will runtime the first time it migrates but this is fine and it solves itself don't worry about it if you see it error features["mam_body_markings"] = safe_json_decode(S["feature_mam_body_markings"]) - S["feature_mam_tail"] >> features["mam_tail"] - S["feature_mam_ears"] >> features["mam_ears"] - S["feature_mam_tail_animated"] >> features["mam_tail_animated"] - S["feature_taur"] >> features["taur"] - S["feature_mam_snouts"] >> features["mam_snouts"] - S["feature_meat"] >> features["meat_type"] + S["feature_mam_tail"] >> features["mam_tail"] + S["feature_mam_ears"] >> features["mam_ears"] + S["feature_mam_tail_animated"] >> features["mam_tail_animated"] + S["feature_taur"] >> features["taur"] + S["feature_mam_snouts"] >> features["mam_snouts"] + S["feature_meat"] >> features["meat_type"] //Xeno features - S["feature_xeno_tail"] >> features["xenotail"] - S["feature_xeno_dors"] >> features["xenodorsal"] - S["feature_xeno_head"] >> features["xenohead"] + S["feature_xeno_tail"] >> features["xenotail"] + S["feature_xeno_dors"] >> features["xenodorsal"] + S["feature_xeno_head"] >> features["xenohead"] //cock features - S["feature_has_cock"] >> features["has_cock"] - S["feature_cock_shape"] >> features["cock_shape"] - S["feature_cock_color"] >> features["cock_color"] - S["feature_cock_length"] >> features["cock_length"] - S["feature_cock_diameter"] >> features["cock_diameter"] - S["feature_cock_taur"] >> features["cock_taur"] - S["feature_cock_visibility"] >> features["cock_visibility"] + S["feature_has_cock"] >> features["has_cock"] + S["feature_cock_shape"] >> features["cock_shape"] + S["feature_cock_color"] >> features["cock_color"] + S["feature_cock_length"] >> features["cock_length"] + S["feature_cock_diameter"] >> features["cock_diameter"] + S["feature_cock_taur"] >> features["cock_taur"] + S["feature_cock_visibility"] >> features["cock_visibility"] //balls features - S["feature_has_balls"] >> features["has_balls"] - S["feature_balls_color"] >> features["balls_color"] - S["feature_balls_shape"] >> features["balls_shape"] - S["feature_balls_size"] >> features["balls_size"] - S["feature_balls_visibility"] >> features["balls_visibility"] + S["feature_has_balls"] >> features["has_balls"] + S["feature_balls_color"] >> features["balls_color"] + S["feature_balls_shape"] >> features["balls_shape"] + S["feature_balls_size"] >> features["balls_size"] + S["feature_balls_visibility"] >> features["balls_visibility"] //breasts features - S["feature_has_breasts"] >> features["has_breasts"] - S["feature_breasts_size"] >> features["breasts_size"] - S["feature_breasts_shape"] >> features["breasts_shape"] - S["feature_breasts_color"] >> features["breasts_color"] - S["feature_breasts_producing"] >> features["breasts_producing"] - S["feature_breasts_visibility"] >> features["breasts_visibility"] + S["feature_has_breasts"] >> features["has_breasts"] + S["feature_breasts_size"] >> features["breasts_size"] + S["feature_breasts_shape"] >> features["breasts_shape"] + S["feature_breasts_color"] >> features["breasts_color"] + S["feature_breasts_producing"] >> features["breasts_producing"] + S["feature_breasts_visibility"] >> features["breasts_visibility"] //vagina features - S["feature_has_vag"] >> features["has_vag"] - S["feature_vag_shape"] >> features["vag_shape"] - S["feature_vag_color"] >> features["vag_color"] - S["feature_vag_visibility"] >> features["vag_visibility"] + S["feature_has_vag"] >> features["has_vag"] + S["feature_vag_shape"] >> features["vag_shape"] + S["feature_vag_color"] >> features["vag_color"] + S["feature_vag_visibility"] >> features["vag_visibility"] //womb features - S["feature_has_womb"] >> features["has_womb"] + S["feature_has_womb"] >> features["has_womb"] //butt features - S["feature_has_butt"] >> features["has_butt"] - S["feature_butt_color"] >> features["butt_color"] - S["feature_butt_size"] >> features["butt_size"] - S["feature_butt_visibility"] >> features["butt_visibility"] + S["feature_has_butt"] >> features["has_butt"] + S["feature_butt_color"] >> features["butt_color"] + S["feature_butt_size"] >> features["butt_size"] + S["feature_butt_visibility"] >> features["butt_visibility"] - //flavor text - //Let's make our players NOT cry desperately as we wipe their savefiles of their special snowflake texts: - if((S["flavor_text"] != "") && (S["flavor_text"] != null) && S["flavor_text"]) //If old text isn't null and isn't "" but still exists. - S["flavor_text"] >> features["flavor_text"] //Load old flavortext as current dna-based flavortext + // Flavor texts, Made into a standard. + S["feature_flavor_text"] >> features["flavor_text"] + S["feature_silicon_flavor_text"] >> features["silicon_flavor_text"] + S["feature_ooc_notes"] >> features["ooc_notes"] - WRITE_FILE(S["feature_flavor_text"], features["flavor_text"]) //Save it in our new type of flavor-text - WRITE_FILE(S["flavor_text"] , "") //Remove old flavortext, completing the cut-and-paste into the new format. + // Barks + S["bark_id"] >> bark_id + S["bark_speed"] >> bark_speed + S["bark_pitch"] >> bark_pitch + S["bark_variance"] >> bark_variance - else //We have no old flavortext, default to new - S["feature_flavor_text"] >> features["flavor_text"] - - - S["silicon_feature_flavor_text"] >> features["silicon_flavor_text"] - - S["feature_ooc_notes"] >> features["ooc_notes"] - S["silicon_flavor_text"] >> features["silicon_flavor_text"] - - S["vore_flags"] >> vore_flags - S["vore_taste"] >> vore_taste - S["vore_smell"] >> vore_smell + S["vore_flags"] >> vore_flags + S["vore_taste"] >> vore_taste + S["vore_smell"] >> vore_smell var/char_vr_path = "[vr_path]/character_[default_slot]_v2.json" if(fexists(char_vr_path)) var/list/json_from_file = json_decode(file2text(char_vr_path)) @@ -869,69 +875,69 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //Sanitize - real_name = reject_bad_name(real_name) - gender = sanitize_gender(gender, TRUE, TRUE) + real_name = reject_bad_name(real_name) + gender = sanitize_gender(gender, TRUE, TRUE) features["body_model"] = sanitize_gender(features["body_model"], FALSE, FALSE, gender == FEMALE ? FEMALE : MALE) if(!real_name) - real_name = random_unique_name(gender) - custom_species = reject_bad_name(custom_species) + real_name = random_unique_name(gender) + custom_species = reject_bad_name(custom_species) for(var/custom_name_id in GLOB.preferences_custom_names) var/namedata = GLOB.preferences_custom_names[custom_name_id] custom_names[custom_name_id] = reject_bad_name(custom_names[custom_name_id],namedata["allow_numbers"]) if(!custom_names[custom_name_id]) custom_names[custom_name_id] = get_default_name(custom_name_id) - nameless = sanitize_integer(nameless, 0, 1, initial(nameless)) - be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name)) - be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body)) + nameless = sanitize_integer(nameless, 0, 1, initial(nameless)) + be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name)) + be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body)) - hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_list) - facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_list) - underwear = sanitize_inlist(underwear, GLOB.underwear_list) - undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list) - undie_color = sanitize_hexcolor(undie_color, 6, FALSE, initial(undie_color)) - shirt_color = sanitize_hexcolor(shirt_color, 6, FALSE, initial(shirt_color)) - socks = sanitize_inlist(socks, GLOB.socks_list) - socks_color = sanitize_hexcolor(socks_color, 6, FALSE, initial(socks_color)) - age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) - hair_color = sanitize_hexcolor(hair_color, 6, FALSE) - facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE) - grad_style = sanitize_inlist(grad_style, GLOB.hair_gradients_list, "None") - grad_color = sanitize_hexcolor(grad_color, 6, FALSE) - eye_type = sanitize_inlist(eye_type, GLOB.eye_types, DEFAULT_EYES_TYPE) - left_eye_color = sanitize_hexcolor(left_eye_color, 6, FALSE) - right_eye_color = sanitize_hexcolor(right_eye_color, 6, FALSE) + hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_list) + facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_list) + underwear = sanitize_inlist(underwear, GLOB.underwear_list) + undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list) + undie_color = sanitize_hexcolor(undie_color, 6, FALSE, initial(undie_color)) + shirt_color = sanitize_hexcolor(shirt_color, 6, FALSE, initial(shirt_color)) + socks = sanitize_inlist(socks, GLOB.socks_list) + socks_color = sanitize_hexcolor(socks_color, 6, FALSE, initial(socks_color)) + age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) + hair_color = sanitize_hexcolor(hair_color, 6, FALSE) + facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE) + grad_style = sanitize_inlist(grad_style, GLOB.hair_gradients_list, "None") + grad_color = sanitize_hexcolor(grad_color, 6, FALSE) + eye_type = sanitize_inlist(eye_type, GLOB.eye_types, DEFAULT_EYES_TYPE) + left_eye_color = sanitize_hexcolor(left_eye_color, 6, FALSE) + right_eye_color = sanitize_hexcolor(right_eye_color, 6, FALSE) var/static/allow_custom_skintones if(isnull(allow_custom_skintones)) allow_custom_skintones = CONFIG_GET(flag/allow_custom_skintones) - use_custom_skin_tone = allow_custom_skintones ? sanitize_integer(use_custom_skin_tone, FALSE, TRUE, initial(use_custom_skin_tone)) : FALSE + use_custom_skin_tone = allow_custom_skintones ? sanitize_integer(use_custom_skin_tone, FALSE, TRUE, initial(use_custom_skin_tone)) : FALSE if(use_custom_skin_tone) - skin_tone = sanitize_hexcolor(skin_tone, 6, TRUE, "#FFFFFF") + skin_tone = sanitize_hexcolor(skin_tone, 6, TRUE, "#FFFFFF") else - skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones - GLOB.nonstandard_skin_tones, initial(skin_tone)) + skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones - GLOB.nonstandard_skin_tones, initial(skin_tone)) - features["horns_color"] = sanitize_hexcolor(features["horns_color"], 6, FALSE, "85615a") - features["wings_color"] = sanitize_hexcolor(features["wings_color"], 6, FALSE, "FFFFFF") - backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag)) - jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style)) - uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc)) - features["mcolor"] = sanitize_hexcolor(features["mcolor"], 6, FALSE) - features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard) - features["tail_human"] = sanitize_inlist(features["tail_human"], GLOB.tails_list_human) - features["snout"] = sanitize_inlist(features["snout"], GLOB.snouts_list) - features["horns"] = sanitize_inlist(features["horns"], GLOB.horns_list) - features["ears"] = sanitize_inlist(features["ears"], GLOB.ears_list) - features["frills"] = sanitize_inlist(features["frills"], GLOB.frills_list) - features["spines"] = sanitize_inlist(features["spines"], GLOB.spines_list) - features["legs"] = sanitize_inlist(features["legs"], GLOB.legs_list, "Plantigrade") - features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None") - features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list) - features["insect_markings"] = sanitize_inlist(features["insect_markings"], GLOB.insect_markings_list, "None") - features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list) - features["arachnid_legs"] = sanitize_inlist(features["arachnid_legs"], GLOB.arachnid_legs_list, "Plain") - features["arachnid_spinneret"] = sanitize_inlist(features["arachnid_spinneret"], GLOB.arachnid_spinneret_list, "Plain") - features["arachnid_mandibles"] = sanitize_inlist(features["arachnid_mandibles"], GLOB.arachnid_mandibles_list, "Plain") + features["horns_color"] = sanitize_hexcolor(features["horns_color"], 6, FALSE, "85615a") + features["wings_color"] = sanitize_hexcolor(features["wings_color"], 6, FALSE, "FFFFFF") + backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag)) + jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style)) + uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc)) + features["mcolor"] = sanitize_hexcolor(features["mcolor"], 6, FALSE) + features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard) + features["tail_human"] = sanitize_inlist(features["tail_human"], GLOB.tails_list_human) + features["snout"] = sanitize_inlist(features["snout"], GLOB.snouts_list) + features["horns"] = sanitize_inlist(features["horns"], GLOB.horns_list) + features["ears"] = sanitize_inlist(features["ears"], GLOB.ears_list) + features["frills"] = sanitize_inlist(features["frills"], GLOB.frills_list) + features["spines"] = sanitize_inlist(features["spines"], GLOB.spines_list) + features["legs"] = sanitize_inlist(features["legs"], GLOB.legs_list, "Plantigrade") + features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None") + features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list) + features["insect_markings"] = sanitize_inlist(features["insect_markings"], GLOB.insect_markings_list, "None") + features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list) + features["arachnid_legs"] = sanitize_inlist(features["arachnid_legs"], GLOB.arachnid_legs_list, "Plain") + features["arachnid_spinneret"] = sanitize_inlist(features["arachnid_spinneret"], GLOB.arachnid_spinneret_list, "Plain") + features["arachnid_mandibles"] = sanitize_inlist(features["arachnid_mandibles"], GLOB.arachnid_mandibles_list, "Plain") var/static/size_min if(!size_min) @@ -939,7 +945,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/static/size_max if(!size_max) size_max = CONFIG_GET(number/body_size_max) - features["body_size"] = sanitize_num_clamp(features["body_size"], size_min, size_max, RESIZE_DEFAULT_SIZE, 0.01) + features["body_size"] = sanitize_num_clamp(features["body_size"], size_min, size_max, RESIZE_DEFAULT_SIZE, 0.01) var/static/list/B_sizes if(!B_sizes) @@ -963,33 +969,33 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/list/L = CONFIG_GET(keyed_list/safe_visibility_toggles) safe_visibilities = L.Copy() - features["breasts_size"] = sanitize_inlist(features["breasts_size"], B_sizes, BREASTS_SIZE_DEF) - features["cock_length"] = sanitize_integer(features["cock_length"], min_D, max_D, COCK_SIZE_DEF) - features["butt_size"] = sanitize_integer(features["butt_size"], min_B, max_B, BUTT_SIZE_DEF) - features["breasts_shape"] = sanitize_inlist(features["breasts_shape"], GLOB.breasts_shapes_list, DEF_BREASTS_SHAPE) - features["cock_shape"] = sanitize_inlist(features["cock_shape"], GLOB.cock_shapes_list, DEF_COCK_SHAPE) - features["balls_shape"] = sanitize_inlist(features["balls_shape"], GLOB.balls_shapes_list, DEF_BALLS_SHAPE) - features["vag_shape"] = sanitize_inlist(features["vag_shape"], GLOB.vagina_shapes_list, DEF_VAGINA_SHAPE) - features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 6, FALSE, "FFFFFF") - features["cock_color"] = sanitize_hexcolor(features["cock_color"], 6, FALSE, "FFFFFF") - features["balls_color"] = sanitize_hexcolor(features["balls_color"], 6, FALSE, "FFFFFF") - features["vag_color"] = sanitize_hexcolor(features["vag_color"], 6, FALSE, "FFFFFF") - features["breasts_visibility"] = sanitize_inlist(features["breasts_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) - features["cock_visibility"] = sanitize_inlist(features["cock_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) - features["balls_visibility"] = sanitize_inlist(features["balls_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) - features["vag_visibility"] = sanitize_inlist(features["vag_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) - features["butt_visibility"] = sanitize_inlist(features["butt_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + features["breasts_size"] = sanitize_inlist(features["breasts_size"], B_sizes, BREASTS_SIZE_DEF) + features["cock_length"] = sanitize_integer(features["cock_length"], min_D, max_D, COCK_SIZE_DEF) + features["butt_size"] = sanitize_integer(features["butt_size"], min_B, max_B, BUTT_SIZE_DEF) + features["breasts_shape"] = sanitize_inlist(features["breasts_shape"], GLOB.breasts_shapes_list, DEF_BREASTS_SHAPE) + features["cock_shape"] = sanitize_inlist(features["cock_shape"], GLOB.cock_shapes_list, DEF_COCK_SHAPE) + features["balls_shape"] = sanitize_inlist(features["balls_shape"], GLOB.balls_shapes_list, DEF_BALLS_SHAPE) + features["vag_shape"] = sanitize_inlist(features["vag_shape"], GLOB.vagina_shapes_list, DEF_VAGINA_SHAPE) + features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 6, FALSE, "FFFFFF") + features["cock_color"] = sanitize_hexcolor(features["cock_color"], 6, FALSE, "FFFFFF") + features["balls_color"] = sanitize_hexcolor(features["balls_color"], 6, FALSE, "FFFFFF") + features["vag_color"] = sanitize_hexcolor(features["vag_color"], 6, FALSE, "FFFFFF") + features["breasts_visibility"] = sanitize_inlist(features["breasts_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + features["cock_visibility"] = sanitize_inlist(features["cock_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + features["balls_visibility"] = sanitize_inlist(features["balls_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + features["vag_visibility"] = sanitize_inlist(features["vag_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + features["butt_visibility"] = sanitize_inlist(features["butt_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) - custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default") - custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default") - additional_language = sanitize_inlist(additional_language, GLOB.roundstart_languages, "None") + custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default") + custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default") + additional_language = sanitize_inlist(additional_language, GLOB.roundstart_languages, "None") - security_records = copytext(security_records, 1, MAX_FLAVOR_LEN) - medical_records = copytext(medical_records, 1, MAX_FLAVOR_LEN) + security_records = copytext(security_records, 1, MAX_FLAVOR_LEN) + medical_records = copytext(medical_records, 1, MAX_FLAVOR_LEN) - features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN) - features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN) - features["ooc_notes"] = copytext(features["ooc_notes"], 1, MAX_FLAVOR_LEN) + features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN) + features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN) + features["ooc_notes"] = copytext(features["ooc_notes"], 1, MAX_FLAVOR_LEN) //load every advanced coloring mode thing in one go //THIS MUST BE DONE AFTER ALL FEATURE SAVES OR IT WILL NOT WORK @@ -1011,11 +1017,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car message_admins("Sprite Accessory Failure (loading data): Accessory [accessory.type] is a matrixed item without any matrixed sections set!") continue if(S["feature_[primary_string]"]) - S["feature_[primary_string]"] >> features[primary_string] + S["feature_[primary_string]"] >> features[primary_string] if(S["feature_[secondary_string]"]) - S["feature_[secondary_string]"] >> features[secondary_string] + S["feature_[secondary_string]"] >> features[secondary_string] if(S["feature_[tertiary_string]"]) - S["feature_[tertiary_string]"] >> features[tertiary_string] + S["feature_[tertiary_string]"] >> features[tertiary_string] persistent_scars = sanitize_integer(persistent_scars) scars_list["1"] = sanitize_text(scars_list["1"]) @@ -1024,7 +1030,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car scars_list["4"] = sanitize_text(scars_list["4"]) scars_list["5"] = sanitize_text(scars_list["5"]) - joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole)) + bark_id = sanitize_inlist(bark_id, GLOB.bark_list, pick(GLOB.bark_random_list)) + var/datum/bark/bark_path = GLOB.bark_list[bark_id] + bark_speed = sanitize_num_clamp(bark_speed, initial(bark_path.minspeed), initial(bark_path.maxspeed), initial(bark_speed)) + bark_pitch = sanitize_num_clamp(bark_pitch, initial(bark_path.minpitch), initial(bark_path.maxpitch), BARK_PITCH_RAND(gender)) + bark_variance = sanitize_num_clamp(bark_variance, initial(bark_path.minvariance), initial(bark_path.maxvariance), BARK_VARIANCE_RAND) + + joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole)) //Validate job prefs for(var/j in job_preferences) if(job_preferences["[j]"] != JP_LOW && job_preferences["[j]"] != JP_MEDIUM && job_preferences["[j]"] != JP_HIGH) @@ -1032,10 +1044,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car all_quirks = SANITIZE_LIST(all_quirks) - vore_flags = sanitize_integer(vore_flags, 0, MAX_VORE_FLAG, 0) - vore_taste = copytext(vore_taste, 1, MAX_TASTE_LEN) - vore_smell = copytext(vore_smell, 1, MAX_TASTE_LEN) - belly_prefs = SANITIZE_LIST(belly_prefs) + vore_flags = sanitize_integer(vore_flags, 0, MAX_VORE_FLAG, 0) + vore_taste = copytext(vore_taste, 1, MAX_TASTE_LEN) + vore_smell = copytext(vore_smell, 1, MAX_TASTE_LEN) + belly_prefs = SANITIZE_LIST(belly_prefs) cit_character_pref_load(S) @@ -1091,6 +1103,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["custom_speech_verb"] , custom_speech_verb) WRITE_FILE(S["custom_tongue"] , custom_tongue) WRITE_FILE(S["additional_language"] , additional_language) + WRITE_FILE(S["bark_id"] , bark_id) + WRITE_FILE(S["bark_speed"] , bark_speed) + WRITE_FILE(S["bark_pitch"] , bark_pitch) + WRITE_FILE(S["bark_variance"] , bark_variance) // records WRITE_FILE(S["security_records"] , security_records) diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index a019ade471..c4d0aa0e80 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -227,6 +227,17 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggleprayersounds)() return C.prefs.toggles & SOUND_PRAYERS +TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggle_bark)() + set name = "Hear/Silence Vocal Barks" + set category = "Preferences" + set desc = "Hear Vocal Barks" + usr.client.prefs.toggles ^= SOUND_BARK + usr.client.prefs.save_preferences() + to_chat(usr, "You will now [(usr.client.prefs.toggles & SOUND_BARK) ? "hear" : "no longer hear"] vocal barks when other people talk.") + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Vocal Barks", "[usr.client.prefs.toggles & SOUND_BARK ? "Enabled" : "Disabled"]")) +/datum/verbs/menu/Settings/Sound/toggle_bark/Get_checked(client/C) + return C.prefs.toggles & SOUND_BARK + /datum/verbs/menu/Settings/Sound/verb/stop_client_sounds() set name = "Stop Sounds" set category = "Preferences" diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm index 4b558d6604..cec4324b3c 100644 --- a/code/modules/clothing/gloves/_gloves.dm +++ b/code/modules/clothing/gloves/_gloves.dm @@ -32,7 +32,7 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color()) + . += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/gloves/update_clothes_damaged_state() ..() diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 6fc0fabf31..d3ad2ca4c7 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -360,3 +360,12 @@ desc = "Thin, pretty gloves intended for use in sexy feminine attire. A tag on the hem claims they pair great with black stockings." icon_state = "eveningblack" item_state = "eveningblack" + +/obj/item/clothing/gloves/polymaid + name = "polychromic maid gloves" + desc = "Colourable maid gloves!" + icon_state = "maid_arms" + +/obj/item/clothing/gloves/polymaid/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm index 29a07fd177..884c23e7c0 100644 --- a/code/modules/clothing/head/_head.dm +++ b/code/modules/clothing/head/_head.dm @@ -55,7 +55,7 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color()) + . += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/head/update_clothes_damaged_state() ..() diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 4e7ccb7111..f3868f703f 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -477,6 +477,15 @@ item_state = "maid" dynamic_hair_suffix = "" +/obj/item/clothing/head/maid/polychromic + name = "polychromic maid headband" + icon_state = "polymaid" + item_state = "polymaid" + +/obj/item/clothing/head/maid/polychromic/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) + /obj/item/clothing/head/widered name = "Wide red hat" desc = "It is both wide, and red. Stylish!" diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm index cca13ce1d8..b30adedb4b 100644 --- a/code/modules/clothing/masks/_masks.dm +++ b/code/modules/clothing/masks/_masks.dm @@ -36,7 +36,7 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color()) + . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/mask/update_clothes_damaged_state() ..() diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index f498c02cfe..f96fe2ac2a 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -113,6 +113,50 @@ to_chat(user, "Your Joy mask now has a [choice] Emotion!") return 1 +/obj/item/clothing/mask/kitsuneblk + name = "Black Kitsune Mask" + desc = "An oriental styled porcelain mask, this one is black and gold." + icon_state = "blackkitsunemask" + item_state = "blackkitsunemask" + w_class = WEIGHT_CLASS_TINY + flags_cover = MASKCOVERSMOUTH + flags_inv = HIDEFACE|HIDEFACIALHAIR + visor_flags_inv = HIDEFACE|HIDEFACIALHAIR + visor_flags_cover = MASKCOVERSMOUTH + slot_flags = ITEM_SLOT_MASK + +/obj/item/clothing/mask/kitsuneblk/attack_self(mob/user) + adjustmask(user) + +/obj/item/clothing/mask/kitsuneblk/AltClick(mob/user) + . = ..() + if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + adjustmask(user) + return TRUE + +/obj/item/clothing/mask/kitsunewhi + name = "White Kitsune Mask" + desc = "An oriental styled porcelain mask, this one is white and red." + icon_state = "whitekitsunemask" + item_state = "whitekitsunemask" + w_class = WEIGHT_CLASS_TINY + flags_cover = MASKCOVERSMOUTH + flags_inv = HIDEFACE|HIDEFACIALHAIR + visor_flags_inv = HIDEFACE|HIDEFACIALHAIR + visor_flags_cover = MASKCOVERSMOUTH + slot_flags = ITEM_SLOT_MASK + +/obj/item/clothing/mask/kitsunewhi/attack_self(mob/user) + adjustmask(user) + +/obj/item/clothing/mask/kitsunewhi/AltClick(mob/user) + . = ..() + if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + adjustmask(user) + return TRUE + /obj/item/clothing/mask/pig name = "pig mask" desc = "A rubber pig mask with a builtin voice modulator." diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 4f852fb301..7ac2f65205 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -13,7 +13,7 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color()) + . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/neck/tie name = "tie" @@ -259,6 +259,15 @@ name = "Collar Key" desc = "A key for a tiny lock on a collar or bag." +/obj/item/clothing/neck/maid + name = "polychromic maid collar" + desc = "A collar that goes with the polychromic maid outfit." + icon_state = "maid_neck" + +/obj/item/clothing/neck/maid/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) + ////////////// //DOPE BLING// ////////////// diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index d8ac875df5..e17396626c 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -19,6 +19,7 @@ var/last_bloodtype = "" //used to track the last bloodtype to have graced these shoes; makes for better performing footprint shenanigans var/last_blood_DNA = "" //same as last one var/last_blood_color = "" + var/last_blood_blend = null ///Whether these shoes have laces that can be tied/untied var/can_be_tied = TRUE @@ -68,6 +69,7 @@ last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works last_blood_DNA = blood_dna[blood_dna.len] last_blood_color = blood_dna["color"] + last_blood_blend = blood_dna["blendmode"] /obj/item/clothing/shoes/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) . = ..() @@ -82,7 +84,7 @@ . += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe") if(bloody) var/file2use = style_flags & STYLE_DIGITIGRADE ? 'icons/mob/clothing/feet_digi.dmi' : 'icons/effects/blood.dmi' - . += mutable_appearance(file2use, "shoeblood", color = blood_DNA_to_color()) + . += mutable_appearance(file2use, "shoeblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/shoes/equipped(mob/user, slot) . = ..() diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 06c2c19ad8..cdf5512fc6 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -213,6 +213,7 @@ heat_protection = FEET|LEGS max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF + lace_time = 10 SECONDS /obj/item/clothing/shoes/cult name = "\improper Nar'Sien invoker boots" diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index fa4614429c..202ee4cc0d 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -20,14 +20,14 @@ . += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]") if(blood_DNA) var/file2use = (style_flags & STYLE_ALL_TAURIC) ? 'modular_citadel/icons/mob/64x32_effects.dmi' : 'icons/effects/blood.dmi' - . += mutable_appearance(file2use, "[blood_overlay_type]blood", color = blood_DNA_to_color()) + . += mutable_appearance(file2use, "[blood_overlay_type]blood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) var/mob/living/carbon/human/M = loc if(ishuman(M) && M.w_uniform) var/obj/item/clothing/under/U = M.w_uniform if(istype(U) && U.attached_accessory) var/obj/item/clothing/accessory/A = U.attached_accessory if(A.above_suit) - . += U.accessory_overlay + . += U.accessory_overlays /obj/item/clothing/suit/update_clothes_damaged_state() ..() diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index e5b3dfe427..c13a8bfa66 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -84,6 +84,23 @@ "Cloak" = "trenchcloak" ) +/obj/item/clothing/suit/armor/hos/platecarrier + name = "plate carrier" + desc = "An armor vest with attached pockets for holding and sorting equipment or ammo." + icon_state = "platecarrier" + item_state = "platecarrier" + body_parts_covered = CHEST|GROIN|ARMS + armor = list (MELEE = 30, BULLET = 40, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 70, WOUND = 10) + cold_protection = CHEST|ARMS + heat_protection = CHEST|ARMS + strip_delay = 80 + mutantrace_variation = STYLE_DIGITIGRADE + +/obj/item/clothing/suit/armor/hos/platecarrier/ComponentInitialize() + . = ..() + var/datum/component/storage/concrete/storage = AddComponent(/datum/component/storage/concrete) + storage.max_items = 5 + /obj/item/clothing/suit/armor/vest/warden name = "warden's jacket" desc = "A navy-blue armored jacket with blue shoulder designations and '/Warden/' stitched into one of the chest pockets." diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index e806ebf906..2fc5270a6b 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -20,7 +20,7 @@ var/alt_covers_chest = FALSE // for adjusted/rolled-down jumpsuits, FALSE = exposes chest and arms, TRUE = exposes arms only var/dummy_thick = FALSE // is able to hold accessories on its item var/obj/item/clothing/accessory/attached_accessory - var/mutable_appearance/accessory_overlay + var/list/accessory_overlays /obj/item/clothing/under/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) . = ..() @@ -29,9 +29,9 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color()) - if(accessory_overlay) - . += accessory_overlay + . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) + if(length(accessory_overlays)) + . += accessory_overlays /obj/item/clothing/under/attackby(obj/item/I, mob/user, params) if((sensordamage || (has_sensor < HAS_SENSORS && has_sensor != NO_SENSORS)) && istype(I, /obj/item/stack/cable_coil)) @@ -154,9 +154,15 @@ if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY)) return TRUE - accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', attached_accessory.icon_state) - accessory_overlay.alpha = attached_accessory.alpha - accessory_overlay.color = attached_accessory.color + var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays") + if(!polychromic) + var/mutable_appearance/accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', attached_accessory.icon_state) + accessory_overlay.alpha = attached_accessory.alpha + accessory_overlay.color = attached_accessory.color + accessory_overlays = list(accessory_overlay) + else + accessory_overlays = list() + polychromic.apply_worn_overlays(I, FALSE, 'icons/mob/clothing/accessories.dmi', I.item_state || I.icon_state, NONE, accessory_overlays) if(ishuman(loc)) var/mob/living/carbon/human/H = loc diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index ca1b8f0552..4d967be1eb 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -57,7 +57,7 @@ plane = initial(plane) U.cut_overlays() U.attached_accessory = null - U.accessory_overlay = null + U.accessory_overlays = null /obj/item/clothing/accessory/proc/on_uniform_equip(obj/item/clothing/under/U, user) return @@ -255,6 +255,15 @@ item_state = "maidapron" minimize_when_attached = FALSE +/obj/item/clothing/accessory/maidapron/polychromic + name = "polychromic maid apron" + icon_state = "polymaidapron" + item_state = "polymaidapron" + +/obj/item/clothing/accessory/maidapron/polychromic/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) + /obj/item/clothing/accessory/sleevecrop name = "one sleeved crop top" desc = "Off the shoulder crop top, for those nights out partying." diff --git a/code/modules/events/anomaly_flux.dm b/code/modules/events/anomaly_flux.dm index 0ba347af57..4dd8dd87c5 100644 --- a/code/modules/events/anomaly_flux.dm +++ b/code/modules/events/anomaly_flux.dm @@ -2,7 +2,6 @@ name = "Anomaly: Hyper-Energetic Flux" typepath = /datum/round_event/anomaly/anomaly_flux - min_players = 10 max_occurrences = 5 weight = 20 diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm index 29c6e15d28..1ac010344e 100644 --- a/code/modules/events/anomaly_pyro.dm +++ b/code/modules/events/anomaly_pyro.dm @@ -2,6 +2,7 @@ name = "Anomaly: Pyroclastic" typepath = /datum/round_event/anomaly/anomaly_pyro + min_players = 5 max_occurrences = 5 weight = 20 diff --git a/code/modules/events/atmos_speed.dm b/code/modules/events/atmos_speed.dm index 9b248e2775..17a02d3dd1 100644 --- a/code/modules/events/atmos_speed.dm +++ b/code/modules/events/atmos_speed.dm @@ -1,13 +1,13 @@ /datum/round_event_control/atmos_flux name = "Atmospheric Flux" typepath = /datum/round_event/atmos_flux - max_occurrences = 1 - weight = 5 - endWhen = 600 - var/original_speed + max_occurrences = 5 + weight = 10 /datum/round_event/atmos_flux announceWhen = 1 + endWhen = 600 + var/original_speed /datum/round_event/atmos_flux/announce(fake) priority_announce("Atmospheric flux in your sector detected. Sensors show that air may move [(SSair.share_max_steps_target > original_speed) ? "faster" : "slower"] than usual for some time.", "Atmos Alert") diff --git a/code/modules/events/brain_trauma.dm b/code/modules/events/brain_trauma.dm index 3d39f8720a..0529d102dc 100644 --- a/code/modules/events/brain_trauma.dm +++ b/code/modules/events/brain_trauma.dm @@ -5,7 +5,8 @@ min_players = 5 /datum/round_event_control/brain_trauma/canSpawnEvent(var/players_amt, var/gamemode) - var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic") + if(!..()) return FALSE + var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic","AI","Chemist","Virologist","Captain","Head of Personnel","Roboticist") for (var/mob/M in GLOB.alive_mob_list) if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles)) return TRUE diff --git a/code/modules/events/cat_surgeon.dm b/code/modules/events/cat_surgeon.dm index 76c72a7ec2..cf6e34fd65 100644 --- a/code/modules/events/cat_surgeon.dm +++ b/code/modules/events/cat_surgeon.dm @@ -2,7 +2,7 @@ name = "Cat Surgeon" typepath = /datum/round_event/cat_surgeon max_occurrences = 1 - weight = 8 + weight = 5 /datum/round_event/cat_surgeon/announce(fake) priority_announce("One of our... ahem... 'special' cases has escaped. As it happens their last known location before their tracker went dead is your station so keep an eye out for them. On an unrelated note, has anyone seen our cats?", diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 490cd0ff21..517cf33b82 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -2,7 +2,7 @@ name = "Disease Outbreak" typepath = /datum/round_event/disease_outbreak max_occurrences = 1 - min_players = 10 + min_players = 3 weight = 5 /datum/round_event/disease_outbreak @@ -12,6 +12,13 @@ var/max_severity = 3 +/datum/round_event_control/disease_outbreak/canSpawnEvent(var/players_amt, var/gamemode) + if(!..()) return FALSE + var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic","AI","Chemist","Virologist","Captain","Head of Personnel", "Geneticist") + for (var/mob/M in GLOB.alive_mob_list) + if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles)) + return TRUE + return FALSE /datum/round_event/disease_outbreak/announce(fake) priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak7") @@ -22,7 +29,10 @@ /datum/round_event/disease_outbreak/start() var/advanced_virus = FALSE - max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + var/player_count = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) + max_severity = 1 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + max_severity += player_count > 5 + max_severity += player_count > 10 if(prob(20 + (10 * max_severity))) advanced_virus = TRUE diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm index eb7edcafbf..3bece46dcd 100644 --- a/code/modules/events/dust.dm +++ b/code/modules/events/dust.dm @@ -17,9 +17,10 @@ /datum/round_event_control/sandstorm name = "Sandstorm" typepath = /datum/round_event/sandstorm - weight = 0 - max_occurrences = 0 - earliest_start = 0 MINUTES + weight = 5 + max_occurrences = 1 + min_players = 5 + earliest_start = 20 MINUTES /datum/round_event/sandstorm startWhen = 1 diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm index 8c33e69107..930a2b884f 100644 --- a/code/modules/events/heart_attack.dm +++ b/code/modules/events/heart_attack.dm @@ -1,9 +1,17 @@ /datum/round_event_control/heart_attack name = "Random Heart Attack" typepath = /datum/round_event/heart_attack - weight = 20 + weight = 10 max_occurrences = 2 - min_players = 40 // To avoid shafting lowpop + min_players = 10 // To avoid shafting lowpop + +/datum/round_event_control/heart_attack/canSpawnEvent(var/players_amt, var/gamemode) + if(!..()) return FALSE + var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic","Chemist") + for (var/mob/M in GLOB.alive_mob_list) + if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles)) + return TRUE + return FALSE /datum/round_event/heart_attack/start() var/list/heart_attack_contestants = list() diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm index 263e3aa660..9824355e4b 100644 --- a/code/modules/events/holiday/halloween.dm +++ b/code/modules/events/holiday/halloween.dm @@ -15,9 +15,9 @@ for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list) Ian.place_on_head(new /obj/item/bedsheet(Ian)) - for(var/mob/living/simple_animal/parrot/Poly/Poly in GLOB.mob_living_list) - new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc) - qdel(Poly) + for(var/mob/living/simple_animal/parrot/Polly/Polly in GLOB.mob_living_list) + new /mob/living/simple_animal/parrot/Polly/ghost(Polly.loc) + qdel(Polly) /datum/round_event/spooky/announce(fake) diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index 0801e38507..d8e52cf46d 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -2,7 +2,7 @@ name = "Mass Hallucination" typepath = /datum/round_event/mass_hallucination weight = 10 - max_occurrences = 2 + max_occurrences = 5 min_players = 1 var/forced_hallucination diff --git a/code/modules/events/supermatter_surge.dm b/code/modules/events/supermatter_surge.dm index 78b5c9e70c..dd78e379ca 100644 --- a/code/modules/events/supermatter_surge.dm +++ b/code/modules/events/supermatter_surge.dm @@ -2,7 +2,7 @@ name = "Supermatter Surge" typepath = /datum/round_event/supermatter_surge weight = 20 - max_occurrences = 4 + max_occurrences = 5 earliest_start = 10 MINUTES /datum/round_event_control/supermatter_surge/canSpawnEvent() @@ -37,7 +37,7 @@ /datum/round_event/supermatter_surge/start() var/obj/machinery/power/supermatter_crystal/supermatter = GLOB.main_supermatter_engine - var/power_proportion = supermatter.powerloss_inhibitor/2 // what % of the power goes into matter power, at most 50% + var/power_proportion = supermatter.powerloss_inhibitor * 0.75 // what % of the power goes into matter power, at most 50% // we reduce the proportion that goes into actual matter power based on powerloss inhibitor // primarily so the supermatter doesn't tesla the instant these happen supermatter.matter_power += power * power_proportion diff --git a/code/modules/events/supernova.dm b/code/modules/events/supernova.dm index b6a389f345..1b45cbf831 100644 --- a/code/modules/events/supernova.dm +++ b/code/modules/events/supernova.dm @@ -1,8 +1,8 @@ /datum/round_event_control/supernova name = "Supernova" typepath = /datum/round_event/supernova - weight = 10 - max_occurrences = 2 + weight = 5 + max_occurrences = 1 min_players = 2 /datum/round_event/supernova diff --git a/code/modules/events/untie_shoes.dm b/code/modules/events/untie_shoes.dm new file mode 100644 index 0000000000..708a72f40b --- /dev/null +++ b/code/modules/events/untie_shoes.dm @@ -0,0 +1,31 @@ +/datum/round_event_control/untied_shoes + name = "Untied Shoes" + typepath = /datum/round_event/untied_shoes + weight = 100 + max_occurrences = 20 + alert_observers = FALSE + +/datum/round_event/untied_shoes + fakeable = FALSE + +/datum/round_event/untied_shoes/start() + var/budget = rand(5 SECONDS,20 SECONDS) + for(var/mob/living/carbon/C in shuffle(GLOB.alive_mob_list)) + if(!C.client) + continue + if(C.stat == DEAD) + continue + if (HAS_TRAIT(C,TRAIT_EXEMPT_HEALTH_EVENTS)) + continue + if(!C.shoes || !C.shoes.can_be_tied || C.shoes.tied != SHOES_TIED || C.shoes.lace_time > budget) + continue + if(!is_station_level(C.z) && prob(50)) + continue + if(prob(5)) + C.shoes.adjust_laces(SHOES_KNOTTED) + budget -= C.shoes.lace_time // doubling up on the budget removal on purpose + else + C.shoes.adjust_laces(SHOES_UNTIED) + budget -= C.shoes.lace_time + if(budget < 5 SECONDS) + return diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index cd7b23a577..57f2648573 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -3,7 +3,6 @@ typepath = /datum/round_event/vent_clog weight = 10 max_occurrences = 3 - min_players = 25 /datum/round_event/vent_clog announceWhen = 1 @@ -11,7 +10,7 @@ endWhen = 35 var/interval = 2 var/list/vents = list() - var/randomProbability = 1 + var/randomProbability = 0 var/reagentsAmount = 100 var/list/saferChems = list( /datum/reagent/water, @@ -92,7 +91,7 @@ var/datum/reagents/R = new/datum/reagents(1000) R.my_atom = vent - if (prob(randomProbability)) + if (randomProbability && prob(randomProbability)) R.add_reagent(get_random_reagent_id(), reagentsAmount) else R.add_reagent(pick(saferChems), reagentsAmount) @@ -106,7 +105,7 @@ name = "Clogged Vents: Threatening" typepath = /datum/round_event/vent_clog/threatening weight = 4 - min_players = 35 + min_players = 15 max_occurrences = 1 earliest_start = 35 MINUTES @@ -118,7 +117,7 @@ name = "Clogged Vents: Catastrophic" typepath = /datum/round_event/vent_clog/catastrophic weight = 2 - min_players = 45 + min_players = 25 max_occurrences = 1 earliest_start = 45 MINUTES diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index 3c0d60907f..9d0e38cdec 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -311,6 +311,7 @@ /obj/item/reagent_containers/food/snacks/pizza/donkpocket = 0.3, /obj/item/reagent_containers/food/snacks/pizza/dank = 0.1) //pizzas here are weighted by chance to be someone's favorite var/static/list/pizza_preferences + COOLDOWN_DECLARE(next_pizza_attunement) /obj/item/pizzabox/infinite/Initialize(mapload) . = ..() @@ -323,11 +324,18 @@ . += "This pizza box is anomalous, and will produce infinite pizza." /obj/item/pizzabox/infinite/attack_self(mob/living/user) - QDEL_NULL(pizza) - if(ishuman(user)) - attune_pizza(user) + if(COOLDOWN_FINISHED(src, next_pizza_attunement)) + QDEL_NULL(pizza) + if(ishuman(user)) + attune_pizza(user) . = ..() +/obj/item/pizzabox/infinite/on_attack_hand(mob/user, act_intent, unarmed_attack_flags) + var/had_pizza = (pizza ? TRUE : FALSE) + . = ..() + if(had_pizza && !pizza) + COOLDOWN_START(src, next_pizza_attunement, (3 SECONDS)) + /obj/item/pizzabox/infinite/proc/attune_pizza(mob/living/carbon/human/noms) //tonight on "proc names I never thought I'd type" if(!pizza_preferences[noms.ckey]) pizza_preferences[noms.ckey] = pickweight(pizza_types) diff --git a/code/modules/food_and_drinks/recipes/drinks_recipes.dm b/code/modules/food_and_drinks/recipes/drinks_recipes.dm index 363e263ad4..217a650b30 100644 --- a/code/modules/food_and_drinks/recipes/drinks_recipes.dm +++ b/code/modules/food_and_drinks/recipes/drinks_recipes.dm @@ -771,8 +771,8 @@ /datum/chemical_reaction/pinkmilk name = "Strawberry Milk" - id = /datum/reagent/consumable/pinkmilk - results = list(/datum/reagent/consumable/pinkmilk = 2) + id = /datum/reagent/consumable/milk/pinkmilk + results = list(/datum/reagent/consumable/milk/pinkmilk = 2) required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/milk = 1) mix_message = "You feel a sweet aroma drift up your nose as the lactic mixture swirls. It reminds you of... a cafeteria." @@ -1016,8 +1016,8 @@ /datum/chemical_reaction/pinktea name = "Strawberry Tea" - id = /datum/reagent/consumable/pinktea - results = list(/datum/reagent/consumable/pinktea = 5) + id = /datum/reagent/consumable/tea/pinktea + results = list(/datum/reagent/consumable/tea/pinktea = 5) required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/tea/arnold_palmer = 1, /datum/reagent/consumable/sugar = 1) /datum/chemical_reaction/catnip_tea diff --git a/code/modules/holiday/dynamic.dm b/code/modules/holiday/dynamic.dm index f75dd37542..69208d91ea 100644 --- a/code/modules/holiday/dynamic.dm +++ b/code/modules/holiday/dynamic.dm @@ -6,5 +6,4 @@ return lowertext(ddd) in days /datum/holiday/dynamic/celebrate() - GLOB.dynamic_forced_threat_level = rand(90, 100) - CONFIG_SET(string/force_gamemode, "dynamic") // prevents the round vote, which prevents extended + GLOB.dynamic_forced_threat_level = rand(50, 100) diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm index 618ba9fcd7..77187532f9 100644 --- a/code/modules/holiday/halloween/jacqueen.dm +++ b/code/modules/holiday/halloween/jacqueen.dm @@ -70,7 +70,7 @@ . = ..() AddComponent(/datum/component/stationloving) -/mob/living/simple_animal/jacq/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/jacq/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!ckey) diff --git a/code/modules/hydroponics/grown/cannabis.dm b/code/modules/hydroponics/grown/cannabis.dm index 1882d5fe97..7771d24e16 100644 --- a/code/modules/hydroponics/grown/cannabis.dm +++ b/code/modules/hydroponics/grown/cannabis.dm @@ -11,8 +11,8 @@ growthstages = 1 instability = 40 growing_icon = 'goon/icons/obj/hydroponics.dmi' - icon_grow = "cannabis-grow" // Uses one growth icons set for all the subtypes - icon_dead = "cannabis-dead" // Same for the dead icon + icon_grow = "cannabis-grow" + icon_dead = "cannabis-dead" genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/cannabis/rainbow, /obj/item/seeds/cannabis/death) @@ -26,6 +26,8 @@ species = "megacannabis" plantname = "Rainbow Weed" product = /obj/item/reagent_containers/food/snacks/grown/cannabis/rainbow + icon_grow = "megacannabis-grow" + icon_dead = "megacannabis-dead" mutatelist = list(/obj/item/seeds/cannabis/ultimate) reagents_add = list(/datum/reagent/toxin/mindbreaker = 0.15, /datum/reagent/toxin/lipolicide = 0.35) rarity = 40 @@ -37,6 +39,8 @@ species = "blackcannabis" plantname = "Deathweed" product = /obj/item/reagent_containers/food/snacks/grown/cannabis/death + icon_grow = "blackcannabis-grow" + icon_dead = "blackcannabis-dead" mutatelist = list(/obj/item/seeds/cannabis/white) reagents_add = list(/datum/reagent/toxin/cyanide = 0.35, /datum/reagent/drug/space_drugs = 0.15, /datum/reagent/toxin/lipolicide = 0.15) rarity = 40 @@ -48,6 +52,8 @@ species = "whitecannabis" plantname = "Lifeweed" product = /obj/item/reagent_containers/food/snacks/grown/cannabis/white + icon_grow = "whitecannabis-grow" + icon_dead = "whitecannabis-dead" mutatelist = list() reagents_add = list(/datum/reagent/medicine/omnizine = 0.35, /datum/reagent/drug/space_drugs = 0.15, /datum/reagent/toxin/lipolicide = 0.15) rarity = 40 @@ -60,6 +66,8 @@ species = "ocannabis" plantname = "Omega Weed" product = /obj/item/reagent_containers/food/snacks/grown/cannabis/ultimate + icon_grow = "ocannabis-grow" + icon_dead = "ocannabis-dead" genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/glow/green) mutatelist = list() reagents_add = list(/datum/reagent/drug/space_drugs = 0.3, diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index c8c6195d5a..3c59deafdc 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -9,7 +9,7 @@ var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item. var/tastes = list("indescribable" = 1) //Stops runtimes. Grown are un-eatable anyways so if you do then its a bug -/obj/item/grown/Initialize(mapload, newloc, obj/item/seeds/new_seed) +/obj/item/grown/Initialize(mapload, obj/item/seeds/new_seed) . = ..() create_reagents(50, NONE, HARVEST_REAGENTS_VALUE) @@ -25,7 +25,7 @@ if(seed) for(var/datum/plant_gene/trait/T in seed.genes) - T.on_new(src, newloc) + T.on_new(src, loc) if(istype(src, seed.product)) // no adding reagents if it is just a trash item seed.prepare_result(src) diff --git a/code/modules/mapping/minimaps.dm b/code/modules/mapping/minimaps.dm index 51fde1f8db..8768ddd1e8 100644 --- a/code/modules/mapping/minimaps.dm +++ b/code/modules/mapping/minimaps.dm @@ -47,21 +47,43 @@ var/meta_color = area_to_color[A] if(!meta_color) - meta_color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) // technically conflicts could happen but it's like very unlikely and it's not that big of a deal if one happens + var/meta_x = LAZYLEN(area_to_color) + 1 + var/meta_y = (((meta_x + 1) - ((meta_x + 1) % 255)) / 255) + var/meta_z = (((meta_y + 1) - ((meta_y + 1) % 255)) / 255) + meta_color = rgb(meta_x % 255, meta_y % 255, meta_z % 255) //This supports exactly 16,581,374 areas with no conflicts whatsoever before it just gives up area_to_color[A] = meta_color color_area_names[meta_color] = A.name meta_icon.DrawBox(meta_color, img_x, img_y) - if(istype(T, /turf/closed/wall)) + if(A.minimap_show_walls && istype(T, /turf/closed/wall)) map_icon.DrawBox("#000000", img_x, img_y) else if(!istype(A, /area/space)) - var/color = A.minimap_color || "#FF00FF" - if(locate(/obj/machinery/power/solar) in T) - color = "#02026a" + var/color = (A.minimap_color2 ? (((img_x + img_y) % 2) ? A.minimap_color2 : A.minimap_color ) : A.minimap_color) || "#FF00FF" + if(A.minimap_show_walls) + var/overridden + for(var/obj/structure/O in T) + if(O.minimap_override_color) + color = O.minimap_override_color + overridden = TRUE + break + else if(O.density && O.anchored) + color = BlendRGB(color, "#000000", 0.5) + overridden = TRUE + break + + //In an ideal world, we'd be able to get away with just doing for(var/obj/O in T) up there, and calling it a day. However. HOWEVER! + //Doing that causes the code to also loop through items. and that uh. Kinda bloats minimap gen time. A LOT. We're talking straight-up doubling the time it takes to gen. + //So instead we take our ctrl+c. We copy the above code. And we ctrl+v. It's awful. We hate it. But it works. It's faster. Funny mapgen go vroom + if(!overridden) + for(var/obj/machinery/O in T) + if(O.minimap_override_color) + color = O.minimap_override_color + break + else if(O.density && O.anchored) + color = BlendRGB(color, "#000000", 0.25) + break - if((locate(/obj/effect/spawner/structure/window) in T) || (locate(/obj/structure/grille) in T)) - color = BlendRGB(color, "#000000", 0.5) map_icon.DrawBox(color, img_x, img_y) map_icon.Crop(crop_x1, crop_y1, crop_x2, crop_y2) @@ -102,22 +124,48 @@ var/list/datas = list() var/list/info = list() - - for(var/i in 1 to length(minimaps))// OLD: for(var/i in 1 to length(minimaps)) + var/buttonfield = "" + var/totalmaps = length(minimaps) + for(var/i in 1 to totalmaps)// OLD: for(var/i in 1 to length(minimaps)) var/datum/minimap/M = minimaps[i] var/map_name = "minimap-[M.id].png" var/meta_name = "minimap-[M.id]-meta.png" M.send(user) info += {" -
+
+ [totalmaps > 1 ? "

Layer [i]

" : ""]
-
+ [totalmaps <= 1 ? "
" : ""]
"} datas += json_encode(M.color_area_names); + buttonfield += "Layer [i] " + + if(totalmaps > 1) + info += "
[buttonfield]
" + + //This is a hacky workaround; the status display is extremely buggy when multiple z-levels are present. We couldn't figure out how to fix this after 7 hours of banging our head against the wall + //We're coder + var/mousemove_bit = {" + canvas.onmousemove = function(e){ + var rect = canvas.getBoundingClientRect(); + var x = Math.floor(e.offsetX * img.width / rect.width); + var y = Math.floor(e.offsetY * img.height / rect.height); + + var color_idx = x * 4 + (y * 4 * imagedata.width); + var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]); + + label.textContent = data\[color]; + canvas.title = data\[color]; + } + canvas.onmouseout = function(e){ + label.textContent = " "; + canvas.title = ""; + } + "} info = info.Join() //this is bad. Too bad! @@ -133,6 +181,14 @@ } return num; } + function switchmap(mapid) { + var targetblock = document.getElementById(mapid); + for(var i = 0; i < [length(minimaps)]; i++) { + var currentblock = document.getElementById("layer-" + (i + 1)); + currentblock.style.display = 'none'; + } + targetblock.style.display = ''; + } window.onload = function() { if(!window.HTMLCanvasElement) { var label = document.getElementById("label-1"); @@ -150,6 +206,7 @@ var canvas = document.createElement("canvas"); canvas.width = img.width * 2; canvas.height = img.height * 2; + canvas.id = "canvas-" + (i+1); var ctx = canvas.getContext('2d'); ctx.msImageSmoothingEnabled = false; @@ -158,31 +215,23 @@ ctx = document.createElement("canvas").getContext('2d'); ctx.canvas.width = img.width; ctx.canvas.height = img.height; + ctx.id = "ctx-" + (i+1); ctx.drawImage(document.getElementById("map-" + (i+1) + "-meta"), 0, 0); var imagedata = ctx.getImageData(0, 0, img.width, img.height); - canvas.onmousemove = function(e){ - var rect = canvas.getBoundingClientRect(); - var x = Math.floor(e.offsetX * img.width / rect.width); - var y = Math.floor(e.offsetY * img.height / rect.height); - - var color_idx = x * 4 + (y * 4 * imagedata.width); - var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]); - var label = document.getElementById("label-" + (i+1)); //label-String(n) - - label.textContent = data\[color]; - canvas.title = data\[color]; - } - canvas.onmouseout = function(e){ - canvas.title = ""; - } + var label = document.getElementById("label-" + (i+1)); //label-String(n); + [totalmaps <= 1 ? mousemove_bit : ""] } } diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 8ede497c83..561dc9c096 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -19,6 +19,7 @@ attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped") sharpness = SHARP_EDGED actions_types = list(/datum/action/item_action/toggle_light) + obj_flags = UNIQUE_RENAME var/list/trophies = list() var/charged = TRUE var/charge_time = 15 diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm index 887556500c..dbcc2cb2b4 100644 --- a/code/modules/mob/dead/new_player/login.dm +++ b/code/modules/mob/dead/new_player/login.dm @@ -9,6 +9,12 @@ ..() + if(!age_verify()) + return + + if(!client) //client can end up null as a result of age_verify() kicking those who fail + return + var/motd = global.config.motd if(motd) to_chat(src, "
[motd]
", handle_whitespace=FALSE) @@ -22,8 +28,11 @@ sight |= SEE_TURFS - new_player_panel() client.playtitlemusic() + + var/datum/asset/asset_datum = get_asset_datum(/datum/asset/simple/lobby) + asset_datum.send(client) + if(SSticker.current_state < GAME_STATE_SETTING_UP) var/tl = SSticker.GetTimeLeft() var/postfix @@ -32,3 +41,7 @@ else postfix = "soon" to_chat(src, "Please set up your character and select \"Ready\". The game will start [postfix].") + + var/datum/hud/new_player/NH = hud_used + if(istype(NH)) + NH.populate_buttons(src) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 9c17578aad..069be0a8ab 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -1,5 +1,3 @@ -#define LINKIFY_READY(string, value) "[string]" - /mob/dead/new_player var/ready = 0 var/spawning = 0//Referenced when you want to delete the new_player later on in the code. @@ -10,6 +8,8 @@ density = FALSE stat = DEAD + hud_type = /datum/hud/new_player + hud_possible = list() var/mob/living/new_character //for instant transfer once the round is set up @@ -43,69 +43,6 @@ /mob/dead/new_player/prepare_huds() return -/mob/dead/new_player/proc/new_player_panel() - var/output = "

Welcome, [client ? client.prefs.real_name : "Unknown User"]

" - output += "

Setup Character

" - - if(SSticker.current_state <= GAME_STATE_PREGAME) - switch(ready) - if(PLAYER_NOT_READY) - output += "

\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | Not Ready | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]

" - if(PLAYER_READY_TO_PLAY) - output += "

\[ Ready | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]

" - if(PLAYER_READY_TO_OBSERVE) - output += "

\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | Observe \]

" - else - output += "

View the Crew Manifest

" - output += "

Join Game!

" - output += "

[LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)]

" - - if(!IsGuestKey(src.key)) - output += playerpolls() - - output += "
" - - //src << browse(output,"window=playersetup;size=210x240;can_close=0") - var/datum/browser/popup = new(src, "playersetup", "
New Player Options
", 250, 265) - popup.set_window_options("can_close=0") - popup.set_content(output) - popup.open(FALSE) - -/mob/dead/new_player/proc/playerpolls() - var/output = "" //hey tg why is this a list? - if (SSdbcore.Connect()) - var/isadmin = FALSE - if(client?.holder) - isadmin = TRUE - var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({" - SELECT id FROM [format_table_name("poll_question")] - WHERE (adminonly = 0 OR :isadmin = 1) - AND Now() BETWEEN starttime AND endtime - AND deleted = 0 - AND id NOT IN ( - SELECT pollid FROM [format_table_name("poll_vote")] - WHERE ckey = :ckey - AND deleted = 0 - ) - AND id NOT IN ( - SELECT pollid FROM [format_table_name("poll_textreply")] - WHERE ckey = :ckey - AND deleted = 0 - ) - "}, list("isadmin" = isadmin, "ckey" = ckey)) - var/rs = REF(src) - if(!query_get_new_polls.Execute()) - qdel(query_get_new_polls) - return - if(query_get_new_polls.NextRow()) - output += "

Show Player Polls (NEW!)

" - else - output += "

Show Player Polls

" - qdel(query_get_new_polls) - if(QDELETED(src)) - return - return output - /mob/dead/new_player/proc/age_gate() var/list/dat = list("
") dat += "Enter your date of birth here, to confirm that you are over 18.
" @@ -152,6 +89,9 @@ if(!(client.prefs.db_flags & DB_FLAG_AGE_CONFIRMATION_INCOMPLETE)) //completed? Skip return TRUE + if(!client) + return FALSE + var/age_verification = age_gate() //ban them and kick them if(age_verification != 1) @@ -269,61 +209,12 @@ if(!age_verify()) return - //Determines Relevent Population Cap - var/relevant_cap - var/hpc = CONFIG_GET(number/hard_popcap) - var/epc = CONFIG_GET(number/extreme_popcap) - if(hpc && epc) - relevant_cap = min(hpc, epc) - else - relevant_cap = max(hpc, epc) - - if(href_list["show_preferences"]) - client.prefs.ShowChoices(src) - return 1 - - if(href_list["ready"]) - var/tready = text2num(href_list["ready"]) - //Avoid updating ready if we're after PREGAME (they should use latejoin instead) - //This is likely not an actual issue but I don't have time to prove that this - //no longer is required - if(SSticker.current_state <= GAME_STATE_PREGAME) - ready = tready - //if it's post initialisation and they're trying to observe we do the needful - if(!SSticker.current_state < GAME_STATE_PREGAME && tready == PLAYER_READY_TO_OBSERVE) - ready = tready - make_me_an_observer() - return - - if(href_list["refresh"]) - src << browse(null, "window=playersetup") //closes the player setup window - new_player_panel() - if(href_list["late_join"]) if(!SSticker || !SSticker.IsRoundInProgress()) to_chat(usr, "The round is either not ready, or has already finished...") return - - if(href_list["late_join"] == "override") - LateChoices() - return - - if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.admin_datums))) - to_chat(usr, "[CONFIG_GET(string/hard_popcap_message)]") - - var/queue_position = SSticker.queued_players.Find(usr) - if(queue_position == 1) - to_chat(usr, "You are next in line to join the game. You will be notified when a slot opens up.") - else if(queue_position) - to_chat(usr, "There are [queue_position-1] players in front of you in the queue to join the game.") - else - SSticker.queued_players += usr - to_chat(usr, "You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].") - return LateChoices() - - if(href_list["manifest"]) - ViewManifest() + return if(href_list["SelectedJob"]) if(!SSticker || !SSticker.IsRoundInProgress()) @@ -337,6 +228,17 @@ to_chat(usr, "There is an administrative lock on entering the game!") return + //Determines Relevent Population Cap + var/relevant_cap + var/hpc = CONFIG_GET(number/hard_popcap) + var/epc = CONFIG_GET(number/extreme_popcap) + if(hpc && epc) + relevant_cap = min(hpc, epc) + else + relevant_cap = max(hpc, epc) + + + if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums)) if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1])) to_chat(usr, "Server is full.") @@ -349,6 +251,15 @@ if(!GLOB.enter_allowed) to_chat(usr, " There is an administrative lock on entering the game!") + //Determines Relevent Population Cap + var/relevant_cap + var/hpc = CONFIG_GET(number/hard_popcap) + var/epc = CONFIG_GET(number/extreme_popcap) + if(hpc && epc) + relevant_cap = min(hpc, epc) + else + relevant_cap = max(hpc, epc) + if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums)) if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1])) to_chat(usr, "Server is full.") @@ -360,13 +271,6 @@ SSticker.queue_delay = 4 qdel(src) - else if(!href_list["late_join"]) - new_player_panel() - - if(href_list["showpoll"]) - handle_player_polling() - return - if(href_list["pollid"]) var/pollid = href_list["pollid"] if(istext(pollid)) @@ -460,7 +364,6 @@ if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes") ready = PLAYER_NOT_READY src << browse(null, "window=playersetup") //closes the player setup window - new_player_panel() return FALSE var/mob/dead/observer/observer = new() diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index a9233938ab..378313311e 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -24,6 +24,9 @@ var/rando_race = pick(GLOB.roundstart_races) pref_species = new rando_race() features = random_features(pref_species?.id, gender) + bark_id = pick(GLOB.bark_random_list) + bark_pitch = BARK_PITCH_RAND(gender) + bark_variance = BARK_VARIANCE_RAND age = rand(AGE_MIN,AGE_MAX) /datum/preferences/proc/update_preview_icon(current_tab) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 4b228e1eb3..94917e4de0 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -121,7 +121,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) remove_verb(src, /mob/dead/observer/verb/boo) remove_verb(src, /mob/dead/observer/verb/possess) - animate(src, pixel_y = 2, time = 10, loop = -1) + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) add_to_dead_mob_list() @@ -534,8 +535,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/stop_orbit(datum/component/orbiter/orbits) . = ..() //restart our floating animation after orbit is done. - pixel_y = 0 - animate(src, pixel_y = 2, time = 10, loop = -1) + pixel_z = 0 + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) /mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak set category = "Ghost" diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index eabf2e2d0e..8d5bd40acc 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -30,7 +30,7 @@ // Takes care blood loss and regeneration -/mob/living/carbon/human/handle_blood() +/mob/living/carbon/human/handle_blood(delta_time, times_fired) if(NOBLOOD in dna.species.species_traits || bleedsuppress || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) return @@ -39,56 +39,57 @@ return if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood. - if(integrating_blood > 0) - var/blood_integrated = max(integrating_blood - 1, 0) - var/blood_diff = integrating_blood - blood_integrated - integrating_blood = blood_integrated - if(blood_volume < BLOOD_VOLUME_MAXIMUM) - blood_volume += blood_diff - if(blood_volume < BLOOD_VOLUME_NORMAL) - var/nutrition_ratio = 0 - if(!HAS_TRAIT(src, TRAIT_NOHUNGER)) - switch(nutrition) - if(0 to NUTRITION_LEVEL_STARVING) - nutrition_ratio = 0.2 - if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) - nutrition_ratio = 0.4 - if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) - nutrition_ratio = 0.6 - if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) - nutrition_ratio = 0.8 - else - nutrition_ratio = 1 - if(satiety > 80) - nutrition_ratio *= 1.25 - adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR) - blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio) + if(dna.species.handle_blood(src, delta_time, times_fired)) // if this returns TRUE, then the species is not handling blood itself and we can control everything + if(integrating_blood > 0) + var/blood_integrated = max(integrating_blood - 1, 0) + var/blood_diff = integrating_blood - blood_integrated + integrating_blood = blood_integrated + if(blood_volume < BLOOD_VOLUME_MAXIMUM) + blood_volume += blood_diff + if(blood_volume < BLOOD_VOLUME_NORMAL) + var/nutrition_ratio = 0 + if(!HAS_TRAIT(src, TRAIT_NOHUNGER)) + switch(nutrition) + if(0 to NUTRITION_LEVEL_STARVING) + nutrition_ratio = 0.2 + if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) + nutrition_ratio = 0.4 + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) + nutrition_ratio = 0.6 + if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) + nutrition_ratio = 0.8 + else + nutrition_ratio = 1 + if(satiety > 80) + nutrition_ratio *= 1.25 + adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR) + blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio) - //Effects of bloodloss - if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange. - var/word = pick("dizzy","woozy","faint") - var/blood_effect_volume = blood_volume + integrating_blood - switch(blood_effect_volume) - if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS) - if(prob(10)) - to_chat(src, "You feel terribly bloated.") - if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) - if(prob(5)) - to_chat(src, "You feel [word].") - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) - if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) - if(prob(5)) - blur_eyes(6) - to_chat(src, "You feel very [word].") - if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) - adjustOxyLoss(5) - if(prob(15)) - Unconscious(rand(20,60)) - to_chat(src, "You feel extremely [word].") - if(-INFINITY to BLOOD_VOLUME_SURVIVE) - if(!HAS_TRAIT(src, TRAIT_NODEATH)) - death() + //Effects of bloodloss + if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange. + var/word = pick("dizzy","woozy","faint") + var/blood_effect_volume = blood_volume + integrating_blood + switch(blood_effect_volume) + if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS) + if(prob(10)) + to_chat(src, "You feel terribly bloated.") + if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) + if(prob(5)) + to_chat(src, "You feel [word].") + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) + if(prob(5)) + blur_eyes(6) + to_chat(src, "You feel very [word].") + if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) + adjustOxyLoss(5) + if(prob(15)) + Unconscious(rand(20,60)) + to_chat(src, "You feel extremely [word].") + if(-INFINITY to BLOOD_VOLUME_SURVIVE) + if(!HAS_TRAIT(src, TRAIT_NODEATH)) + death() var/temp_bleed = 0 //Bleeding out @@ -193,6 +194,7 @@ blood_data["blood_DNA"] = dna.unique_enzymes blood_data["bloodcolor"] = dna.species.exotic_blood_color + blood_data["bloodblend"] = dna.species.exotic_blood_blend_mode if(disease_resistances && disease_resistances.len) blood_data["resistances"] = disease_resistances.Copy() var/list/temp_chem = list() @@ -264,7 +266,7 @@ "O-" = list("O-","SY"), "O+" = list("O-", "O+","SY"), "L" = list("L","SY"), - "U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY"), + "U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY", "BUG"), "HF" = list("HF", "SY"), "X*" = list("X*", "SY"), "SY" = list("SY"), @@ -370,27 +372,6 @@ if(!B) B = new(T) -//This is a terrible way of handling it. -/mob/living/proc/ResetBloodVol() - if(ishuman(src)) - var/mob/living/carbon/human/H = src - if (HAS_TRAIT(src, TRAIT_HIGH_BLOOD)) - blood_ratio = 1.2 - H.handle_blood() - return - blood_ratio = 1 - H.handle_blood() - return - blood_ratio = 1 - -/mob/living/proc/AdjustBloodVol(value) - if(blood_ratio == value) - return - blood_ratio = value - if(ishuman(src)) - var/mob/living/carbon/human/H = src - H.handle_blood() - /mob/living/proc/adjust_integration_blood(value, remove_actual_blood, force) if(integrating_blood + value < 0 && remove_actual_blood) blood_volume += value + integrating_blood diff --git a/code/modules/mob/living/brain/life.dm b/code/modules/mob/living/brain/life.dm index 823d47dee2..e42f82d5cd 100644 --- a/code/modules/mob/living/brain/life.dm +++ b/code/modules/mob/living/brain/life.dm @@ -1,5 +1,5 @@ -/mob/living/brain/BiologicalLife(seconds, times_fired) +/mob/living/brain/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return handle_emp_damage() diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index 9563959ebc..ff4a7d2bba 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -51,7 +51,7 @@ // update_icons() //Handled in update_transform(), leaving this here as a reminder update_transform() -/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that. +/mob/living/carbon/alien/humanoid/update_transform(do_animate) //The old method of updating lying/standing was update_icons(). Aliens still expect that. if(lying > 0) lying = 90 //Anything else looks silly ..() diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index f0004b5ed9..b22ff68531 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/alien/larva/BiologicalLife(seconds, times_fired) +/mob/living/carbon/alien/larva/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return // GROW! diff --git a/code/modules/mob/living/carbon/alien/larva/update_icons.dm b/code/modules/mob/living/carbon/alien/larva/update_icons.dm index e6e7e657e8..85416261c7 100644 --- a/code/modules/mob/living/carbon/alien/larva/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/larva/update_icons.dm @@ -21,7 +21,7 @@ else icon_state = "larva[state]" -/mob/living/carbon/alien/larva/update_transform() //All this is handled in update_icons() +/mob/living/carbon/alien/larva/update_transform(do_animate) //All this is handled in update_icons() ..() return update_icons() diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 530d2acd63..b56c897b03 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/alien/BiologicalLife(seconds, times_fired) +/mob/living/carbon/alien/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return findQueen() diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index 1a159a56bb..85c188d2ab 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -90,10 +90,12 @@ /mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, toxins_type = TOX_DEFAULT) if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER) && toxins_type != TOX_SYSCORRUPT) //damage becomes healing and healing becomes damage amount = -amount + // don't allow toxinlover to push blood levels past BLOOD_VOLUME_MAXIMUM, but also don't set it back down to this if it's higher from something else + var/blood_cap = blood_volume > BLOOD_VOLUME_MAXIMUM ? blood_volume : BLOOD_VOLUME_MAXIMUM if(amount > 0) - blood_volume -= 3 * amount //5x was too much, this is punishing enough. + blood_volume = min((blood_volume - (3 * amount)), blood_cap) //5x was too much, this is punishing enough. else - blood_volume -= amount + blood_volume = min((blood_volume - amount), blood_cap) return ..() /mob/living/carbon/getStaminaLoss() diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 5eabae16f7..958a8b599a 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -6,7 +6,7 @@ var/t_has = p_have() var/t_is = p_are() - . = list("*---------*\nThis is [icon2html(src, user)] \a [src]!") + . = list("This is [icon2html(src, user)] \a [src]!") if (handcuffed) . += "[t_He] [t_is] [icon2html(handcuffed, user)] handcuffed!" @@ -152,8 +152,11 @@ . += "[t_He] look[p_s()] very happy." if(MOOD_LEVEL_HAPPY4 to INFINITY) . += "[t_He] look[p_s()] ecstatic." + + if(LAZYLEN(.) > 1) + .[2] = "
[.[2]]" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) - . += "*---------*
" /mob/living/carbon/examine_more(mob/user) if(!all_scars) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 32a4fac90f..93bd4c4eba 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -13,7 +13,7 @@ if(HAS_TRAIT(L, TRAIT_PROSOPAGNOSIA)) obscure_name = TRUE - . = list("*---------*\nThis is [!obscure_name ? name : "Unknown"]!") + . = list("This is [!obscure_name ? name : "Unknown"]!") var/vampDesc = ReturnVampExamine(user) // Vamps recognize the names of other vamps. var/vassDesc = ReturnVassalExamine(user) // Vassals recognize each other's marks. @@ -442,9 +442,10 @@ else if(isobserver(user) && traitstring) . += "Traits: [traitstring]" - SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now + if(LAZYLEN(.) > 2) //Want this to appear after species text + .[3] = "
[.[3]]" - . += "*---------*
" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now /mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects! var/list/dat = list() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 5b6fae8e1b..1de40ec80c 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -550,7 +550,7 @@ to_chat(src, "You succesfuly remove the durathread strand.") remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) return - var/to_send = "" + var/to_send = "
" visible_message("[src] examines [p_them()]self.", \ "You check yourself for injuries.") @@ -597,27 +597,27 @@ var/no_damage if(status == "OK" || status == "no damage") no_damage = TRUE - to_send += "\t Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" + to_send += "Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" for(var/thing in LB.wounds) var/datum/wound/W = thing var/msg switch(W.severity) if(WOUND_SEVERITY_TRIVIAL) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]." + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]." if(WOUND_SEVERITY_MODERATE) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" if(WOUND_SEVERITY_SEVERE) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" if(WOUND_SEVERITY_CRITICAL) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!" + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!" to_chat(src, msg) for(var/obj/item/I in LB.embedded_objects) if(I.isEmbedHarmless()) - to_chat(src, "\t There is \a [I] stuck to your [LB.name]!") + to_chat(src, "There is \a [I] stuck to your [LB.name]!") else - to_chat(src, "\t There is \a [I] embedded in your [LB.name]!") + to_chat(src, "There is \a [I] embedded in your [LB.name]!") for(var/t in missing) to_send += "Your [parse_zone(t)] is missing!\n" @@ -724,6 +724,8 @@ if(roundstart_quirks.len) to_send += "You have these quirks: [get_trait_string()].\n" + to_send += "
" + to_chat(src, to_send) else if(wear_suit) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 54d6771c6c..141fbb89d7 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -85,6 +85,7 @@ FP.blood_DNA["color"] = S.last_blood_color else FP.blood_DNA["color"] = BlendRGB(FP.blood_DNA["color"], S.last_blood_color) + FP.blood_DNA["blendmode"] = S.last_blood_blend FP.update_icon() update_inv_shoes() //End bloody footprints diff --git a/code/modules/mob/living/carbon/human/innate_abilities/coiling.dm b/code/modules/mob/living/carbon/human/innate_abilities/coiling.dm index 52e2a87a7d..2cfbf9fb73 100644 --- a/code/modules/mob/living/carbon/human/innate_abilities/coiling.dm +++ b/code/modules/mob/living/carbon/human/innate_abilities/coiling.dm @@ -30,6 +30,10 @@ currently_coiled.pixel_x = 12 /datum/action/innate/ability/coiling/proc/coil_mob(var/mob/living/carbon/human/H) + if(currently_coiling) + to_chat(owner, span_warning("You are already coiling someone!")) + return + // begin the coiling action H.visible_message("[owner] coils [H] with their tail!", \ "[owner] coils you with their tail!") @@ -58,6 +62,9 @@ /datum/action/innate/ability/coiling/proc/cancel_coil() var/mob/living/carbon/human/H = owner + + if(!currently_coiling) + return // cancel the coiling action by removing the overlay currently_coiled.pixel_x = 0 diff --git a/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm b/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm index ce36397c91..6f3809c232 100644 --- a/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm +++ b/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm @@ -25,25 +25,21 @@ /datum/action/innate/ability/limb_regrowth/Activate() var/mob/living/carbon/human/H = owner var/list/limbs_to_heal = H.get_missing_limbs() - if(limbs_to_heal.len < 1) - to_chat(H, "You feel intact enough as it is.") + if(!length(limbs_to_heal)) + to_chat(H, span_notice("You feel intact enough as it is.")) return - to_chat(H, "You focus intently on your missing [limbs_to_heal.len >= 2 ? "limbs" : "limb"]...") - var/mode = H.get_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE) - switch(mode) - if(REGROWTH_USES_BLOOD) - if(H.blood_volume >= 40*limbs_to_heal.len+(BLOOD_VOLUME_OKAY*H.blood_ratio)) - H.regenerate_limbs() - H.blood_volume -= 40*limbs_to_heal.len - to_chat(H, "...and after a moment you finish reforming!") - return - else if(H.blood_volume >= 40)//We can partially heal some limbs - while(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40) - var/healed_limb = pick(limbs_to_heal) - H.regenerate_limb(healed_limb) - limbs_to_heal -= healed_limb - H.blood_volume -= 40 - to_chat(H, "...but there is not enough of you to fix everything! You must attain more mass to heal completely!") - return - to_chat(H, "...but there is not enough of you to go around! You must attain more mass to heal!") - + to_chat(H, span_notice("You focus intently on your missing [length(limbs_to_heal) >= 2 ? "limbs" : "limb"]...")) + if(H.blood_volume >= 40*length(limbs_to_heal)+BLOOD_VOLUME_OKAY) + H.regenerate_limbs() + H.blood_volume -= 40*length(limbs_to_heal) + to_chat(H, span_notice("...and after a moment you finish reforming!")) + return + else if(H.blood_volume >= 40)//We can partially heal some limbs + while(H.blood_volume >= BLOOD_VOLUME_OKAY+40) + var/healed_limb = pick(limbs_to_heal) + H.regenerate_limb(healed_limb) + limbs_to_heal -= healed_limb + H.blood_volume -= 40 + to_chat(H, span_warning("...but there is not enough of you to fix everything! You must attain more mass to heal completely!")) + return + to_chat(H, span_warning("...but there is not enough of you to go around! You must attain more mass to heal!")) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 1ea28211af..4221df31f6 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -18,7 +18,7 @@ #define THERMAL_PROTECTION_HAND_LEFT 0.025 #define THERMAL_PROTECTION_HAND_RIGHT 0.025 -/mob/living/carbon/human/BiologicalLife(seconds, times_fired) +/mob/living/carbon/human/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return handle_active_genes() diff --git a/code/modules/mob/living/carbon/human/login.dm b/code/modules/mob/living/carbon/human/login.dm index ebf76eeafa..cccee4a7ef 100644 --- a/code/modules/mob/living/carbon/human/login.dm +++ b/code/modules/mob/living/carbon/human/login.dm @@ -7,8 +7,8 @@ return var/list/print_msg = list() - print_msg += "*---------*" print_msg += "As you snap back to consciousness, you recall people messing with your stuff..." + print_msg += "
" afk_thefts = reverseRange(afk_thefts) @@ -22,13 +22,14 @@ var/time_since = world.time - iter_theft[AFK_THEFT_TIME] if(time_since > AFK_THEFT_FORGET_DETAILS_TIME) - print_msg += "\tSomeone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago." + print_msg += "Someone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago." else - print_msg += "\t[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago." + print_msg += "[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago." + + print_msg += "
" if(LAZYLEN(afk_thefts) >= AFK_THEFT_MAX_MESSAGES) print_msg += "There may have been more, but that's all you can remember..." - print_msg += "*---------*" to_chat(src, print_msg.Join("\n")) LAZYNULL(afk_thefts) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 4eccbc62c7..afceabf2a6 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -65,6 +65,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/exotic_bloodtype = "" /// Assume human as the default blood colour, override this default by species subtypes var/exotic_blood_color = BLOOD_COLOR_HUMAN + /// Which blend mode should this species blood use? + var/exotic_blood_blend_mode = BLEND_MULTIPLY ///What the species drops when gibbed by a gibber machine. var/meat = /obj/item/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing var/list/gib_types = list(/obj/effect/gibspawner/human, /obj/effect/gibspawner/human/bodypartless) @@ -826,13 +828,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/left_state = DEFAULT_LEFT_EYE_STATE var/right_state = DEFAULT_RIGHT_EYE_STATE if(eye_type in GLOB.eye_types) - left_state = eye_type + "_left_eye" - right_state = eye_type + "_right_eye" + left_state = "[eye_type]_left_eye" + right_state = "[eye_type]_right_eye" var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER) var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER) if((EYECOLOR in species_traits) && has_eyes) - left_eye.color = "#" + H.left_eye_color - right_eye.color = "#" + H.right_eye_color + left_eye.color = "#[H.left_eye_color]" + right_eye.color = "#[H.right_eye_color]" if(OFFSET_EYES in offset_features) left_eye.pixel_x += offset_features[OFFSET_EYES][1] left_eye.pixel_y += offset_features[OFFSET_EYES][2] @@ -2450,6 +2452,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return TRUE return FALSE +//////////////// +//Blood Stuff/// +//////////////// +// true = handle blood normally, false = do not (and then handle blood in this proc instead please!!) +/datum/species/proc/handle_blood(mob/living/carbon/human/H, delta_time, times_fired) + return TRUE + //////////////// //Tail Wagging// //////////////// diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 3b84752e1e..4712fe4475 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -17,6 +17,7 @@ exotic_blood = /datum/reagent/blood/jellyblood exotic_bloodtype = "GEL" exotic_blood_color = "BLOOD_COLOR_SLIME" + exotic_blood_blend_mode = BLEND_DEFAULT damage_overlay_type = "" liked_food = TOXIC | MEAT disliked_food = null @@ -31,6 +32,7 @@ species_category = SPECIES_CATEGORY_JELLY wings_icons = SPECIES_WINGS_JELLY ass_image = 'icons/ass/assslime.png' + blacklisted_quirks = list(/datum/quirk/glass_bones) /datum/species/jelly/on_species_loss(mob/living/carbon/C) C.faction -= "slime" @@ -53,38 +55,46 @@ //update blood color to body color exotic_blood_color = "#" + H.dna.features["mcolor"] -/datum/species/jelly/spec_life(mob/living/carbon/human/H) - if(H.stat == DEAD || HAS_TRAIT(H, TRAIT_NOMARROW)) //can't farm slime jelly from a dead slime/jelly person indefinitely, and no regeneration for bloodsuckers - return - if(!H.blood_volume) - H.adjust_integration_blood(5) - H.adjustBruteLoss(5) - to_chat(H, "You feel empty!") +/datum/species/jelly/handle_blood(mob/living/carbon/human/H, delta_time, times_fired) + if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely + return TRUE // we dont handle blood when dead - if(H.blood_volume < (BLOOD_VOLUME_NORMAL * H.blood_ratio)) + if(H.blood_volume <= 0) + H.blood_volume += 2.5 * delta_time + H.adjustBruteLoss(2.5 * delta_time) + to_chat(H, span_danger("You feel empty!")) + + if(H.blood_volume < BLOOD_VOLUME_NORMAL) if(H.nutrition >= NUTRITION_LEVEL_STARVING) - H.adjust_integration_blood(3) - H.nutrition -= 2.5 - if(H.blood_volume < (BLOOD_VOLUME_OKAY*H.blood_ratio)) - if(prob(5)) - to_chat(H, "You feel drained!") - if(H.blood_volume < (BLOOD_VOLUME_BAD*H.blood_ratio)) + H.blood_volume += 1.5 * delta_time + H.adjust_nutrition(-1.25 * delta_time) + + if(H.blood_volume < BLOOD_VOLUME_OKAY) + if(DT_PROB(2.5, delta_time)) + to_chat(H, span_danger("You feel drained!")) + + if(H.blood_volume < BLOOD_VOLUME_BAD) Cannibalize_Body(H) - ..() + + var/datum/action/innate/ability/regrowth = H.ability_actions[INNATE_ABILITY_LIMB_REGROWTH] + if(regrowth) + regrowth.UpdateButtonIcon() + + return FALSE // to let living/handle_blood know that the species is handling blood instead /datum/species/jelly/proc/Cannibalize_Body(mob/living/carbon/human/H) var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs() var/obj/item/bodypart/consumed_limb - if(!limbs_to_consume.len) + if(!length(limbs_to_consume)) H.losebreath++ return if(H.get_num_legs(FALSE)) //Legs go before arms limbs_to_consume -= list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM) consumed_limb = H.get_bodypart(pick(limbs_to_consume)) consumed_limb.drop_limb() - to_chat(H, "Your [consumed_limb] is drawn back into your body, unable to maintain its shape!") + to_chat(H, span_userdanger("Your [consumed_limb] is drawn back into your body, unable to maintain its shape!")) qdel(consumed_limb) - H.adjust_integration_blood(20) + H.blood_volume += 20 ////////////////////////////////////////////////////////SLIMEPEOPLE/////////////////////////////////////////////////////////////////// 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 9c29856084..5fb816867f 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -26,6 +26,7 @@ wings_icons = SPECIES_WINGS_SKELETAL ass_image = 'icons/ass/assplasma.png' + blacklisted_quirks = list(/datum/quirk/paper_skin) /datum/species/plasmaman/spec_life(mob/living/carbon/human/H) var/datum/gas_mixture/environment = H.loc.return_air() 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 5a927397fb..9c52a6a9d1 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -17,6 +17,7 @@ species_category = SPECIES_CATEGORY_SKELETON //they have their own category that's disassociated from undead, paired with plasmapeople wings_icons = SPECIES_WINGS_SKELETAL + blacklisted_quirks = list(/datum/quirk/paper_skin) /datum/species/skeleton/New() if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) //skeletons are stronger during the spooky season! diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index cb2458e376..a0620c8990 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -209,7 +209,7 @@ There are several things that need to be remembered: inv.update_icon() if(!gloves && bloody_hands) - var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color()) + var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) if(get_num_arms(FALSE) < 2) if(has_left_hand(FALSE)) bloody_overlay.icon_state = "bloodyhands_left" diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 27f795015e..dadf169c35 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -1,6 +1,6 @@ -/mob/living/carbon/BiologicalLife(seconds, times_fired) +/mob/living/carbon/BiologicalLife(delta_time, times_fired) //Reagent processing needs to come before breathing, to prevent edge cases. - handle_organs(seconds, times_fired) + handle_organs(delta_time, times_fired) . = ..() // if . is false, we are dead. if(stat == DEAD) stop_sound_channel(CHANNEL_HEARTBEAT) @@ -9,7 +9,7 @@ . = FALSE if(!.) return - handle_blood() + handle_blood(delta_time, times_fired) // handle_blood *could* kill us. // we should probably have a better system for if we need to check for death or something in the future hmw if(stat != DEAD) @@ -23,7 +23,7 @@ handle_brain_damage() if(stat != DEAD) - handle_liver(seconds, times_fired) + handle_liver(delta_time, times_fired) if(stat != DEAD) handle_corruption() @@ -375,7 +375,7 @@ miasma_turf.air_update_turf() -/mob/living/carbon/proc/handle_blood() +/mob/living/carbon/proc/handle_blood(delta_time, times_fired) return /mob/living/carbon/proc/handle_bodyparts(seconds, times_fired) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index ffb0e329be..a7bc0c11d5 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -3,7 +3,7 @@ /mob/living/carbon/monkey -/mob/living/carbon/monkey/BiologicalLife(seconds, times_fired) +/mob/living/carbon/monkey/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(client) diff --git a/code/modules/mob/living/carbon/monkey/punpun.dm b/code/modules/mob/living/carbon/monkey/punpun.dm index c8b8dbbc9d..585a93f304 100644 --- a/code/modules/mob/living/carbon/monkey/punpun.dm +++ b/code/modules/mob/living/carbon/monkey/punpun.dm @@ -33,7 +33,7 @@ if(relic_mask) equip_to_slot_or_del(new relic_mask, ITEM_SLOT_MASK) -/mob/living/carbon/monkey/punpun/BiologicalLife(seconds, times_fired) +/mob/living/carbon/monkey/punpun/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) @@ -46,6 +46,7 @@ ..() /mob/living/carbon/monkey/punpun/proc/Read_Memory() + var/saved_color if(fexists("data/npc_saves/Punpun.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Punpun.sav") S["ancestor_name"] >> ancestor_name @@ -62,6 +63,9 @@ ancestor_chain = json["ancestor_chain"] relic_hat = json["relic_hat"] relic_mask = json["relic_hat"] + saved_color = json["color"] + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed) var/json_file = file("data/npc_saves/Punpun.json") @@ -71,10 +75,12 @@ file_data["ancestor_chain"] = null file_data["relic_hat"] = null file_data["relic_mask"] = null + file_data["color"] = null else file_data["ancestor_name"] = ancestor_name ? ancestor_name : name file_data["ancestor_chain"] = dead ? ancestor_chain + 1 : ancestor_chain file_data["relic_hat"] = head ? head.type : null file_data["relic_mask"] = wear_mask ? wear_mask.type : null + file_data["color"] = color ? json_encode(color) : null fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 99396ca09e..d59978d993 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -518,6 +518,8 @@ /datum/emote/living/circle/run_emote(mob/user, params) . = ..() + if(!.) + return var/obj/item/circlegame/N = new(user) if(user.put_in_hands(N)) to_chat(user, "You make a circle with your hand.") diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 447256cb69..f4f8060fb3 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -42,8 +42,8 @@ * Handles biological life processes like chemical metabolism, breathing, etc * Returns TRUE or FALSE based on if we were interrupted. This is used by overridden variants to check if they should stop. */ -/mob/living/proc/BiologicalLife(seconds, times_fired) - SEND_SIGNAL(src,COMSIG_LIVING_BIOLOGICAL_LIFE, seconds, times_fired) +/mob/living/proc/BiologicalLife(delta_time, times_fired) + SEND_SIGNAL(src,COMSIG_LIVING_BIOLOGICAL_LIFE, delta_time, times_fired) handle_diseases()// DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not. handle_wounds() @@ -67,7 +67,7 @@ //stuff in the stomach handle_stomach() - handle_block_parry(seconds) + handle_block_parry(delta_time) handle_traits() // eye, ear, brain damages diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 6f394c1135..779e949f79 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -81,6 +81,7 @@ //Called when we bump onto a mob /mob/living/proc/MobBump(mob/M) + SEND_SIGNAL(src, COMSIG_LIVING_MOB_BUMP, M) //Even if we don't push/swap places, we "touched" them, so spread fire spreadFire(M) @@ -88,6 +89,7 @@ return TRUE var/they_can_move = TRUE + if(isliving(M)) var/mob/living/L = M they_can_move = CHECK_MOBILITY(L, MOBILITY_MOVE) @@ -105,16 +107,16 @@ //Should stop you pushing a restrained person out of the way if(L.pulledby && L.pulledby != src && L.restrained()) if(!(world.time % 5)) - to_chat(src, "[L] is restrained, you cannot push past.") - return 1 + to_chat(src, span_warning("[L] is restrained, you cannot push past.")) + return TRUE if(L.pulling) if(ismob(L.pulling)) var/mob/P = L.pulling if(P.restrained()) if(!(world.time % 5)) - to_chat(src, "[L] is restraining [P], you cannot push past.") - return 1 + to_chat(src, span_warning("[L] is restraining [P], you cannot push past.")) + return TRUE //CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks or over prone bodies without a short delay if(!CHECK_MOBILITY(src, MOBILITY_STAND)) @@ -142,7 +144,7 @@ //END OF CIT CHANGES if(moving_diagonally)//no mob swap during diagonal moves. - return 1 + return TRUE if(!M.buckled && !M.has_buckled_mobs()) var/mob_swap = FALSE @@ -151,7 +153,8 @@ if(!too_strong) mob_swap = TRUE else - if(M.pulledby == src && a_intent == INTENT_GRAB) + //You can swap with the person you are dragging on grab intent, and restrained people in most cases + if(M.pulledby == src && !too_strong) mob_swap = TRUE //restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP)) @@ -159,8 +162,8 @@ if(mob_swap) //switch our position with M if(loc && !loc.Adjacent(M.loc)) - return 1 - now_pushing = 1 + return TRUE + now_pushing = TRUE var/oldloc = loc var/oldMloc = M.loc @@ -180,27 +183,31 @@ if(!M_passmob) M.pass_flags &= ~PASSMOB - now_pushing = 0 + now_pushing = FALSE if(!move_failed) - return 1 + return TRUE //okay, so we didn't switch. but should we push? //not if he's not CANPUSH of course if(!(M.status_flags & CANPUSH)) - return 1 + return TRUE if(isliving(M)) var/mob/living/L = M if(HAS_TRAIT(L, TRAIT_PUSHIMMUNE)) - return 1 - //If they're a human, and they're not in help intent, block pushing - if(ishuman(M) && (M.a_intent != INTENT_HELP)) - return TRUE + return TRUE + if(M.a_intent != INTENT_HELP) + //If they're a human, and they're not in help intent, block pushing + if(ishuman(M)) + return TRUE + //if they are a cyborg, and they're alive and not in help intent, block pushing + if(iscyborg(M) && M.stat != DEAD) + return TRUE //anti-riot equipment is also anti-push for(var/obj/item/I in M.held_items) if(!istype(M, /obj/item/clothing)) if(prob(I.block_chance*2)) - return 1 + return TRUE /mob/living/get_photo_description(obj/item/camera/camera) var/list/mob_details = list() @@ -231,21 +238,40 @@ if(!client && (mob_size < MOB_SIZE_SMALL)) return now_pushing = TRUE - var/t = get_dir(src, AM) + SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_MOVABLE, AM) + var/dir_to_target = get_dir(src, AM) + + // If there's no dir_to_target then the player is on the same turf as the atom they're trying to push. + // This can happen when a player is stood on the same turf as a directional window. All attempts to push + // the window will fail as get_dir will return 0 and the player will be unable to move the window when + // it should be pushable. + // In this scenario, we will use the facing direction of the /mob/living attempting to push the atom as + // a fallback. + if(!dir_to_target) + dir_to_target = dir + var/push_anchored = FALSE if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force) - if(move_crush(AM, move_force, t)) + if(move_crush(AM, move_force, dir_to_target)) push_anchored = TRUE - if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally - if(force_push(AM, move_force, t, push_anchored)) + if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally + if(force_push(AM, move_force, dir_to_target, push_anchored)) push_anchored = TRUE + if(ismob(AM)) + var/mob/mob_to_push = AM + var/atom/movable/mob_buckle = mob_to_push.buckled + // If we can't pull them because of what they're buckled to, make sure we can push the thing they're buckled to instead. + // If neither are true, we're not pushing anymore. + if(mob_buckle && (mob_buckle.buckle_prevents_pull || (force < (mob_buckle.move_resist * MOVE_FORCE_PUSH_RATIO)))) + now_pushing = FALSE + return if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO))) now_pushing = FALSE return - if (istype(AM, /obj/structure/window)) + if(istype(AM, /obj/structure/window)) var/obj/structure/window/W = AM if(W.fulltile) - for(var/obj/structure/window/win in get_step(W,t)) + for(var/obj/structure/window/win in get_step(W, dir_to_target)) now_pushing = FALSE return if(pulling == AM) @@ -253,8 +279,9 @@ var/current_dir if(isliving(AM)) current_dir = AM.dir - if(step(AM, t) && Process_Spacemove(t)) - step(src, t) + if(AM.Move(get_step(AM.loc, dir_to_target), dir_to_target, glide_size)) + AM.add_fingerprint(src) + Move(get_step(loc, dir_to_target), dir_to_target) if(current_dir) AM.setDir(current_dir) now_pushing = FALSE @@ -354,29 +381,33 @@ offset = GRAB_PIXEL_SHIFT_NECK if(GRAB_KILL) offset = GRAB_PIXEL_SHIFT_NECK - M.setDir(get_dir(M, src)) - switch(M.dir) - if(NORTH) - animate(M, pixel_x = 0, pixel_y = offset, 3) - if(SOUTH) - animate(M, pixel_x = 0, pixel_y = -offset, 3) - if(EAST) - if(M.lying == 270) //update the dragged dude's direction if we've turned - M.lying = 90 - M.update_transform() //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so - M.lying_prev = M.lying - animate(M, pixel_x = offset, pixel_y = 0, 3) - if(WEST) - if(M.lying == 90) - M.lying = 270 - M.update_transform() - M.lying_prev = M.lying - animate(M, pixel_x = -offset, pixel_y = 0, 3) + var/target_dir = get_dir(M, src) + M.setDir(target_dir) + var/target_x + var/target_y + if(target_dir & NORTH) + target_y += offset + if(target_dir & SOUTH) + target_y -= offset + if(target_dir & EAST) + target_x += offset + if(target_dir & WEST) + target_x -= offset + if(target_x || target_y) + if(0 < target_x && M.lying == 270) + M.lying = 90 + M.update_transform(FALSE) //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so + M.lying_prev = M.lying + if(0 > target_x && M.lying == 90) + M.lying = 270 + M.update_transform(FALSE) + M.lying_prev = M.lying + animate(M, pixel_x = target_x, pixel_y = target_y, time = 3, flags = ANIMATION_PARALLEL) /mob/living/proc/reset_pull_offsets(mob/living/M, override) if(!override && M.buckled) return - animate(M, pixel_x = 0, pixel_y = 0, 1) + animate(M, pixel_x = 0, pixel_y = 0, time = 3, flags = ANIMATION_PARALLEL) //mob verbs are a lot faster than object verbs //for more info on why this is not atom/pull, see examinate() in mob.dm @@ -885,12 +916,11 @@ if(anchored || (buckled && buckled.anchored)) fixed = 1 if(on && !(movement_type & FLOATING) && !fixed) - animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1) - sleep(10) - animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1) + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) setMovetype(movement_type | FLOATING) else if(((!on || fixed) && (movement_type & FLOATING))) - animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10) + animate(src, pixel_z = get_standard_pixel_y_offset(lying), time = 10) setMovetype(movement_type & ~FLOATING) // The src mob is trying to strip an item from someone @@ -989,7 +1019,7 @@ var/pixel_y_diff = rand(-amplitude/3, amplitude/3) var/final_pixel_x = get_standard_pixel_x_offset(lying) var/final_pixel_y = get_standard_pixel_y_offset(lying) - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6) + animate(src, pixel_x = pixel_x_diff, pixel_y = pixel_y_diff , time = 2, loop = 6, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE) animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2) floating_need_update = TRUE diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 3aeabd1d51..02a3e3684e 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -238,7 +238,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( /mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) //parent calls can't overwrite the current proc args. - if(!client) + if(!client && !audiovisual_redirect) return var/deaf_message var/deaf_type @@ -297,8 +297,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list( AM.Hear(rendered, src, message_language, message, null, spans, message_mode, source) SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message) - if(client && !eavesdrop_range && say_test(message) == "2") // Yell hook - process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source) + var/is_yell = (say_test(message) == "2") + if(client && !eavesdrop_range && is_yell) // Yell hook + listening |= process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source) //speech bubble var/list/speech_bubble_recipients = list() @@ -309,6 +310,23 @@ GLOBAL_LIST_INIT(department_radio_keys, list( I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30) + //Listening gets trimmed here if a vocal bark's present. If anyone ever makes this proc return listening, make sure to instead initialize a copy of listening in here to avoid wonkiness + if(SEND_SIGNAL(src, COMSIG_MOVABLE_QUEUE_BARK, listening, args) || vocal_bark || vocal_bark_id) + for(var/mob/M in listening) + if(!M.client) + continue + if(!(M.client.prefs.toggles & SOUND_BARK)) + listening -= M + var/barks = min(round((LAZYLEN(message) / vocal_speed)) + 1, BARK_MAX_BARKS) + var/total_delay + vocal_current_bark = world.time + for(var/i in 1 to barks) + if(total_delay > BARK_MAX_TIME) + break + addtimer(CALLBACK(src, /atom/movable/proc/bark, listening, (message_range * (is_yell ? 4 : 1)), (vocal_volume * (is_yell ? 1.5 : 1)), BARK_DO_VARY(vocal_pitch, vocal_pitch_range), vocal_current_bark), total_delay) + total_delay += rand(DS2TICKS(vocal_speed / BARK_SPEED_BASELINE), DS2TICKS(vocal_speed / BARK_SPEED_BASELINE) + DS2TICKS((vocal_speed / BARK_SPEED_BASELINE) * (is_yell ? 0.5 : 1))) TICKS + + /atom/movable/proc/process_yelling(list/already_heard, rendered, atom/movable/speaker, datum/language/message_language, message, list/spans, message_mode, obj/source) if(last_yell > (world.time - 10)) to_chat(src, "Your voice doesn't project as far as you try to yell in such quick succession.") // yeah no, no spamming an expensive floodfill. @@ -333,6 +351,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/atom/movable/AM = _AM AM.Hear(rendered, speaker, message_language, message, null, spans, message_mode, source) + return overhearing + /mob/proc/binarycheck() return FALSE diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index a822917aa4..deaf50973d 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -47,6 +47,7 @@ var/mob/living/simple_animal/bot/Bot var/tracking = FALSE //this is 1 if the AI is currently tracking somebody, but the track has not yet been completed. var/datum/effect_system/spark_spread/spark_system//So they can initialize sparks whenever/N + var/obj/machinery/status_display/controlled_display //MALFUNCTION var/datum/module_picker/malf_picker @@ -660,7 +661,7 @@ "goat" = 'icons/mob/animal.dmi', "cat" = 'icons/mob/pets.dmi', "cat2" = 'icons/mob/pets.dmi', - "poly" = 'icons/mob/animal.dmi', + "polly" = 'icons/mob/animal.dmi', "pug" = 'icons/mob/pets.dmi', "spider" = 'icons/mob/animal.dmi' ) @@ -669,7 +670,7 @@ if(input) qdel(holo_icon) switch(input) - if("poly") + if("polly") holo_icon = getHologramIcon(icon(icon_list[input],"parrot_fly")) if("chicken") holo_icon = getHologramIcon(icon(icon_list[input],"chicken_brown")) @@ -1043,3 +1044,14 @@ /mob/living/silicon/ai/zMove(dir, feedback = FALSE) . = eyeobj.zMove(dir, feedback) + +/mob/living/silicon/ai/proc/stop_controlling_display() + if(!controlled_display) + return + controlled_display.master = null + controlled_display.cut_overlay(controlled_display.ai_vtuber_overlay) + controlled_display.ai_vtuber_overlay = null + if(current == controlled_display) + current = null + controlled_display.update_appearance() + controlled_display = null diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm index 4cf9b81592..86de4c7c60 100644 --- a/code/modules/mob/living/silicon/ai/examine.dm +++ b/code/modules/mob/living/silicon/ai/examine.dm @@ -1,5 +1,5 @@ /mob/living/silicon/ai/examine(mob/user) - . = list("*---------*\nThis is [icon2html(src, user)] [src]!") + . = list("This is [icon2html(src, user)] [src]!") if (stat == DEAD) . += "It appears to be powered-down." else @@ -17,6 +17,8 @@ . += "The wireless networking light is blinking." else if (!shunted && !client) . += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem..." - . += "*---------*" + + if(LAZYLEN(.) > 1) + .[2] = "
[.[2]]" . += ..() diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index bc6ab7c34e..bce18462b2 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -92,6 +92,8 @@ ai.light_cameras() if(ai.master_multicam) ai.master_multicam.refresh_view() + if(ai.controlled_display) + ai.stop_controlling_display() //it uses setLoc not forceMove, talks to the sillycone and not the camera mob /mob/camera/aiEye/zMove(dir, feedback = FALSE) @@ -168,6 +170,9 @@ if(!user.tracking) user.cameraFollow = null + if(user.controlled_display) + user.stop_controlling_display() + // Return to the Core. /mob/living/silicon/ai/proc/view_core() if(istype(current,/obj/machinery/holopad)) diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index f14f2edcd4..ed969e49fb 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -3,7 +3,7 @@ #define POWER_RESTORATION_SEARCH_APC 2 #define POWER_RESTORATION_APC_FOUND 3 -/mob/living/silicon/ai/BiologicalLife(seconds, times_fired) +/mob/living/silicon/ai/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return //I'm not removing that shitton of tabs, unneeded as they are. -- Urist diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 2b5d3d98f2..76eaa6ad0d 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -34,8 +34,6 @@ //For holopads only. Usable by AI. /mob/living/silicon/ai/proc/holopad_talk(message, language) - - message = trim(message) if (!message) @@ -56,6 +54,29 @@ to_chat(src, "No holopad connected.") +//For status displays only. Usable by AI. +/mob/living/silicon/ai/proc/statusdisplay_talk(message, language) + message = trim(message) + + if (!message) + return + + var/obj/machinery/status_display/T = controlled_display + if(T) + var/turf/padturf = get_turf(T) + var/padloc + if(padturf) + padloc = AREACOORD(padturf) + else + padloc = "(UNKNOWN)" + src.log_talk(message, LOG_SAY, tag="STATUS DISPLAY in [padloc]") + send_speech(message, 7, T, "robot", message_language = language) + to_chat(src, "Status Display message transmitted, [real_name] \"[message]\"") + else + to_chat(src, "No status display connected.") + + + // Make sure that the code compiles with AI_VOX undefined #ifdef AI_VOX #define VOX_DELAY 600 diff --git a/code/modules/mob/living/silicon/examine.dm b/code/modules/mob/living/silicon/examine.dm index 7de281de5f..0840ea1191 100644 --- a/code/modules/mob/living/silicon/examine.dm +++ b/code/modules/mob/living/silicon/examine.dm @@ -1,5 +1,4 @@ /mob/living/silicon/examine(mob/user) //Displays a silicon's laws to ghosts - . = ..() if(laws && isobserver(user)) . += "[src] has the following laws:" for(var/law in laws.get_law_list(include_zeroth = TRUE)) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index fdde445379..ffe88705e4 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -152,7 +152,7 @@ if(possible_chassis[chassis]) AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD) -/mob/living/silicon/pai/BiologicalLife(seconds, times_fired) +/mob/living/silicon/pai/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(hacking) diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index d499c2abae..5563f47e61 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -8,7 +8,7 @@ var/unrestricted = TRUE /datum/emote/sound/silicon/run_emote(mob/user, params) - if(!unrestricted && !(issilicon(user) || isipcperson(user))) + if(!unrestricted && !(issilicon(user) || isrobotic(user))) return return ..() diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 45a3d15635..4ebd4c3be8 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -1,5 +1,5 @@ /mob/living/silicon/robot/examine(mob/user) - . = list("*---------*\nThis is [icon2html(src, user)] \a [src], a [src.module.name] unit!") + . = list("This is [icon2html(src, user)] \a [src], a [src.module.name] unit!") if(desc) . += "[desc]" @@ -49,8 +49,9 @@ if(DEAD) . += "It looks like its system is corrupted and requires a reset." + if(LAZYLEN(.) > 1) + .[2] = "
[.[2]]" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, usr, .) - . += "*---------*
" - . += ..() diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index d1eaeeacc5..e902d57ddd 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -1,4 +1,4 @@ -/mob/living/silicon/robot/BiologicalLife(seconds, times_fired) +/mob/living/silicon/robot/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return adjustOxyLoss(-10) //we're a robot! diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index f2f1f8adbe..d7c6dfe479 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -421,8 +421,8 @@ if("Alina") cyborg_base_icon = "alina-med" cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi' - special_light_key = "alina" - sleeper_overlay = "alinasleeper" + special_light_key = "alina-med" + sleeper_overlay = "valemedsleeper" moduleselect_icon = "medihound" moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi' dogborg = TRUE @@ -536,9 +536,9 @@ dogborg = TRUE if("Alina") cyborg_base_icon = "alina-eng" - special_light_key = "alina" + special_light_key = "alina-eng" cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi' - sleeper_overlay = "alinasleeper" + sleeper_overlay = "valeengsleeper" dogborg = TRUE else return FALSE @@ -620,8 +620,8 @@ dogborg = TRUE if("Alina") cyborg_base_icon = "alina-sec" - special_light_key = "alina" - sleeper_overlay = "alinasleeper" + special_light_key = "alina-sec" + sleeper_overlay = "valesecsleeper" cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi' dogborg = TRUE if("K9 Dark") diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index b97536b7a4..76bfcf6eba 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -50,6 +50,9 @@ typing_indicator_state = /obj/effect/overlay/typing_indicator/machine + vocal_bark_id = "synth" + vocal_pitch_range = 0.1 + /mob/living/silicon/Initialize(mapload) . = ..() GLOB.silicon_mobs += src @@ -413,7 +416,7 @@ src << browse(dat, "window=airoster") onclose(src, "airoster") -/mob/living/silicon/update_transform() +/mob/living/silicon/update_transform(do_animate) var/matrix/ntransform = matrix(transform) //aka transform.Copy() var/changed = 0 if(resize != RESIZE_DEFAULT_SIZE) diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 0ad684ab4b..806fc60156 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -19,6 +19,7 @@ path_image_color = "#993299" weather_immunities = list("lava","ash") + var/base_icon = "cleanbot" var/clean_time = 50 //How long do we take to clean? var/upgrades = 0 @@ -126,13 +127,21 @@ /mob/living/simple_animal/bot/cleanbot/turn_on() ..() - icon_state = "cleanbot[on]" bot_core.updateUsrDialog() + update_icon() /mob/living/simple_animal/bot/cleanbot/turn_off() ..() - icon_state = "cleanbot[on]" bot_core.updateUsrDialog() + update_icon() + +/mob/living/simple_animal/bot/cleanbot/update_icon_state() + . = ..() + switch(mode) + if(BOT_CLEANING) + icon_state = "[base_icon]-c" + else + icon_state = "[base_icon][on]" /mob/living/simple_animal/bot/cleanbot/bot_reset() ..() @@ -381,6 +390,12 @@ target = null mode = BOT_IDLE icon_state = "cleanbot[on]" + else if(istype(A, /turf)) //for player-controlled cleanbots so they can clean unclickable messes like dirt + var/turf/T = A + for(var/atom/S in T.contents) + if(istype(S, /obj/effect/decal/cleanable)) //clean the first mess found + UnarmedAttack(S) + return else if(istype(A, /obj/item) || istype(A, /obj/effect/decal/remains)) visible_message("[src] sprays hydrofluoric acid at [A]!") playsound(src, 'sound/effects/spray2.ogg', 50, TRUE, -6) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 3e32712fb3..7d37039fa1 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -83,13 +83,12 @@ /mob/living/simple_animal/hostile/construct/examine(mob/user) var/t_He = p_they(TRUE) var/t_s = p_s() - . = list("*---------*\nThis is [icon2html(src, user)] \a [src]!\n[desc]") + . = list("This is [icon2html(src, user)] \a [src]!\n[desc]") if(health < maxHealth) if(health >= maxHealth/2) . += "[t_He] look[t_s] slightly dented." else . += "[t_He] look[t_s] severely dented!" - . += "*---------*" /mob/living/simple_animal/hostile/construct/attack_animal(mob/living/simple_animal/M) if(isconstruct(M)) //is it a construct? diff --git a/code/modules/mob/living/simple_animal/eldritch_demons.dm b/code/modules/mob/living/simple_animal/eldritch_demons.dm index 6fb53d42a4..eafac41303 100644 --- a/code/modules/mob/living/simple_animal/eldritch_demons.dm +++ b/code/modules/mob/living/simple_animal/eldritch_demons.dm @@ -223,7 +223,7 @@ QDEL_NULL(back) // chain destruction baby return ..() -/mob/living/simple_animal/hostile/eldritch/armsy/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/eldritch/armsy/BiologicalLife(delta_time, times_fired) adjustBruteLoss(-2) /mob/living/simple_animal/hostile/eldritch/armsy/proc/heal() diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 0d04d4b562..9673857a1b 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -35,6 +35,9 @@ collar_type = "cat" var/held_icon = "cat2" footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "mutedc4" + vocal_pitch = 1.4 + vocal_pitch_range = 0.4 /mob/living/simple_animal/pet/cat/Initialize(mapload) . = ..() @@ -115,7 +118,7 @@ Read_Memory() . = ..() -/mob/living/simple_animal/pet/cat/Runtime/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/cat/Runtime/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!cats_deployed && SSticker.current_state >= GAME_STATE_SETTING_UP) @@ -136,6 +139,7 @@ ..() /mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory() + var/saved_color if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Runtime.sav") S["family"] >> family @@ -146,14 +150,21 @@ return var/list/json = json_decode(file2text(json_file)) family = json["family"] + saved_color = json["color"] if(isnull(family)) family = list() + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Runtime.json") var/list/file_data = list() family = list() if(!dead) + if(color) + file_data["color"] = json_encode(color) + else + file_data["color"] = null for(var/mob/living/simple_animal/pet/cat/kitten/C in children) if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats continue @@ -161,6 +172,8 @@ family[C.type] += 1 else family[C.type] = 1 + else + file_data["color"] = null file_data["family"] = family fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) @@ -178,7 +191,7 @@ gold_core_spawnable = NO_SPAWN unique_pet = TRUE -/mob/living/simple_animal/pet/cat/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/cat/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && !buckled && !client) @@ -272,7 +285,7 @@ to_chat(src, "Your name is now \"new_name\"!") name = new_name -/mob/living/simple_animal/pet/cat/cak/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/cat/cak/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat) diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index 8fd97a465c..775ad05c11 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -30,7 +30,7 @@ . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) -/mob/living/simple_animal/crab/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/crab/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return //CRAB movement diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index a12b28ea77..e4d042a4cc 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -20,6 +20,9 @@ footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "bullet" + vocal_speed = 6 + /mob/living/simple_animal/pet/dog/ComponentInitialize() . = ..() AddElement(/datum/element/wuv, "yaps happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE) @@ -424,7 +427,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( RemoveElement(/datum/element/mob_holder, held_icon) AddElement(/datum/element/mob_holder, "old_corgi") -/mob/living/simple_animal/pet/dog/corgi/Ian/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/dog/corgi/Ian/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) @@ -438,6 +441,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( /mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory() set waitfor = FALSE + var/saved_color if(fexists("data/npc_saves/Ian.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Ian.sav") S["age"] >> age @@ -452,12 +456,15 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( age = json["age"] record_age = json["record_age"] saved_head = json["saved_head"] + saved_color = json["color"] if(isnull(age)) age = 0 if(isnull(record_age)) record_age = 1 if(saved_head) place_on_head(new saved_head) + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/simple_animal/pet/dog/corgi/Ian/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Ian.json") @@ -472,10 +479,15 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( file_data["saved_head"] = inventory_head.type else file_data["saved_head"] = null + if(color) + file_data["color"] = json_encode(color) + else + file_data["color"] = null else file_data["age"] = 0 file_data["record_age"] = record_age file_data["saved_head"] = null + file_data["color"] = null fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) @@ -553,7 +565,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( nofur = TRUE unique_pet = TRUE -/mob/living/simple_animal/pet/dog/corgi/narsie/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/dog/corgi/narsie/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return for(var/mob/living/simple_animal/pet/P in range(1, src)) @@ -632,6 +644,8 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( mob_size = MOB_SIZE_SMALL collar_type = "puppy" + vocal_pitch = 1.6 + //puppies cannot wear anything. /mob/living/simple_animal/pet/dog/corgi/puppy/Topic(href, href_list) if(href_list["remove_inv"] || href_list["add_inv"]) @@ -653,6 +667,8 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( maxbodytemp = T0C + 40 held_icon = "void_puppy" + vocal_pitch = 0.6 + /mob/living/simple_animal/pet/dog/corgi/puppy/void/Process_Spacemove(movement_dir = 0) return 1 //Void puppies can navigate space. @@ -679,7 +695,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( return ..() -/mob/living/simple_animal/pet/dog/corgi/Lisa/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/dog/corgi/Lisa/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return @@ -693,7 +709,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( setDir(i) sleep(1) -/mob/living/simple_animal/pet/dog/pug/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/dog/pug/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index 9ecc60f7eb..d35f12b0f6 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -178,7 +178,7 @@ /mob/living/simple_animal/drone/examine(mob/user) - . = list("*---------*\nThis is [icon2html(src, user)] \a [src]!") + . = list("This is [icon2html(src, user)] \a [src]!") //Hands for(var/obj/item/I in held_items) @@ -214,7 +214,7 @@ . += "A message repeatedly flashes on its display: \"REBOOT -- REQUIRED\"." else . += "A message repeatedly flashes on its display: \"ERROR -- OFFLINE\"." - . += "*---------*" + . += "" /mob/living/simple_animal/drone/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //Secbots won't hunt maintenance drones. diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index c6dfc772c1..7893f7b26b 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -36,6 +36,7 @@ var/datum/reagent/milk_reagent = /datum/reagent/consumable/milk footstep_type = FOOTSTEP_MOB_SHOE + vocal_bark_id = "banjoc3" /mob/living/simple_animal/hostile/retaliate/goat/Initialize(mapload, /datum/reagent/milk_reagent) udder = new (null, milk_reagent) @@ -46,7 +47,7 @@ udder = null return ..() -/mob/living/simple_animal/hostile/retaliate/goat/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/retaliate/goat/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat == CONSCIOUS) @@ -143,6 +144,8 @@ blood_volume = BLOOD_VOLUME_NORMAL footstep_type = FOOTSTEP_MOB_SHOE + vocal_bark_id = "mutedc2" + vocal_pitch = 1.2 /mob/living/simple_animal/cow/Initialize(mapload) udder = new(null, milk_reagent) @@ -160,7 +163,7 @@ else return ..() -/mob/living/simple_animal/cow/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/cow/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat == CONSCIOUS) @@ -247,6 +250,8 @@ gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "squeak" + vocal_pitch = 1.4 /mob/living/simple_animal/chick/Initialize(mapload) . = ..() @@ -254,7 +259,7 @@ pixel_y = rand(0, 10) AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) -/mob/living/simple_animal/chick/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/chick/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && !ckey) @@ -263,7 +268,7 @@ new /mob/living/simple_animal/chicken(src.loc) qdel(src) -/mob/living/simple_animal/chick/holo/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/chick/holo/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return amount_grown = 0 @@ -309,6 +314,9 @@ var/static/chicken_count = 0 footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "synthgrunt" + vocal_pitch = 1.4 + vocal_pitch_range = 0.4 /mob/living/simple_animal/chicken/Initialize(mapload) . = ..() @@ -339,7 +347,7 @@ else ..() -/mob/living/simple_animal/chicken/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/chicken/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if((!stat && prob(3) && eggsleft > 0) && egg_type) @@ -403,6 +411,8 @@ var/static/kiwi_count = 0 footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "squeak" + vocal_pitch = 1.4 /mob/living/simple_animal/kiwi/Destroy() --kiwi_count @@ -414,7 +424,7 @@ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) -/mob/living/simple_animal/kiwi/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/kiwi/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if((!stat && prob(3) && eggsleft > 0) && egg_type) @@ -481,6 +491,8 @@ gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "squeak" + vocal_pitch = 1.4 /mob/living/simple_animal/babyKiwi/Initialize(mapload) . = ..() @@ -489,7 +501,7 @@ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) -/mob/living/simple_animal/babyKiwi/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/babyKiwi/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && !ckey) @@ -557,3 +569,4 @@ maxHealth = 75 blood_volume = BLOOD_VOLUME_NORMAL footstep_type = FOOTSTEP_MOB_SHOE + vocal_bark_id = "mutedc4" diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index 4e4fd7ccfc..475b50d44a 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -23,6 +23,11 @@ gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "bullet" + vocal_speed = 2 + vocal_pitch = 1.6 + vocal_pitch_range = 0.4 + /mob/living/simple_animal/pet/fox/ComponentInitialize() . = ..() AddElement(/datum/element/mob_holder, "fox") diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index d49eb1251d..f67c5dcb97 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -29,6 +29,8 @@ gold_core_spawnable = FRIENDLY_SPAWN var/chew_probability = 1 faction = list("rat") + vocal_bark_id = "squeak" + vocal_pitch = 1.4 /mob/living/simple_animal/mouse/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/simple_animal/friendly/plushie.dm b/code/modules/mob/living/simple_animal/friendly/plushie.dm index ff95e8fe86..6a8e2565f1 100644 --- a/code/modules/mob/living/simple_animal/friendly/plushie.dm +++ b/code/modules/mob/living/simple_animal/friendly/plushie.dm @@ -29,6 +29,8 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 pressure_resistance = 200 + vocal_bark_id = "squeak" + vocal_pitch_range = 0.4 /mob/living/simple_animal/pet/plushie/ComponentInitialize() . = ..() @@ -72,7 +74,7 @@ qdel(src) //low regen over time -/mob/living/simple_animal/pet/plushie/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/plushie/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(health < maxHealth) diff --git a/code/modules/mob/living/simple_animal/guardian/types/charger.dm b/code/modules/mob/living/simple_animal/guardian/types/charger.dm index ee5a648067..9715d4f63c 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/charger.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/charger.dm @@ -14,7 +14,7 @@ var/charging = 0 var/atom/movable/screen/alert/chargealert -/mob/living/simple_animal/hostile/guardian/charger/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/guardian/charger/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(ranged_cooldown <= world.time) diff --git a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm index 6d421d326e..1fd1e623db 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm @@ -18,14 +18,14 @@ /mob/living/simple_animal/hostile/guardian/dextrous/examine(mob/user) if(dextrous) - . = list("*---------*\nThis is [icon2html(src)] \a [src]!\n[desc]") + . = list("This is [icon2html(src)] \a [src]!\n[desc]") for(var/obj/item/I in held_items) if(!(I.item_flags & ABSTRACT)) . += "It has [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))]." if(internal_storage && !(internal_storage.item_flags & ABSTRACT)) . += "It is holding [internal_storage.get_examine_string(user)] in its internal storage." - . += "*---------*" + . += "" else return ..() diff --git a/code/modules/mob/living/simple_animal/guardian/types/fire.dm b/code/modules/mob/living/simple_animal/guardian/types/fire.dm index a05cd517fb..68e05f3f8c 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/fire.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/fire.dm @@ -13,7 +13,7 @@ tech_fluff_string = "Boot sequence complete. Crowd control modules activated. Holoparasite swarm online." carp_fluff_string = "CARP CARP CARP! You caught one! OH GOD, EVERYTHING'S ON FIRE. Except you and the fish." -/mob/living/simple_animal/hostile/guardian/fire/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/guardian/fire/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(summoner) diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index c7772f780d..ba81ad72da 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -129,7 +129,7 @@ attack_verb_continuous = "slaps" attack_verb_simple = "slap" -/mob/living/simple_animal/hostile/bear/butter/BiologicalLife(seconds, times_fired) //Heals butter bear really fast when he takes damage. +/mob/living/simple_animal/hostile/bear/butter/BiologicalLife(delta_time, times_fired) //Heals butter bear really fast when he takes damage. if(stat) return if(health < maxHealth) diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 98dddab7bd..7f7589dae4 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -46,7 +46,7 @@ if(regen_amount) regen_cooldown = world.time + REGENERATION_DELAY -/mob/living/simple_animal/hostile/carp/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/carp/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(regen_amount && regen_cooldown < world.time) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 1b6f417b7b..89f27f067e 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -79,7 +79,7 @@ foes = null return ..() -/mob/living/simple_animal/hostile/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/BiologicalLife(delta_time, times_fired) if(!(. = ..())) walk(src, 0) //stops walking return diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm index f561f0d43c..edefa028f9 100644 --- a/code/modules/mob/living/simple_animal/hostile/illusion.dm +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -23,7 +23,7 @@ deathmessage = "vanishes into thin air! It was a fake!" has_field_of_vision = FALSE //not meant to be played anyway. -/mob/living/simple_animal/hostile/illusion/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/illusion/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(world.time > life_span) diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index a0528b4109..f3676e752a 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -165,7 +165,7 @@ if(!hopping) Hop() -/mob/living/simple_animal/hostile/jungle/leaper/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/jungle/leaper/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return update_icons() diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm index 31303bd7f1..1e0116f52c 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm @@ -26,7 +26,7 @@ footstep_type = FOOTSTEP_MOB_CLAW -/mob/living/simple_animal/hostile/jungle/mega_arachnid/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/jungle/mega_arachnid/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target && ranged_cooldown > world.time && iscarbon(target)) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 04967f081d..efef46f2ef 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -89,7 +89,7 @@ Difficulty: Normal /mob/living/simple_animal/hostile/megafauna/hierophant/spawn_crusher_loot() new /obj/item/crusher_trophy/vortex_talisman(get_turf(spawned_beacon)) -/mob/living/simple_animal/hostile/megafauna/hierophant/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/megafauna/hierophant/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(spawned_beacon && !QDELETED(spawned_beacon) && !client) @@ -500,6 +500,8 @@ Difficulty: Normal var/obj/item/projectile/P = mover if(P.firer == caster) return TRUE + if(mover != caster) + return FALSE if(mover == caster) return TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm index 6ce43ed409..a8910f5104 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm @@ -74,7 +74,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa step(R, ddir) //Step the swarmers, instead of spawning them there, incase the turf is solid -/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return var/createtype = GetUncappedAISwarmerType() diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index c2d05e43d9..6370fae0e3 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -118,7 +118,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca overlay_googly_eyes = FALSE CopyObject(copy, creator, destroy_original) -/mob/living/simple_animal/hostile/mimic/copy/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/mimic/copy/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(idledamage && !target && !ckey) //Objects eventually revert to normal if no one is around to terrorize diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index cda54e32f9..232bdb04c4 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -95,7 +95,7 @@ wanted_objects = list(/obj/item/pen/survival, /obj/item/stack/ore/diamond) field_of_vision_type = FOV_270_DEGREES //Obviously, it's one eyeball. -/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat == CONSCIOUS) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm index 5ee249c767..d7b7dc3dae 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm @@ -98,7 +98,7 @@ if(CALL_CHILDREN) call_children() -/mob/living/simple_animal/hostile/asteroid/elite/broodmother/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/elite/broodmother/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(health < maxHealth * 0.5 && rand_tent < world.time) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm index 50b15933a9..5daeaff9e8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm @@ -95,7 +95,7 @@ if(AOE_SQUARES) aoe_squares(target) -/mob/living/simple_animal/hostile/asteroid/elite/pandora/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/elite/pandora/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(health >= maxHealth * 0.5) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index 2b7943d130..115681a7d4 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -38,7 +38,7 @@ footstep_type = FOOTSTEP_MOB_HEAVY -/mob/living/simple_animal/hostile/asteroid/goliath/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/goliath/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return handle_preattack() @@ -129,7 +129,7 @@ var/turf/last_location var/tentacle_recheck_cooldown = 100 -/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(isturf(loc)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm index d0aa25aabc..f08b52040b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm @@ -114,7 +114,7 @@ name = "guthen" gender = FEMALE -/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(udder.reagents.total_volume == udder.reagents.maximum_volume) //Only breed when we're full. diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index 757272ca98..f2ffd54cbd 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -198,7 +198,7 @@ swarming = TRUE var/can_infest_dead = FALSE -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(isturf(loc)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm index d40cd8636c..2cf96bf51b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm @@ -62,7 +62,7 @@ SLEEP_CHECK_DEATH(8) return ..() -/mob/living/simple_animal/hostile/asteroid/ice_demon/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/ice_demon/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm index 7214fd71e0..8ab61d2450 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm @@ -43,7 +43,7 @@ var/list/burn_turfs = getline(src, T) - get_turf(src) dragon_fire_line(src, burn_turfs) -/mob/living/simple_animal/hostile/asteroid/ice_whelp/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/ice_whelp/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm index de9464cc16..9a81d74dc8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm @@ -44,7 +44,7 @@ aggressive_message_said = TRUE rapid_melee = 2 -/mob/living/simple_animal/hostile/asteroid/polarbear/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/polarbear/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm index 8c4db48434..148d71ecd8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm @@ -51,7 +51,7 @@ retreat_message_said = TRUE retreat_distance = 30 -/mob/living/simple_animal/hostile/asteroid/wolf/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/wolf/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target) diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index 527fd51260..378dbefae7 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -51,7 +51,7 @@ else . += "It looks like it's been roughed up." -/mob/living/simple_animal/hostile/mushroom/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/mushroom/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat)//Mushrooms slowly regenerate if conscious, for people who want to save them from being eaten diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm index 06db07daf6..a1e135d038 100644 --- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm +++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm @@ -45,7 +45,7 @@ var/chosen_sound = pick(migo_sounds) playsound(src, chosen_sound, 100, TRUE) -/mob/living/simple_animal/hostile/netherworld/migo/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/netherworld/migo/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat) diff --git a/code/modules/mob/living/simple_animal/hostile/plaguerat.dm b/code/modules/mob/living/simple_animal/hostile/plaguerat.dm index 7112740b39..73dace85cd 100644 --- a/code/modules/mob/living/simple_animal/hostile/plaguerat.dm +++ b/code/modules/mob/living/simple_animal/hostile/plaguerat.dm @@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(plague_rats) walk_to(src, entry_vent) break -/mob/living/simple_animal/hostile/plaguerat/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/plaguerat/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(isopenturf(loc)) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index 0233cb9c5d..2919c6d070 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -56,7 +56,7 @@ ..() playsound(src.loc, 'sound/items/bikehorn.ogg', 50, TRUE) -/mob/living/simple_animal/hostile/retaliate/clown/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/retaliate/clown/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(banana_time && banana_time < world.time) diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index 600d60eb4d..9356c962fd 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -81,7 +81,7 @@ return 0 return ..() -/mob/living/simple_animal/hostile/statue/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/statue/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!client && target) // If we have a target and we're AI controlled diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 978d58339d..9f53c11df3 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -44,7 +44,7 @@ gold_core_spawnable = HOSTILE_SPAWN del_on_death = 1 -/mob/living/simple_animal/hostile/tree/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/tree/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(isopenturf(loc)) diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 452138fa80..e724da5cc3 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -100,7 +100,7 @@ /mob/living/simple_animal/hostile/venus_human_trap/ghost_playable playable_plant = TRUE //For admins that want to buss some harmless plants -/mob/living/simple_animal/hostile/venus_human_trap/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/venus_human_trap/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return pull_vines() diff --git a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm index eb35606e0d..33b9be4757 100644 --- a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm +++ b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm @@ -47,7 +47,7 @@ QDEL_NULL(E) return ..() -/mob/living/simple_animal/hostile/asteroid/fugu/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/fugu/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!wumbo) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index fe479bb943..0c24dd36fa 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -44,6 +44,10 @@ emote_hear = list("squawks.","bawks!") emote_see = list("flutters its wings.") + vocal_bark_id = "banjoc4" + vocal_pitch = 1.4 + vocal_pitch_range = 0.4 + speak_chance = 1 //1% (1 in 100) chance every tick; So about once per 150 seconds, assuming an average tick is 1.5s turns_per_move = 5 butcher_results = list(/obj/item/reagent_containers/food/snacks/cracker/ = 1) @@ -80,7 +84,7 @@ var/speech_shuffle_rate = 20 var/list/available_channels = list() - //Headset for Poly to yell at engineers :) + //Headset for Polly to yell at engineers :) var/obj/item/radio/headset/ears = null /// spawns with headset var/spawns_with_headset = FALSE @@ -345,7 +349,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( parrot_state |= PARROT_FLEE icon_state = icon_living drop_held_item(0) - else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Poly wants a cracker. + else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Polly wants a cracker. qdel(O) if(health < maxHealth) adjustBruteLoss(-10) @@ -372,7 +376,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( /* * AI - Not really intelligent, but I'm calling it AI anyway. */ -/mob/living/simple_animal/parrot/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/parrot/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return //Sprite update for when a parrot gets pulled @@ -890,10 +894,10 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( /* * Sub-types */ -/mob/living/simple_animal/parrot/Poly - name = "Poly" - desc = "Poly the Parrot. An expert on quantum cracker theory." - speak = list("Poly wanna cracker!", ":e Check the crystal, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS ABOUT TO DELAMINATE CALL THE SHUTTLE") +/mob/living/simple_animal/parrot/Polly + name = "Polly" + desc = "Polly the Parrot. An expert on quantum cracker theory." + speak = list("Polly wanna cracker!", ":e Check the crystal, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS ABOUT TO DELAMINATE CALL THE SHUTTLE") gold_core_spawnable = NO_SPAWN speak_chance = 3 spawns_with_headset = TRUE @@ -902,7 +906,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( var/longest_survival = 0 var/longest_deathstreak = 0 -/mob/living/simple_animal/parrot/Poly/Initialize(mapload) +/mob/living/simple_animal/parrot/Polly/Initialize(mapload) ears = new /obj/item/radio/headset/headset_eng(src) available_channels = list(":e") Read_Memory() @@ -910,11 +914,13 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( speak += pick("...[longest_survival].", "The things I've seen!", "I have lived many lives!", "What are you before me?") desc += " Old as sin, and just as loud. Claimed to be [rounds_survived]." speak_chance = 20 //His hubris has made him more annoying/easier to justify killing - add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY) + if(!color) + add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY) else if(rounds_survived == longest_deathstreak) speak += pick("What are you waiting for!", "Violence breeds violence!", "Blood! Blood!", "Strike me down if you dare!") desc += " The squawks of [-rounds_survived] dead parrots ring out in your ears..." - add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY) + if(!color) + add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY) else if(rounds_survived > 0) speak += pick("...again?", "No, It was over!", "Let me out!", "It never ends!") desc += " Over [rounds_survived] shifts without a \"terrible\" \"accident\"!" @@ -923,30 +929,31 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( . = ..() -/mob/living/simple_animal/parrot/Poly/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) +/mob/living/simple_animal/parrot/Polly/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) . = ..() - if(. && !client && prob(1) && prob(1)) //Only the one true bird may speak across dimensions. - world.TgsTargetedChatBroadcast("A stray squawk is heard... \"[message]\"", FALSE) + if(. && !client && prob(1) && prob(1) && CONFIG_GET(string/chat_squawk_tag)) //Only the one true bird may speak across dimensions. + send2chat("A stray squawk is heard... \"[message]\"", CONFIG_GET(string/chat_squawk_tag)) -/mob/living/simple_animal/parrot/Poly/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/parrot/Polly/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) Write_Memory(FALSE) memory_saved = TRUE -/mob/living/simple_animal/parrot/Poly/death(gibbed) +/mob/living/simple_animal/parrot/Polly/death(gibbed) if(!memory_saved) Write_Memory(TRUE) if(rounds_survived == longest_survival || rounds_survived == longest_deathstreak || prob(0.666)) - var/mob/living/simple_animal/parrot/Poly/ghost/G = new(loc) + var/mob/living/simple_animal/parrot/Polly/ghost/G = new(loc) if(mind) mind.transfer_to(G) else transfer_ckey(G) ..(gibbed) -/mob/living/simple_animal/parrot/Poly/proc/Read_Memory() +/mob/living/simple_animal/parrot/Polly/proc/Read_Memory() + var/saved_color if(fexists("data/npc_saves/Poly.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Poly.sav") S["phrases"] >> speech_buffer @@ -963,10 +970,13 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( rounds_survived = json["roundssurvived"] longest_survival = json["longestsurvival"] longest_deathstreak = json["longestdeathstreak"] + saved_color = json["color"] if(!islist(speech_buffer)) speech_buffer = list() + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) -/mob/living/simple_animal/parrot/Poly/proc/Write_Memory(dead) +/mob/living/simple_animal/parrot/Polly/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Poly.json") var/list/file_data = list() if(islist(speech_buffer)) @@ -978,6 +988,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( file_data["longestdeathstreak"] = rounds_survived - 1 else file_data["longestdeathstreak"] = longest_deathstreak + file_data["color"] = null else file_data["roundssurvived"] = rounds_survived + 1 if(rounds_survived + 1 > longest_survival) @@ -985,17 +996,21 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( else file_data["longestsurvival"] = longest_survival file_data["longestdeathstreak"] = longest_deathstreak + if(color) + file_data["color"] = json_encode(color) + else + file_data["color"] = null fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) -/mob/living/simple_animal/parrot/Poly/ratvar_act() +/mob/living/simple_animal/parrot/Polly/ratvar_act() playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 75, TRUE) var/mob/living/simple_animal/parrot/clock_hawk/H = new(loc) H.setDir(dir) qdel(src) -/mob/living/simple_animal/parrot/Poly/ghost - name = "The Ghost of Poly" +/mob/living/simple_animal/parrot/Polly/ghost + name = "The Ghost of Polly" desc = "Doomed to squawk the Earth." color = "#FFFFFF" alpha = 77 @@ -1004,16 +1019,16 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( incorporeal_move = INCORPOREAL_MOVE_BASIC butcher_results = list(/obj/item/ectoplasm = 1) -/mob/living/simple_animal/parrot/Poly/ghost/Initialize(mapload) +/mob/living/simple_animal/parrot/Polly/ghost/Initialize(mapload) memory_saved = TRUE //At this point nothing is saved . = ..() -/mob/living/simple_animal/parrot/Poly/ghost/handle_automated_speech() +/mob/living/simple_animal/parrot/Polly/ghost/handle_automated_speech() if(ismob(loc)) return ..() -/mob/living/simple_animal/parrot/Poly/ghost/handle_automated_movement() +/mob/living/simple_animal/parrot/Polly/ghost/handle_automated_movement() if(isliving(parrot_interest)) if(!ishuman(parrot_interest)) parrot_interest = null @@ -1022,7 +1037,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( Possess(parrot_interest) ..() -/mob/living/simple_animal/parrot/Poly/ghost/proc/Possess(mob/living/carbon/human/H) +/mob/living/simple_animal/parrot/Polly/ghost/proc/Possess(mob/living/carbon/human/H) if(!ishuman(H)) return var/datum/disease/parrot_possession/P = new diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 9cc82f6a1a..4d992f274e 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -225,7 +225,7 @@ length += emote_see.len var/randomValue = rand(1,length) if(randomValue <= speak.len) - say(pick(speak), forced = "poly") + say(pick(speak), forced = "polly") else randomValue -= speak.len if(emote_see && randomValue <= emote_see.len) @@ -233,7 +233,7 @@ else emote("me [pick(emote_hear)]", 2) else - say(pick(speak), forced = "poly") + say(pick(speak), forced = "polly") else if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len)) emote("me", EMOTE_VISIBLE, pick(emote_see)) @@ -482,7 +482,7 @@ update_action_buttons_icon() return mobility_flags -/mob/living/simple_animal/update_transform() +/mob/living/simple_animal/update_transform(do_animate) var/matrix/ntransform = matrix(transform) //aka transform.Copy() var/changed = 0 diff --git a/code/modules/mob/living/simple_animal/slime/emote.dm b/code/modules/mob/living/simple_animal/slime/emote.dm index 94f054345d..ac0ce1c1e5 100644 --- a/code/modules/mob/living/simple_animal/slime/emote.dm +++ b/code/modules/mob/living/simple_animal/slime/emote.dm @@ -27,6 +27,8 @@ /datum/emote/slime/mood/run_emote(mob/user, params) . = ..() + if(!.) + return var/mob/living/simple_animal/slime/S = user S.mood = mood S.regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 2ce355a0ef..274af333fc 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -8,7 +8,7 @@ typing_indicator_state = /obj/effect/overlay/typing_indicator/slime -/mob/living/simple_animal/slime/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/slime/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(buckled) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 9812307300..dc9d6ff6a3 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -421,7 +421,7 @@ return /mob/living/simple_animal/slime/examine(mob/user) - . = list("*---------*\nThis is [icon2html(src, user)] \a [src]!") + . = list("This is [icon2html(src, user)] \a [src]!") if (src.stat == DEAD) . += "It is limp and unresponsive." else @@ -446,7 +446,7 @@ if(10) . += "It is radiating with massive levels of electrical activity!" - . += "*---------*" + . += "" /mob/living/simple_animal/slime/proc/discipline_slime(mob/user) if(stat) diff --git a/code/modules/mob/living/update_icons.dm b/code/modules/mob/living/update_icons.dm index f8d5d7e0ba..9705be3ad0 100644 --- a/code/modules/mob/living/update_icons.dm +++ b/code/modules/mob/living/update_icons.dm @@ -1,5 +1,5 @@ //IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can. -/mob/living/update_transform() +/mob/living/update_transform(do_animate = TRUE) var/matrix/ntransform = matrix(transform) //aka transform.Copy() var/final_pixel_y = pixel_y var/changed = 0 @@ -21,5 +21,9 @@ resize = RESIZE_DEFAULT_SIZE if(changed) - animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT) + if(do_animate) + animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT, flags = ANIMATION_PARALLEL) + else + transform = ntransform + pixel_y = final_pixel_y floating_need_update = TRUE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f5c89312e3..7ef26c7818 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -138,7 +138,7 @@ return hearers -= ignored_mobs - if(target_message && target && istype(target) && target.client) + if(target_message && target && istype(target) && (target.client || target.audiovisual_redirect)) hearers -= target if(omni) target.show_message(target_message) @@ -155,7 +155,7 @@ if(self_message) hearers -= src for(var/mob/M in hearers) - if(!M.client) + if(!M.client && !M.audiovisual_redirect) continue if(omni) M.show_message(message) @@ -330,7 +330,7 @@ else result = A.examine(src) // if a tree is examined but no client is there to see it, did the tree ever really exist? - to_chat(src, result.Join("\n")) + to_chat(src, "
[result.Join("\n")]
") SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, A) /mob/proc/clear_from_recent_examines(atom/A) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 561425c710..90a7aae95e 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -229,22 +229,38 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return copytext_char(sanitize(.),1,MAX_MESSAGE_LEN) /proc/shake_camera(mob/M, duration, strength=1) - if(!M || !M.client || duration < 1) + set waitfor = FALSE + if(!M || !M.client || duration <= 0) return var/client/C = M.client + if (C.prefs.screenshake==0) + return var/oldx = C.pixel_x var/oldy = C.pixel_y - var/max = strength*world.icon_size - var/min = -(strength*world.icon_size) + var/clientscreenshake = (C.prefs.screenshake * 0.01) + var/max = (strength*clientscreenshake) * world.icon_size + var/min = -((strength*clientscreenshake) * world.icon_size) + var/roundedduration = -round(-duration) // round() with only one arg will always round down. so uh. this is Something all right - for(var/i in 0 to duration-1) + for(var/i in 0 to roundedduration-1) + duration-- if (i == 0) - animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) + animate(C, pixel_x=(rand(min,max)*duration), pixel_y=(rand(min,max)*duration), time=1) else animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) animate(pixel_x=oldx, pixel_y=oldy, time=1) - +/proc/directional_recoil(mob/M, strength=1, angle = 0) + if(!M || !M.client) + return + var/client/C = M.client + var/client_screenshake = (C.prefs.recoil_screenshake * 0.01) + strength *= client_screenshake + var/recoil_x = -sin(angle)*4*strength + rand(-strength, strength) + var/recoil_y = -cos(angle)*4*strength + rand(-strength, strength) + animate(C, pixel_x=recoil_x, pixel_y=recoil_y, time=1, easing=SINE_EASING|EASE_OUT, flags=ANIMATION_PARALLEL|ANIMATION_RELATIVE) + animate(pixel_x=0, pixel_y=0, time=3, easing=SINE_EASING|EASE_IN) // according to bhjin this works on more recent byond versions + // if you havent updated uuh sucks to be you then /proc/findname(msg) if(!istext(msg)) diff --git a/code/modules/modular_computers/file_system/programs/signaler.dm b/code/modules/modular_computers/file_system/programs/signaler.dm index b7bbcacaa0..ded70f7f37 100644 --- a/code/modules/modular_computers/file_system/programs/signaler.dm +++ b/code/modules/modular_computers/file_system/programs/signaler.dm @@ -15,40 +15,29 @@ /// Radio connection datum used by signalers. var/datum/radio_frequency/radio_connection -/datum/computer_file/program/signaler/run_program(mob/living/user) - . = ..() - if (!.) - return - if(!computer?.get_modular_computer_part(MC_SIGNALER)) //Giving a clue to users why the program is spitting out zeros. - to_chat(user, span_warning("\The [computer] flashes an error: \"hardware\\signal_hardware\\startup.bin -- file not found\".")) - +/datum/computer_file/program/signaler/New() + set_frequency(signal_frequency) + return ..() /datum/computer_file/program/signaler/ui_data(mob/user) var/list/data = get_header_data() - var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER) - if(sensor?.check_functionality()) - data["frequency"] = signal_frequency - data["code"] = signal_code - data["minFrequency"] = MIN_FREE_FREQ - data["maxFrequency"] = MAX_FREE_FREQ + data["frequency"] = signal_frequency + data["code"] = signal_code + data["minFrequency"] = MIN_FREE_FREQ + data["maxFrequency"] = MAX_FREE_FREQ return data /datum/computer_file/program/signaler/ui_act(action, list/params) . = ..() if(.) return - var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER) - if(!(sensor?.check_functionality())) - playsound(src, 'sound/machines/scanbuzz.ogg', 100, FALSE) - return switch(action) if("signal") INVOKE_ASYNC(src, .proc/signal) . = TRUE if("freq") - signal_frequency = unformat_frequency(params["freq"]) - signal_frequency = sanitize_frequency(signal_frequency, TRUE) - set_frequency(signal_frequency) + var/new_signal_frequency = sanitize_frequency(unformat_frequency(params["freq"]), TRUE) + set_frequency(new_signal_frequency) . = TRUE if("code") signal_code = text2num(params["code"]) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 0ad49e192d..cb9570e02f 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -173,7 +173,7 @@ O.renamedByPlayer = TRUE if(penchoice == "Change description") - var/input = stripped_input(user,"Describe [O] here:", ,"[O.desc]", 140) + var/input = stripped_input(user,"Describe [O] here:", ,"[O.desc]", 350) var/olddesc = O.desc if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) return diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 16e49cd451..1052752c82 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -182,7 +182,7 @@ . = ..() if(active) if(!bitcoinmining) - . += "[src]'s display states that it has stored [DisplayPower(stored_power)], and is processing [DisplayPower((RAD_COLLECTOR_OUTPUT)*((60 SECONDS)/SSmachines.wait))] per minute.
The plasma within it's tank is being irradiated into tritium.
" + . += "[src]'s display states that it has stored [DisplayEnergy(stored_power)], and is processing [DisplayPower((RAD_COLLECTOR_OUTPUT)*((1 SECONDS)/SSmachines.wait))].
The plasma within it's tank is being irradiated into tritium.
" else . += "[src]'s display states that it's producing a total of [(last_push*RAD_COLLECTOR_MINING_CONVERSION_RATE)*((60 SECONDS)/SSmachines.wait)] research points per minute.
The tritium and oxygen within it's tank is being combusted into carbon dioxide.
" else diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index fad48b4854..27fb30a459 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -5,6 +5,7 @@ desc = "A solar panel. Generates electricity when in contact with sunlight." icon = 'goon/icons/obj/power.dmi' icon_state = "sp_base" + minimap_override_color = "#02026a" density = TRUE use_power = NO_POWER_USE idle_power_usage = 0 diff --git a/code/modules/projectiles/ammunition/ballistic/lmg.dm b/code/modules/projectiles/ammunition/ballistic/lmg.dm index bf8b4007bf..1c39a73f1f 100644 --- a/code/modules/projectiles/ammunition/ballistic/lmg.dm +++ b/code/modules/projectiles/ammunition/ballistic/lmg.dm @@ -1,36 +1,28 @@ -// 1.95x129mm (SAW) +// 7.12x82mm (SAW) -/obj/item/ammo_casing/mm195x129 - name = "1.95x129mm bullet casing" - desc = "A 1.95x129mm bullet casing." +/obj/item/ammo_casing/mm712x82 + name = "7.12x82mm bullet casing" + desc = "A 7.12x82mm bullet casing." icon_state = "762-casing" - caliber = "mm195129" - projectile_type = /obj/item/projectile/bullet/mm195x129 + caliber = "mm71282" + projectile_type = /obj/item/projectile/bullet/mm712x82 -/obj/item/ammo_casing/mm195x129/ap - name = "1.95x129mm armor-piercing bullet casing" - desc = "A 1.95x129mm bullet casing designed with a hardened-tipped core to help penetrate armored targets." - projectile_type = /obj/item/projectile/bullet/mm195x129_ap +/obj/item/ammo_casing/mm712x82/ap + name = "7.12x82mm armor-piercing bullet casing" + desc = "A 7.12x82mm bullet casing designed with a hardened-tipped core to help penetrate armored targets." + projectile_type = /obj/item/projectile/bullet/mm712x82_ap -/obj/item/ammo_casing/mm195x129/hollow - name = "1.95x129mm hollow-point bullet casing" - desc = "A 1.95x129mm bullet casing designed to cause more damage to unarmored targets." - projectile_type = /obj/item/projectile/bullet/mm195x129_hp +/obj/item/ammo_casing/mm712x82/hollow + name = "7.12x82mm hollow-point bullet casing" + desc = "A 7.12x82mm bullet casing designed to cause more damage to unarmored targets." + projectile_type = /obj/item/projectile/bullet/mm712x82_hp -/obj/item/ammo_casing/mm195x129/incen - name = "1.95x129mm incendiary bullet casing" - desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames." - projectile_type = /obj/item/projectile/bullet/incendiary/mm195x129 +/obj/item/ammo_casing/mm712x82/incen + name = "7.12x82mm incendiary bullet casing" + desc = "A 7.12x82mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames." + projectile_type = /obj/item/projectile/bullet/incendiary/mm712x82 /obj/item/ammo_casing/mm712x82/match name = "7.12x82mm match bullet casing" desc = "A 7.12x82mm bullet casing manufactured to unfailingly high standards, you could pull off some cool trickshots with this." - projectile_type = /obj/item/projectile/bullet/mm712x82_match - -/obj/item/projectile/bullet/mm712x82_match - name = "7.12x82mm match bullet" - damage = 40 - ricochets_max = 2 - ricochet_chance = 60 - ricochet_auto_aim_range = 4 - ricochet_incidence_leeway = 35 + projectile_type = /obj/item/projectile/bullet/mm712x82/match diff --git a/code/modules/projectiles/boxes_magazines/external/lmg.dm b/code/modules/projectiles/boxes_magazines/external/lmg.dm index 95ba17c733..e8447950ce 100644 --- a/code/modules/projectiles/boxes_magazines/external/lmg.dm +++ b/code/modules/projectiles/boxes_magazines/external/lmg.dm @@ -1,23 +1,23 @@ -/obj/item/ammo_box/magazine/mm195x129 - name = "box magazine (1.95x129mm)" +/obj/item/ammo_box/magazine/mm712x82 + name = "box magazine (7.12x82mm)" icon_state = "a762-50" - ammo_type = /obj/item/ammo_casing/mm195x129 - caliber = "mm195129" + ammo_type = /obj/item/ammo_casing/mm712x82 + caliber = "mm71282" max_ammo = 50 -/obj/item/ammo_box/magazine/mm195x129/hollow - name = "box magazine (Hollow-Point 1.95x129mm)" - ammo_type = /obj/item/ammo_casing/mm195x129/hollow +/obj/item/ammo_box/magazine/mm712x82/hollow + name = "box magazine (Hollow-Point 7.12x82mm)" + ammo_type = /obj/item/ammo_casing/mm712x82/hollow -/obj/item/ammo_box/magazine/mm195x129/ap - name = "box magazine (Armor Penetrating 1.95x129mm)" - ammo_type = /obj/item/ammo_casing/mm195x129/ap +/obj/item/ammo_box/magazine/mm712x82/ap + name = "box magazine (Armor Penetrating 7.12x82mm)" + ammo_type = /obj/item/ammo_casing/mm712x82/ap -/obj/item/ammo_box/magazine/mm195x129/incen - name = "box magazine (Incendiary 1.95x129mm)" - ammo_type = /obj/item/ammo_casing/mm195x129/incen +/obj/item/ammo_box/magazine/mm712x82/incen + name = "box magazine (Incendiary 7.12x82mm)" + ammo_type = /obj/item/ammo_casing/mm712x82/incen -/obj/item/ammo_box/magazine/mm195x129/update_icon() +/obj/item/ammo_box/magazine/mm712x82/update_icon() ..() icon_state = "a762-[round(ammo_count(),10)]" diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 3210ad2d15..a4d3c3a63a 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -94,6 +94,9 @@ var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds + /// directional recoil multiplier + var/dir_recoil_amp = 10 + /obj/item/gun/Initialize(mapload) . = ..() if(no_pin_required) @@ -159,7 +162,7 @@ /obj/item/gun/proc/shoot_live_shot(mob/living/user, pointblank = FALSE, mob/pbtarget, message = 1, stam_cost = 0) if(recoil) - shake_camera(user, recoil + 1, recoil) + directional_recoil(user, recoil*dir_recoil_amp, Get_Angle(user, pbtarget)) if(stam_cost) //CIT CHANGE - makes gun recoil cause staminaloss var/safe_cost = clamp(stam_cost, 0, user.stamina_buffer)*(firing && burst_size >= 2 ? 1/burst_size : 1) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 836ed3b804..3f2f4d3e65 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -3,6 +3,7 @@ name = "projectile gun" icon_state = "pistol" w_class = WEIGHT_CLASS_NORMAL + recoil = 0.25 var/spawnwithmagazine = TRUE var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info var/obj/item/ammo_box/magazine/magazine diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index aa3ac20cb8..4b871d59b2 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -296,13 +296,13 @@ /obj/item/gun/ballistic/automatic/l6_saw name = "\improper L6 SAW" - desc = "A heavily modified 1.95x129mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation." + desc = "A heavily modified 7.12x82mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation." icon_state = "l6closed100" item_state = "l6closedmag" fire_sound = "sound/weapons/lmgshot.ogg" w_class = WEIGHT_CLASS_HUGE slot_flags = 0 - mag_type = /obj/item/ammo_box/magazine/mm195x129 + mag_type = /obj/item/ammo_box/magazine/mm712x82 weapon_weight = WEAPON_HEAVY var/cover_open = FALSE can_suppress = FALSE diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index afb30631e0..f3b07aa7a4 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -5,6 +5,7 @@ mag_type = /obj/item/ammo_box/magazine/internal/cylinder fire_sound = "sound/weapons/revolvershot.ogg" casing_ejector = FALSE + recoil = 0.5 /obj/item/gun/ballistic/revolver/Initialize(mapload) . = ..() @@ -166,6 +167,7 @@ icon_state = "goldrevolver" fire_sound = 'sound/weapons/resonator_blast.ogg' recoil = 8 + dir_recoil_amp = 5 // 40 directional recoil is already really funny pin = /obj/item/firing_pin /obj/item/gun/ballistic/revolver/nagant @@ -285,6 +287,7 @@ item_state = "shotgun" w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_MEDIUM + recoil = 1 force = 10 flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BACK diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index f7d57b43a0..b52620e7e0 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -5,6 +5,7 @@ item_state = "shotgun" fire_sound = "sound/weapons/gunshotshotgunshot.ogg" w_class = WEIGHT_CLASS_BULKY + recoil = 1 force = 10 flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BACK diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index dd759f9e3c..03dfc46713 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -16,6 +16,7 @@ name = "energy gun" desc = "A basic energy-based gun." icon = 'icons/obj/guns/energy.dmi' + recoil = 0.1 var/obj/item/stock_parts/cell/cell //What type of power cell this uses var/cell_type = /obj/item/stock_parts/cell diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index a785e4e0e8..5fd158c028 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -8,6 +8,7 @@ item_flags = NONE obj_flags = UNIQUE_RENAME weapon_weight = WEAPON_LIGHT + recoil = 0.5 can_flashlight = 1 flight_x_offset = 15 flight_y_offset = 9 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 15acd40172..bb7b21596f 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -167,6 +167,11 @@ /obj/item/gun/energy/plasmacutter/use(amount) return cell.use(amount * 100) +/obj/item/gun/energy/plasmacutter/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks, skill_gain_mult) + target.add_overlay(GLOB.welding_sparks) + . = ..() + target.cut_overlay(GLOB.welding_sparks) + /obj/item/gun/energy/plasmacutter/adv name = "advanced plasma cutter" icon_state = "adv_plasmacutter" diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm index 07066023b3..8de7633a79 100644 --- a/code/modules/projectiles/guns/misc/syringe_gun.dm +++ b/code/modules/projectiles/guns/misc/syringe_gun.dm @@ -4,6 +4,7 @@ icon_state = "syringegun" item_state = "syringegun" w_class = WEIGHT_CLASS_NORMAL + recoil = 0.1 throw_speed = 3 throw_range = 7 force = 4 diff --git a/code/modules/projectiles/projectile/bullets/lmg.dm b/code/modules/projectiles/projectile/bullets/lmg.dm index e3eff6dcb0..177a98201c 100644 --- a/code/modules/projectiles/projectile/bullets/lmg.dm +++ b/code/modules/projectiles/projectile/bullets/lmg.dm @@ -21,22 +21,22 @@ /obj/item/projectile/bullet/syndicate_turret damage = 20 -// 1.95x129mm (SAW) +// 7.12x82mm (SAW) -/obj/item/projectile/bullet/mm195x129 - name = "1.95x129mm bullet" +/obj/item/projectile/bullet/mm712x82 + name = "7.12x82mm bullet" damage = 40 armour_penetration = 5 wound_bonus = -50 wound_falloff_tile = 0 -/obj/item/projectile/bullet/mm195x129_ap - name = "1.95x129mm armor-piercing bullet" +/obj/item/projectile/bullet/mm712x82_ap + name = "7.12x82mm armor-piercing bullet" damage = 40 armour_penetration = 75 -/obj/item/projectile/bullet/mm195x129_hp - name = "1.95x129mm hollow-point bullet" +/obj/item/projectile/bullet/mm712x82_hp + name = "7.12x82mm hollow-point bullet" damage = 50 armour_penetration = -60 sharpness = SHARP_EDGED @@ -44,7 +44,15 @@ bare_wound_bonus = 30 wound_falloff_tile = -8 -/obj/item/projectile/bullet/incendiary/mm195x129 - name = "1.95x129mm incendiary bullet" +/obj/item/projectile/bullet/incendiary/mm712x82 + name = "7.12x82mm incendiary bullet" damage = 20 fire_stacks = 3 + +/obj/item/projectile/bullet/mm712x82/match + name = "7.12x82mm match bullet" + damage = 40 + ricochets_max = 2 + ricochet_chance = 60 + ricochet_auto_aim_range = 4 + ricochet_incidence_leeway = 35 diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 4376805e2c..c0892ce1e2 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -1034,7 +1034,7 @@ M.update_transform() ..() -/datum/reagent/consumable/pinkmilk +/datum/reagent/consumable/milk/pinkmilk name = "Strawberry Milk" description = "A drink of a bygone era of milk and artificial sweetener back on a rock." color = "#f76aeb"//rgb(247, 106, 235) @@ -1045,13 +1045,13 @@ glass_desc = "Delicious flavored strawberry syrup mixed with milk." value = REAGENT_VALUE_VERY_COMMON -/datum/reagent/consumable/tea/pinkmilk/on_mob_life(mob/living/carbon/M) +/datum/reagent/consumable/milk/pinkmilk/on_mob_life(mob/living/carbon/M) if(prob(15)) to_chat(M, "[pick("You cant help to smile.","You feel nostalgia all of sudden.","You remember to relax.")]") ..() . = 1 -/datum/reagent/consumable/pinktea //Tiny Tim song +/datum/reagent/consumable/tea/pinktea //Tiny Tim song name = "Strawberry Tea" description = "A timeless classic!" color = "#f76aeb"//rgb(247, 106, 235) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index abe3aef82d..9e49e8556b 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -1,5 +1,5 @@ /datum/reagent/blood - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null,"quirks"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "bloodblend" = BLEND_MULTIPLY, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null,"quirks"=null) name = "Blood" chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_UNCOMMON // $$$ blood ""donations"" $$$ @@ -81,6 +81,7 @@ B.blood_DNA["color"] = data["bloodcolor"] else B.blood_DNA["color"] = BlendRGB(B.blood_DNA["color"], data["bloodcolor"]) + B.blood_DNA["blendmode"] = data["bloodblend"] if(B.reagents) B.reagents.add_reagent(type, reac_volume) B.update_icon() @@ -148,7 +149,7 @@ . += D /datum/reagent/blood/synthetics - data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "bloodblend" = BLEND_MULTIPLY, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) name = "Synthetic Blood" description = "A synthetically produced imitation of blood." taste_description = "oil" @@ -156,7 +157,7 @@ value = REAGENT_VALUE_NONE /datum/reagent/blood/jellyblood - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "bloodblend" = BLEND_DEFAULT, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) name = "Slime Jelly Blood" description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL." color = BLOOD_COLOR_SLIME @@ -165,7 +166,7 @@ pH = 4 /datum/reagent/blood/tomato - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "bloodblend" = BLEND_MULTIPLY, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) name = "Tomato Blood" description = "This highly resembles blood, but it doesnt actually function like it, resembling more ketchup, with a more blood-like consistency." taste_description = "sap" //Like tree sap? @@ -189,7 +190,7 @@ description = "You don't even want to think about what's in here." taste_description = "gross iron" shot_glass_icon_state = "shotglassred" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "bloodblend" = BLEND_MULTIPLY, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) pH = 7.45 /datum/reagent/liquidgibs/xeno @@ -197,7 +198,7 @@ color = BLOOD_COLOR_XENO taste_description = "blended heresy" shot_glass_icon_state = "shotglassgreen" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "bloodblend" = BLEND_MULTIPLY, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) pH = 2.5 /datum/reagent/liquidgibs/slime @@ -205,20 +206,20 @@ color = BLOOD_COLOR_SLIME taste_description = "slime" shot_glass_icon_state = "shotglassgreen" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "bloodblend" = BLEND_DEFAULT, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) pH = 4 /datum/reagent/liquidgibs/synth name = "Synthetic sludge" color = BLOOD_COLOR_SYNTHETIC taste_description = "jellied plastic" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "bloodblend" = BLEND_MULTIPLY, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) /datum/reagent/liquidgibs/oil name = "Hydraulic sludge" color = BLOOD_COLOR_OIL taste_description = "chunky burnt oil" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "bloodblend" = BLEND_MULTIPLY, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) pH = 9.75 /datum/reagent/vaccine diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index c6df9ebb0c..87349058a4 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -13,7 +13,7 @@ /obj/item/reagent_containers/blood/Initialize(mapload) . = ..() if(blood_type != null) - reagents.add_reagent(/datum/reagent/blood, 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"bloodcolor"=bloodtype_to_color(blood_type), "blood_type"=blood_type,"resistances"=null,"trace_chem"=null)) + reagents.add_reagent(/datum/reagent/blood, 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"bloodcolor"=bloodtype_to_color(blood_type), "bloodblend" = BLEND_MULTIPLY, "blood_type"=blood_type,"resistances"=null,"trace_chem"=null)) update_icon() /obj/item/reagent_containers/blood/on_reagent_change(changetype) diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm index 7b36a614a7..93df1e2351 100644 --- a/code/modules/research/bepis.dm +++ b/code/modules/research/bepis.dm @@ -103,7 +103,7 @@ return account.adjust_money(-deposit_value) //The money vanishes, not paid to any accounts. SSblackbox.record_feedback("amount", "BEPIS_credits_spent", deposit_value) - //log_econ("[deposit_value] credits were inserted into [src] by [account.account_holder]") + log_econ("[deposit_value] credits were inserted into [src] by [key_name(usr)] (account: [account.account_holder])") banked_cash += deposit_value use_power(1000 * power_saver) say("Cash deposit successful. There is [banked_cash] in the chamber.") diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index d542694236..dc07a5a184 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -17,7 +17,7 @@ var/list/obj/machinery/computer/rdconsole/consoles_accessing = list() var/id = "generic" var/list/research_logs = list() //IC logs. - var/largest_bomb_value = 0 + var/largest_values = list() var/organization = "Third-Party" //Organization name, used for display. var/list/next_income = list() //To be applied on the next passive techweb income var/list/last_bitcoins = list() //Current per-second production, used for display only. diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index e51e4852e6..1c7951a2d6 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -603,14 +603,14 @@ return ..() /datum/status_effect/stabilized/darkpurple/tick() - var/obj/item/I = owner.get_active_held_item() - var/obj/item/reagent_containers/food/snacks/F = I - if(istype(F)) - if(F.cooked_type) + var/obj/item/item = owner.get_active_held_item() + if(item) + var/obj/item/reagent_containers/food/snacks/F = item + if(istype(F) && F.cooked_type) to_chat(owner, "[linked_extract] flares up brightly, and your hands alone are enough cook [F]!") F.microwave_act() - else - I.attackby(fire, owner) + else + item.attackby(fire, owner) return ..() /datum/status_effect/stabilized/darkpurple/on_remove() diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index a89727d183..2d8150d087 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -228,6 +228,8 @@ var/mangled_state = get_mangled_state() var/bio_state = owner.get_biological_state() var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%) + var/glass_bones = HAS_TRAIT(owner, TRAIT_GLASS_BONES) + var/paper_skin = HAS_TRAIT(owner, TRAIT_PAPER_SKIN) if(wounding_type == WOUND_BLUNT) if(sharpness == SHARP_EDGED) @@ -242,22 +244,29 @@ if(wounding_type == WOUND_SLASH) wounding_type = WOUND_BLUNT wounding_dmg *= (easy_dismember ? 1 : 0.5) + wounding_dmg *= (glass_bones ? 1.5 : 1) else if(wounding_type == WOUND_PIERCE) wounding_type = WOUND_BLUNT wounding_dmg *= (easy_dismember ? 1 : 0.75) + wounding_dmg *= (glass_bones ? 1.5 : 1) if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)) return // if we're flesh only, all blunt attacks become weakened slashes in terms of wound damage if(BIO_JUST_FLESH) if(wounding_type == WOUND_BLUNT) wounding_type = WOUND_SLASH - wounding_dmg *= (easy_dismember ? 1 : 0.3) + wounding_dmg *= (easy_dismember ? 1 : 0.5) + wounding_dmg *= (paper_skin ? 1.5 : 1) if((mangled_state & BODYPART_MANGLED_FLESH) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)) return // standard humanoids if(BIO_FLESH_BONE) // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate // So a big sharp weapon is still all you need to destroy a limb + if(wounding_type == WOUND_SLASH || wounding_type == WOUND_PIERCE) + wounding_dmg *= (paper_skin ? 1.5 : 1) + else + wounding_dmg *= (glass_bones ? 1.5 : 1) if(mangled_state == BODYPART_MANGLED_FLESH && sharpness) playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100) if(wounding_type == WOUND_SLASH && !easy_dismember) diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm index 80b7599ec3..d572deca73 100644 --- a/code/modules/surgery/organs/ears.dm +++ b/code/modules/surgery/organs/ears.dm @@ -18,10 +18,9 @@ // to hear anything. var/deaf = 0 - // `ear_damage` measures long term damage to the ears, if too high, + // `damage` in this case measures long term damage to the ears, if too high, // the person will not have either `deaf` or `ear_damage` decrease // without external aid (earmuffs, drugs) - var/ear_damage = 0 //Resistance against loud noises var/bang_protect = 0 @@ -44,16 +43,22 @@ /obj/item/organ/ears/proc/restoreEars() deaf = 0 - ear_damage = 0 + damage = 0 + prev_damage = 0 organ_flags &= ~ORGAN_FAILING var/mob/living/carbon/C = owner if(iscarbon(owner) && HAS_TRAIT(C, TRAIT_DEAF)) deaf = 1 + var/mess = check_damage_thresholds() + if(mess && owner) + to_chat(owner, mess) /obj/item/organ/ears/proc/adjustEarDamage(ddmg, ddeaf) - ear_damage = max(ear_damage + (ddmg*damage_multiplier), 0) + if(owner.status_flags & GODMODE) + return + setOrganDamage(max(damage + (ddmg*damage_multiplier), 0)) deaf = max(deaf + (ddeaf*damage_multiplier), 0) /obj/item/organ/ears/proc/minimumDeafTicks(value) diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index cb2c02fa7c..058de79d04 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -300,7 +300,7 @@ to_chat(H, "Your throat closes up!") H.silent = max(H.silent, 3) else - H.adjustFireLoss(nitryl_pp/4) + H.adjustFireLoss(nitryl_pp/2) gas_breathed = breath.get_moles(GAS_NITRYL) if (gas_breathed > gas_stimulation_min) H.reagents.add_reagent(/datum/reagent/nitryl,1) diff --git a/code/modules/surgery/organs/tails.dm b/code/modules/surgery/organs/tails.dm index 289e9df9d4..8478ae5d27 100644 --- a/code/modules/surgery/organs/tails.dm +++ b/code/modules/surgery/organs/tails.dm @@ -13,6 +13,9 @@ owner.dna.species.stop_wagging_tail(owner) return ..() +/obj/item/organ/tail/on_life() + return + /obj/item/organ/tail/cat name = "cat tail" desc = "A severed cat tail. Who's wagging now?" diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 06415e7685..a4eafc4b01 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -123,6 +123,8 @@ if(locate(/obj/structure/table/optable, T)) propability = 1 + else if(locate(/obj/machinery/stasis)) + propability = 0.9 else if(locate(/obj/structure/table, T)) propability = 0.8 else if(locate(/obj/structure/bed, T)) diff --git a/code/modules/tcg/pack_nuclear.dm b/code/modules/tcg/pack_nuclear.dm index 96ec174a4b..cb82c98571 100644 --- a/code/modules/tcg/pack_nuclear.dm +++ b/code/modules/tcg/pack_nuclear.dm @@ -59,7 +59,7 @@ /datum/tcg_card/pack_nuclear/l6saw name = "L6 Saw LMG" - desc = "A heavily modified 1.95x129mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation." + desc = "A heavily modified 7.12x82mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation." rules = "After equipped unit dies, this card goes to the bottom of draw deck" icon_state = "l6saw" diff --git a/code/modules/unit_tests/character_saving.dm b/code/modules/unit_tests/character_saving.dm index 8d978a630d..cca17b81e4 100644 --- a/code/modules/unit_tests/character_saving.dm +++ b/code/modules/unit_tests/character_saving.dm @@ -1,18 +1,29 @@ +#define UNIT_TEST_SAVING_FLAVOR_TEXT "Space" +#define UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT "Station" +#define UNIT_TEST_SAVING_OOC_NOTES "Thirteen" + /datum/unit_test/character_saving/Run() try var/datum/preferences/P = new P.load_path("test") - P.features["flavor_text"] = "Foo" - P.features["ooc_notes"] = "Bar" + P.features["flavor_text"] = UNIT_TEST_SAVING_FLAVOR_TEXT + P.features["silicon_flavor_text"] = UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT + P.features["ooc_notes"] = UNIT_TEST_SAVING_OOC_NOTES P.save_character() P.load_character() - if(P.features["flavor_text"] != "Foo") + if(P.features["flavor_text"] != UNIT_TEST_SAVING_FLAVOR_TEXT) Fail("Flavor text is failing to save.") - if(P.features["ooc_notes"] != "Bar") + if(P.features["silicon_flavor_text"] != UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT) + Fail("Silicon flavor text is failing to save.") + if(P.features["ooc_notes"] != UNIT_TEST_SAVING_OOC_NOTES) Fail("OOC text is failing to save.") P.save_character() P.load_character() - if(P.features["flavor_text"] != "Foo") + if((P.features["flavor_text"] != UNIT_TEST_SAVING_FLAVOR_TEXT) || (P.features["silicon_flavor_text"] != UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT) || (P.features["ooc_notes"] != UNIT_TEST_SAVING_OOC_NOTES)) Fail("Repeated saving and loading possibly causing save deletion.") catch(var/exception/e) Fail("Failed to save and load character due to exception [e.file]:[e.line], [e.name]") + +#undef UNIT_TEST_SAVING_FLAVOR_TEXT +#undef UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT +#undef UNIT_TEST_SAVING_OOC_NOTES diff --git a/code/modules/uplink/uplink_items/uplink_ammo.dm b/code/modules/uplink/uplink_items/uplink_ammo.dm index a1c96d1082..1ce8b7914a 100644 --- a/code/modules/uplink/uplink_items/uplink_ammo.dm +++ b/code/modules/uplink/uplink_items/uplink_ammo.dm @@ -209,29 +209,29 @@ purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/machinegun/basic - name = "1.95x129mm Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use with the L6 SAW. \ + name = "7.12x82mm Box Magazine" + desc = "A 50-round magazine of 7.12x82mm ammunition for use with the L6 SAW. \ By the time you need to use this, you'll already be standing on a pile of corpses" - item = /obj/item/ammo_box/magazine/mm195x129 + item = /obj/item/ammo_box/magazine/mm712x82 /datum/uplink_item/ammo/machinegun/ap - name = "1.95x129mm (Armor Penetrating) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with special properties \ + name = "7.12x82mm (Armor Penetrating) Box Magazine" + desc = "A 50-round magazine of 7.12x82mm ammunition for use in the L6 SAW; equipped with special properties \ to puncture even the most durable armor." - item = /obj/item/ammo_box/magazine/mm195x129/ap + item = /obj/item/ammo_box/magazine/mm712x82/ap cost = 9 /datum/uplink_item/ammo/machinegun/hollow - name = "1.95x129mm (Hollow-Point) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ + name = "7.12x82mm (Hollow-Point) Box Magazine" + desc = "A 50-round magazine of 7.12x82mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ with the unarmored masses of crew." - item = /obj/item/ammo_box/magazine/mm195x129/hollow + item = /obj/item/ammo_box/magazine/mm712x82/hollow /datum/uplink_item/ammo/machinegun/incen - name = "1.95x129mm (Incendiary) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; tipped with a special flammable \ + name = "7.12x82mm (Incendiary) Box Magazine" + desc = "A 50-round magazine of 7.12x82mm ammunition for use in the L6 SAW; tipped with a special flammable \ mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn." - item = /obj/item/ammo_box/magazine/mm195x129/incen + item = /obj/item/ammo_box/magazine/mm712x82/incen /datum/uplink_item/ammo/rocket purchasable_from = UPLINK_NUKE_OPS diff --git a/code/modules/uplink/uplink_items/uplink_dangerous.dm b/code/modules/uplink/uplink_items/uplink_dangerous.dm index dac426db2b..6bfe3f5bb8 100644 --- a/code/modules/uplink/uplink_items/uplink_dangerous.dm +++ b/code/modules/uplink/uplink_items/uplink_dangerous.dm @@ -213,7 +213,7 @@ /datum/uplink_item/dangerous/machinegun name = "L6 Squad Automatic Weapon" desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \ - This deadly weapon has a massive 50-round magazine of devastating 1.95x129mm ammunition." + This deadly weapon has a massive 50-round magazine of devastating 7.12x82mm ammunition." item = /obj/item/gun/ballistic/automatic/l6_saw cost = 18 surplus = 0 diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 99020ec7df..f1e4d4468b 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -272,7 +272,7 @@ /obj/vehicle/sealed/mecha/proc/update_part_values() ///Updates the values given by scanning module and capacitor tier, called when a part is removed or inserted. if(scanmod) - normal_step_energy_drain = 20 - (5 * scanmod.rating) //10 is normal, so on lowest part its worse, on second its ok and on higher its real good up to 0 on best + normal_step_energy_drain = initial(normal_step_energy_drain) * (1.5 / (scanmod.rating - 0.5)) //movement power cost is 3x of default at T1, 1x at T2, 0.6x at T3 and 0.4x at T4 step_energy_drain = normal_step_energy_drain else normal_step_energy_drain = 500 @@ -641,6 +641,9 @@ if(!Process_Spacemove(direction)) return FALSE if(!has_charge(step_energy_drain)) + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MESSAGE)) + to_chat(occupants, "[icon2html(src, occupants)]Insufficient power to move!") + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS) return FALSE if(zoom_mode) to_chat(occupants, "[icon2html(src, occupants)]Unable to move while in zoom mode!") @@ -651,7 +654,7 @@ if(!scanmod || !capacitor) to_chat(occupants, "[icon2html(src, occupants)]Missing [scanmod? "capacitor" : "scanning module"].") return FALSE - if(lavaland_only && is_mining_level(z)) + if(lavaland_only && !is_mining_level(z)) to_chat(occupants, "[icon2html(src, occupants)]Invalid Environment.") return FALSE @@ -683,6 +686,7 @@ return TRUE set_glide_size(DELAY_TO_GLIDE_SIZE(movedelay)) + use_power(step_energy_drain) //Otherwise just walk normally . = step(src,direction, dir) diff --git a/code/modules/vehicles/mecha/combat/five_stars.dm b/code/modules/vehicles/mecha/combat/five_stars.dm index 6a73c3adde..def8e94cc8 100644 --- a/code/modules/vehicles/mecha/combat/five_stars.dm +++ b/code/modules/vehicles/mecha/combat/five_stars.dm @@ -4,7 +4,6 @@ icon = 'icons/mecha/mecha_96x96.dmi' icon_state = "five_stars" armor = list(MELEE = 100, BULLET = 50, LASER = 35, ENERGY = 35, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) - step_in = 4 dir_in = 1 //Facing North. max_integrity = 800 pixel_x = -32 diff --git a/code/modules/vehicles/mecha/combat/gygax.dm b/code/modules/vehicles/mecha/combat/gygax.dm index 29746a5fc7..ae7f846142 100644 --- a/code/modules/vehicles/mecha/combat/gygax.dm +++ b/code/modules/vehicles/mecha/combat/gygax.dm @@ -9,12 +9,13 @@ deflect_chance = 5 armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) max_temperature = 25000 - leg_overload_coeff = 80 + leg_overload_coeff = 300 + overload_step_energy_drain_min = 300 force = 25 wreckage = /obj/structure/mecha_wreckage/gygax internal_damage_threshold = 35 max_equip = 3 - step_energy_drain = 3 + normal_step_energy_drain = 3 /obj/vehicle/sealed/mecha/combat/gygax/dark desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications." @@ -24,7 +25,8 @@ deflect_chance = 20 armor = list(MELEE = 40, BULLET = 40, LASER = 50, ENERGY = 35, BOMB = 20, BIO = 0, RAD =20, FIRE = 100, ACID = 100) max_temperature = 35000 - leg_overload_coeff = 70 + leg_overload_coeff = 100 + overload_step_energy_drain_min = 100 force = 30 operation_req_access = list(ACCESS_SYNDICATE) internals_req_access = list(ACCESS_SYNDICATE) diff --git a/code/modules/vehicles/mecha/combat/medigax.dm b/code/modules/vehicles/mecha/combat/medigax.dm index 6b2f54a976..ec38dd37db 100644 --- a/code/modules/vehicles/mecha/combat/medigax.dm +++ b/code/modules/vehicles/mecha/combat/medigax.dm @@ -11,7 +11,7 @@ max_temperature = 25000 wreckage = /obj/structure/mecha_wreckage/odysseus internal_damage_threshold = 35 - step_energy_drain = 6 + normal_step_energy_drain = 6 infra_luminosity = 6 internals_req_access = list(ACCESS_ROBOTICS, ACCESS_MEDICAL) diff --git a/code/modules/vehicles/mecha/combat/phazon.dm b/code/modules/vehicles/mecha/combat/phazon.dm index c964b17e36..fad2b0783c 100644 --- a/code/modules/vehicles/mecha/combat/phazon.dm +++ b/code/modules/vehicles/mecha/combat/phazon.dm @@ -4,7 +4,7 @@ icon_state = "phazon" movedelay = 2 dir_in = 2 //Facing South. - step_energy_drain = 3 + normal_step_energy_drain = 3 max_integrity = 200 deflect_chance = 30 armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 50, FIRE = 100, ACID = 100) diff --git a/code/modules/vehicles/mecha/combat/reticence.dm b/code/modules/vehicles/mecha/combat/reticence.dm index b0c8b07aaf..300023b7ab 100644 --- a/code/modules/vehicles/mecha/combat/reticence.dm +++ b/code/modules/vehicles/mecha/combat/reticence.dm @@ -14,7 +14,7 @@ mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS internal_damage_threshold = 25 max_equip = 2 - step_energy_drain = 3 + normal_step_energy_drain = 3 color = "#87878715" stepsound = null turnsound = null diff --git a/code/modules/vehicles/mecha/mecha_control_console.dm b/code/modules/vehicles/mecha/mecha_control_console.dm index 38224fbbdd..ff5ea13059 100644 --- a/code/modules/vehicles/mecha/mecha_control_console.dm +++ b/code/modules/vehicles/mecha/mecha_control_console.dm @@ -118,7 +118,12 @@ return ..() /obj/item/mecha_parts/mecha_tracking/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) - if(!..()) + for(var/obj/item/I in M.contents) + if(istype(I, src)) + to_chat(user, "[M] already has a tracking beacon!") + return + . = ..() + if(!.) return M.trackers += src M.diag_hud_set_mechtracking() diff --git a/code/modules/vehicles/mecha/medical/odysseus.dm b/code/modules/vehicles/mecha/medical/odysseus.dm index bd415cd64f..dd693f9dbb 100644 --- a/code/modules/vehicles/mecha/medical/odysseus.dm +++ b/code/modules/vehicles/mecha/medical/odysseus.dm @@ -9,7 +9,7 @@ wreckage = /obj/structure/mecha_wreckage/odysseus internal_damage_threshold = 35 deflect_chance = 15 - step_energy_drain = 6 + normal_step_energy_drain = 6 internals_req_access = list(ACCESS_ROBOTICS, ACCESS_MEDICAL) /obj/vehicle/sealed/mecha/medical/odysseus/moved_inside(mob/living/carbon/human/H) diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm index 965cdbedd9..40b2e61402 100644 --- a/code/modules/vehicles/mecha/working/ripley.dm +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -96,7 +96,7 @@ movedelay = 4 lights_power = 7 wreckage = /obj/structure/mecha_wreckage/ripley/deathripley - step_energy_drain = 0 + normal_step_energy_drain = 0 enclosed = TRUE enter_delay = 40 silicon_icon_state = null diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 700a2fea7e..f84ced508e 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -864,21 +864,10 @@ GLOBAL_LIST_EMPTY(vending_products) if(isliving(usr)) var/mob/living/L = usr C = L.get_idcard(TRUE) - if(!C) - say("No card found.") + if(!can_transact(C)) flick(icon_deny,src) vend_ready = TRUE return - else if (!C.registered_account) - say("No account found.") - flick(icon_deny,src) - vend_ready = TRUE - return - else if(!C.registered_account.account_job) - say("Departmental accounts have been blacklisted from personal expenses due to embezzlement.") - flick(icon_deny, src) - vend_ready = TRUE - return // else if(age_restrictions && R.age_restricted && (!C.registered_age || C.registered_age < AGE_MINOR)) // say("You are not of legal age to purchase [R.name].") // if(!(usr in GLOB.narcd_underages)) @@ -901,16 +890,13 @@ GLOBAL_LIST_EMPTY(vending_products) price_to_use = 0 // it's free shut up if(coin_records.Find(R) || hidden_records.Find(R)) price_to_use = R.custom_premium_price ? R.custom_premium_price : extra_price - if(price_to_use && !account.adjust_money(-price_to_use)) + if(price_to_use && !attempt_transact(C, price_to_use)) say("You do not possess the funds to purchase [R.name].") flick(icon_deny,src) vend_ready = TRUE return - var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department) - if(D) - D.adjust_money(price_to_use) - SSblackbox.record_feedback("amount", "vending_spent", price_to_use) - // log_econ("[price_to_use] credits were inserted into [src] by [D.account_holder] to buy [R].") + SSblackbox.record_feedback("amount", "vending_spent", price_to_use) + log_econ("[price_to_use] credits were inserted into [src] by [key_name(usr)] (account: [account.account_holder]) to buy [R].") if(last_shopper != REF(usr) || purchase_message_cooldown < world.time) say("Thank you for shopping with [src]!") purchase_message_cooldown = world.time + 5 SECONDS @@ -1169,7 +1155,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(owner) owner.adjust_money(S.custom_price) SSblackbox.record_feedback("amount", "vending_spent", S.custom_price) - // log_econ("[S.custom_price] credits were spent on [src] buying a [S] by [owner.account_holder], owned by [private_a.account_holder].") + log_econ("[S.custom_price] credits were spent on [src] buying a [S] by [key_name(usr)] (account: [owner.account_holder]), owned by [private_a.account_holder].") vending_machine_input[N] = max(vending_machine_input[N] - 1, 0) S.forceMove(drop_location()) loaded_items-- diff --git a/code/modules/wiremod/preset/speech_relay.dm b/code/modules/wiremod/preset/speech_relay.dm index a1e66832c9..bc84568cc0 100644 --- a/code/modules/wiremod/preset/speech_relay.dm +++ b/code/modules/wiremod/preset/speech_relay.dm @@ -1,7 +1,7 @@ /** * # Speech Relay preset * - * Acts like poly. Says whatever it hears. + * Acts like polly. Says whatever it hears. */ /obj/item/integrated_circuit/loaded/speech_relay diff --git a/config/config.txt b/config/config.txt index c0c683373d..63adaee716 100644 --- a/config/config.txt +++ b/config/config.txt @@ -15,6 +15,7 @@ $include entries/admin.txt $include entries/alert.txt $include entries/antag_rep.txt +$include entries/bot.txt $include entries/comms.txt $include entries/connections.txt $include entries/dbconfig.txt diff --git a/config/entries/bot.txt b/config/entries/bot.txt new file mode 100644 index 0000000000..eb9e8855e7 --- /dev/null +++ b/config/entries/bot.txt @@ -0,0 +1,17 @@ +## Chat Announce Options +## Various messages to be sent to game chats +## Uncommenting these will enable them, by default they will be broadcast to Game chat channels on TGS3 or non-admin channels on TGS4 +## If using TGS4, the string option can be set as a chat channel tag to limit the message to channels of that tag type (case-sensitive) +## i.e. CHAT_ANNOUNCE_NEW_GAME chat_channel_tag + +## Announcements for when a new round begins. +#CHAT_ANNOUNCE_NEW_GAME + +## Announcements for when the round ends, pending server reboot. +#CHAT_ROUNDEND_NOTICE_TAG + +## For where should the one true bird speak? +#CHAT_SQUAWK_TAG + +## Role ID that, when present, will be pinged every round end. +#CHAT_REBOOT_ROLE diff --git a/config/entries/general.txt b/config/entries/general.txt index 7fef691006..3688b8197b 100644 --- a/config/entries/general.txt +++ b/config/entries/general.txt @@ -31,15 +31,6 @@ ALLOW_HOLIDAYS ## Uncomment to show the names of the admin sending a pm from IRC instead of showing as a stealthmin. #SHOW_IRC_NAME -## Chat Announce Options -## Various messages to be sent to game chats -## Uncommenting these will enable them, by default they will be broadcast to Game chat channels on TGS3 or non-admin channels on TGS4 -## If using TGS4, the string option can be set as a chat channel tag to limit the message to channels of that tag type (case-sensitive) -## i.e. CHAT_ANNOUNCE_NEW_GAME chat_channel_tag - -## Send a message with the station name starting a new game -#CHAT_ANNOUNCE_NEW_GAME - ##Default screen resolution, in tiles. ## By default, this is 15x15, which gets simplified to 7 by BYOND, as it is a 1:1 screen ratio. ## For reference, Goonstation uses a resolution of 21x15 for it's widescreen mode. diff --git a/config/entries/logging.txt b/config/entries/logging.txt index 57588d7cd3..8da1ac4474 100644 --- a/config/entries/logging.txt +++ b/config/entries/logging.txt @@ -61,11 +61,14 @@ LOG_JOB_DEBUG ## Log shuttle related actions LOG_SHUTTLE +## Log economy-related actions +LOG_ECON + ## log all world.Topic() calls LOG_WORLD_TOPIC ## enables use of the proc twitterize() that lets you take a large list of strings and turn it into a JSON file of tweet sized strings. -## As an example of how this could be """useful""" look towards Poly (https://twitter.com/Poly_the_Parrot) +## As an example of how this could be """useful""" look towards Polly (https://twitter.com/Poly_the_Parrot) # LOG_TWITTER ## Enable logging pictures diff --git a/goon/icons/obj/power.dmi b/goon/icons/obj/power.dmi index bb787c0b3c..d2a623bf6c 100644 Binary files a/goon/icons/obj/power.dmi and b/goon/icons/obj/power.dmi differ diff --git a/html/changelogs/archive/2022-05.yml b/html/changelogs/archive/2022-05.yml index 92a19f4e1c..e55d2a3bca 100644 --- a/html/changelogs/archive/2022-05.yml +++ b/html/changelogs/archive/2022-05.yml @@ -38,3 +38,12 @@ 2022-05-17: timothyteakettle: - rscadd: poly alt cloak can now be renamed/dedescriptioned in loadout +2022-05-19: + timothyteakettle: + - rscadd: quirks are now organised into three tabs for positive, neutral and negative +2022-05-21: + Bhijn & Myr: + - bugfix: Blood trails no longer have a duplicate directionless iconstate as their + base sprite, fixing the Wonkiness of blood trails going west/east. + SandPoot: + - bugfix: Silicon flavor texts are no longer broken... maybe? diff --git a/html/changelogs/archive/2022-06.yml b/html/changelogs/archive/2022-06.yml new file mode 100644 index 0000000000..9365a633b1 --- /dev/null +++ b/html/changelogs/archive/2022-06.yml @@ -0,0 +1,171 @@ +2022-06-01: + DeltaFire15: + - bugfix: Mechs now use power when moving. + - bugfix: The check for mining-only mechs is no longer inverted to only allow non-mining + z levels. + - bugfix: Reverted an accidental buff from the /tg/ mech code port and its adjustment + to citadel's mech state. + - bugfix: 'Mechs with different base movement power cost now actually have it apply + instead of immediately being overwritten. tweak: Adjusted part impact on movement + power use to make more sense.' + timothyteakettle: + - rscadd: 'optimises quirks somewhat tweak: nyctophobia will now stop run intent + when you try to move in darkness with it on, compared to the old behaviour of + automatically turning it off in darkness when it is on and you have been in + darkness for >= 0.2 seconds tweak: nyctophobia and lightless will both not update + your mood until you move now, as part of the optimisations made by changing + them to tg code' +2022-06-02: + Bhijn & Myr: + - bugfix: You can no longer attach multiple tracking beacons to a single mech, fixing + an exploit where mechs can be nuked with minimal effort. + - bugfix: Omegastation's airmix filter is no longer inverted! The oxygen:nitrogen + levels of Omega later in the round should now be normal again. + - rscadd: 'The TGS bot is now capable of pinging the reboot role! Rejoice! tweak: + The TGS bot''s automated output can now be configured to define which channels + certain messages are output to.' + - rscadd: Jukeboxes now have a queue! You can pay 40 credits to have any song of + your choosing queued up for playback on the jukebox! + - rscadd: Jukeboxes can now be emagged, allowing you to boost their volume up to + 210%, along with removing all of its access restrictions. Additionally, a sufficiently + loud jukebox is fully capable of causing potentially permanent damage to your + ears. + - rscadd: 'Jukeboxes now support multi-z! This is self-explanatory. tweak: Volume + knobs now work on jukeboxes! tweak: Muffled jukeboxes have been given a buff. + tweak: Sounds now factor in the distance multiplier for their baseline z offset. + tweak: SOUND_UPDATE now bypasses the can_hear() check in playsound_local() (thanks + Azarak for helping figure this out!)' + - bugfix: 'Jukebox audio no longer uses playsound_local(), allowing falloff to properly + apply to jukeboxes (this fixes the bug where they were significantly quieter + than intended) tweak: When deaf, jukeboxes no longer mute the playing track + permanently.' + - bugfix: Ears are capable of taking damage again. + - rscadd: Jukeboxes have been added to Boxstation, Lambdastation, Metastation, and + Omegastation + - bugfix: Boxstation's incinerator sensor now properly reports to atmos's machinery + again + Putnam3145: + - balance: Nitryl is higher risk, can't be sold for as much + - refactor: Gas prices are now part of the gas data structure + TrojanCoyote: + - rscadd: sprites for muzzled and non muzzled mobs for the masks, along with the + adjusted versions, icons for the masks as well. + bunny232: + - rscadd: Universal blood type now accepts bug blood. +2022-06-03: + Bhijn & Myr: + - bugfix: Solar panels now actually face the proper direction. This is achieved + by reducing the iconstate to only 1 dir. +2022-06-06: + SandPoot: + - refactor: Completely replaces the new player panel *not the admin one* with TG's. + timothyteakettle: + - rscadd: adds paper skin and glass bones quirks +2022-06-08: + Bhijn & Myr: + - bugfix: Audiovisual redirection now works exactly as it used to. In laymen's terms, + this means folks in VR sleepers are aware of the world around them again! + - rscadd: During pride month, station nukes are significantly more efficient at + revealing genders. + - rscadd: Station pets now retain their color between shifts! + - bugfix: The shake animation, jiggle animation, squish animation, jitter animation, + and float animation, have all been fixed. + - bugfix: This also means that storage animations are fully working again. It's + been a few years! + - bugfix: 'The pull animation no longer interrupts ongoing animations. tweak: The + pull animation now supports diagonal directions (currently only applies to the + initial grab! pull code is spaghetti)' + - bugfix: All screenshake sources now fully support the screenshake pref + - code_imp: cit_screenshake.dm has been fully merged into the base files. + - bugfix: You can no longer remotely apply fingerprints to storage objects by clicking + and dragging it around. Additionally, storage objects now rustle again when + clicking and dragging (only took like,, a year to fix) + - bugfix: 'The pickup animation now properly slides into your spaceman again, instead + of just kinda disappearing. tweak: When pulling a resting mob, they''ll now + skip the laying animation entirely, fixing a visual oddity where they shrink + and grow to flip. tweak: Alerts are now a little snappier and bouncier, as they''ve + been swapped from sine easing, to back easing. tweak: Radial menus now use sine + easing, rather than linear easing. This just looks a little prettier. tweak: + Runechat now properly respects an object''s X offset. Previously, it relied + on a hardcoded check for dogborgs. tweak: The float animation now uses pixel_z + instead of pixel_y, fixing issues where the Y offset gets wiped due to the float + animation. This also makes floating fully compatible with ctrl+WASD.' + - bugfix: Admin vote deobfuscation now properly displays votes as 0 if they were + simply never voted for. + SandPoot: + - refactor: Does some extremely minor touches on pulling/pushing code. + timothyteakettle: + - rscadd: updates existing poly maid outfit with tg sprite but polychromatic + - rscadd: adds polychromic maid apron, gloves, collar, headband + - rscadd: adds support for polychromic accessories +2022-06-12: + Bhijn & Myr: + - rscadd: The station minimap now features higher detail! Instead of just windows + and grilles being outlined, all dense+anchored structures and machinery are + shown on the minimap. + - rscadd: The station minimap now supports obfuscating entire areas, via the minimap_show_walls + var. + - rscadd: 'The station minimap now supports defining two area colors, allowing for + a checkerboard pattern! tweak: Hallways and maint have been given white and + gray colors, respectively, for ease of readability. tweak: Ruins are now obfuscated + on the minimap, and have been given a subtle, yet distinct, color pattern!' + - bugfix: The station minimap no longer errors when you mouse over it + - rscadd: 'The station minimap now supports multiz! (However, due to bugginess, + multiz minimaps won''t display area tooltips.) tweak: The station minimap now + features pixel-perfect scaling.' + - code_imp: The station minimap can now support managing data for up to 16,581,374 + areas without any conflicts at all! Before, BYOND's psuedorandom RNG meant that + it was somewhat common for areas to collide with each others' data. + - rscadd: Talking is now accompanied with fully-customizable sounds! You can modify + your character's speech under the speech tab in chargen, and you can toggle + these sounds via the "Hear/Silence Vocal Barks" verb under the preferences tab! + This also fully supports genetics. + - bugfix: Admittedly an unatomized change, but Cit's DNA blocks can now properly + be updated through genetics. Before, these required a complete genetics reset + to apply. + - rscadd: 'The chat now supports blockquotes! tweak: Examining, medical scanners, + self-checking, and mood checkups, have all been converted to make use of blockquotes.' + Bhijn & Myr (+ UI work and cleanup by Sandpoot!): + - rscadd: 'Colormates now have HSV coloration! tweak: Colormates have had their + "please use white clothing" message removed, as that recommendation''s now mostly + pointless tweak: The default mode for colormates is now HSV coloration tweak: + The temp messages in colormates have been tweaked slightly to be more user-friendly, + as they''re user-facing. tweak: The description for constants in the colormate + matrix mode has been fixed; the constant variables have nothing to do with contrast, + they simply add color tweak: Matrix mode has been made a lot more usable; it''s + now clamped between -10 and 10, and features a step of 0.01, making it much + easier to simply click and drag to adjust the values, rather than having to + punch them in manually' + Putnam3145: + - balance: QCD matter is now worth 10x as much and makes 2 research pointer per + mole + SandPoot: + - rscadd: Added a search box to all vending machine uis. + - qol: Vending machines have candystripes for better clarity. + - bugfix: Fixed items that use strip_mod and strip_silence (stripping people faster + or without giving them a message) + keronshb: + - bugfix: Families fixed from crashing +2022-06-13: + Bhijn & Myr: + - bugfix: Jukebox audio is now audible within closets, crates, etc! +2022-06-19: + IHOPMommyLich: + - rscdel: Removed the forced dynamic, allowing the standard game mode vote. + TripleShades: + - bugfix: Cannabis mutation variants now use the proper growth state icons + - bugfix: Picking to make tea cups will now give the right starting glasswork base + - bugfix: Picking to make tea plates will now give the right starting glasswork + base + - spellcheck: Fixed a state typo in tea cup glassworking + - spellcheck: Fixed an incorrect step displayed on spout glassworking + - code_imp: Enables the make priority announcement admin verb for admin use +2022-06-21: + Bhijn & Myr: + - balance: Ling abilities now have a default loudness of 0.5. This change applies + to every single ability that used to have 0 loudness. + TrojanCoyote: + - rscadd: Adds a plate carrier to HoS loadout, sprites for such +2022-06-29: + Putnam3145: + - bugfix: GAS_OXYGEN -> GAS_O2 diff --git a/html/changelogs/archive/2022-07.yml b/html/changelogs/archive/2022-07.yml new file mode 100644 index 0000000000..99a1e1103e --- /dev/null +++ b/html/changelogs/archive/2022-07.yml @@ -0,0 +1,103 @@ +2022-07-05: + Putnam3145: + - bugfix: Miasma is brown again +2022-07-09: + Bhijn & Myr: + - code_imp: Barks can now be intercepted via component signals. Both bark queuing + and individual barks can be intercepted via signals! + - rscadd: The "Brassy" bark has been added, using the cog installation sound as + a sample! This works surprisingly well as a bark + - rscadd: 'Genetics can now give people goose1.ogg tweak: If new barks are queued + before the current barks are finished, this will interrupt all ongoing barks + tweak: Yelling no longer cuts the minimum bark time variance down to half, as + this proved to sound pretty awful with most barks. tweak: Chitter now uses a + completely unique audio sample, which is based on the original ratchet.ogg it + used to be. This new sample is shorter, and has significantly less harsh noise + on the higher frequencies, making it much easier on the ears. Additionally, + the minimum speed for chitter has been reduced from 6 to 4. tweak: Setting vocal_bark + to a file should now automatically turn it into a sound datum (in theory, at + least! as of writing i haven''t tested this at all)' + - bugfix: Barks and other DNA features after the first mob color now work exactly + as you'd expect. This was the cause for horrid eldritch bark sounds when the + wrong part of DNA gets hit. The first mob color has lost some genetics resolution + as an indirect result of this (the higher resolution is what caused this bug) + UDaV73rus, Tokoriso, dragomagol: + - rscadd: welding now has an animation! + timothyteakettle: + - rscadd: slimes no longer die from having no blood, properly consume limbs when + at low blood, and suffer brute damage and oxygen loss for having no blood and + no limbs left to consume respectably, they cannot go past BLOOD_VOLUME_MAXIMUM + from consuming toxin +2022-07-16: + MediHound: + - rscdel: Removed old Alina sprites + - rscadd: Added new Alina sprites + SandPoot: + - bugfix: The tweak tag for changelogs should now work. +2022-07-20: + Putnam3145: + - balance: quark matter is now worth 5% as much and gives 10% the research points + timothyteakettle: + - bugfix: makes brain trauma event respect canSpawnEvent conditions such as min + players +2022-07-21: + SandPoot: + - bugfix: If you have a dark purple stabilized extract and are holding nothing in + your hand, no longer attempts to heat nothing, which caused immense amounts + of runtimes. + - bugfix: The syndicate has fixed the radiation health analyzer allowing you to + check on the ui again. +2022-07-23: + TripleShades: + - rscdel: Snow Cabin turbine + - tweak: Snow Cabin, Jungle Resort, and Plasma Outpost gateways now use RTGs for + power generation + - balance: Snow Cabin SMES unit is now non-magical + - bugfix: Snow Cabin gateway wiring now connected properly +2022-07-24: + Bhijn & Myr: + - tweak: The typo in Polly's name has been fixed, severing the decade-old reference + to a 2012-era TGstation coder. If you know, you know. + BlueWildrose: + - qol: Two new Kinkmates have been added to Deltastation in the dorms and arrivals + area. + - bugfix: Cleanbots will no longer go invisible when they get turned on or off. + - qol: Public library paintings have been added to Omegastation. You can now submit + paintings that will appear in later rounds on that station. +2022-07-25: + BlueWildrose: + - bugfix: Fixes hierophant walls letting non-casters pass through them. + - qol: Player-controlled cleanbots can now clean messes that ordinarily wouldn't + be clickable as long as they are clicking the tile it's on. + - bugfix: The shocked autolathe will no longer infinitely zap you with the menu + open. + - bugfix: Using wirecutters on an autolathe with an open panel will now have appropriate + behavior of opening the wire menu. + - bugfix: Harvested grown inedibles now take their seed stats into account instead + of acting like they got adminspawned. + - bugfix: Tea now dispenses from dispensers again. + - bugfix: Pink tea and Pink milk are pathed correctly. + SandPoot: + - bugfix: Put arguments into handle_blood (it needs them). +2022-07-27: + timothyteakettle: + - bugfix: slime limb regeneration ability fix +2022-07-31: + Putnam3145: + - rscadd: Atmospheric flux event (properly) + - rscadd: Sandstorm event (was in files, just disabled; 10 space dusts all at once) + - tweak: Random brain trauma can now trigger if there's an AI, chemist, virologist, + captain, HoP or roboticist + - balance: Flux anomaly min player count 10->0 + - balance: Pyroclastic anomaly min player count 0->5 + - balance: Cat surgeon weight 8->5 + - balance: Disease outbreak min player count 10->3, now requires medbay + - balance: Heart attack min player count 40->10, now requires medbay + - balance: Mass hallucination max occurrences 2->5 + - balance: Supermatter surge max occurrences 2->5, now half as strong on CO2less + setups (lerping up to old value for 100% CO2) + - balance: Supernova max occurrences 2->1, weight 10->5 + - balance: 'Vent Clog: Normal min players 25->0, random chem prob 1%->0%' + - balance: 'Vent Clog: Threatening min players 35->15' + - balance: 'Vent Clog: Catastrophic min players 45->25' + - rscadd: Random shoe untying diff --git a/html/changelogs/archive/2022-08.yml b/html/changelogs/archive/2022-08.yml new file mode 100644 index 0000000000..a5f7fa3e87 --- /dev/null +++ b/html/changelogs/archive/2022-08.yml @@ -0,0 +1,50 @@ +2022-08-01: + Putnam3145: + - bugfix: rad collectors display the right units now + - balance: Stasis beds are now 90% as good as surgery tables for surgery +2022-08-02: + SandPoot: + - admin: Alphabetically ordered bitfields for admin editing. + - admin: It is now easier to change the flags of turrets. + - refactor: Allows for defining bitfields in other files. +2022-08-03: + Putnam3145: + - balance: Research bomb "midpoint" at which it's worth exactly 50000 points from + 240->300 + - code_imp: doesn't snowflake the bomb cap for linux anymore, servers that need + to tweak it can do it themselves (I didn't even put it down right, should be + 5000 instead of 50000, yikes) +2022-08-04: + MrJWhit: + - rscadd: Adds more AI screens on box + TripleShades: + - qol: Three gateways will no longer lose power via Magical SMES Units + timothyteakettle: + - rscadd: lets AIs control status displays (vtuber mode) +2022-08-05: + Hatterhat: + - tweak: The L6 Squad Automatic Weapon, as used by Syndicate nuclear operatives, + now fires 7.12x82mm, with no change in ballistic performance. This has the side + effect of making it now capable of utilizing match-grade ammunition, which some + would think are mutually incompatible concepts. + Putnam3145: + - tweak: Untied shoelaces probabilities rework + - balance: Miner boots are slightly harder to tie/untie now +2022-08-08: + Hatterhat: + - tweak: Proto-kinetic crushers and variants can now be renamed via pen. + - tweak: Custom descriptions on items tagged with UNIQUE_RENAME can now go to 350 + characters, up from 140. + - tweak: Recoil now pushes your screen in the opposite direction of where you're + shooting. It makes sense in context, I swear. Adjust the setting for this in + your client prefs, because it defaults to on. + Linzolle: + - bugfix: catwalk overlays behave properly, appearing on top of cables and such + Putnam3145: + - tweak: Various gases now have shortened names for filters + - balance: Nitric oxide now removes from the power mix like nitrogen/pluoxium do + - balance: Nitric oxide now becomes, at most, 20% nitrogen dioxide instead of 50% + SandPoot: + - bugfix: Fixed the lack of eyes making ERROR appear on people. + - qol: Set up for the dmi editor extension, very helpful as you can see the existant + states and their names opposed to only images in a huge spritesheet. diff --git a/icons/blanks/32x32.dmi b/icons/blanks/32x32.dmi new file mode 100644 index 0000000000..6c4f2b33e0 Binary files /dev/null and b/icons/blanks/32x32.dmi differ diff --git a/icons/blanks/96x96.dmi b/icons/blanks/96x96.dmi new file mode 100644 index 0000000000..d79e60c111 Binary files /dev/null and b/icons/blanks/96x96.dmi differ diff --git a/icons/blanks/blank_title.png b/icons/blanks/blank_title.png new file mode 100644 index 0000000000..387a21f03a Binary files /dev/null and b/icons/blanks/blank_title.png differ diff --git a/icons/default_title.dmi b/icons/default_title.dmi deleted file mode 100644 index 633bd434b8..0000000000 Binary files a/icons/default_title.dmi and /dev/null differ diff --git a/icons/effects/welding_effect.dmi b/icons/effects/welding_effect.dmi new file mode 100644 index 0000000000..8b8db2dcae Binary files /dev/null and b/icons/effects/welding_effect.dmi differ diff --git a/icons/hud/lobby/background.dmi b/icons/hud/lobby/background.dmi new file mode 100644 index 0000000000..baae06fc1b Binary files /dev/null and b/icons/hud/lobby/background.dmi differ diff --git a/icons/hud/lobby/bottom_buttons.dmi b/icons/hud/lobby/bottom_buttons.dmi new file mode 100644 index 0000000000..d0aa1228c7 Binary files /dev/null and b/icons/hud/lobby/bottom_buttons.dmi differ diff --git a/icons/hud/lobby/character_setup.dmi b/icons/hud/lobby/character_setup.dmi new file mode 100644 index 0000000000..d3b94fb43e Binary files /dev/null and b/icons/hud/lobby/character_setup.dmi differ diff --git a/icons/hud/lobby/join.dmi b/icons/hud/lobby/join.dmi new file mode 100644 index 0000000000..416f315770 Binary files /dev/null and b/icons/hud/lobby/join.dmi differ diff --git a/icons/hud/lobby/observe.dmi b/icons/hud/lobby/observe.dmi new file mode 100644 index 0000000000..f59252b3ea Binary files /dev/null and b/icons/hud/lobby/observe.dmi differ diff --git a/icons/hud/lobby/poll_overlay.dmi b/icons/hud/lobby/poll_overlay.dmi new file mode 100644 index 0000000000..2fc9716260 Binary files /dev/null and b/icons/hud/lobby/poll_overlay.dmi differ diff --git a/icons/hud/lobby/ready.dmi b/icons/hud/lobby/ready.dmi new file mode 100644 index 0000000000..d2a45a883f Binary files /dev/null and b/icons/hud/lobby/ready.dmi differ diff --git a/icons/mob/clothing/accessories.dmi b/icons/mob/clothing/accessories.dmi index 03849efa5a..f801c483f1 100644 Binary files a/icons/mob/clothing/accessories.dmi and b/icons/mob/clothing/accessories.dmi differ diff --git a/icons/mob/clothing/hands.dmi b/icons/mob/clothing/hands.dmi index ca8a7312fa..9bd206e04e 100644 Binary files a/icons/mob/clothing/hands.dmi and b/icons/mob/clothing/hands.dmi differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index 2413b52d71..3c50e4d42d 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/clothing/mask_muzzled.dmi b/icons/mob/clothing/mask_muzzled.dmi index 9f483c8d47..5e0bb46c34 100644 Binary files a/icons/mob/clothing/mask_muzzled.dmi and b/icons/mob/clothing/mask_muzzled.dmi differ diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi index 20b8576277..2b317737d7 100644 Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ diff --git a/icons/mob/clothing/suit.dmi b/icons/mob/clothing/suit.dmi index 8be696eb45..e99623dfc6 100644 Binary files a/icons/mob/clothing/suit.dmi and b/icons/mob/clothing/suit.dmi differ diff --git a/icons/mob/clothing/suit_digi.dmi b/icons/mob/clothing/suit_digi.dmi index 13840507a6..a7d419545c 100644 Binary files a/icons/mob/clothing/suit_digi.dmi and b/icons/mob/clothing/suit_digi.dmi differ diff --git a/icons/mob/clothing/uniform.dmi b/icons/mob/clothing/uniform.dmi index 04d9b20a75..ce25963360 100644 Binary files a/icons/mob/clothing/uniform.dmi and b/icons/mob/clothing/uniform.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index 4b8dba160a..c4927ea06b 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi index 79cb2bff77..f633f030c3 100644 Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index d4cd4b4f2f..17073805c9 100644 Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index f5bc9e7046..b86731babd 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi index 8540b2f392..c9491af6b2 100644 Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 5493361129..a6e5e1f037 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index c16b416cd8..de7dd234b1 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/runtime/README.md b/icons/runtime/README.md new file mode 100644 index 0000000000..804cb2f285 --- /dev/null +++ b/icons/runtime/README.md @@ -0,0 +1,5 @@ +# Runtime Loaded Icons + +These icons are not compiled into the .rsc or are otherwise loaded at runtime. + +Please keep all (non-config) icons that do this in this folder as it is needed by the [deploy.sh](../../tools/deploy.sh) script to minimize build output. diff --git a/icons/runtime/default_title.dmi b/icons/runtime/default_title.dmi new file mode 100644 index 0000000000..17f4787f84 Binary files /dev/null and b/icons/runtime/default_title.dmi differ diff --git a/icons/runtime/tcg/default.dmi b/icons/runtime/tcg/default.dmi new file mode 100644 index 0000000000..f42113f30e Binary files /dev/null and b/icons/runtime/tcg/default.dmi differ diff --git a/icons/runtime/tcg/xenos.dmi b/icons/runtime/tcg/xenos.dmi new file mode 100644 index 0000000000..682b0a6966 Binary files /dev/null and b/icons/runtime/tcg/xenos.dmi differ diff --git a/icons/turf/floors/catwalk_plating.dmi b/icons/turf/floors/catwalk_plating.dmi index 24954e4a17..c9ad36653b 100644 Binary files a/icons/turf/floors/catwalk_plating.dmi and b/icons/turf/floors/catwalk_plating.dmi differ diff --git a/modular_citadel/code/game/objects/cit_screenshake.dm b/modular_citadel/code/game/objects/cit_screenshake.dm deleted file mode 100644 index 222de37f82..0000000000 --- a/modular_citadel/code/game/objects/cit_screenshake.dm +++ /dev/null @@ -1,51 +0,0 @@ -//we vlambeer now - -/obj/proc/shake_camera(mob/M, duration, strength=1)//byond's wonky with this shit - set waitfor = FALSE - if(!M || !M.client || duration <= 0) - return - var/client/C = M.client - if (C.prefs.screenshake==0) - return - var/oldx = C.pixel_x - var/oldy = C.pixel_y - var/clientscreenshake = (C.prefs.screenshake * 0.01) - var/max = (strength*clientscreenshake) * world.icon_size - var/min = -((strength*clientscreenshake) * world.icon_size) - - for(var/i in 0 to duration-1) - if (i == 0) - animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) - else - animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) - animate(pixel_x=oldx, pixel_y=oldy, time=1) - -/obj/item/gun/energy - recoil = 0.1 - -/obj/item/gun/energy/kinetic_accelerator - recoil = 0.5 - -/obj/item/gun/ballistic - recoil = 0.25 - -/obj/item/gun/ballistic/shotgun - recoil = 1 - -/obj/item/gun/ballistic/revolver - recoil = 0.5 - -/obj/item/gun/ballistic/revolver/doublebarrel - recoil = 1 - -/obj/item/gun/syringe - recoil = 0.1 - -/obj/item/pneumatic_cannon/fire_items(turf/target, mob/user) - . = ..() - shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75)) - -/obj/item/attack_obj(obj/O, mob/living/user) - . = ..() - if(force >= 20) - shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01)) diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index fe53574470..931324bf8f 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -579,3 +579,9 @@ path = /obj/item/storage/box/pockerchips ckeywhitelist = list("greed2323") +/datum/gear/donator/psychedelicjumpsuit + name = "psychedelic jumpsuit" + slot = ITEM_SLOT_ICLOTHING + path = /obj/item/clothing/under/misc/psyche + ckeywhitelist = list("commandnotrecognized") + diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm index 3824993009..0573a1a22a 100644 --- a/modular_citadel/code/modules/client/loadout/backpack.dm +++ b/modular_citadel/code/modules/client/loadout/backpack.dm @@ -175,3 +175,9 @@ /datum/gear/backpack/necklace//this is here because loadout doesn't support proper accessories name = "A renameable necklace" path = /obj/item/clothing/accessory/necklace + +/datum/gear/backpack/polymaidapron //this is ALSO here because loadout doesn't support proper accessories + name = "Polychromic maid apron" + path = /obj/item/clothing/accessory/maidapron/polychromic + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") diff --git a/modular_citadel/code/modules/client/loadout/gloves.dm b/modular_citadel/code/modules/client/loadout/gloves.dm index 2a80d43bb1..960be356e2 100644 --- a/modular_citadel/code/modules/client/loadout/gloves.dm +++ b/modular_citadel/code/modules/client/loadout/gloves.dm @@ -14,6 +14,12 @@ name = "Midnight gloves" path = /obj/item/clothing/gloves/evening/black +/datum/gear/gloves/maidpoly // WHAT DO YOU EVEN CALL THEM + name = "Polychromic maid gloves" + path = /obj/item/clothing/gloves/polymaid + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") + /datum/gear/gloves/goldring name = "A gold ring" path = /obj/item/clothing/gloves/ring diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm index f2a7ead5be..d0563d2986 100644 --- a/modular_citadel/code/modules/client/loadout/head.dm +++ b/modular_citadel/code/modules/client/loadout/head.dm @@ -58,6 +58,12 @@ name = "Maid headband" path= /obj/item/clothing/head/maid +/datum/gear/head/maidband/poly + name = "Polychromic maid headband" + path= /obj/item/clothing/head/maid/polychromic + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") + /datum/gear/head/flakhelm name = "Flak Helmet" path = /obj/item/clothing/head/flakhelm diff --git a/modular_citadel/code/modules/client/loadout/mask.dm b/modular_citadel/code/modules/client/loadout/mask.dm index 16b47e60e7..f1cf2a5d9f 100644 --- a/modular_citadel/code/modules/client/loadout/mask.dm +++ b/modular_citadel/code/modules/client/loadout/mask.dm @@ -15,6 +15,16 @@ path = /obj/item/clothing/mask/joy cost = 3 +/datum/gear/mask/kitsune + name = "White Kitsune Mask" + path = /obj/item/clothing/mask/kitsunewhi + cost = 2 + +/datum/gear/mask/black_kitsune + name = "Black Kitsune Mask" + path = /obj/item/clothing/mask/kitsuneblk + cost = 2 + /datum/gear/mask/gas name = "Gas Mask" path = /obj/item/clothing/mask/gas diff --git a/modular_citadel/code/modules/client/loadout/neck.dm b/modular_citadel/code/modules/client/loadout/neck.dm index dc7735de2b..64d1fcdc1f 100644 --- a/modular_citadel/code/modules/client/loadout/neck.dm +++ b/modular_citadel/code/modules/client/loadout/neck.dm @@ -106,3 +106,9 @@ path = /obj/item/clothing/neck/cloak/cancloak/polychromic loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#585858", "#373737", "#BEBEBE") + +/datum/gear/neck/maid + name = "Polychromatic Maid Collar" + path = /obj/item/clothing/neck/maid + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 2b2f3b53e4..d70d3d4fa1 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -52,7 +52,7 @@ name = "Polychromic maid costume" path = /obj/item/clothing/under/rank/civilian/janitor/maid/polychromic loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC - loadout_initial_colors = list("#FFFFFF", "#000000") + loadout_initial_colors = list("#333333", "#FFFFFF") /datum/gear/uniform/mailmanuniform name = "Mailman's jumpsuit" diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm index 102ae41921..4942a1041f 100644 --- a/modular_citadel/code/modules/client/preferences_savefile.dm +++ b/modular_citadel/code/modules/client/preferences_savefile.dm @@ -35,5 +35,4 @@ WRITE_FILE(S["feature_xeno_head"], features["xenohead"]) //flavor text WRITE_FILE(S["feature_flavor_text"], features["flavor_text"]) - WRITE_FILE(S["silicon_feature_flavor_text"], features["silicon_flavor_text"]) - + WRITE_FILE(S["feature_silicon_flavor_text"], features["silicon_flavor_text"]) diff --git a/modular_citadel/code/modules/mob/cit_emotes.dm b/modular_citadel/code/modules/mob/cit_emotes.dm index 0adb12e5a1..8a6643d239 100644 --- a/modular_citadel/code/modules/mob/cit_emotes.dm +++ b/modular_citadel/code/modules/mob/cit_emotes.dm @@ -77,7 +77,8 @@ restraint_check = TRUE /datum/emote/living/snap/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -93,7 +94,8 @@ restraint_check = TRUE /datum/emote/living/snap2/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -109,7 +111,8 @@ restraint_check = TRUE /datum/emote/living/snap3/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -125,7 +128,8 @@ restraint_check = FALSE /datum/emote/living/awoo/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -141,7 +145,8 @@ restraint_check = FALSE /datum/emote/living/hiss/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -157,7 +162,8 @@ restraint_check = FALSE /datum/emote/living/meow/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -173,7 +179,8 @@ restraint_check = FALSE /datum/emote/living/purr/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -189,7 +196,8 @@ restraint_check = FALSE /datum/emote/living/nya/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -205,7 +213,8 @@ restraint_check = FALSE /datum/emote/living/weh/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -221,7 +230,8 @@ restraint_check = FALSE /datum/emote/living/peep/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -244,7 +254,8 @@ restraint_check = FALSE /datum/emote/living/mothsqueak/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -260,7 +271,8 @@ restraint_check = FALSE /datum/emote/living/merp/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -276,7 +288,8 @@ restraint_check = FALSE /datum/emote/living/bark/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -293,7 +306,8 @@ restraint_check = FALSE /datum/emote/living/squish/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -310,7 +324,8 @@ restraint_check = FALSE /datum/emote/living/pain/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -331,6 +346,7 @@ restraint_check = TRUE /datum/emote/living/clap1/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return playsound(user, 'modular_citadel/sound/voice/clap.ogg', 50, 1, -1) diff --git a/modular_citadel/icons/mob/widerobot.dmi b/modular_citadel/icons/mob/widerobot.dmi index 50c29bb75f..cc986cfa9d 100644 Binary files a/modular_citadel/icons/mob/widerobot.dmi and b/modular_citadel/icons/mob/widerobot.dmi differ diff --git a/sound/voice/barks/chitter.ogg b/sound/voice/barks/chitter.ogg new file mode 100644 index 0000000000..0d162fa303 Binary files /dev/null and b/sound/voice/barks/chitter.ogg differ diff --git a/strings/cas_white.txt b/strings/cas_white.txt index 3e229862a2..397c7febff 100644 --- a/strings/cas_white.txt +++ b/strings/cas_white.txt @@ -72,7 +72,7 @@ Supermatter undergarments. A permaban. Stealing all the miners' ore. Bluespace artillery. -Poly reading porn over the radio again. +Polly reading porn over the radio again. Mining the shaft. Grab intent. A blob zombie with an erection. diff --git a/strings/phobia.json b/strings/phobia.json index fc8fb31995..ee25cc62fa 100644 --- a/strings/phobia.json +++ b/strings/phobia.json @@ -250,6 +250,7 @@ "bird", "beak", "poly", + "polly", "wing", "claw", "peck", diff --git a/tgstation.dme b/tgstation.dme index 00a8286bdc..6878f256e2 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -28,6 +28,7 @@ #include "code\__DEFINES\admin.dm" #include "code\__DEFINES\antagonists.dm" #include "code\__DEFINES\atmospherics.dm" +#include "code\__DEFINES\bitfields.dm" #include "code\__DEFINES\blackmarket.dm" #include "code\__DEFINES\botany.dm" #include "code\__DEFINES\callbacks.dm" @@ -154,6 +155,9 @@ #include "code\__DEFINES\dcs\flags.dm" #include "code\__DEFINES\dcs\helpers.dm" #include "code\__DEFINES\dcs\signals.dm" +#include "code\__DEFINES\dcs\signals\signals_subsystem.dm" +#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movement.dm" +#include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_living.dm" #include "code\__DEFINES\mapping\maploader.dm" #include "code\__DEFINES\material\worth.dm" #include "code\__DEFINES\mobs\innate_abilities.dm" @@ -174,6 +178,7 @@ #include "code\__HELPERS\angles.dm" #include "code\__HELPERS\areas.dm" #include "code\__HELPERS\chat.dm" +#include "code\__HELPERS\clients.dm" #include "code\__HELPERS\cmp.dm" #include "code\__HELPERS\config.dm" #include "code\__HELPERS\custom_holoforms.dm" @@ -283,6 +288,7 @@ #include "code\_onclick\hud\map_popups.dm" #include "code\_onclick\hud\monkey.dm" #include "code\_onclick\hud\movable_screen_objects.dm" +#include "code\_onclick\hud\new_player.dm" #include "code\_onclick\hud\picture_in_picture.dm" #include "code\_onclick\hud\plane_master.dm" #include "code\_onclick\hud\radial.dm" @@ -321,6 +327,7 @@ #include "code\controllers\configuration\entries\admin.dm" #include "code\controllers\configuration\entries\alert.dm" #include "code\controllers\configuration\entries\antag_rep.dm" +#include "code\controllers\configuration\entries\bot.dm" #include "code\controllers\configuration\entries\comms.dm" #include "code\controllers\configuration\entries\connections.dm" #include "code\controllers\configuration\entries\dbconfig.dm" @@ -415,7 +422,7 @@ #include "code\controllers\subsystem\persistence\_persistence.dm" #include "code\controllers\subsystem\persistence\cleanable_debris.dm" #include "code\controllers\subsystem\persistence\panic_bunker.dm" -#include "code\controllers\subsystem\persistence\poly_parrot.dm" +#include "code\controllers\subsystem\persistence\polly_parrot.dm" #include "code\controllers\subsystem\persistence\recent_votes_etc.dm" #include "code\controllers\subsystem\persistence\secret_satchels.dm" #include "code\controllers\subsystem\persistence\trophies.dm" @@ -439,6 +446,7 @@ #include "code\datums\action.dm" #include "code\datums\ai_laws.dm" #include "code\datums\armor.dm" +#include "code\datums\bark.dm" #include "code\datums\beam.dm" #include "code\datums\beepsky_fashion.dm" #include "code\datums\browser.dm" @@ -2114,6 +2122,7 @@ #include "code\modules\events\anomaly_grav.dm" #include "code\modules\events\anomaly_pyro.dm" #include "code\modules\events\anomaly_vortex.dm" +#include "code\modules\events\atmos_speed.dm" #include "code\modules\events\aurora_caelus.dm" #include "code\modules\events\blob.dm" #include "code\modules\events\brain_trauma.dm" @@ -2160,6 +2169,7 @@ #include "code\modules\events\supermatter_surge.dm" #include "code\modules\events\supernova.dm" #include "code\modules\events\travelling_trader.dm" +#include "code\modules\events\untie_shoes.dm" #include "code\modules\events\vent_clog.dm" #include "code\modules\events\wisdomcow.dm" #include "code\modules\events\wormholes.dm" @@ -3706,6 +3716,7 @@ #include "code\modules\vehicles\mecha\mecha_wreckage.dm" #include "code\modules\vehicles\mecha\combat\combat.dm" #include "code\modules\vehicles\mecha\combat\durand.dm" +#include "code\modules\vehicles\mecha\combat\five_stars.dm" #include "code\modules\vehicles\mecha\combat\gygax.dm" #include "code\modules\vehicles\mecha\combat\honker.dm" #include "code\modules\vehicles\mecha\combat\marauder.dm" @@ -3776,7 +3787,6 @@ #include "interface\skin.dmf" #include "modular_citadel\code\datums\components\souldeath.dm" #include "modular_citadel\code\datums\status_effects\chems.dm" -#include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" #include "modular_citadel\code\modules\admin\holder2.dm" #include "modular_citadel\code\modules\admin\secrets.dm" diff --git a/tgui/packages/tgui-panel/styles/components/Chat.scss b/tgui/packages/tgui-panel/styles/components/Chat.scss index b439ace8c5..a199963fd0 100644 --- a/tgui/packages/tgui-panel/styles/components/Chat.scss +++ b/tgui/packages/tgui-panel/styles/components/Chat.scss @@ -98,3 +98,24 @@ $color-bg-section: base.$color-bg-section !default; pointer-events: none; } } + +blockquote { + background-color: rgba($text-color, 0.05); + border-left: 0.15em solid; + border-color: $text-color; + padding-left: 0.3em; + padding-right: 0.3em; + margin-bottom: 0.15em; + margin-left: 0.3em; + margin-right: 0em; +} + +hr { + background-color: rgba($text-color, 0.25); + height: 0.15em; + border-style: none; + margin-left: 1em; + margin-right: 2em; + margin-bottom: 0.3em; + margin-top: 0.3em; +} diff --git a/tgui/packages/tgui-panel/styles/goon/chat-dark.scss b/tgui/packages/tgui-panel/styles/goon/chat-dark.scss index 4406d24015..aa75db6c0d 100644 --- a/tgui/packages/tgui-panel/styles/goon/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/goon/chat-dark.scss @@ -447,6 +447,10 @@ em { font-style: italic; } +blockquote.warning { + border-color: #c51e1e; +} + .alertwarning { color: #FF0000; font-weight: bold; @@ -486,10 +490,18 @@ em { color: #9ab0ff; } +blockquote.info { + border-color: #9ab0ff; +} + .notice { color: #6685f5; } +blockquote.notice { + border-color: #6685f5; +} + .tinynotice { color: #6685f5; font-size: 85%; @@ -545,18 +557,34 @@ em { color: #059223; } +blockquote.green { + border-color: #059223; +} + .red { color: #FF0000; } +blockquote.red { + border-color: #FF0000; +} + .blue { color: #215cff; } +blockquote.blue { + border-color: #215cff; +} + .nicegreen { color: #059223; } +blockquote.nicegreen { + border-color: #059223; +} + /* hornichems */ .userlove { color: #ff42a6; @@ -575,6 +603,10 @@ em { color: #973e3b; } +blockquote.cult { + border-color: #973e3b; +} + .cultitalic { color: #973e3b; font-style: italic; @@ -630,6 +662,10 @@ em { color: #9956d3; } +blockquote.purple { + border-color: #9956d3; +} + .holoparasite { color: #88809c; } @@ -693,6 +729,10 @@ em { color: #BE8700; } +blockquote.brass { + border-color: #BE8700; +} + .heavy_brass { color: #BE8700; font-weight: bold; diff --git a/tgui/packages/tgui-panel/styles/goon/chat-light.scss b/tgui/packages/tgui-panel/styles/goon/chat-light.scss index e94d2a4e4b..42e2e478ae 100644 --- a/tgui/packages/tgui-panel/styles/goon/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/goon/chat-light.scss @@ -484,6 +484,10 @@ h1.alert, h2.alert { font-style: italic; } +blockquote.warning { + border-color: #ff0000; +} + .alertwarning { color: #FF0000; font-weight: bold; @@ -522,11 +526,18 @@ h1.alert, h2.alert { .info { color: #0000CC; } +blockquote.info { + border-color: #0000CC; +} .notice { color: #000099; } +blockquote.notice { + border-color: #000099; +} + .tinynotice { color: #000099; font-size: 85%; @@ -582,18 +593,33 @@ h1.alert, h2.alert { color: #03ff39; } +blockquote.green { + border-color: #03ff39; +} + .red { color: #FF0000; } +blockquote.red { + border-color: #FF0000; +} .blue { color: #0000FF; } +blockquote.blue { + border-color: #0000FF; +} + .nicegreen { color: #14a833; } +blockquote.nicegreen { + border-color: #14a833; +} + .userlove { color: #FF1493; font-style: italic; @@ -611,6 +637,10 @@ h1.alert, h2.alert { color: #973e3b; } +blockquote.cult { + border-color: #973e3b; +} + .cultitalic { color: #973e3b; font-style: italic; @@ -666,6 +696,10 @@ h1.alert, h2.alert { color: #5e2d79; } +blockquote.purple { + border-color: #5e2d79; +} + .holoparasite { color: #35333a; } @@ -730,6 +764,10 @@ h1.alert, h2.alert { color: #BE8700; } +blockquote.brass { + border-color: #BE8700; +} + .heavy_brass { color: #BE8700; font-weight: bold; diff --git a/tgui/packages/tgui/constants.js b/tgui/packages/tgui/constants.js index bc20e9ac9c..a5ac6aceb0 100644 --- a/tgui/packages/tgui/constants.js +++ b/tgui/packages/tgui/constants.js @@ -181,6 +181,12 @@ const GASES = [ 'label': 'N₂O', 'color': 'red', }, + { + 'id': 'no', + 'name': 'Nitric Oxide', + 'label': 'NO', + 'color': 'red', + }, { 'id': 'no2', 'name': 'Nitryl', @@ -223,6 +229,24 @@ const GASES = [ 'label': 'H₂', 'color': 'white', }, + { + 'id': 'methane', + 'name': 'Methane', + 'label': 'CH₄', + 'color': 'grey', + }, + { + 'id': 'methyl_bromide', + 'name': 'Methyl Bromide', + 'label': 'CH₃Br', + 'color': 'brown', + }, + { + 'id': 'qcd', + 'name': 'Quark Matter', + 'label': 'QGP', + 'color': 'pink', + }, ]; export const getGasLabel = (gasId, fallbackValue) => { diff --git a/tgui/packages/tgui/interfaces/Colormate.js b/tgui/packages/tgui/interfaces/Colormate.js index f376547102..02810f2943 100644 --- a/tgui/packages/tgui/interfaces/Colormate.js +++ b/tgui/packages/tgui/interfaces/Colormate.js @@ -1,115 +1,120 @@ import { useBackend } from '../backend'; -import { Button, Flex, Icon, NoticeBox, NumberInput, Section, Tabs } from '../components'; +import { Button, Icon, NoticeBox, NumberInput, Section, Table, Tabs, Slider } from '../components'; import { Window } from '../layouts'; export const Colormate = (props, context) => { const { act, data } = useBackend(context); - const { matrixactive, temp } = data; + const { activemode, temp } = data; const item = data.item || []; return ( - {temp ? ( - {temp} - ) : (null)} - {Object.keys(item).length ? ( - <> - -
-
Item:
- -
-
-
Preview:
- -
-
-
+
+ {temp ? ( + {temp} + ) : (null)} + {Object.keys(item).length ? ( + <> + + +
+
Item:
+ +
+
+ +
+
Preview:
+ +
+
+
act('switch_modes', { - mode: "0", + mode: 1, })} > - Regular coloring + Tint coloring (Simple) act('switch_modes', { - mode: "1", + mode: 2, })} > - Matrixed coloring + HSV coloring (Normal) + + act('switch_modes', { + mode: 3, + })} > + Matrix coloring (Advanced) - {matrixactive ? ( - <> -
Coloring: {item.name}
- - - ) : ( - <> -
Coloring: {item.name}
- - - )} -
- - ) : ( -
+
Coloring: {item.name}
+ + +
+ + ) : (
No item inserted.
-
- )} + )} +
); }; -export const ColormateNoMatrix = (props, context) => { +export const ColormateTint = (props, context) => { const { act, data } = useBackend(context); return ( -
- - -
+