diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index c00e2688f1..e14c5d1624 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -111,6 +111,9 @@ The use of the : operator to override type safety checks is not allowed. You mus ### Type paths must begin with a / eg: `/datum/thing`, not `datum/thing` +### Type paths must be lowercase +eg: `/datum/thing/blue`, not `datum/thing/BLUE` or `datum/thing/Blue` + ### Datum type paths must began with "datum" In DM, this is optional, but omitting it makes finding definitions harder. @@ -240,6 +243,8 @@ This prevents nesting levels from getting deeper then they need to be. * Queries must never specify the database, be it in code, or in text files in the repo. +* Primary keys are inherently immutable and you must never do anything to change the primary key of a row or entity. This includes preserving auto increment numbers of rows when copying data to a table in a conversion script. No amount of bitching about gaps in ids or out of order ids will save you from this policy. + ### Mapping Standards * TGM Format & Map Merge * All new maps submitted to the repo through a pull request must be in TGM format (unless there is a valid reason present to have it in the default BYOND format.) This is done using the [Map Merge](https://github.com/tgstation/tgstation/wiki/Map-Merger) utility included in the repo to convert the file to TGM format. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 949f1c4c44..0000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,9 +0,0 @@ -[Round ID]: # (If you discovered this issue from playing tgstation hosted servers:) -[Round ID]: # (**INCLUDE THE ROUND ID**) -[Round ID]: # (It can be found in the Status panel or retrieved from https://atlantaned.space/statbus/round.php ! The round id let's us look up valuable information and logs for the round the bug happened.) - -[Testmerges]: # (If you believe the issue to be caused by a test merge [OOC tab -> Show Server Revision], report it in the pull request's comment section instead.) - -[Reproduction]: # (Explain your issue in detail, including the steps to reproduce it. Issues without proper reproduction steps or explanation are open to being ignored/closed by maintainers.) - -[For Admins]: # (Oddities induced by var-edits and other admin tools are not necessarily bugs. Verify that your issues occur under regular circumstances before reporting them.) \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..09f99f6c85 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,20 @@ +--- +name: Bug report +about: Create a report to help reproduce and fix the issue +--- + +## Round ID: + + + +## Testmerges: + + + +## Reproduction: + + + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..2c9eb90c72 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,7 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +Please be aware that feature discussions most often take place on the Citadel Station Discord and should not be requested here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7855fd5782..f204eb0a72 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,16 @@ -[Changelogs]: # (Your PR should contain a detailed changelog of notable changes, titled and categorized appropriately. This includes, new features, sprites, sounds, balance changes, admin tools, map edits, removals, big refactors, config changes, hosting changes and important fixes. An example changelog has been provided below for you to edit. If you need additional help, read https://github.com/tgstation/tgstation/wiki/Changelogs) + + -:cl: optional name here +## About The Pull Request + + + +## Why It's Good For The Game + + + +## Changelog +:cl: add: Added new things add: Added more things del: Removed old things @@ -19,4 +29,5 @@ admin: messed with admin stuff server: something server ops should know /:cl: -[why]: # (Please add a short description [two lines down] of why you think these changes would benefit the game. If you can't justify it in words, it might not be worth adding.) + + diff --git a/Dockerfile b/Dockerfile index 7cc479b926..a28b231eab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM tgstation/byond:512.1463 as base +FROM tgstation/byond:512.1467 as base FROM base as build_base diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm index ba291fc258..fd2e56a53f 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm @@ -272,7 +272,14 @@ /obj/machinery/light, /turf/open/floor/plasteel/freezer, /area/ruin/powered/seedvault) - +"Z" = ( +/obj/item/disk/design_disk/plant_disk, +/obj/machinery/autolathe{ + hacked = TRUE; + desc = "This autolathe seems to have its safety light off." + }, +/turf/open/floor/plasteel/freezer, +/area/ruin/powered/seedvault) (1,1,1) = {" a a @@ -375,7 +382,7 @@ h h u R -u +Z Q a a diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm index ef36495c58..e820b06f61 100644 --- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm @@ -2183,9 +2183,7 @@ /obj/effect/turf_decal/tile/purple{ dir = 8 }, -/turf/open/floor/plasteel/white{ - icon_state = "whitepurple" - }, +/turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) "fU" = ( /obj/effect/decal/cleanable/dirt, diff --git a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm index 99f7f19621..c64a73eada 100644 --- a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm +++ b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm @@ -509,7 +509,9 @@ /obj/machinery/button/door{ id = "a3"; name = "privacy button"; - pixel_y = -24 + normaldoorcontrol = 1; + pixel_y = -24; + specialfunctions = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, @@ -557,7 +559,9 @@ /obj/machinery/button/door{ id = "a4"; name = "privacy button"; - pixel_y = -24 + normaldoorcontrol = 1; + pixel_y = -24; + specialfunctions = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, @@ -605,7 +609,9 @@ /obj/machinery/button/door{ id = "a5"; name = "privacy button"; - pixel_y = -24 + normaldoorcontrol = 1; + pixel_y = -24; + specialfunctions = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, @@ -653,7 +659,9 @@ /obj/machinery/button/door{ id = "a6"; name = "privacy button"; - pixel_y = -24 + normaldoorcontrol = 1; + pixel_y = -24; + specialfunctions = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, @@ -1097,7 +1105,9 @@ /obj/machinery/button/door{ id = "a2"; name = "privacy button"; - pixel_y = 24 + normaldoorcontrol = 1; + pixel_y = 24; + specialfunctions = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, @@ -1159,7 +1169,9 @@ /obj/machinery/button/door{ id = "a1"; name = "privacy button"; - pixel_y = 24 + normaldoorcontrol = 1; + pixel_y = 24; + specialfunctions = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, @@ -1807,7 +1819,9 @@ /area/ruin/space/has_grav/hotel/bar) "fE" = ( /obj/machinery/vending/boozeomat{ - req_access_txt = "200" + extended_inventory = 1; + req_access_txt = "200"; + scan_id = 0 }, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ @@ -4496,7 +4510,6 @@ /turf/closed/wall, /area/ruin/space/has_grav/hotel/custodial) "me" = ( -/mob/living/simple_animal/bot/cleanbot, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -4507,6 +4520,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/mob/living/simple_animal/bot/cleanbot, /turf/open/floor/plasteel, /area/ruin/space/has_grav/hotel/custodial) "mf" = ( diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 053136a434..dcd2c47cb2 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -250,7 +250,9 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/cryopod, +/obj/machinery/cryopod{ + dir = 8 + }, /turf/open/floor/plasteel, /area/security/prison) "aaH" = ( @@ -319,6 +321,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/computer/cryopod{ + dir = 8; + pixel_x = 26 + }, /turf/open/floor/plasteel/cafeteria, /area/security/prison) "aaQ" = ( @@ -12182,11 +12188,12 @@ /obj/machinery/airalarm{ pixel_y = 23 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ +/obj/machinery/cryopod, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/carpet, -/area/crew_quarters/dorms) +/area/crew_quarters/cryopod) "aCe" = ( /obj/effect/landmark/xeno_spawn, /obj/item/bikehorn/rubberducky, @@ -12822,6 +12829,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/machinery/camera{ + c_tag = "Dormitory South"; + dir = 8 + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aDH" = ( @@ -12846,11 +12857,16 @@ /turf/closed/wall/r_wall, /area/ai_monitored/storage/eva) "aDK" = ( -/obj/machinery/door/airlock{ - name = "Cryo airlock" +/obj/machinery/door/airlock/public/glass{ + name = "Cryogenics " }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/firedoor, /turf/open/floor/plasteel, -/area/crew_quarters/dorms) +/area/crew_quarters/cryopod) "aDL" = ( /obj/structure/sink{ dir = 8; @@ -12865,6 +12881,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet) "aDM" = ( @@ -12894,7 +12913,7 @@ "aDQ" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/cable{ - icon_state = "2-4" + icon_state = "4-8" }, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet) @@ -13386,13 +13405,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aFe" = ( -/obj/machinery/camera{ - c_tag = "Dormitory South"; - dir = 4 - }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, @@ -13402,12 +13420,21 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aFf" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet) "aFg" = ( @@ -13423,6 +13450,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet) "aFi" = ( @@ -13435,7 +13465,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-8" + }, /turf/open/floor/plasteel/freezer, /area/crew_quarters/toilet) "aFj" = ( @@ -27869,8 +27901,8 @@ pixel_x = 30 }, /obj/machinery/light, -/mob/living/simple_animal/bot/cleanbot{ - name = "C.L.E.A.N." +/obj/machinery/computer/crew{ + dir = 1 }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) @@ -31564,7 +31596,7 @@ /area/medical/sleeper) "bwC" = ( /obj/machinery/computer/med_data{ - dir = 4 + dir = 3 }, /turf/open/floor/plasteel/white, /area/medical/sleeper) @@ -36632,14 +36664,11 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "bHT" = ( -/obj/machinery/door/poddoor/preopen{ - id = "medpriv1"; - name = "privacy door" - }, /obj/effect/spawner/structure/window, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/machinery/door/firedoor, /turf/open/floor/plating, /area/medical/medbay/central) "bHU" = ( @@ -37955,22 +37984,23 @@ /turf/open/floor/plating, /area/maintenance/aft) "bKM" = ( -/obj/machinery/vending/wallmed{ - pixel_y = 28 - }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/machinery/airalarm{ + pixel_y = 24 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bKN" = ( /obj/machinery/door/airlock/medical{ - name = "Patient Room 2"; + name = "Apothecary"; req_access_txt = "5" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/door/firedoor, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bKO" = ( @@ -38424,24 +38454,17 @@ /turf/open/floor/plating, /area/maintenance/aft) "bLU" = ( -/obj/structure/table, -/obj/item/folder/white, -/obj/item/clothing/neck/stethoscope, /obj/machinery/light/small{ dir = 8 }, +/obj/machinery/chem_dispenser, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bLV" = ( -/obj/structure/closet/secure_closet/personal/patient, -/obj/machinery/button/door{ - id = "medpriv1"; - name = "Privacy Shutters"; - pixel_y = -25 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/machinery/chem_heater, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bLW" = ( @@ -45999,6 +46022,9 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/delivery, +/obj/machinery/shower{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cek" = ( @@ -46007,6 +46033,9 @@ name = "engineering security door" }, /obj/effect/turf_decal/delivery, +/obj/machinery/shower{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cel" = ( @@ -56571,16 +56600,31 @@ /obj/structure/reagent_dispensers/keg/gargle, /turf/open/floor/wood, /area/maintenance/bar) +"dgz" = ( +/turf/closed/wall, +/area/crew_quarters/cryopod) "dqu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) +"dvc" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/crew_quarters/cryopod) "dvO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, /turf/closed/wall, /area/science/circuit) +"dzi" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/carpet, +/area/crew_quarters/cryopod) "dKP" = ( /turf/closed/wall, /area/maintenance/bar) @@ -56625,6 +56669,11 @@ /obj/structure/grille, /turf/open/space/basic, /area/space/nearstation) +"eVC" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/crew_quarters/cryopod) "eVL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/light_switch{ @@ -56664,8 +56713,14 @@ /turf/open/floor/plasteel/dark, /area/engine/engineering) "fvY" = ( +/obj/machinery/computer/cryopod{ + pixel_y = 26 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, /turf/open/floor/carpet, -/area/crew_quarters/dorms) +/area/crew_quarters/cryopod) "fxa" = ( /obj/structure/chair/wood/normal, /turf/open/floor/wood{ @@ -56684,6 +56739,16 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/science/circuit) +"fTg" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 2; + pixel_y = 24 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) "gbq" = ( /obj/structure/cable{ icon_state = "4-8" @@ -56696,6 +56761,12 @@ /obj/item/stack/sheet/glass/fifty, /turf/open/floor/plating, /area/maintenance/department/medical/morgue) +"gfD" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/carpet, +/area/crew_quarters/cryopod) "gjl" = ( /turf/closed/wall, /area/quartermaster/warehouse) @@ -56811,6 +56882,12 @@ /obj/item/pen, /turf/open/floor/plasteel/white, /area/science/circuit) +"ium" = ( +/mob/living/simple_animal/bot/cleanbot{ + name = "C.L.E.A.N." + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) "izv" = ( /obj/machinery/vending/clothing, /obj/machinery/light/small{ @@ -56835,6 +56912,14 @@ /obj/structure/reagent_dispensers/cooking_oil, /turf/open/floor/plasteel/showroomfloor, /area/crew_quarters/kitchen) +"iVU" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/crew_quarters/cryopod) "jbf" = ( /obj/structure/cable{ icon_state = "0-2" @@ -57233,11 +57318,8 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/computer/cryopod{ - pixel_y = -30 - }, /turf/open/floor/carpet, -/area/crew_quarters/dorms) +/area/crew_quarters/cryopod) "rcD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -57392,15 +57474,15 @@ }, /area/maintenance/bar) "tqg" = ( -/obj/machinery/light/small{ - dir = 8 - }, /obj/machinery/cryopod{ - icon_state = "cryopod-open"; - dir = 1 + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 2; + pixel_y = 24 }, /turf/open/floor/carpet, -/area/crew_quarters/dorms) +/area/crew_quarters/cryopod) "trb" = ( /obj/machinery/light{ dir = 4 @@ -57430,6 +57512,10 @@ /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar) +"tRe" = ( +/obj/machinery/chem_master, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) "tRF" = ( /obj/machinery/light/small{ dir = 8 @@ -57471,15 +57557,11 @@ /turf/open/floor/plasteel/dark, /area/engine/engineering) "ujF" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ +/obj/machinery/cryopod{ dir = 4 }, -/obj/machinery/cryopod{ - icon_state = "cryopod-open"; - dir = 1 - }, /turf/open/floor/carpet, -/area/crew_quarters/dorms) +/area/crew_quarters/cryopod) "uoB" = ( /obj/structure/table/reinforced, /obj/item/multitool, @@ -57567,6 +57649,11 @@ /obj/machinery/meter, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"vsM" = ( +/obj/machinery/power/apc/auto_name/south, +/obj/structure/cable, +/turf/open/floor/carpet, +/area/crew_quarters/cryopod) "vxh" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/maintenance{ @@ -57599,6 +57686,16 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel/white, /area/science/circuit) +"vHj" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Cryogenics " + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/crew_quarters/cryopod) "vHY" = ( /turf/open/floor/plating, /area/science/mixing) @@ -57616,6 +57713,12 @@ "wkN" = ( /turf/closed/wall, /area/science/circuit) +"woR" = ( +/obj/machinery/cryopod{ + dir = 1 + }, +/turf/open/floor/carpet, +/area/crew_quarters/cryopod) "wph" = ( /obj/docking_port/stationary{ area_type = /area/construction/mining/aux_base; @@ -87629,12 +87732,12 @@ arf arf arf arf -arf -arf -arf -arf -anF -ahn +dgz +dgz +dgz +dgz +dgz +dgz aJn aJn aJq @@ -87886,12 +87989,12 @@ atf arf aqa atf -arf +dgz tqg ujF -arf -anF -ahn +ujF +ujF +dgz aaa aJn aJq @@ -88143,12 +88246,12 @@ ath arf apY ath -arf +dgz fvY -ath -arf -anF -ahn +dvc +dzi +vsM +dgz aaa aJn aLY @@ -88400,12 +88503,12 @@ ath arf ayV ath -arf +dgz aCd qIw -arf -anF -ahn +gfD +woR +dgz aJw aJw aMh @@ -88657,12 +88760,12 @@ awo arf asd aAb -arf -asd +dgz +iVU aDK -arf -aoa -ahn +vHj +eVC +dgz aJv aKG aMg @@ -94085,7 +94188,7 @@ blm bmL boi bpw -bhh +ium bsx btX bvj @@ -95642,8 +95745,8 @@ bof bof bof bJE -bof -bof +bJE +bJE bNd bIJ bPo @@ -95899,7 +96002,7 @@ bof bGT bIo bof -bIo +tRe bLU bNd bII @@ -96413,7 +96516,7 @@ bof bGU bqQ bof -bCR +fTg bLV bNd bOm diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 3269d53588..c8e551b9fe 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -18876,6 +18876,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/machinery/computer/cryopod{ + pixel_y = 26 + }, /turf/open/floor/plasteel, /area/security/prison) "aMm" = ( @@ -74297,6 +74300,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/machinery/computer/cryopod{ + dir = 8; + pixel_x = 26 + }, /turf/open/floor/plasteel, /area/crew_quarters/locker) "cuC" = ( @@ -75916,10 +75923,6 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/computer/cryopod{ - pixel_x = 30 - }, -/obj/machinery/cryopod, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -75930,6 +75933,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/cryopod{ + dir = 8 + }, /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "cxs" = ( @@ -76886,7 +76892,6 @@ /obj/machinery/status_display{ pixel_x = 32 }, -/obj/machinery/cryopod, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -76897,6 +76902,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/cryopod{ + dir = 8 + }, /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "cyX" = ( @@ -77710,6 +77718,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/closet/wardrobe/white, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -78713,6 +78722,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/closet/wardrobe/mixed, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -78880,7 +78890,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/structure/closet/wardrobe/mixed, +/obj/machinery/cryopod{ + dir = 8 + }, /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "cCc" = ( @@ -79859,20 +79871,6 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/locker) -"cDB" = ( -/obj/structure/closet/wardrobe/white, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/crew_quarters/locker) "cDC" = ( /obj/effect/decal/cleanable/blood/old, /obj/effect/decal/cleanable/dirt{ @@ -80973,20 +80971,6 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) -"cFv" = ( -/obj/structure/closet/wardrobe/grey, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/crew_quarters/locker) "cFw" = ( /obj/item/clipboard{ pixel_x = -4; @@ -81692,7 +81676,6 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "cGM" = ( -/obj/item/twohanded/required/kirbyplants/random, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -81703,6 +81686,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/closet/wardrobe/grey, /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "cGN" = ( @@ -81738,9 +81722,6 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "cGP" = ( -/obj/structure/table, -/obj/item/paper_bin, -/obj/item/pen, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -81751,6 +81732,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/closet/wardrobe/black, /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "cGQ" = ( @@ -81785,20 +81767,6 @@ }, /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) -"cGS" = ( -/obj/structure/closet/wardrobe/black, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/crew_quarters/locker) "cGT" = ( /obj/machinery/button/door{ id = "Dorm1"; @@ -101846,6 +101814,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/effect/landmark/start/medical_doctor, /turf/open/floor/plasteel/white, /area/medical/genetics/cloning) "dpo" = ( @@ -126328,6 +126297,20 @@ /obj/machinery/atmospherics/pipe/simple/general/visible, /turf/closed/wall/r_wall, /area/science/mixing) +"eLw" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/chem_dispenser, +/turf/open/floor/plasteel/dark, +/area/medical/medbay/central) "eMD" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable/white{ @@ -126387,6 +126370,22 @@ }, /turf/open/floor/plasteel/white, /area/science/misc_lab) +"fhE" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical{ + name = "Apothecary" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/medical/medbay/central) "fno" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -126616,6 +126615,13 @@ /obj/item/restraints/handcuffs/fake, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) +"hSf" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/medical/medbay/central) "iaF" = ( /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, @@ -126625,6 +126631,18 @@ /obj/item/reagent_containers/glass/beaker, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) +"iwL" = ( +/obj/machinery/status_display{ + pixel_x = 32 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) "ixL" = ( /obj/structure/sign/warning/vacuum{ pixel_x = 32 @@ -126775,6 +126793,23 @@ }, /turf/open/floor/plasteel, /area/medical/morgue) +"jOE" = ( +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/chem_master, +/turf/open/floor/plasteel/dark, +/area/medical/medbay/central) "jRy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -126885,6 +126920,22 @@ }, /turf/open/floor/engine, /area/science/mixing) +"lzF" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/firealarm{ + pixel_y = 26 + }, +/turf/open/floor/plasteel/dark, +/area/medical/medbay/central) "lEl" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -126941,6 +126992,23 @@ }, /turf/open/floor/plating, /area/construction/mining/aux_base) +"lTx" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/table, +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/turf/open/floor/plasteel/dark, +/area/medical/medbay/central) "lXF" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -127291,6 +127359,16 @@ dir = 10 }, /area/science/misc_lab) +"tRT" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/chem_heater, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) "upk" = ( /obj/machinery/door/airlock/public/glass{ name = "Holodeck Access" @@ -127461,6 +127539,19 @@ }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) +"xKS" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/locker) "xMn" = ( /obj/structure/disposalpipe/trunk, /obj/machinery/disposal/bin, @@ -174209,9 +174300,9 @@ dfL dCM dEb cPy -dfL -dCM -dEb +cNz +fhE +hSf cPy dhs dMS @@ -174466,7 +174557,7 @@ dBo cSF dEc cPy -dBo +lzF cSF dEc cPy @@ -174980,8 +175071,8 @@ dBq dCN dEe cPy -dBq -dCN +lTx +cSK dEe cPy cMg @@ -175237,9 +175328,9 @@ dBr dCO dEf cPy -dBr +eLw dCO -dEf +tRT cPy dLo dMW @@ -175494,9 +175585,9 @@ dBs dCP dEg cPy -dBs +jOE dCP -dEg +iwL cPy dLp dMV @@ -177002,7 +177093,7 @@ cAu cBZ cDA cFt -cGM +xKS cxi cJg cKV @@ -177514,9 +177605,9 @@ cxr cyW cqd cCb -cDB -cFv -cGS +cCb +cCb +cCb cqd cJi cKX diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index c24244dcea..78ffa3881c 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -911,7 +911,9 @@ dir = 8; pixel_x = 24 }, -/obj/machinery/cryopod, +/obj/machinery/cryopod{ + dir = 8 + }, /turf/open/floor/plasteel, /area/security/prison) "acy" = ( @@ -1090,6 +1092,10 @@ pixel_y = 7 }, /obj/item/pen, +/obj/machinery/computer/cryopod{ + dir = 8; + pixel_x = 26 + }, /turf/open/floor/plasteel, /area/security/prison) "acN" = ( @@ -2682,10 +2688,13 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness/recreation) "afv" = ( -/obj/structure/easel, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness/recreation) "afw" = ( @@ -2714,6 +2723,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness/recreation) "afy" = ( @@ -3276,6 +3286,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "agx" = ( @@ -3720,6 +3731,7 @@ "ahj" = ( /obj/structure/chair, /obj/effect/landmark/start/assistant, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "ahk" = ( @@ -5184,9 +5196,7 @@ /obj/structure/chair/stool{ pixel_y = 8 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "ajS" = ( @@ -5974,10 +5984,6 @@ /turf/open/floor/plating, /area/maintenance/fore) "alf" = ( -/obj/machinery/cryopod{ - icon_state = "cryopod-open"; - dir = 1 - }, /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness/recreation) "alg" = ( @@ -6797,23 +6803,6 @@ }, /turf/open/floor/plating, /area/maintenance/fore) -"amv" = ( -/obj/machinery/cryopod{ - icon_state = "cryopod-open"; - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/crew_quarters/fitness/recreation) "amw" = ( /obj/structure/window/reinforced, /obj/machinery/door/window/eastright{ @@ -6826,11 +6815,16 @@ /area/crew_quarters/fitness/recreation) "amx" = ( /obj/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness/recreation) "amy" = ( /obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness/recreation) "amz" = ( @@ -64373,6 +64367,7 @@ /obj/structure/cable/yellow{ icon_state = "1-8" }, +/obj/effect/landmark/start/medical_doctor, /turf/open/floor/plasteel/white, /area/medical/patients_rooms/room_a) "cum" = ( @@ -65469,24 +65464,9 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "cwo" = ( -/obj/structure/table, -/obj/item/folder/white{ - pixel_x = 4; - pixel_y = -3 - }, -/obj/item/clothing/neck/stethoscope, /obj/machinery/light/small{ dir = 8 }, -/obj/machinery/power/apc{ - dir = 8; - name = "Patient Room B APC"; - areastring = "/area/medical/patients_rooms/room_b"; - pixel_x = -26 - }, -/obj/structure/cable/yellow{ - icon_state = "0-4" - }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, @@ -65499,31 +65479,24 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/chem_dispenser{ + layer = 2.7 + }, /turf/open/floor/plasteel/white, -/area/medical/patients_rooms/room_b) +/area/medical/medbay/aft) "cwp" = ( /obj/structure/chair/office/light{ dir = 8 }, -/obj/structure/cable/yellow{ - icon_state = "2-8" - }, -/obj/effect/landmark/start/medical_doctor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/vending/wallmed{ - pixel_y = 28 +/obj/machinery/airalarm{ + pixel_y = 23 }, /turf/open/floor/plasteel/white, -/area/medical/patients_rooms/room_b) +/area/medical/medbay/aft) "cwq" = ( -/obj/structure/closet/secure_closet/personal/patient, -/obj/machinery/button/door{ - id = "isolb"; - name = "Privacy Shutters"; - pixel_y = 25 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -65531,19 +65504,19 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/chem_heater{ + pixel_x = 4 + }, /turf/open/floor/plasteel/white, -/area/medical/patients_rooms/room_b) +/area/medical/medbay/aft) "cwr" = ( -/obj/effect/spawner/structure/window, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/poddoor/preopen{ - id = "isolb"; - name = "privacy shutters" - }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/firedoor, /turf/open/floor/plating, -/area/medical/patients_rooms/room_b) +/area/medical/medbay/aft) "cws" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -65968,65 +65941,53 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "cxe" = ( -/obj/structure/bed, -/obj/item/bedsheet/medical, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/chem_master, /turf/open/floor/plasteel/white, -/area/medical/patients_rooms/room_b) +/area/medical/medbay/aft) "cxf" = ( -/obj/structure/cable/yellow{ - icon_state = "1-4" - }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, /turf/open/floor/plasteel/white, -/area/medical/patients_rooms/room_b) +/area/medical/medbay/aft) "cxg" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ dir = 4 }, /turf/open/floor/plasteel/white, -/area/medical/patients_rooms/room_b) +/area/medical/medbay/aft) "cxh" = ( -/obj/machinery/door/airlock/medical{ - name = "Patient Room B"; - req_access_txt = "5" - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/door/airlock/medical/glass{ + name = "Apothecary"; + req_access_txt = "5" + }, +/obj/machinery/door/firedoor, /turf/open/floor/plasteel/white, -/area/medical/patients_rooms/room_b) +/area/medical/medbay/aft) "cxi" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -66039,9 +66000,6 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, /turf/open/floor/plasteel/white, /area/medical/medbay/aft) "cxk" = ( @@ -80731,9 +80689,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, -/obj/machinery/computer/cryopod{ - pixel_x = -30 - }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "dhq" = ( @@ -83268,6 +83223,12 @@ }, /turf/open/floor/plasteel/dark, /area/chapel/office) +"eHn" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/crew_quarters/cryopod) "eZe" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -83281,6 +83242,19 @@ /obj/structure/closet/firecloset, /turf/open/floor/plating, /area/engine/engineering) +"fpY" = ( +/turf/closed/wall, +/area/crew_quarters/cryopod) +"fzR" = ( +/obj/machinery/door/airlock{ + name = "Cryogenics" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "fDD" = ( /obj/machinery/light_switch{ pixel_y = -25 @@ -83302,6 +83276,12 @@ }, /turf/open/floor/plasteel/white, /area/science/circuit) +"gde" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "gnZ" = ( /obj/item/radio/intercom{ pixel_y = -30 @@ -83321,6 +83301,18 @@ /obj/item/clothing/suit/apron/chef, /turf/open/floor/plating, /area/maintenance/port/aft) +"gqO" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) "gra" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -83415,6 +83407,12 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/science/circuit) +"ivu" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "izu" = ( /obj/machinery/autolathe{ name = "public autolathe" @@ -83452,6 +83450,13 @@ }, /turf/open/floor/plating, /area/quartermaster/storage) +"jfW" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/recreation) "jwW" = ( /turf/closed/wall/mineral/plastitanium, /area/crew_quarters/fitness/recreation) @@ -83609,6 +83614,12 @@ }, /turf/open/floor/plasteel/white, /area/science/circuit) +"lzG" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "lGS" = ( /obj/docking_port/stationary/public_mining_dock, /turf/open/floor/plating, @@ -83643,6 +83654,13 @@ }, /turf/open/floor/plasteel/dark, /area/tcommsat/server) +"maM" = ( +/obj/machinery/cryopod, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "mjJ" = ( /obj/machinery/nuclearbomb/beer{ pixel_x = 2; @@ -83650,6 +83668,10 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"mnV" = ( +/obj/structure/lattice, +/turf/closed/wall, +/area/crew_quarters/cryopod) "mvj" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -83666,6 +83688,14 @@ }, /turf/open/floor/plasteel/white, /area/science/circuit) +"mAU" = ( +/obj/machinery/cryopod, +/obj/machinery/camera{ + c_tag = "Fitness Room - Fore"; + dir = 2 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "mWg" = ( /obj/structure/girder, /obj/structure/grille, @@ -83783,6 +83813,13 @@ /obj/structure/sign/poster/official/random, /turf/closed/wall, /area/hydroponics) +"oFq" = ( +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) +"oLq" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "oLW" = ( /obj/structure/table/reinforced, /obj/structure/cable/yellow{ @@ -83819,6 +83856,13 @@ /obj/item/pen, /turf/open/floor/plasteel/white, /area/science/circuit) +"oXn" = ( +/obj/machinery/computer/cryopod{ + dir = 4; + pixel_x = -26 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "oZg" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -83868,6 +83912,14 @@ }, /turf/open/floor/plating, /area/maintenance/starboard) +"pEv" = ( +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "pMX" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -83912,6 +83964,20 @@ }, /turf/open/floor/plasteel, /area/science/misc_lab) +"qvY" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/recreation) "qBh" = ( /obj/structure/table, /obj/item/paicard, @@ -83935,6 +84001,11 @@ /obj/item/storage/photo_album, /turf/open/floor/engine/cult, /area/library) +"qLE" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/crew_quarters/cryopod) "qRM" = ( /obj/machinery/camera{ c_tag = "Research Division Circuitry Lab"; @@ -83952,6 +84023,13 @@ }, /turf/open/floor/wood, /area/library) +"qXt" = ( +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "rzX" = ( /obj/structure/chair/office/light{ dir = 1; @@ -83998,10 +84076,23 @@ }, /turf/open/floor/plasteel, /area/science/circuit) +"sdw" = ( +/turf/open/space/basic, +/area/space/nearstation) "siF" = ( /obj/structure/grille, /turf/open/floor/plating/airless, /area/space/nearstation) +"soh" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) "sFv" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -84043,6 +84134,23 @@ "sJW" = ( /turf/closed/wall/mineral/plastitanium, /area/engine/break_room) +"sME" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/cryopod, +/obj/machinery/light_switch{ + pixel_x = -26 + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) +"tap" = ( +/obj/machinery/power/apc/auto_name/east, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "tsx" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -84091,6 +84199,10 @@ /obj/machinery/air_sensor/atmos/toxins_mixing_tank, /turf/open/floor/engine/vacuum, /area/science/mixing) +"ugc" = ( +/obj/machinery/cryopod, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "upN" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -84182,6 +84294,23 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) +"vxG" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/fitness/recreation) "vyx" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 4 @@ -84193,6 +84322,11 @@ /obj/structure/lattice, /turf/open/space/basic, /area/space) +"wdu" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/floor/plating, +/area/space/nearstation) "wgw" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, @@ -84221,6 +84355,12 @@ }, /turf/open/floor/plating, /area/engine/atmos) +"wzH" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/crew_quarters/cryopod) "wFH" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -84254,6 +84394,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/science/misc_lab) +"xeC" = ( +/obj/machinery/light, +/turf/open/floor/plasteel/dark, +/area/crew_quarters/cryopod) "xkG" = ( /obj/item/integrated_electronics/wirer, /obj/structure/table/reinforced, @@ -105582,8 +105726,8 @@ css dux dux dux -dux -dux +cxU +cxU cxU cyO czP @@ -119110,11 +119254,11 @@ aaa aaa aaa aai -aaa -aaa -aaf -aaa -acP +fpY +fpY +mnV +fpY +fpY acP ags acP @@ -119122,7 +119266,7 @@ acP acP acP alf -amv +afA acP aoS acP @@ -119367,11 +119511,11 @@ aaa aaa aaa aag -aaa -aaa -aaf -aaa -acQ +fpY +sME +oXn +qXt +qLE aft agt ahf @@ -119623,17 +119767,17 @@ aaa aaa aaa aaa -aag -aaa -aaa -aaf -aaa -acQ +wdu +qLE +ugc +oFq +oLq +wzH afu -agu -ahg -ahg -ahg +soh +aiX +aiX +aiX ajR ahg ahg @@ -119881,13 +120025,13 @@ aaa aaa aaa aag -aaa -aaa -aaf -aaa -acQ +fpY +ugc +ivu +gde +fzR afv -agu +gqO ahh ahh aiR @@ -120138,11 +120282,11 @@ aaa aaa aaa aai -aaa -aaa -aaf -aaf -acP +fpY +mAU +lzG +xeC +fpY acP agv ahh @@ -120395,11 +120539,11 @@ aaa aaa aaa aag -aaa -aaa -aaf -aaa -acQ +fpY +ugc +lzG +oFq +qLE afw agu ahi @@ -120652,18 +120796,18 @@ aaa aaa aaa aag -aaa -aaa -aaf -aaa -acQ +qLE +maM +tap +pEv +eHn afx agw ahj -ahX -afA -ajU -afA +jfW +qvY +vxG +qvY amy anI aoX @@ -120909,11 +121053,11 @@ aaa aaa aaf aai -aaf -aaf -aaf -aaa -acQ +fpY +fpY +fpY +fpY +fpY afy agx ahk @@ -121168,7 +121312,7 @@ aaf aaa aaa aaa -aaf +sdw aaa acP acP diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index 4799c57bcd..de42e1ac63 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -2639,6 +2639,13 @@ }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) +"il" = ( +/obj/machinery/computer/cryopod{ + dir = 4; + pixel_x = -26 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) "ir" = ( /obj/structure/stone_tile/slab/cracked{ dir = 5 @@ -3534,6 +3541,12 @@ }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) +"Po" = ( +/obj/machinery/cryopod{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) "Uq" = ( /obj/docking_port/stationary{ area_type = /area/lavaland/surface/outdoors; @@ -9244,8 +9257,8 @@ ap ar ar aq -az -az +Po +il az az az diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 19df3bca53..dbb26f8808 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -13798,7 +13798,6 @@ /area/crew_quarters/dorms) "axG" = ( /obj/effect/turf_decal/bot, -/obj/machinery/cryopod, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -13809,6 +13808,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/cryopod{ + dir = 8 + }, /turf/open/floor/plasteel/dark, /area/crew_quarters/dorms) "axH" = ( @@ -16798,6 +16800,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aDG" = ( +/obj/effect/landmark/event_spawn, /turf/open/floor/wood, /area/crew_quarters/dorms) "aDH" = ( @@ -36561,10 +36564,6 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bxJ" = ( -/obj/effect/landmark/event_spawn, -/obj/machinery/computer/cryopod{ - pixel_x = 30 - }, /obj/machinery/light{ dir = 4; light_color = "#e8eaff" @@ -36573,6 +36572,13 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/machinery/computer/cryopod{ + dir = 8; + pixel_x = 26 + }, +/obj/machinery/cryopod{ + dir = 8 + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "bxK" = ( diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 50a2df3ec1..f9792a736e 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -8707,7 +8707,9 @@ /obj/machinery/computer/cryopod{ pixel_y = 30 }, -/obj/machinery/cryopod, +/obj/machinery/cryopod{ + dir = 8 + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "avm" = ( @@ -44323,7 +44325,9 @@ dir = 1; pixel_y = -22 }, -/obj/structure/closet/radiation, +/obj/machinery/shower{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/break_room) "bWF" = ( @@ -44350,7 +44354,10 @@ dir = 6 }, /obj/effect/turf_decal/delivery, -/obj/structure/closet/radiation, +/obj/machinery/shower{ + dir = 8; + pixel_y = -4 + }, /turf/open/floor/plasteel, /area/engine/break_room) "bWH" = ( @@ -44930,6 +44937,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/structure/closet/radiation, /turf/open/floor/plasteel, /area/engine/engineering) "bYn" = ( @@ -44954,6 +44962,7 @@ /obj/machinery/light{ dir = 4 }, +/obj/structure/closet/radiation, /turf/open/floor/plasteel, /area/engine/engineering) "bYp" = ( @@ -53537,6 +53546,12 @@ /obj/structure/chair/office/dark, /turf/open/floor/wood, /area/lawoffice) +"epj" = ( +/obj/machinery/cryopod{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/dorms) "epJ" = ( /obj/structure/sign/poster/contraband/random{ pixel_y = 32 @@ -53769,6 +53784,13 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"eSB" = ( +/obj/machinery/computer/cryopod{ + dir = 1; + pixel_y = -26 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "eSL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/item/beacon, @@ -54140,7 +54162,9 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/cryopod, +/obj/machinery/cryopod{ + dir = 8 + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "fIN" = ( @@ -55936,7 +55960,9 @@ /turf/open/floor/plating, /area/maintenance/department/science) "jXF" = ( -/obj/machinery/cryopod, +/obj/machinery/cryopod{ + dir = 1 + }, /turf/open/floor/plasteel/dark, /area/security/prison) "jXV" = ( @@ -82772,7 +82798,7 @@ aeU afo afG aeU -aeU +eSB agy agL agZ @@ -102071,7 +102097,7 @@ apX apX avl fIu -dbi +epj aIh azA dbi diff --git a/_maps/map_files/generic/City_of_Cogs.dmm b/_maps/map_files/generic/City_of_Cogs.dmm index e67a829221..889abe66c3 100644 --- a/_maps/map_files/generic/City_of_Cogs.dmm +++ b/_maps/map_files/generic/City_of_Cogs.dmm @@ -212,11 +212,8 @@ /turf/open/indestructible/reebe_void, /area/reebe) "aR" = ( -/obj/effect/clockwork/servant_blocker{ - dir = 1 - }, -/obj/structure/lattice/clockwork, -/turf/open/indestructible/reebe_void, +/obj/effect/landmark/city_of_cogs, +/turf/open/indestructible/clock_spawn_room, /area/reebe/city_of_cogs) "aS" = ( /obj/effect/clockwork/servant_blocker{ @@ -242,17 +239,20 @@ /turf/open/indestructible/reebe_void/spawning/lattices, /area/reebe) "aX" = ( -/obj/effect/landmark/city_of_cogs, +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/belligerent_eye, /turf/open/indestructible/clock_spawn_room, /area/reebe/city_of_cogs) "aY" = ( -/obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/belligerent_eye/blind_eye, -/turf/open/indestructible/clock_spawn_room, -/area/reebe/city_of_cogs) +/obj/effect/clockwork/servant_blocker{ + dir = 1 + }, +/obj/structure/lattice/clockwork, +/turf/open/indestructible/reebe_void, +/area/reebe) "aZ" = ( /obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/belligerent_eye, +/obj/item/clockwork/component/belligerent_eye/blind_eye, /turf/open/indestructible/clock_spawn_room, /area/reebe/city_of_cogs) "ba" = ( @@ -262,32 +262,32 @@ /area/reebe/city_of_cogs) "bb" = ( /obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/replicant_alloy, +/obj/item/clockwork/component/geis_capacitor, /turf/open/indestructible/clock_spawn_room, /area/reebe/city_of_cogs) "bc" = ( /obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment, +/obj/item/clockwork/component/geis_capacitor/antennae, /turf/open/indestructible/clock_spawn_room, /area/reebe/city_of_cogs) "bd" = ( /obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/replicant_alloy/replication_plate, +/obj/item/clockwork/component/geis_capacitor/fallen_armor, /turf/open/indestructible/clock_spawn_room, /area/reebe/city_of_cogs) "be" = ( /obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/geis_capacitor/antennae, +/obj/item/clockwork/component/hierophant_ansible, /turf/open/indestructible/clock_spawn_room, /area/reebe/city_of_cogs) "bf" = ( /obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/geis_capacitor/fallen_armor, +/obj/item/clockwork/component/hierophant_ansible/obelisk, /turf/open/indestructible/clock_spawn_room, /area/reebe/city_of_cogs) "bg" = ( /obj/structure/table/reinforced/brass, -/obj/item/clockwork/component/geis_capacitor, +/obj/item/clockwork/component/replicant_alloy, /turf/open/indestructible/clock_spawn_room, /area/reebe/city_of_cogs) "bh" = ( @@ -304,6 +304,51 @@ /obj/structure/destructible/clockwork/eminence_spire, /turf/open/floor/clockwork/reebe, /area/reebe/city_of_cogs) +"bk" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/replicant_alloy/replication_plate, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bl" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bm" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/vanguard_cogwheel, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bn" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bo" = ( +/obj/structure/window/reinforced/clockwork/fulltile, +/obj/structure/grille/ratvar, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bp" = ( +/obj/structure/window/reinforced/clockwork/fulltile, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bu" = ( +/obj/structure/table/reinforced/brass, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bw" = ( +/obj/structure/chair/brass{ + dir = 8 + }, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bx" = ( +/obj/structure/chair/brass{ + dir = 4 + }, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) (1,1,1) = {" aa @@ -26909,7 +26954,7 @@ ab ab ab ab -aa +ab aa aa aa @@ -27166,8 +27211,8 @@ ab ab ab ab -aa -aa +ab +ab aa aa aa @@ -27423,9 +27468,9 @@ ab ab ab ab -aa -aa -aa +ab +ab +ab aa aa aa @@ -27680,10 +27725,10 @@ ab ab ab ab -aa -aa -aa -aa +ab +ab +ab +ab aa aa aa @@ -27923,25 +27968,25 @@ ab ab ab ab +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae ab ab ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa aa aa aa @@ -28166,40 +28211,40 @@ ab ab ab ab -ab -ab aF +aF +aY +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ah +ah +bo +bo +bo +bo +bo +bo +bo +ah +ah +ae +ae +ae ab ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -28424,39 +28469,39 @@ aF aF aF aF -aF -aF -ae -ae -ae +aG +aS +ah +ah +ah +ah +ah +ah +ah +ah +ah +ah +ah +ah +ah +aT +aT +aT +aT +aT +aT +aT +aT +aT +ah +ah +ah ae ae ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -28682,38 +28727,38 @@ aG aG aG aG -aR -ah -ah -ah -ah -ah -ae -ae -ae -ae -ae -ae -ae +aS +bu +bu +bu +bu +bu +bu +bu +bu +bu +bu +bu +bu +aU +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +aX +bo +ag ae ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -28940,37 +28985,37 @@ aj aj aj aS +bw +bw +bw +bw +bw +bw +bw +bw +bw +bw +bw +bw +aU aT aT +aR +aT +aR +aT +aR aT aT -ah -ah -ai -ai -ai -ai -ai -ah -ah +bo +aZ +bo +ag ae ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -29201,7 +29246,6 @@ aT aT aT aT -ah aT aT aT @@ -29209,15 +29253,22 @@ aT aT aT aT -ah +aT +bo +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +ba +bo ag ae -ab -ab -ab -ab -ab -ae bi ab ab @@ -29339,12 +29390,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa "} (114,1,1) = {" aa @@ -29458,7 +29503,6 @@ aT aT aT aT -aU aT aT aT @@ -29466,15 +29510,22 @@ aT aT aT aT -ah -ah -ah -ab -ab -ab -ab -ab -ab +aT +aV +aT +aT +aR +aT +aR +aT +aR +aT +aT +bo +bb +bo +ag +ae ab ae ac @@ -29596,12 +29647,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa "} (115,1,1) = {" aa @@ -29715,33 +29760,33 @@ aT aT aT aT -aU aT aT -aX -aX -aX aT aT -ai -aY -ai +aT +aT +aT +aT +bo +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +bc +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -29972,33 +30017,33 @@ aT aT aT aT -aV aT aT -aX -aX -aX aT aT -ai -aZ -ai +aT +aT +aT +aT +aU +aT +aT +aR +aT +aR +aT +aR +aT +aT +bo +bd +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -30229,33 +30274,33 @@ aT aT aT aT +aT +aT +aT +aT +aT +aT +aT +aT aU aT aT -aX -aX -aX aT aT -ai -ba -ai +aT +aT +aT +aT +aT +bo +be +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -30486,7 +30531,17 @@ aT aT aT aT -aU +aT +aT +aT +aT +aT +aT +bp +bp +ah +aT +aT aT aT aT @@ -30497,22 +30552,12 @@ aT ah ah ah +ae +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -30743,33 +30788,33 @@ aT aT aT aT +aT +aT +aT +aT +aT +aT +bp +bg ah -aT -aT -aT -aT -aT -aT -aT ah -ag +bo +bo +bo +bo +bo +bo +bo +ah +ah +ae +ae ae ab ab ab ab ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -31000,33 +31045,33 @@ aT aT aT aT +aT +aT +aT +aT +aT +aT +bp +bp +ah +aT +aT +aT +aT +aT +aT +aT +aT +aT ah ah -aU -aU -aV -aU -aU ah -ah -ag +ae ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -31257,7 +31302,6 @@ aT aT aT aT -ah aT aT aT @@ -31265,25 +31309,26 @@ aT aT aT aT -ah +aT +aU +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +bf +bo ag ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -31514,33 +31559,33 @@ aT aT aT aT +aT +aT +aT +aT +aT +aT +aT +aT aU aT aT +aR +aT +aR +aT +aR aT aT -aT -aT -aT -ah -ah -ah +bo +bg +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -31771,33 +31816,33 @@ aT aT aT aT -aU aT aT -aX -aX -aX +aT +aT +aT +aT aT aT ai -bb -ai +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +bk +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -32028,33 +32073,33 @@ aT aT aT aT +aT +aT +aT +aT +aT +aT +aT +aT aV aT aT -aX -aX -aX +aR +aT +aR +aT +aR aT aT -ai -bc -ai +bo +bl +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -32285,33 +32330,33 @@ aT aT aT aT -aU aT aT -aX -aX -aX +aT +aT +aT +aT aT aT ai -bd -ai +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +bm +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -32542,33 +32587,33 @@ aT aT aT aT +aT +aT +aT +aT +aT +aT +aT +aT aU aT aT +aR +aT +aR +aT +aR aT aT -aT -aT -aT -ah -ah -ah +bo +bn +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -32799,7 +32844,6 @@ aT aT aT aT -ah aT aT aT @@ -32807,25 +32851,26 @@ aT aT aT aT -ah +aT +aU +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +aX +bo ag ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -33056,33 +33101,33 @@ aT aT aT aT +aT +aT +aT +aT +aT +aT +bp +bp +ah +aT +aT +aT +aT +aT +aT +aT +aT +aT ah ah -aU -aU -aV -aU -aU ah -ah -ag +ae ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -33313,16 +33358,25 @@ aT aT aT aT +aT +aT +aT +aT +aT +aT +bp +bk +ah +ah +bo +bo +bo +bo +bo +bo +bo ah -aT -aT -aT -aT -aT -aT -aT ah -ag ae ab ab @@ -33331,15 +33385,6 @@ ab ab ab ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -33570,7 +33615,17 @@ aT aT aT aT -aU +aT +aT +aT +aT +aT +aT +bp +bp +ah +aT +aT aT aT aT @@ -33581,22 +33636,12 @@ aT ah ah ah +ae +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -33827,33 +33872,33 @@ aT aT aT aT +aT +aT +aT +aT +aT +aT +aT +aT aU aT aT -aX -aX -aX aT aT -ai -be -ai +aT +aT +aT +aT +aT +bo +aZ +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -34084,33 +34129,33 @@ aT aT aT aT -aV aT aT -aX -aX -aX aT aT -ai -bf -ai +aT +aT +aT +aT +aU +aT +aT +aR +aT +aR +aT +aR +aT +aT +bo +ba +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -34341,33 +34386,33 @@ aT aT aT aT -aU aT aT -aX -aX -aX aT aT -ai -bg -ai +aT +aT +aT +aT +bo +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +bb +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -34598,7 +34643,6 @@ aT aT aT aT -aU aT aT aT @@ -34606,25 +34650,26 @@ aT aT aT aT -ah -ah -ah +aT +aV +aT +aT +aR +aT +aR +aT +aR +aT +aT +bo +bc +bo +ag +ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -34855,7 +34900,6 @@ aT aT aT aT -ah aT aT aT @@ -34863,25 +34907,26 @@ aT aT aT aT -ah +aT +bo +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +bd +bo ag ae ab ab ab ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -35108,37 +35153,37 @@ aj aj aj aS +bx +bx +bx +bx +bx +bx +bx +bx +bx +bx +bx +bx +aU aT aT +aR +aT +aR +aT +aR aT aT -ah -ah -ai -ai -ai -ai -ai -ah -ah +bo +be +bo +ag ae ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -35364,38 +35409,38 @@ aG aG aG aG -aR -ah -ah -ah -ah -ah -ae -ae -ae -ae -ae -ae -ae +aS +bu +bu +bu +bu +bu +bu +bu +bu +bu +bu +bu +bu +aU +aT +aT +aT +aT +aT +aT +aT +aT +aT +bo +bf +bo +ag ae ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -35620,39 +35665,39 @@ aF aF aF aF -aF -aF -ae -ae -ae +aG +aS +ah +ah +ah +ah +ah +ah +ah +ah +ah +ah +ah +ah +ah +aT +aT +aT +aT +aT +aT +aT +aT +aT +ah +ah +ah ae ae ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -35878,7 +35923,31 @@ ab ab ab ab -aF +aY +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ah +ah +bo +bo +bo +bo +bo +bo +bo +ah +ah +ae ab ab ab @@ -35886,30 +35955,6 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa -aa -aa -aa -aa aa aa aa @@ -36147,12 +36192,18 @@ ab ab ab ab -ab -ab -ab -ab -ab -ab +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae +ae ae ab ab @@ -36160,12 +36211,6 @@ ab ab ab ab -ab -aa -aa -aa -aa -aa aa aa aa @@ -36410,18 +36455,18 @@ ab ab ab ab -ac -ac ab ab ab ab ab ab -aa -aa -aa -aa +ab +ab +ab +ab +ab +ab aa aa aa @@ -36667,17 +36712,17 @@ ab ab ab ab -ac -bh -ae ab ab ab ab ab -aa -aa -aa +ab +ab +ab +ab +ab +ab aa aa aa @@ -36932,8 +36977,8 @@ ab ab ab ab -aa -aa +ab +ab aa aa aa @@ -37189,7 +37234,7 @@ ab ab ab ab -aa +ab aa aa aa @@ -37438,9 +37483,9 @@ ab ab ab ab -ab -ab -ab +ac +bh +ae ab ab ab diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index aea7d42be6..4ed099d9e2 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -121,3 +121,4 @@ #define ORGAN_SLOT_BRAIN_ANTIDROP "brain_antidrop" #define ORGAN_SLOT_BRAIN_ANTISTUN "brain_antistun" #define ORGAN_SLOT_TAIL "tail" +#define ORGAN_SLOT_PENIS "penis" diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index e04639baf2..fb42bc46c0 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -71,6 +71,7 @@ #define ADMIN_PUNISHMENT_ROD "Immovable Rod" #define ADMIN_PUNISHMENT_SUPPLYPOD "Supply Pod" #define ADMIN_PUNISHMENT_MAZING "Puzzle" +#define ADMIN_PUNISHMENT_PIE "Cream Pie" #define AHELP_ACTIVE 1 #define AHELP_CLOSED 2 diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 4c454aa61a..e35defd485 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -35,3 +35,8 @@ //Overthrow time to update heads obj #define OBJECTIVE_UPDATING_TIME 300 + +//Gangshit +#define NOT_DOMINATING -1 +#define MAX_LEADERS_GANG 3 +#define INITIAL_DOM_ATTEMPTS 3 diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index b5ba44d956..928837979c 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -1,8 +1,5 @@ //LISTMOS //indices of values in gas lists. -#define MOLES 1 -#define ARCHIVE 2 -#define GAS_META 3 #define META_GAS_SPECIFIC_HEAT 1 #define META_GAS_NAME 2 #define META_GAS_MOLES_VISIBLE 3 @@ -242,20 +239,25 @@ //HELPERS #define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) - -#define ADD_GAS(gas_id, out_list)\ - var/list/tmp_gaslist = GLOB.gaslist_cache[gas_id]; out_list[gas_id] = tmp_gaslist.Copy(); - -#define ASSERT_GAS(gas_id, gas_mixture) if (!gas_mixture.gases[gas_id]) { ADD_GAS(gas_id, gas_mixture.gases) }; - +#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that + once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ //prefer this to gas_mixture/total_moles in performance critical areas #define TOTAL_MOLES(cached_gases, out_var)\ out_var = 0;\ for(var/total_moles_id in cached_gases){\ - out_var += cached_gases[total_moles_id][MOLES];\ + out_var += cached_gases[total_moles_id];\ } +//Unomos - So for whatever reason, garbage collection actually drastically decreases the cost of atmos later in the round. Turning this into a define yields massively improved performance. +#define GAS_GARBAGE_COLLECT(GASGASGAS)\ + var/list/CACHE_GAS = GASGASGAS;\ + for(var/id in CACHE_GAS){\ + if(QUANTIZE(CACHE_GAS[id]) <= 0)\ + CACHE_GAS -= id;\ + } + +#define ARCHIVE_TEMPERATURE(gas) gas.temperature_archived = gas.temperature GLOBAL_LIST_INIT(pipe_paint_colors, list( "amethyst" = rgb(130,43,255), //supplymain diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index ef14dbcaa3..2abe0db04e 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -33,8 +33,8 @@ #define BALLS_VOLUME_MULT 1 #define BALLS_SIZE_MIN 1 -#define BALLS_SIZE_DEF 3 -#define BALLS_SIZE_MAX 7 +#define BALLS_SIZE_DEF 2 +#define BALLS_SIZE_MAX 3 #define BALLS_SACK_SIZE_MIN 1 #define BALLS_SACK_SIZE_DEF 8 @@ -76,6 +76,9 @@ #define MILK_RATE_MULT 1 #define MILK_EFFICIENCY 1 +#define AROUSAL_MINIMUM_DEFAULT 0 +#define AROUSAL_MAXIMUM_DEFAULT 100 +#define AROUSAL_START_VALUE 1 //Individual logging define #define INDIVIDUAL_LOOC_LOG "LOOC log" @@ -95,8 +98,11 @@ #define NOAROUSAL 37 //Stops all arousal effects #define NOGENITALS 38 //Cannot create, use, or otherwise have genitals #define MATRIXED 39 //if icon is color matrix'd +#define SKINTONE 40 //uses skin tones //Citadel istypes +#define isgenital(A) (istype(A, /obj/item/organ/genital)) + #define isborer(A) (istype(A, /mob/living/simple_animal/borer)) #define isipcperson(A) (is_species(A, /datum/species/ipc)) #define ismammal(A) (is_species(A, /datum/species/mammal)) diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm index 070b92acc7..47b00e67f7 100644 --- a/code/__DEFINES/clockcult.dm +++ b/code/__DEFINES/clockcult.dm @@ -28,9 +28,9 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us #define SCRIPTURE_APPLICATION "Application" //Various costs related to power. -#define MAX_CLOCKWORK_POWER 50000 //The max power in W that the cult can stockpile -#define SCRIPT_UNLOCK_THRESHOLD 25000 //Scripts will unlock if the total power reaches this amount -#define APPLICATION_UNLOCK_THRESHOLD 40000 //Applications will unlock if the total powre reaches this amount +#define MAX_CLOCKWORK_POWER 80000 //The max power in W that the cult can stockpile +#define SCRIPT_UNLOCK_THRESHOLD 35000 //Scripts will unlock if the total power reaches this amount +#define APPLICATION_UNLOCK_THRESHOLD 50000 //Applications will unlock if the total powre reaches this amount #define ABSCOND_ABDUCTION_COST 95 diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index 4811d0041f..de9c7af221 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -53,4 +53,5 @@ #define COLOR_ASSEMBLY_GREEN "#44843C" #define COLOR_ASSEMBLY_LBLUE "#5D99BE" #define COLOR_ASSEMBLY_BLUE "#38559E" -#define COLOR_ASSEMBLY_PURPLE "#6F6192" \ No newline at end of file +#define COLOR_ASSEMBLY_PURPLE "#6F6192" +#define COLOR_ASSEMBLY_PINK "#ff4adc" \ No newline at end of file diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 15e8048926..7cab82149d 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -79,6 +79,8 @@ #define ATTACK_EFFECT_SMASH "smash" #define ATTACK_EFFECT_CLAW "claw" #define ATTACK_EFFECT_DISARM "disarm" +#define ATTACK_EFFECT_ASS_SLAP "ass_slap" +#define ATTACK_EFFECT_FACE_SLAP "face_slap" #define ATTACK_EFFECT_BITE "bite" #define ATTACK_EFFECT_MECHFIRE "mech_fire" #define ATTACK_EFFECT_MECHTOXIN "mech_toxin" diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 3338fc1cda..dbe8cfbb62 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -142,8 +142,9 @@ #define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) // /obj signals -#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled) -#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value) +#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled) +#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag) +#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value) // /obj/item signals #define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index aab49720f6..aa9c5cf34e 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -102,6 +102,8 @@ #define CAT_SANDWICH "Sandwiches" #define CAT_SOUP "Soups" #define CAT_SPAGHETTI "Spaghettis" +#define CAT_SUSHI "Fish" +#define CAT_ICE "Frozen" #define RCD_FLOORWALL 1 #define RCD_AIRLOCK 2 diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index ad9aef5a8b..60148e0388 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -56,9 +56,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define FLYING (1<<1) #define VENTCRAWLING (1<<2) -// Flags for reagents -#define REAGENT_NOREACT (1<<0) - //Fire and Acid stuff, for resistance_flags #define LAVA_PROOF (1<<0) #define FIRE_PROOF (1<<1) //100% immune to fire damage (but not necessarily to lava or heat) diff --git a/code/__DEFINES/footsteps.dm b/code/__DEFINES/footsteps.dm index e66d518644..ef96b83cc8 100644 --- a/code/__DEFINES/footsteps.dm +++ b/code/__DEFINES/footsteps.dm @@ -6,6 +6,14 @@ #define FOOTSTEP_GRASS "grass" #define FOOTSTEP_WATER "water" #define FOOTSTEP_LAVA "lava" +//barefoot sounds +#define FOOTSTEP_WOOD_BAREFOOT "woodbarefoot" +#define FOOTSTEP_WOOD_CLAW "woodclaw" +#define FOOTSTEP_HARD_BAREFOOT "hardbarefoot" +#define FOOTSTEP_HARD_CLAW "hardclaw" +#define FOOTSTEP_CARPET_BAREFOOT "carpetbarefoot" +//misc footstep sounds +#define FOOTSTEP_GENERIC_HEAVY "heavy" /* @@ -63,4 +71,104 @@ GLOBAL_LIST_INIT(footstep, list( 'sound/effects/footstep/lava1.ogg', 'sound/effects/footstep/lava2.ogg', 'sound/effects/footstep/lava3.ogg'), 100, 0), -)) \ No newline at end of file +)) + +//bare footsteps lists +GLOBAL_LIST_INIT(barefootstep, list( + FOOTSTEP_WOOD_BAREFOOT = list(list( + 'sound/effects/footstep/woodbarefoot1.ogg', + 'sound/effects/footstep/woodbarefoot2.ogg', + 'sound/effects/footstep/woodbarefoot3.ogg', + 'sound/effects/footstep/woodbarefoot4.ogg', + 'sound/effects/footstep/woodbarefoot5.ogg'), 80, -1), + FOOTSTEP_HARD_BAREFOOT = list(list( + 'sound/effects/footstep/hardbarefoot1.ogg', + 'sound/effects/footstep/hardbarefoot2.ogg', + 'sound/effects/footstep/hardbarefoot3.ogg', + 'sound/effects/footstep/hardbarefoot4.ogg', + 'sound/effects/footstep/hardbarefoot5.ogg'), 80, -1), + FOOTSTEP_CARPET_BAREFOOT = list(list( + 'sound/effects/footstep/carpetbarefoot1.ogg', + 'sound/effects/footstep/carpetbarefoot2.ogg', + 'sound/effects/footstep/carpetbarefoot3.ogg', + 'sound/effects/footstep/carpetbarefoot4.ogg', + 'sound/effects/footstep/carpetbarefoot5.ogg'), 75, -2), + FOOTSTEP_SAND = list(list( + 'sound/effects/footstep/asteroid1.ogg', + 'sound/effects/footstep/asteroid2.ogg', + 'sound/effects/footstep/asteroid3.ogg', + 'sound/effects/footstep/asteroid4.ogg', + 'sound/effects/footstep/asteroid5.ogg'), 75, 0), + FOOTSTEP_GRASS = list(list( + 'sound/effects/footstep/grass1.ogg', + 'sound/effects/footstep/grass2.ogg', + 'sound/effects/footstep/grass3.ogg', + 'sound/effects/footstep/grass4.ogg'), 75, 0), + FOOTSTEP_WATER = list(list( + 'sound/effects/footstep/water1.ogg', + 'sound/effects/footstep/water2.ogg', + 'sound/effects/footstep/water3.ogg', + 'sound/effects/footstep/water4.ogg'), 100, 1), + FOOTSTEP_LAVA = list(list( + 'sound/effects/footstep/lava1.ogg', + 'sound/effects/footstep/lava2.ogg', + 'sound/effects/footstep/lava3.ogg'), 100, 0), +)) + +//claw footsteps lists +GLOBAL_LIST_INIT(clawfootstep, list( + FOOTSTEP_WOOD_CLAW = list(list( + 'sound/effects/footstep/woodclaw1.ogg', + 'sound/effects/footstep/woodclaw2.ogg', + 'sound/effects/footstep/woodclaw3.ogg', + 'sound/effects/footstep/woodclaw2.ogg', + 'sound/effects/footstep/woodclaw1.ogg'), 90, 1), + FOOTSTEP_HARD_CLAW = list(list( + 'sound/effects/footstep/hardclaw1.ogg', + 'sound/effects/footstep/hardclaw2.ogg', + 'sound/effects/footstep/hardclaw3.ogg', + 'sound/effects/footstep/hardclaw4.ogg', + 'sound/effects/footstep/hardclaw1.ogg'), 90, 1), + FOOTSTEP_CARPET_BAREFOOT = list(list( + 'sound/effects/footstep/carpetbarefoot1.ogg', + 'sound/effects/footstep/carpetbarefoot2.ogg', + 'sound/effects/footstep/carpetbarefoot3.ogg', + 'sound/effects/footstep/carpetbarefoot4.ogg', + 'sound/effects/footstep/carpetbarefoot5.ogg'), 75, -2), + FOOTSTEP_SAND = list(list( + 'sound/effects/footstep/asteroid1.ogg', + 'sound/effects/footstep/asteroid2.ogg', + 'sound/effects/footstep/asteroid3.ogg', + 'sound/effects/footstep/asteroid4.ogg', + 'sound/effects/footstep/asteroid5.ogg'), 75, 0), + FOOTSTEP_GRASS = list(list( + 'sound/effects/footstep/grass1.ogg', + 'sound/effects/footstep/grass2.ogg', + 'sound/effects/footstep/grass3.ogg', + 'sound/effects/footstep/grass4.ogg'), 75, 0), + FOOTSTEP_WATER = list(list( + 'sound/effects/footstep/water1.ogg', + 'sound/effects/footstep/water2.ogg', + 'sound/effects/footstep/water3.ogg', + 'sound/effects/footstep/water4.ogg'), 100, 1), + FOOTSTEP_LAVA = list(list( + 'sound/effects/footstep/lava1.ogg', + 'sound/effects/footstep/lava2.ogg', + 'sound/effects/footstep/lava3.ogg'), 100, 0), +)) + +//heavy footsteps list +GLOBAL_LIST_INIT(heavyfootstep, list( + FOOTSTEP_GENERIC_HEAVY = list(list( + 'sound/effects/footstep/heavy1.ogg', + 'sound/effects/footstep/heavy2.ogg'), 100, 2), + FOOTSTEP_WATER = list(list( + 'sound/effects/footstep/water1.ogg', + 'sound/effects/footstep/water2.ogg', + 'sound/effects/footstep/water3.ogg', + 'sound/effects/footstep/water4.ogg'), 100, 2), + FOOTSTEP_LAVA = list(list( + 'sound/effects/footstep/lava1.ogg', + 'sound/effects/footstep/lava2.ogg', + 'sound/effects/footstep/lava3.ogg'), 100, 0), +)) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 15eaadb2f2..8ff40c3ef9 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -67,7 +67,7 @@ #define islarva(A) (istype(A, /mob/living/carbon/alien/larva)) -#define isalienadult(A) (istype(A, /mob/living/carbon/alien/humanoid)) +#define isalienadult(A) (istype(A, /mob/living/carbon/alien/humanoid) || istype(A, /mob/living/simple_animal/hostile/alien)) #define isalienhunter(A) (istype(A, /mob/living/carbon/alien/humanoid/hunter)) @@ -123,6 +123,47 @@ #define isclown(A) (istype(A, /mob/living/simple_animal/hostile/retaliate/clown)) +GLOBAL_LIST_INIT(shoefootmob, typecacheof(list( + /mob/living/carbon/human/, + /mob/living/simple_animal/cow, + /mob/living/simple_animal/hostile/cat_butcherer, + /mob/living/simple_animal/hostile/faithless, + /mob/living/simple_animal/hostile/nanotrasen, + /mob/living/simple_animal/hostile/pirate, + /mob/living/simple_animal/hostile/russian, + /mob/living/simple_animal/hostile/syndicate, + /mob/living/simple_animal/hostile/wizard, + /mob/living/simple_animal/hostile/zombie, + /mob/living/simple_animal/hostile/retaliate/clown, + /mob/living/simple_animal/hostile/retaliate/spaceman, + /mob/living/simple_animal/hostile/retaliate/nanotrasenpeace, + /mob/living/simple_animal/hostile/retaliate/goat, + /mob/living/carbon/true_devil, + ))) + +GLOBAL_LIST_INIT(clawfootmob, typecacheof(list( + /mob/living/carbon/alien/humanoid, + /mob/living/simple_animal/hostile/alien, + /mob/living/simple_animal/pet/cat, + /mob/living/simple_animal/pet/dog, + /mob/living/simple_animal/pet/fox, + /mob/living/simple_animal/chicken, + /mob/living/simple_animal/hostile/bear, + /mob/living/simple_animal/hostile/jungle/mega_arachnid + ))) + +GLOBAL_LIST_INIT(barefootmob, typecacheof(list( + /mob/living/carbon/monkey, + /mob/living/simple_animal/pet/penguin, + /mob/living/simple_animal/hostile/gorilla, + /mob/living/simple_animal/hostile/jungle/mook + ))) + +GLOBAL_LIST_INIT(heavyfootmob, typecacheof(list( + /mob/living/simple_animal/hostile/megafauna, + /mob/living/simple_animal/hostile/jungle/leaper + ))) + //Misc mobs #define isobserver(A) (istype(A, /mob/dead/observer)) @@ -136,6 +177,15 @@ #define iseminence(A) (istype(A, /mob/camera/eminence)) +//Footstep helpers +#define isshoefoot(A) (is_type_in_typecache(A, GLOB.shoefootmob)) + +#define isclawfoot(A) (is_type_in_typecache(A, GLOB.clawfootmob)) + +#define isbarefoot(A) (is_type_in_typecache(A, GLOB.barefootmob)) + +#define isheavyfoot(A) (is_type_in_typecache(A, GLOB.heavyfootmob)) + //Objects #define isobj(A) istype(A, /obj) //override the byond proc because it returns true on children of /atom/movable that aren't objs diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 709a4daeba..19710a89fe 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -218,6 +218,9 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) //Gets the turf this atom inhabits #define get_turf(A) (get_step(A, 0)) +//Same as above except gets the area instead +#define get_area(A) (isarea(A) ? A : get_step(A, 0)?.loc) + //Ghost orbit types: #define GHOST_ORBIT_CIRCLE "circle" #define GHOST_ORBIT_TRIANGLE "triangle" @@ -474,4 +477,6 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE)) #define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (istype(I, /client) ? I : (istype(I, /datum/mind) ? I:current?:client : null))) #define AREASELECT_CORNERA "corner A" -#define AREASELECT_CORNERB "corner B" \ No newline at end of file +#define AREASELECT_CORNERB "corner B" + +#define PREF_SAVELOAD_COOLDOWN 5 \ No newline at end of file diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index f8f59a367f..c3682d905d 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -2,7 +2,7 @@ #define LIQUID 2 #define GAS 3 -// container_type defines +// reagents_flags defines #define INJECTABLE (1<<0) // Makes it possible to add reagents through droppers and syringes. #define DRAWABLE (1<<1) // Makes it possible to remove reagents through syringes. @@ -11,6 +11,7 @@ #define TRANSPARENT (1<<4) // Used on containers which you want to be able to see the reagents off. #define AMOUNT_VISIBLE (1<<5) // For non-transparent containers that still have the general amount of reagents in them visible. +#define NO_REACT (1<<6) // Applied to a reagent holder, the contents will not react with each other. // Is an open container for all intents and purposes. #define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT) diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm index 9c81305241..0820d63247 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -35,6 +35,7 @@ #define CLEAN_BOT (1<<3) // Cleanbots #define MED_BOT (1<<4) // Medibots #define HONK_BOT (1<<5) // Honkbots & ED-Honks +#define FIRE_BOT (1<<6) // Firebots //AI notification defines #define NEW_BORG 1 diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 6773d55e53..b316c003a9 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -33,7 +33,8 @@ #define ROLE_DRONE "drone" #define ROLE_DEATHSQUAD "deathsquad" #define ROLE_LAVALAND "lavaland" -#define ROLE_INTERNAL_AFFAIRS "internal affairs agent" +#define ROLE_INTERNAL_AFFAIRS "internal affairs agent" +#define ROLE_GANG "gangster" //Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR. //The gamemode specific ones are just so the gamemodes can query whether a player is old enough @@ -58,7 +59,8 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_SERVANT_OF_RATVAR = /datum/game_mode/clockwork_cult, ROLE_OVERTHROW = /datum/game_mode/overthrow, ROLE_INTERNAL_AFFAIRS = /datum/game_mode/traitor/internal_affairs, - ROLE_SENTIENCE + ROLE_SENTIENCE, + ROLE_GANG = /datum/game_mode/gang )) //Job defines for what happens when you fail to qualify for any job during job selection diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index a5617e6148..12e222e1ef 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -1,3 +1,61 @@ +// trait accessor defines +#define ADD_TRAIT(target, trait, source) \ + do { \ + var/list/_L; \ + if (!target.status_traits) { \ + target.status_traits = list(); \ + _L = target.status_traits; \ + _L[trait] = list(source); \ + } else { \ + _L = target.status_traits; \ + if (_L[trait]) { \ + _L[trait] |= list(source); \ + } else { \ + _L[trait] = list(source); \ + } \ + } \ + } while (0) +#define REMOVE_TRAIT(target, trait, sources) \ + do { \ + var/list/_L = target.status_traits; \ + var/list/_S; \ + if (sources && !islist(sources)) { \ + _S = list(sources); \ + } else { \ + _S = sources\ + }; \ + if (_L && _L[trait]) { \ + for (var/_T in _L[trait]) { \ + if ((!_S && (_T != ROUNDSTART_TRAIT)) || (_T in _S)) { \ + _L[trait] -= _T \ + } \ + };\ + if (!length(_L[trait])) { \ + _L -= trait \ + }; \ + if (!length(_L)) { \ + target.status_traits = null \ + }; \ + } \ + } while (0) +#define REMOVE_TRAITS_NOT_IN(target, sources) \ + do { \ + var/list/_L = target.status_traits; \ + var/list/_S = sources; \ + if (_L) { \ + for (var/_T in _L) { \ + _L[_T] &= _S;\ + if (!length(_L[_T])) { \ + _L -= _T } \ + };\ + if (!length(_L)) { \ + target.status_traits = null\ + };\ + }\ + } while (0) +#define HAS_TRAIT(target, trait) (target.status_traits ? (target.status_traits[trait] ? TRUE : FALSE) : FALSE) +#define HAS_TRAIT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (source in target.status_traits[trait]) : FALSE) : FALSE) + //mob traits #define TRAIT_BLIND "blind" #define TRAIT_MUTE "mute" @@ -69,6 +127,13 @@ #define TRAIT_TAGGER "tagger" #define TRAIT_PHOTOGRAPHER "photographer" #define TRAIT_MUSICIAN "musician" +#define TRAIT_CROCRIN_IMMUNE "crocin_immune" +#define TRAIT_NYMPHO "nymphomania" +#define TRAIT_MASO "masochism" +#define TRAIT_EMPATH "empath" +#define TRAIT_FRIENDLY "friendly" +#define TRAIT_ASSBLASTUSA "assblastusa" +#define TRAIT_CULT_EYES "cult_eyes" // common trait sources #define TRAIT_GENERIC "generic" @@ -91,4 +156,3 @@ #define STASIS_MUTE "stasis" #define GENETICS_SPELL "genetics_spell" #define EYES_COVERED "eyes_covered" -#define CULT_EYES "cult_eyes" diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm index eb2a564d1b..668b151b6e 100644 --- a/code/__HELPERS/_cit_helpers.dm +++ b/code/__HELPERS/_cit_helpers.dm @@ -58,8 +58,11 @@ GLOBAL_LIST_EMPTY(ipc_antennas_list) //Genitals and Arousal Lists GLOBAL_LIST_EMPTY(cock_shapes_list)//global_lists.dm for the list initializations //Now also _DATASTRUCTURES globals.dm GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states for cockshapes. +GLOBAL_LIST_EMPTY(balls_shapes_list) +GLOBAL_LIST_EMPTY(balls_shapes_icons) GLOBAL_LIST_EMPTY(breasts_size_list) GLOBAL_LIST_EMPTY(breasts_shapes_list) +GLOBAL_LIST_EMPTY(breasts_shapes_icons) GLOBAL_LIST_EMPTY(vagina_shapes_list) GLOBAL_LIST_INIT(cum_into_containers_list, list(/obj/item/reagent_containers/food/snacks/pie)) //Yer fuggin snowflake name list jfc GLOBAL_LIST_INIT(dick_nouns, list("dick","cock","member","shaft")) @@ -123,36 +126,36 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE) /mob/living/carbon/proc/has_penis() if(getorganslot("penis"))//slot shared with ovipositor if(istype(getorganslot("penis"), /obj/item/organ/genital/penis)) - return 1 - return 0 + return TRUE + return FALSE /mob/living/carbon/proc/has_balls() if(getorganslot("balls")) if(istype(getorganslot("balls"), /obj/item/organ/genital/testicles)) - return 1 - return 0 + return TRUE + return FALSE /mob/living/carbon/proc/has_vagina() if(getorganslot("vagina")) - return 1 - return 0 + return TRUE + return FALSE /mob/living/carbon/proc/has_breasts() if(getorganslot("breasts")) - return 1 - return 0 + return TRUE + return FALSE /mob/living/carbon/proc/has_ovipositor() if(getorganslot("penis"))//shared slot if(istype(getorganslot("penis"), /obj/item/organ/genital/ovipositor)) - return 1 - return 0 + return TRUE + return FALSE /mob/living/carbon/human/proc/has_eggsack() if(getorganslot("balls")) if(istype(getorganslot("balls"), /obj/item/organ/genital/eggsack)) - return 1 - return 0 + return TRUE + return FALSE /mob/living/carbon/human/proc/is_bodypart_exposed(bodypart) @@ -161,16 +164,16 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE) L = get_equipped_items() for(var/obj/item/I in L) if(I.body_parts_covered & GROIN) - return 0 - return 1 + return FALSE + return TRUE /mob/living/carbon/proc/is_chest_exposed(var/list/L) if(!L) L = get_equipped_items() for(var/obj/item/I in L) if(I.body_parts_covered & CHEST) - return 0 - return 1 + return FALSE + return TRUE //////////////////////// //DANGER | DEBUG PROCS// @@ -191,40 +194,3 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE) H.give_vagina() H.give_womb() H.give_breasts() - -/client/proc/test_mammal_overlays() - set name = "Mass Give Mammalitus" - set category = "Dangerous" - set desc = "Turns every human into a mammal with tails, ears, etc. WARNING: NOT FOR LIVE SERVER USAGE!!" - - log_admin("[src] turned everyone into mammals.") - message_admins("[src] turned everyone into mammals.") - for(var/mob/living/carbon/human/H in GLOB.mob_list) - if(!H.dna) - continue - var/datum/dna/hdna = H.dna - H.set_species(/datum/species/mammal) - var/subspec = pick("Fox","Wolf","Fennec") - switch(subspec) - if("Wolf") - hdna.features["mam_tail"] = "Wolf" - hdna.features["mam_ears"] = "Wolf" - hdna.features["mam_snouts"] = "Wolf" - hdna.features["mam_body_markings"] = "Wolf" - hdna.features["mcolor"] = "555" - hdna.features["mcolor2"] = "999" - hdna.features["mcolor3"] = "999" - if("Fox") - hdna.features["mam_tail"] = "Fox" - hdna.features["mam_ears"] = "Fox" - hdna.features["mam_snouts"] = "Fox, Long" - hdna.features["mam_body_markings"] = "Fox" - hdna.features["mcolor"] = "f60" - hdna.features["mcolor2"] = "fff" - hdna.features["mcolor3"] = "fff" - if("Fennec") - hdna.features["mam_tail"] = "Fennec" - hdna.features["mam_ears"] = "Fennec" - hdna.features["mam_snouts"] = "Fox, Short" - hdna.features["mam_body_markings"] = "Fox" - H.regenerate_icons() diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index ad29125d95..c741a08108 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -8,12 +8,6 @@ #define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL)) #define CULT_POLL_WAIT 2400 -/proc/get_area(atom/A) - if(isarea(A)) - return A - var/turf/T = get_turf(A) - return T ? T.loc : null - /proc/get_area_name(atom/X, format_text = FALSE) var/area/A = isarea(X) ? X : get_area(X) if(!A) @@ -221,9 +215,10 @@ else // A variation of get_hear inlined here to take advantage of the compiler's fastpath for obj/mob in view var/lum = T.luminosity T.luminosity = 6 // This is the maximum luminosity - for(var/mob/M in view(R, T)) + var/list/cachedview = view(R, T) + for(var/mob/M in cachedview) processing_list += M - for(var/obj/O in view(R, T)) + for(var/obj/O in cachedview) processing_list += O T.luminosity = lum diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index f6ef08fe0d..ac113b4e08 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -46,7 +46,6 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list) //genitals init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) - for(var/K in GLOB.cock_shapes_list) var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K] GLOB.cock_shapes_icons[K] = value.icon_state @@ -54,6 +53,14 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. + for(var/K in GLOB.breasts_shapes_list) + var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K] + GLOB.breasts_shapes_icons[K] = value.icon_state + + init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list) + for(var/K in GLOB.balls_shapes_list) + var/datum/sprite_accessory/testicles/value = GLOB.balls_shapes_list[K] + GLOB.balls_shapes_icons[K] = value.icon_state //END OF CIT CHANGES //Species diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 74a1fbd785..51c814a5f9 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -77,6 +77,8 @@ //CIT CHANGES - genitals and such if(!GLOB.cock_shapes_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) + if(!GLOB.balls_shapes_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list) if(!GLOB.vagina_shapes_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) if(!GLOB.breasts_shapes_list.len) @@ -168,6 +170,7 @@ "balls_amount" = 2, "balls_sack_size" = BALLS_SACK_SIZE_DEF, "balls_size" = BALLS_SIZE_DEF, + "balls_shape" = "Pair", "balls_cum_rate" = CUM_RATE, "balls_cum_mult" = CUM_RATE_MULT, "balls_efficiency" = CUM_EFFICIENCY, @@ -185,7 +188,7 @@ "has_breasts" = FALSE, "breasts_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), "breasts_size" = pick(GLOB.breasts_size_list), - "breasts_shape" = pick(GLOB.breasts_shapes_list), + "breasts_shape" = "Pair", "breasts_fluid" = "milk", "has_vag" = FALSE, "vag_shape" = pick(GLOB.vagina_shapes_list), @@ -294,7 +297,7 @@ GLOBAL_LIST_EMPTY(species_list) else return "unknown" -/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null) +/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null, ignorehelditem = 0) if(!user || !target) return 0 var/user_loc = user.loc @@ -327,7 +330,7 @@ GLOBAL_LIST_EMPTY(species_list) drifting = 0 user_loc = user.loc - if((!drifting && user.loc != user_loc) || target.loc != target_loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke())) + if((!drifting && user.loc != user_loc) || target.loc != target_loc || (!ignorehelditem && user.get_active_held_item() != holding) || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke())) . = 0 break if (progress) diff --git a/code/__HELPERS/radio.dm b/code/__HELPERS/radio.dm index 84b354b6cd..c55fb8095d 100644 --- a/code/__HELPERS/radio.dm +++ b/code/__HELPERS/radio.dm @@ -12,3 +12,8 @@ /proc/format_frequency(frequency) frequency = text2num(frequency) return "[round(frequency / 10)].[frequency % 10]" + +//Opposite of format, returns as a number +/proc/unformat_frequency(frequency) + frequency = text2num(frequency) + return frequency * 10 diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 165cea9557..cdd2e99dd8 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -199,6 +199,10 @@ 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) + CHECK_TICK //These need update to actually reflect the real antagonists diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 7d6c017b77..7d8eb108f3 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -94,6 +94,8 @@ // Used to get a properly sanitized multiline input, of max_length /proc/stripped_multiline_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) var/name = input(user, message, title, default) as message|null + if(isnull(name)) // Return null if canceled. + return null if(no_trim) return copytext(html_encode(name), 1, max_length) else diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 835a733752..c37e6fa531 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -115,9 +115,6 @@ GLOBAL_LIST_INIT(bitfields, list( "GOLIATH_RESISTANCE" = GOLIATH_RESISTANCE, "GOLIATH_WEAKNESS" = GOLIATH_WEAKNESS ), - "reagents_holder_flags" = list( - "REAGENT_NOREACT" = REAGENT_NOREACT - ), "flags_1" = list( "NOJAUNT_1" = NOJAUNT_1, "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1, @@ -158,13 +155,14 @@ GLOBAL_LIST_INIT(bitfields, list( "SMOOTH_BORDER" = SMOOTH_BORDER, "SMOOTH_QUEUED" = SMOOTH_QUEUED, ), - "container_type" = list( + "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, diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 8b0ac278cd..47b7e2ab62 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -40,6 +40,54 @@ GLOBAL_LIST_EMPTY(caps_list) GLOBAL_LIST_INIT(ghost_forms_with_directions_list, list("ghost")) //stores the ghost forms that support directional sprites GLOBAL_LIST_INIT(ghost_forms_with_accessories_list, list("ghost")) //stores the ghost forms that support hair and other such things +GLOBAL_LIST_INIT(ai_core_display_screens, list( + ":thinking:", + "Alien", + "Angel", + "Banned", + "Bliss", + "Blue", + "Clown", + "Database", + "Dorf", + "Firewall", + "Fuzzy", + "Gentoo", + "Glitchman", + "Gondola", + "Goon", + "Hades", + "Heartline", + "Helios", + "House", + "Inverted", + "Matrix", + "Monochrome", + "Murica", + "Nanotrasen", + "Not Malf", + "President", + "Random", + "Rainbow", + "Red", + "Red October", + "Static", + "Syndicat Meow", + "TechDemon", + "Text", + "Too Deep", + "Triumvirate", + "Triumvirate-M", + "Weird")) + +/proc/resolve_ai_icon(input) + if(!input || !(input in GLOB.ai_core_display_screens)) + return "ai" + else + if(input == "Random") + input = pick(GLOB.ai_core_display_screens - "Random") + return "ai-[lowertext(input)]" + GLOBAL_LIST_INIT(security_depts_prefs, list(SEC_DEPT_RANDOM, SEC_DEPT_NONE, SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, SEC_DEPT_SCIENCE, SEC_DEPT_SUPPLY)) //Backpacks @@ -117,7 +165,7 @@ GLOBAL_LIST_INIT(TAGGERLOCATIONS, list("Disposals", "CMO Office", "Chemistry", "Research", "RD Office", "Robotics", "HoP Office", "Library", "Chapel", "Theatre", "Bar", "Kitchen", "Hydroponics", "Janitor Closet","Genetics", - "Circuitry", "Toxins", "Dormitories", "Virology", + "Circuitry", "Toxins", "Dormitories", "Virology", "Xenobiology", "Law Office","Detective's Office")) GLOBAL_LIST_INIT(station_prefixes, world.file2list("strings/station_prefixes.txt") + "") diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index d0506c7dcb..aa1cdcb40a 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -108,5 +108,8 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/toy/eightball = 1, /obj/item/reagent_containers/pill/floorpill = 1, /obj/item/storage/daki = 3, //VERY IMPORTANT CIT CHANGE - adds bodypillows to maint + /obj/item/storage/pill_bottle/penis_enlargement = 2, + /obj/item/clothing/shoes/wheelys = 1, + /obj/item/clothing/shoes/kindleKicks = 1, "" = 3 )) diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 03b951e6bb..df91223ed1 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -1,4 +1,7 @@ #define NEXT_PAGE_ID "__next__" +#define DEFAULT_CHECK_DELAY 20 + +GLOBAL_LIST_EMPTY(radial_menus) /obj/screen/radial icon = 'icons/mob/radial.dmi' @@ -10,14 +13,19 @@ icon_state = "radial_slice" var/choice var/next_page = FALSE + var/tooltips = FALSE /obj/screen/radial/slice/MouseEntered(location, control, params) . = ..() icon_state = "radial_slice_focus" + if(tooltips) + openToolTip(usr, src, params, title = name) /obj/screen/radial/slice/MouseExited(location, control, params) . = ..() icon_state = "radial_slice" + if(tooltips) + closeToolTip(usr) /obj/screen/radial/slice/Click(location, control, params) if(usr.client == parent.current_user) @@ -30,6 +38,14 @@ name = "Close Menu" icon_state = "radial_center" +/obj/screen/radial/center/MouseEntered(location, control, params) + . = ..() + icon_state = "radial_center_focus" + +/obj/screen/radial/center/MouseExited(location, control, params) + . = ..() + icon_state = "radial_center" + /obj/screen/radial/center/Click(location, control, params) if(usr.client == parent.current_user) parent.finished = TRUE @@ -48,6 +64,9 @@ var/atom/anchor var/image/menu_holder var/finished = FALSE + var/datum/callback/custom_check_callback + var/next_check = 0 + var/check_delay = DEFAULT_CHECK_DELAY var/radius = 32 var/starting_angle = 0 @@ -57,7 +76,7 @@ var/max_elements var/pages = 1 var/current_page = 1 - + var/hudfix_method = TRUE //TRUE to change anchor to user, FALSE to shift by py_shift var/py_shift = 0 var/entry_animation = TRUE @@ -75,7 +94,7 @@ restrict_to_dir(NORTH) //I was going to parse screen loc here but that's more effort than it's worth. //Sets defaults -//These assume 45 deg min_angle +//These assume 45 deg min_angle /datum/radial_menu/proc/restrict_to_dir(dir) switch(dir) if(NORTH) @@ -91,18 +110,19 @@ starting_angle = 180 ending_angle = 45 -/datum/radial_menu/proc/setup_menu() +/datum/radial_menu/proc/setup_menu(use_tooltips) if(ending_angle > starting_angle) zone = ending_angle - starting_angle else zone = 360 - starting_angle + ending_angle - + max_elements = round(zone / min_angle) var/paged = max_elements < choices.len if(elements.len < max_elements) var/elements_to_add = max_elements - elements.len for(var/i in 1 to elements_to_add) //Create all elements - var/obj/screen/radial/new_element = new /obj/screen/radial/slice + var/obj/screen/radial/slice/new_element = new /obj/screen/radial/slice + new_element.tooltips = use_tooltips new_element.parent = src elements += new_element @@ -163,7 +183,7 @@ else E.pixel_y = py E.pixel_x = px - + //Visuals E.alpha = 255 E.mouse_opacity = MOUSE_OPACITY_ICON @@ -183,7 +203,7 @@ E.next_page = FALSE if(choices_icons[choice_id]) E.add_overlay(choices_icons[choice_id]) - + /datum/radial_menu/New() close_button = new close_button.parent = src @@ -200,7 +220,7 @@ /datum/radial_menu/proc/get_next_id() return "c_[choices.len]" -/datum/radial_menu/proc/set_choices(list/new_choices) +/datum/radial_menu/proc/set_choices(list/new_choices, use_tooltips) if(choices.len) Reset() for(var/E in new_choices) @@ -211,7 +231,7 @@ var/I = extract_image(new_choices[E]) if(I) choices_icons[id] = I - setup_menu() + setup_menu(use_tooltips) /datum/radial_menu/proc/extract_image(E) @@ -220,7 +240,7 @@ MA.layer = ABOVE_HUD_LAYER MA.appearance_flags |= RESET_TRANSFORM return MA - + /datum/radial_menu/proc/next_page() if(pages > 1) @@ -243,28 +263,49 @@ if(current_user) current_user.images -= menu_holder -/datum/radial_menu/proc/wait() +/datum/radial_menu/proc/wait(atom/user, atom/anchor, require_near = FALSE) while (current_user && !finished && !selected_choice) + if(require_near && !in_range(anchor, user)) + return + if(custom_check_callback && next_check < world.time) + if(!custom_check_callback.Invoke()) + return + else + next_check = world.time + check_delay stoplag(1) /datum/radial_menu/Destroy() Reset() hide() + QDEL_NULL(custom_check_callback) . = ..() + /* - Presents radial menu to user anchored to anchor (or user if the anchor is currently in users screen) + Presents radial menu to user anchored to anchor (or user if the anchor is currently in users screen) Choices should be a list where list keys are movables or text used for element names and return value and list values are movables/icons/images used for element icons */ -/proc/show_radial_menu(mob/user,atom/anchor,list/choices) +/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE) + if(!user || !anchor || !length(choices)) + return + if(!uniqueid) + uniqueid = "defmenu_[REF(user)]_[REF(anchor)]" + + if(GLOB.radial_menus[uniqueid]) + return + var/datum/radial_menu/menu = new - if(!user) - user = usr + GLOB.radial_menus[uniqueid] = menu + if(radius) + menu.radius = radius + if(istype(custom_check)) + menu.custom_check_callback = custom_check menu.anchor = anchor menu.check_screen_border(user) //Do what's needed to make it look good near borders or on hud - menu.set_choices(choices) + menu.set_choices(choices, tooltips) menu.show_to(user) - menu.wait() + menu.wait(user, anchor, require_near) var/answer = menu.selected_choice qdel(menu) + GLOB.radial_menus -= uniqueid return answer \ No newline at end of file diff --git a/code/_onclick/hud/radial_persistent.dm b/code/_onclick/hud/radial_persistent.dm new file mode 100644 index 0000000000..0b5e8dc356 --- /dev/null +++ b/code/_onclick/hud/radial_persistent.dm @@ -0,0 +1,76 @@ +/* + A derivative of radial menu which persists onscreen until closed and invokes a callback each time an element is clicked +*/ + +/obj/screen/radial/persistent/center + name = "Close Menu" + icon_state = "radial_center" + +/obj/screen/radial/persistent/center/Click(location, control, params) + if(usr.client == parent.current_user) + parent.element_chosen(null,usr) + +/obj/screen/radial/persistent/center/MouseEntered(location, control, params) + . = ..() + icon_state = "radial_center_focus" + +/obj/screen/radial/persistent/center/MouseExited(location, control, params) + . = ..() + icon_state = "radial_center" + + + +/datum/radial_menu/persistent + var/uniqueid + var/datum/callback/select_proc_callback + +/datum/radial_menu/persistent/New() + close_button = new /obj/screen/radial/persistent/center + close_button.parent = src + + +/datum/radial_menu/persistent/element_chosen(choice_id,mob/user) + select_proc_callback.Invoke(choices_values[choice_id]) + + +/datum/radial_menu/persistent/proc/change_choices(list/newchoices, tooltips) + if(!newchoices.len) + return + Reset() + set_choices(newchoices,tooltips) + +/datum/radial_menu/persistent/Destroy() + QDEL_NULL(select_proc_callback) + GLOB.radial_menus -= uniqueid + Reset() + hide() + . = ..() + +/* + Creates a persistent radial menu and shows it to the user, anchored to anchor (or user if the anchor is currently in users screen). + Choices should be a list where list keys are movables or text used for element names and return value + and list values are movables/icons/images used for element icons + Select_proc is the proc to be called each time an element on the menu is clicked, and should accept the chosen element as its final argument + Clicking the center button will return a choice of null +*/ +/proc/show_radial_menu_persistent(mob/user, atom/anchor, list/choices, datum/callback/select_proc, uniqueid, radius, tooltips = FALSE) + if(!user || !anchor || !length(choices) || !select_proc) + return + if(!uniqueid) + uniqueid = "defmenu_[REF(user)]_[REF(anchor)]" + + if(GLOB.radial_menus[uniqueid]) + return + + var/datum/radial_menu/persistent/menu = new + menu.uniqueid = uniqueid + GLOB.radial_menus[uniqueid] = menu + if(radius) + menu.radius = radius + menu.select_proc_callback = select_proc + menu.anchor = anchor + menu.check_screen_border(user) //Do what's needed to make it look good near borders or on hud + menu.set_choices(choices, tooltips) + menu.show_to(user) + return menu + diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index d23d0905e9..2a14d232aa 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -64,7 +64,7 @@ to_chat(user, "You're too exhausted.") // CIT CHANGE - ditto return // CIT CHANGE - ditto - if(force && user.has_trait(TRAIT_PACIFISM)) + if(force && HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to harm other living beings!") return diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 4cd317318f..cfd57b4850 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -360,3 +360,7 @@ min_val = 0 /datum/config_entry/flag/disable_stambuffer + +/datum/config_entry/number/auto_transfer_delay + config_entry_value = 72000 + min_val = 0 diff --git a/code/controllers/subsystem/processing/circuit.dm b/code/controllers/subsystem/processing/circuit.dm index 1ae5bad23c..880e7a16a8 100644 --- a/code/controllers/subsystem/processing/circuit.dm +++ b/code/controllers/subsystem/processing/circuit.dm @@ -50,17 +50,20 @@ PROCESSING_SUBSYSTEM_DEF(circuit) /obj/item/electronic_assembly/simple, /obj/item/electronic_assembly/hook, /obj/item/electronic_assembly/pda, + /obj/item/electronic_assembly/dildo, /obj/item/electronic_assembly/small/default, /obj/item/electronic_assembly/small/cylinder, /obj/item/electronic_assembly/small/scanner, /obj/item/electronic_assembly/small/hook, /obj/item/electronic_assembly/small/box, + /obj/item/electronic_assembly/small/dildo, /obj/item/electronic_assembly/medium/default, /obj/item/electronic_assembly/medium/box, /obj/item/electronic_assembly/medium/clam, /obj/item/electronic_assembly/medium/medical, /obj/item/electronic_assembly/medium/gun, /obj/item/electronic_assembly/medium/radio, + /obj/item/electronic_assembly/medium/dildo, /obj/item/electronic_assembly/large/default, /obj/item/electronic_assembly/large/scope, /obj/item/electronic_assembly/large/terminal, @@ -89,4 +92,4 @@ PROCESSING_SUBSYSTEM_DEF(circuit) /obj/item/card/data/full_color, /obj/item/card/data/disk ) - + diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 78cceddc8b..08f657a1b9 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -76,6 +76,7 @@ SUBSYSTEM_DEF(shuttle) if(!supply) WARNING("No /obj/docking_port/mobile/supply placed on the map!") realtimeofstart = world.realtime + auto_call = CONFIG_GET(number/auto_transfer_delay) return ..() /datum/controller/subsystem/shuttle/proc/initial_load() diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index de58c1a0d7..77ad712b99 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -116,7 +116,7 @@ SUBSYSTEM_DEF(throwing) return dist_travelled++ - + if (dist_travelled > MAX_THROWING_DIST) finalize() return @@ -154,7 +154,7 @@ SUBSYSTEM_DEF(throwing) /datum/thrownthing/proc/hitcheck() for (var/thing in get_turf(thrownthing)) var/atom/movable/AM = thing - if (AM == thrownthing) + if (AM == thrownthing || (AM == thrower && !ismob(thrownthing))) continue if (AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags_1 & ON_BORDER_1)) finalize(hit=TRUE, target=AM) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 9a4cad3667..4a3143da79 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -564,6 +564,9 @@ SUBSYSTEM_DEF(ticker) if(news_message) send2otherserver(news_source, news_message,"News_Report") + return news_message + else + return "We regret to inform you that shit be whack, yo. None of our reporters have any idea of what may or may not have gone on." /datum/controller/subsystem/ticker/proc/GetTimeLeft() if(isnull(SSticker.timeLeft)) diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index 05105dca1e..d70493dedf 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -14,7 +14,8 @@ SUBSYSTEM_DEF(traumas) //phobia types is to pull from randomly for brain traumas, e.g. conspiracies is for special assignment only phobia_types = list("spiders", "space", "security", "clowns", "greytide", "lizards", "skeletons", "snakes", "robots", "doctors", "authority", "the supernatural", - "aliens", "strangers", "birds", "falling", "anime", "mimes", "cats" + "aliens", "strangers", "birds", "falling", "anime", "mimes", "cats", "syndicate", + "eye" ) phobia_words = list("spiders" = strings(PHOBIA_FILE, "spiders"), @@ -36,7 +37,9 @@ SUBSYSTEM_DEF(traumas) "falling" = strings(PHOBIA_FILE, "falling"), "anime" = strings(PHOBIA_FILE, "anime"), "mimes" = strings(PHOBIA_FILE, "mimes"), - "cats" = strings(PHOBIA_FILE, "cats") + "cats" = strings(PHOBIA_FILE, "cats"), + "syndicate"= strings(PHOBIA_FILE, "syndicate"), + "eye" = strings(PHOBIA_FILE, "eye") ) phobia_mobs = list("spiders" = typecacheof(list(/mob/living/simple_animal/hostile/poison/giant_spider)), @@ -56,7 +59,9 @@ SUBSYSTEM_DEF(traumas) "birds" = typecacheof(list(/mob/living/simple_animal/parrot, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, /mob/living/simple_animal/pet/penguin)), "anime" = typecacheof(list(/mob/living/simple_animal/hostile/guardian)), - "cats"= typecacheof(list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/pet/cat, /mob/living/simple_animal/hostile/cat_butcherer)) + "cats"= typecacheof(list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/pet/cat, /mob/living/simple_animal/hostile/cat_butcherer)), + "syndicate" = typecacheof(list(/mob/living/simple_animal/hostile/syndicate, /mob/living/simple_animal/hostile/viscerator, /mob/living/simple_animal/hostile/carp/cayenne, /mob/living/silicon/robot/modules/syndicate)), + "eye" = typecacheof(list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher, /mob/living/simple_animal/hostile/carp/eyeball)) ) @@ -157,7 +162,23 @@ SUBSYSTEM_DEF(traumas) /obj/item/clothing/under/sexymime, /obj/item/toy/figure/mime, /obj/item/toy/crayon/mime, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced, /obj/mecha/combat/reticence)), "cats" = typecacheof(list(/obj/item/organ/ears/cat, /obj/item/organ/tail/cat, /obj/item/laser_pointer, /obj/item/toy/cattoy, /obj/item/clothing/head/kitty, - /obj/item/clothing/head/collectable/kitty, /obj/item/melee/chainofcommand/tailwhip/kitty, /obj/item/stack/sheet/animalhide/cat)) + /obj/item/clothing/head/collectable/kitty, /obj/item/melee/chainofcommand/tailwhip/kitty, /obj/item/stack/sheet/animalhide/cat)), + + "syndicate" = typecacheof(list(/obj/item/stack/tile/mineral/plastitanium, /obj/machinery/computer/shuttle/syndicate, /obj/machinery/computer/shuttle/syndicate/recall, /obj/machinery/computer/shuttle/syndicate/drop_pod, /obj/machinery/computer/camera_advanced/shuttle_docker/syndicate, /obj/machinery/recharge_station, + /obj/machinery/porta_turret/syndicate, /obj/structure/closet/syndicate, /obj/machinery/suit_storage_unit/syndicate, /obj/item/clothing/under/syndicate, /obj/item/folder/syndicate, /obj/item/documents/syndicate, /obj/item/clothing/glasses/phantomthief/syndicate, /obj/item/antag_spawner/nuke_ops, /obj/item/storage/box/syndicate, + /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/syndie, + /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/twohanded/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/mecha/combat/gygax/dark, /obj/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/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate, + /obj/machinery/computer/pod/old/syndicate, /obj/machinery/vending/medical/syndicate_access, /obj/item/mmi/syndie, /obj/item/target/syndicate, /obj/machinery/vending/cigarette/syndicate, /obj/item/robot_module/syndicate, /obj/item/clothing/mask/gas/syndicate, /obj/machinery/power/singularity_beacon/syndicate, /obj/item/clothing/head/syndicatefake, + /obj/item/radio/headset/syndicate, /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate, /obj/item/pda/syndicate, /obj/item/clothing/suit/armor/vest/capcarapace/syndicate, /obj/item/gun/ballistic/automatic/flechette, /obj/item/ammo_box/magazine/flechette, /obj/item/clothing/suit/toggle/lawyer/black/syndie, /obj/item/melee/transforming/energy/sword/cx/traitor, + /obj/structure/sign/poster/contraband/syndicate_pistol, /obj/structure/sign/poster/contraband/syndicate_recruitment, /obj/item/bedsheet/syndie, /obj/item/borg/upgrade/syndicate, /obj/item/tank/jetpack/oxygen/harness, /obj/item/firing_pin/implant/pindicate, /obj/item/reagent_containers/glass/bottle/traitor, /obj/item/storage/belt/military, + /obj/item/twohanded/shockpaddles/syndicate, /obj/item/clothing/mask/cigarette/syndicate, /obj/item/toy/plush/nukeplushie)), + + "eye" = typecacheof(list(/obj/item/organ/eyes, /obj/item/reagent_containers/syringe)) ) phobia_turfs = list("space" = typecacheof(list(/turf/open/space, /turf/open/floor/holofloor/space, /turf/open/floor/fakespace)), @@ -165,18 +186,19 @@ SUBSYSTEM_DEF(traumas) /turf/open/floor/plasteel/cult, /turf/closed/wall/mineral/cult)), "aliens" = typecacheof(list(/turf/open/floor/plating/abductor, /turf/open/floor/plating/abductor2, /turf/open/floor/mineral/abductor, /turf/closed/wall/mineral/abductor)), - "falling" = typecacheof(list(/turf/open/chasm, /turf/open/floor/fakepit)) + "falling" = typecacheof(list(/turf/open/chasm, /turf/open/floor/fakepit)), + "syndicate" = typecacheof(list(/turf/closed/wall/mineral/plastitanium, /turf/open/floor/mineral/plastitanium, /turf/open/floor/plasteel/shuttle/red/syndicate)) ) phobia_species = list("lizards" = typecacheof(list(/datum/species/lizard)), "skeletons" = typecacheof(list(/datum/species/skeleton, /datum/species/plasmaman)), - "conspiracies" = typecacheof(list(/datum/species/abductor, /datum/species/lizard, /datum/species/synth)), - "robots" = typecacheof(list(/datum/species/android)), + "conspiracies" = typecacheof(list(/datum/species/abductor, /datum/species/lizard, /datum/species/synth, /datum/species/corporate)), + "robots" = typecacheof(list(/datum/species/android, /datum/species/synth)), "the supernatural" = typecacheof(list(/datum/species/golem/clockwork, /datum/species/golem/runic)), - "aliens" = typecacheof(list(/datum/species/abductor, /datum/species/jelly, /datum/species/pod, - /datum/species/shadow)), + "aliens" = typecacheof(list(/datum/species/abductor, /datum/species/jelly, /datum/species/pod, /datum/species/shadow)), "anime" = typecacheof(list(/datum/species/human/felinid)), - "cats" = typecacheof(list(/datum/species/human/felinid)) + "cats" = typecacheof(list(/datum/species/human/felinid)), + "syndicate" = typecacheof(list(/datum/species/corporate, /datum/species/zombie/infectious)) ) return ..() diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 14a092d1f9..422b1eda26 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -228,6 +228,7 @@ SUBSYSTEM_DEF(vote) to_chat(world, "\n[text]\nType vote or click here to place your votes.\nYou have [DisplayTimeText(vp)] to vote.") time_remaining = round(vp/10) for(var/c in GLOB.clients) + SEND_SOUND(c, sound('sound/misc/server-ready.ogg')) var/client/C = c var/datum/action/vote/V = new if(question) diff --git a/code/datums/action.dm b/code/datums/action.dm index b7089279cb..f64a549b29 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -195,11 +195,16 @@ /datum/action/item_action/toggle_firemode name = "Toggle Firemode" -/datum/action/item_action/rcl +/datum/action/item_action/rcl_col name = "Change Cable Color" icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "rcl_rainbow" +/datum/action/item_action/rcl_gui + name = "Toggle Fast Wiring Gui" + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "rcl_gui" + /datum/action/item_action/startchainsaw name = "Pull The Starting Cord" diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index afd53726db..f2fec3bb63 100644 --- a/code/datums/brain_damage/mild.dm +++ b/code/datums/brain_damage/mild.dm @@ -42,7 +42,7 @@ lose_text = "You feel smart again." /datum/brain_trauma/mild/dumbness/on_gain() - owner.add_trait(TRAIT_DUMB, TRAUMA_TRAIT) + ADD_TRAIT(owner, TRAIT_DUMB, TRAUMA_TRAIT) SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "dumb", /datum/mood_event/oblivious) ..() @@ -55,7 +55,7 @@ ..() /datum/brain_trauma/mild/dumbness/on_lose() - owner.remove_trait(TRAIT_DUMB, TRAUMA_TRAIT) + REMOVE_TRAIT(owner, TRAIT_DUMB, TRAUMA_TRAIT) owner.derpspeech = 0 SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "dumb") ..() diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index a8adbfbce8..e790e539c8 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -13,11 +13,11 @@ lose_text = "You suddenly remember how to speak." /datum/brain_trauma/severe/mute/on_gain() - owner.add_trait(TRAIT_MUTE, TRAUMA_TRAIT) + ADD_TRAIT(owner, TRAIT_MUTE, TRAUMA_TRAIT) ..() /datum/brain_trauma/severe/mute/on_lose() - owner.remove_trait(TRAIT_MUTE, TRAUMA_TRAIT) + REMOVE_TRAIT(owner, TRAIT_MUTE, TRAUMA_TRAIT) ..() /datum/brain_trauma/severe/aphasia @@ -121,7 +121,7 @@ stress -= 4 /datum/brain_trauma/severe/monophobia/proc/check_alone() - if(owner.has_trait(TRAIT_BLIND)) + if(HAS_TRAIT(owner, TRAIT_BLIND)) return TRUE for(var/mob/M in oview(owner, 7)) if(!isliving(M)) //ghosts ain't people @@ -183,11 +183,11 @@ lose_text = "You feel in control of your hands again." /datum/brain_trauma/severe/discoordination/on_gain() - owner.add_trait(TRAIT_MONKEYLIKE, TRAUMA_TRAIT) + ADD_TRAIT(owner, TRAIT_MONKEYLIKE, TRAUMA_TRAIT) ..() /datum/brain_trauma/severe/discoordination/on_lose() - owner.remove_trait(TRAIT_MONKEYLIKE, TRAUMA_TRAIT) + REMOVE_TRAIT(owner, TRAIT_MONKEYLIKE, TRAUMA_TRAIT) ..() /datum/brain_trauma/severe/pacifism @@ -198,9 +198,9 @@ lose_text = "You no longer feel compelled to not harm." /datum/brain_trauma/severe/pacifism/on_gain() - owner.add_trait(TRAIT_PACIFISM, TRAUMA_TRAIT) + ADD_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT) ..() /datum/brain_trauma/severe/pacifism/on_lose() - owner.remove_trait(TRAIT_PACIFISM, TRAUMA_TRAIT) + REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT) ..() \ No newline at end of file diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm index 9ce65717f1..612af13392 100644 --- a/code/datums/brain_damage/split_personality.dm +++ b/code/datums/brain_damage/split_personality.dm @@ -192,7 +192,7 @@ return //no random switching /datum/brain_trauma/severe/split_personality/brainwashing/on_hear(message, speaker, message_language, raw_message, radio_freq) - if(owner.has_trait(TRAIT_DEAF) || owner == speaker) + if(HAS_TRAIT(owner, TRAIT_DEAF) || owner == speaker) return message if(findtext(message, codeword)) message = replacetext(message, codeword, "[codeword]") diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm index 1e1b7a0a48..838a1b576a 100644 --- a/code/datums/components/caltrop.dm +++ b/code/datums/components/caltrop.dm @@ -24,7 +24,7 @@ if(ishuman(AM)) var/mob/living/carbon/human/H = AM - if(H.has_trait(TRAIT_PIERCEIMMUNE)) + if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) return if((flags & CALTROP_IGNORE_WALKERS) && H.m_intent == MOVE_INTENT_WALK) @@ -46,7 +46,7 @@ return var/damage = rand(min_damage, max_damage) - if(H.has_trait(TRAIT_LIGHT_STEP)) + if(HAS_TRAIT(H, TRAIT_LIGHT_STEP)) damage *= 0.75 H.apply_damage(damage, BRUTE, picked_def_zone) diff --git a/code/datums/components/earhealing.dm b/code/datums/components/earhealing.dm index 9396eab3a3..6eb71285e0 100644 --- a/code/datums/components/earhealing.dm +++ b/code/datums/components/earhealing.dm @@ -23,7 +23,7 @@ if (!wearer) STOP_PROCESSING(SSobj, src) return - if(!wearer.has_trait(TRAIT_DEAF)) + if(!HAS_TRAIT(wearer, TRAIT_DEAF)) var/obj/item/organ/ears/ears = wearer.getorganslot(ORGAN_SLOT_EARS) if (ears) ears.deaf = max(ears.deaf - 1, (ears.ear_damage < UNHEALING_EAR_DAMAGE ? 0 : 1)) // Do not clear deafness while above the unhealing ear damage threshold diff --git a/code/datums/components/footstep.dm b/code/datums/components/footstep.dm index c93be4dae3..bfcc49f453 100644 --- a/code/datums/components/footstep.dm +++ b/code/datums/components/footstep.dm @@ -1,39 +1,105 @@ -/datum/component/footstep - var/steps = 0 - var/volume - var/e_range - -/datum/component/footstep/Initialize(volume_ = 0.5, e_range_ = -1) - if(!isliving(parent)) - return COMPONENT_INCOMPATIBLE - volume = volume_ - e_range = e_range_ - RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_footstep) - -/datum/component/footstep/proc/play_footstep() - var/turf/open/T = get_turf(parent) - if(!istype(T)) - return - var/mob/living/LM = parent - var/v = volume - var/e = e_range - if(!T.footstep || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING)) - return - if(iscarbon(LM)) - var/mob/living/carbon/C = LM - if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG)) - return - if(ishuman(C) && C.m_intent == MOVE_INTENT_WALK) - v /= 2 - e -= 5 - steps++ - if(steps >= 3) - steps = 0 - else - return - if(prob(80) && !LM.has_gravity(T)) // don't need to step as often when you hop around - return - playsound(T, pick(GLOB.footstep[T.footstep][1]), - GLOB.footstep[T.footstep][2] * v, - TRUE, - GLOB.footstep[T.footstep][3] + e) +/datum/component/footstep + var/steps = 0 + var/volume + var/e_range + +/datum/component/footstep/Initialize(volume_ = 0.5, e_range_ = -1) + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + volume = volume_ + e_range = e_range_ + RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_footstep) + +/datum/component/footstep/proc/play_footstep() + var/turf/open/T = get_turf(parent) + if(!istype(T)) + return + + var/mob/living/LM = parent + var/v = volume + var/e = e_range + if(!T.footstep || LM.buckled || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING)) + if (LM.lying && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying + playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v) + return + + if(iscarbon(LM)) + var/mob/living/carbon/C = LM + if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG)) + return + if(ishuman(C) && C.m_intent == MOVE_INTENT_WALK) + v /= 2 + e -= 5 + steps++ + + if(steps >= 3) + steps = 0 + + else + return + + if(prob(80) && !LM.has_gravity(T)) // don't need to step as often when you hop around + return + + //begin playsound shenanigans// + + //for barefooted non-clawed mobs like monkeys + if(isbarefoot(LM)) + playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]), + GLOB.barefootstep[T.barefootstep][2] * v, + TRUE, + GLOB.barefootstep[T.barefootstep][3] + e) + return + + //for xenomorphs, dogs, and other clawed mobs + if(isclawfoot(LM)) + if(isalienadult(LM)) //xenos are stealthy and get quieter footsteps + v /= 3 + e -= 5 + + playsound(T, pick(GLOB.clawfootstep[T.clawfootstep][1]), + GLOB.clawfootstep[T.clawfootstep][2] * v, + TRUE, + GLOB.clawfootstep[T.clawfootstep][3] + e) + return + + //for megafauna and other large and imtimidating mobs such as the bloodminer + if(isheavyfoot(LM)) + playsound(T, pick(GLOB.heavyfootstep[T.heavyfootstep][1]), + GLOB.heavyfootstep[T.heavyfootstep][2] * v, + TRUE, + GLOB.heavyfootstep[T.heavyfootstep][3] + e) + return + + //for slimes + if(isslime(LM)) + playsound(T, 'sound/effects/footstep/slime1.ogg', 15 * v) + return + + //for (simple) humanoid mobs (clowns, russians, pirates, etc.) + if(isshoefoot(LM)) + if(!ishuman(LM)) + playsound(T, pick(GLOB.footstep[T.footstep][1]), + GLOB.footstep[T.footstep][2] * v, + TRUE, + GLOB.footstep[T.footstep][3] + e) + return + if(ishuman(LM)) //for proper humans, they're special + var/mob/living/carbon/human/H = LM + var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET)) + + if (H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle") //are we a naga or tentacle taur creature + playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v) + return + + if(H.shoes || feetCover) //are we wearing shoes + playsound(T, pick(GLOB.footstep[T.footstep][1]), + GLOB.footstep[T.footstep][2] * v, + TRUE, + GLOB.footstep[T.footstep][3] + e) + + if((!H.shoes && !feetCover)) //are we NOT wearing shoes + playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]), + GLOB.barefootstep[T.barefootstep][2] * v, + TRUE, + GLOB.barefootstep[T.barefootstep][3] + e) \ No newline at end of file diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index 933c38505b..b32921a4ce 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -15,7 +15,7 @@ /datum/component/mood/Initialize() if(!isliving(parent)) return COMPONENT_INCOMPATIBLE - + START_PROCESSING(SSmood, src) RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event) @@ -150,17 +150,17 @@ else owner.crit_threshold -= (holdmyinsanityeffect - insanity_effect) - if(owner.has_trait(TRAIT_DEPRESSION)) + if(HAS_TRAIT(owner, TRAIT_DEPRESSION)) if(prob(0.05)) add_event(null, "depression", /datum/mood_event/depression) clear_event(null, "jolly") - if(owner.has_trait(TRAIT_JOLLY)) + if(HAS_TRAIT(owner, TRAIT_JOLLY)) if(prob(0.05)) add_event(null, "jolly", /datum/mood_event/jolly) clear_event(null, "depression") holdmyinsanityeffect = insanity_effect - + HandleNutrition(owner) /datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE) diff --git a/code/datums/components/storage/concrete/_concrete.dm b/code/datums/components/storage/concrete/_concrete.dm index 4d7e8bddc5..0b78605869 100644 --- a/code/datums/components/storage/concrete/_concrete.dm +++ b/code/datums/components/storage/concrete/_concrete.dm @@ -6,6 +6,8 @@ /datum/component/storage/concrete var/drop_all_on_deconstruct = TRUE var/drop_all_on_destroy = FALSE + var/drop_all_on_break = FALSE + var/unlock_on_break = FALSE var/transfer_contents_on_component_transfer = FALSE var/list/datum/component/storage/slaves = list() @@ -16,6 +18,7 @@ . = ..() RegisterSignal(parent, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del) RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, .proc/on_deconstruct) + RegisterSignal(parent, COMSIG_OBJ_BREAK, .proc/on_break) /datum/component/storage/concrete/Destroy() var/atom/real_location = real_location() @@ -100,6 +103,12 @@ if(drop_all_on_deconstruct) do_quick_empty() +/datum/component/storage/concrete/proc/on_break(datum/source, damage_flag) + if(drop_all_on_break) + do_quick_empty() + if(unlock_on_break) + set_locked(source, FALSE) + /datum/component/storage/concrete/can_see_contents() . = ..() for(var/i in slaves) diff --git a/code/datums/components/storage/concrete/emergency.dm b/code/datums/components/storage/concrete/emergency.dm new file mode 100644 index 0000000000..e5f9d83a17 --- /dev/null +++ b/code/datums/components/storage/concrete/emergency.dm @@ -0,0 +1,22 @@ +/datum/component/storage/concrete/emergency + drop_all_on_break = TRUE + unlock_on_break = TRUE + locked = TRUE + +/datum/component/storage/concrete/emergency/Initialize() + . = ..() + RegisterSignal(parent, COMSIG_ATOM_EMAG_ACT, .proc/unlock_me) + +/datum/component/storage/concrete/emergency/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE) + if(!silent && istype(I, /obj/item/card/emag)) + silent = TRUE // suppresses the message + return ..() + +/datum/component/storage/concrete/check_locked(datum/source, mob/user, message = FALSE) + . = locked && GLOB.security_level < SEC_LEVEL_RED + if(message && . && user) + to_chat(user, "The storage unit will only unlock during a Red or Delta security alert.") + +/datum/component/storage/concrete/emergency/proc/unlock_me(datum/source) + if(locked) + set_locked(source, FALSE) diff --git a/code/datums/components/storage/concrete/pockets.dm b/code/datums/components/storage/concrete/pockets.dm index 3d03c2adbd..e0a23b0209 100644 --- a/code/datums/components/storage/concrete/pockets.dm +++ b/code/datums/components/storage/concrete/pockets.dm @@ -19,6 +19,22 @@ max_items = 1 attack_hand_interact = FALSE +/datum/component/storage/concrete/pockets/small/collar + max_items = 1 + +/datum/component/storage/concrete/pockets/small/collar/Initialize() + . = ..() + can_hold = typecacheof(list( + /obj/item/reagent_containers/food/snacks/cookie, + /obj/item/reagent_containers/food/snacks/sugarcookie)) + +/datum/component/storage/concrete/pockets/small/collar/locked/Initialize() + . = ..() + can_hold = typecacheof(list( + /obj/item/reagent_containers/food/snacks/cookie, + /obj/item/reagent_containers/food/snacks/sugarcookie, + /obj/item/key/collar)) + /datum/component/storage/concrete/pockets/tiny max_items = 1 max_w_class = WEIGHT_CLASS_TINY diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index dc25729e37..869fe59ae9 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -156,8 +156,7 @@ next += slave.parent /datum/component/storage/proc/attack_self(datum/source, mob/M) - if(locked) - to_chat(M, "[parent] seems to be locked!") + if(check_locked(source, M, TRUE)) return FALSE if((M.get_active_held_item() == parent) && allow_quick_empty) quick_empty(M) @@ -166,8 +165,7 @@ if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE)) return FALSE . = COMPONENT_NO_ATTACK - if(locked) - to_chat(M, "[parent] seems to be locked!") + if(check_locked(source, M, TRUE)) return FALSE var/atom/A = parent var/obj/item/I = O @@ -238,8 +236,7 @@ var/atom/A = parent if((!ishuman(M) && (A.loc != M)) || (M.stat != CONSCIOUS) || M.restrained() || !M.canmove) return - if(locked) - to_chat(M, "[parent] seems to be locked!") + if(check_locked(null, M, TRUE)) return FALSE A.add_fingerprint(M) to_chat(M, "You start dumping out [parent].") @@ -281,7 +278,7 @@ /datum/component/storage/proc/set_locked(datum/source, new_state) locked = new_state - if(locked) + if(check_locked()) close_all() /datum/component/storage/proc/_process_numerical_display() @@ -456,8 +453,7 @@ var/atom/A = parent var/atom/dump_destination = dest_object.get_dumping_location() if(A.Adjacent(M) && dump_destination && M.Adjacent(dump_destination)) - if(locked) - to_chat(M, "[parent] seems to be locked!") + if(check_locked(null, M, TRUE)) return FALSE if(dump_destination.storage_contents_dump_act(src, M)) playsound(A, "rustle", 50, 1, -5) @@ -563,10 +559,9 @@ var/atom/host = parent if(real_location == I.loc) return FALSE //Means the item is already in the storage item - if(locked) + if(check_locked(null, M, !stop_messages)) if(M && !stop_messages) host.add_fingerprint(M) - to_chat(M, "[host] seems to be locked!") return FALSE if(real_location.contents.len >= max_items) if(!stop_messages) @@ -659,8 +654,10 @@ /datum/component/storage/proc/on_check() return TRUE -/datum/component/storage/proc/check_locked() - return locked +/datum/component/storage/proc/check_locked(datum/source, mob/user, message = FALSE) + . = locked + if(message && . && user) + to_chat(user, "[parent] seems to be locked!") /datum/component/storage/proc/signal_take_type(datum/source, type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted) if(!force) @@ -720,9 +717,7 @@ if(A.loc == user) . = COMPONENT_NO_ATTACK_HAND - if(locked) - to_chat(user, "[parent] seems to be locked!") - else + if(!check_locked(source, user, TRUE)) show_to(user) A.do_jiggle() @@ -747,8 +742,7 @@ /datum/component/storage/proc/on_alt_click(datum/source, mob/user) if(!isliving(user) || !user.CanReach(parent)) return - if(locked) - to_chat(user, "[parent] seems to be locked!") + if(check_locked(source, user, TRUE)) return var/atom/A = parent diff --git a/code/datums/dash_weapon.dm b/code/datums/dash_weapon.dm index 03badb2069..a870ecae66 100644 --- a/code/datums/dash_weapon.dm +++ b/code/datums/dash_weapon.dm @@ -32,7 +32,7 @@ if(!IsAvailable()) return var/turf/T = get_turf(target) - if(target in view(user.client.view, get_turf(user))) + if(target in view(user.client.view, user)) var/obj/spot1 = new phaseout(get_turf(user), user.dir) user.forceMove(T) playsound(T, dash_sound, 25, 1) diff --git a/code/datums/datum.dm b/code/datums/datum.dm index e74e30b536..cdb195dd82 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -2,6 +2,7 @@ var/gc_destroyed //Time when this object was destroyed. var/list/active_timers //for SStimer var/list/datum_components //for /datum/components + var/list/status_traits var/list/comp_lookup //it used to be for looking up components which had registered a signal but now anything can register var/list/signal_procs var/signal_enabled = FALSE diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index ba570eca06..e1432bf9a6 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -117,7 +117,7 @@ /mob/living/carbon/AirborneContractDisease(datum/disease/D, force_spread) if(internal) return - if(has_trait(TRAIT_NOBREATH)) + if(HAS_TRAIT(src, TRAIT_NOBREATH)) return ..() @@ -137,7 +137,7 @@ /mob/living/carbon/human/CanContractDisease(datum/disease/D) if(dna) - if(has_trait(TRAIT_VIRUSIMMUNE) && !D.bypasses_immunity) + if(HAS_TRAIT(src, TRAIT_VIRUSIMMUNE) && !D.bypasses_immunity) return FALSE for(var/thing in D.required_organs) diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index 0ace2ca8fd..e666c7acd6 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -233,7 +233,7 @@ /datum/symptom/heal/coma/CanHeal(datum/disease/advance/A) var/mob/living/M = A.affected_mob - if(M.has_trait(TRAIT_DEATHCOMA)) + if(HAS_TRAIT(M, TRAIT_DEATHCOMA)) return power else if(M.IsUnconscious() || M.stat == UNCONSCIOUS) return power * 0.9 @@ -364,15 +364,15 @@ /datum/symptom/heal/plasma/CanHeal(datum/disease/advance/A) var/mob/living/M = A.affected_mob var/datum/gas_mixture/environment - var/list/gases + var/plasmamount . = 0 if(M.loc) environment = M.loc.return_air() if(environment) - gases = environment.gases - if(gases["plasma"] && gases["plasma"][MOLES] > gases["plasma"][GAS_META][META_GAS_MOLES_VISIBLE]) //if there's enough plasma in the air to see + plasmamount = environment.gases[/datum/gas/plasma] + if(plasmamount && plasmamount > GLOB.meta_gas_visibility[/datum/gas/plasma]) //if there's enough plasma in the air to see . += power * 0.5 if(M.reagents.has_reagent("plasma")) . += power * 0.75 diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index ffc145bd72..8d7cc5ed70 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -85,14 +85,14 @@ if(4, 5) M.restoreEars() - if(M.has_trait(TRAIT_BLIND, EYE_DAMAGE)) + if(HAS_TRAIT_FROM(M, TRAIT_BLIND, EYE_DAMAGE)) if(prob(20)) to_chat(M, "Your vision slowly returns...") M.cure_blind(EYE_DAMAGE) M.cure_nearsighted(EYE_DAMAGE) M.blur_eyes(35) - else if(M.has_trait(TRAIT_NEARSIGHT, EYE_DAMAGE)) + else if(HAS_TRAIT_FROM(M, TRAIT_NEARSIGHT, EYE_DAMAGE)) to_chat(M, "You can finally focus your eyes on distant objects.") M.cure_nearsighted(EYE_DAMAGE) M.blur_eyes(10) diff --git a/code/datums/diseases/advance/symptoms/vision.dm b/code/datums/diseases/advance/symptoms/vision.dm index 0b42012f76..d1cc6905a6 100644 --- a/code/datums/diseases/advance/symptoms/vision.dm +++ b/code/datums/diseases/advance/symptoms/vision.dm @@ -61,7 +61,7 @@ Bonus M.become_nearsighted(EYE_DAMAGE) if(prob(eyes.eye_damage - 10 + 1)) if(!remove_eyes) - if(!M.has_trait(TRAIT_BLIND)) + if(!HAS_TRAIT(M, TRAIT_BLIND)) to_chat(M, "You go blind!") M.become_blind(EYE_DAMAGE) else diff --git a/code/datums/diseases/heart_failure.dm b/code/datums/diseases/heart_failure.dm index 3fbf6ef177..2389052a54 100644 --- a/code/datums/diseases/heart_failure.dm +++ b/code/datums/diseases/heart_failure.dm @@ -57,8 +57,8 @@ if(H.stat == CONSCIOUS) H.visible_message("[H] clutches at [H.p_their()] chest as if [H.p_their()] heart is stopping!") H.adjustStaminaLoss(60) - H.reagents.add_reagent("corazone", 3) // To give the victim a final chance to shock their heart before losing consciousness H.set_heartattack(TRUE) + H.reagents.add_reagent("corazone", 3) // To give the victim a final chance to shock their heart before losing consciousness cure() else diff --git a/code/datums/dna.dm b/code/datums/dna.dm index b3f3f7efa1..938515625d 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -9,6 +9,7 @@ var/list/features = list("FFF") //first value is mutant color var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings, var/nameless = FALSE + var/custom_species //siiiiigh I guess this is important var/list/mutations = list() //All mutations are from now on here var/list/temporary_mutations = list() //Timers for temporary mutations var/list/previous = list() //For temporary name/ui/ue/blood_type modifications @@ -45,6 +46,7 @@ destination.dna.features = features.Copy() destination.dna.real_name = real_name destination.dna.nameless = nameless + destination.dna.custom_species = custom_species destination.dna.temporary_mutations = temporary_mutations.Copy() if(ishuman(destination)) var/mob/living/carbon/human/H = destination @@ -62,6 +64,7 @@ new_dna.species = new species.type new_dna.real_name = real_name new_dna.nameless = nameless + new_dna.custom_species = custom_species new_dna.mutations = mutations.Copy() /datum/dna/proc/add_mutation(mutation_name) @@ -202,7 +205,7 @@ /datum/dna/proc/is_same_as(datum/dna/D) - if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name && nameless == D.nameless) + if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name && nameless == D.nameless && custom_species == D.custom_species) if(species.type == D.species.type && features == D.features && blood_type == D.blood_type) return 1 return 0 diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm index 57cdb9bcf5..6c91cc3a7d 100644 --- a/code/datums/emotes.dm +++ b/code/datums/emotes.dm @@ -133,7 +133,7 @@ if(isliving(user)) var/mob/living/L = user - if(L.has_trait(TRAIT_EMOTEMUTE)) + if(HAS_TRAIT(L, TRAIT_EMOTEMUTE)) return FALSE /datum/emote/sound diff --git a/code/datums/ert.dm b/code/datums/ert.dm index d3c256308d..d61c95c8f2 100644 --- a/code/datums/ert.dm +++ b/code/datums/ert.dm @@ -21,6 +21,8 @@ /datum/ert/amber code = "Amber" + leader_role = /datum/antagonist/ert/commander/red + roles = list(/datum/antagonist/ert/security/red, /datum/antagonist/ert/medic/red, /datum/antagonist/ert/engineer/red) /datum/ert/red leader_role = /datum/antagonist/ert/commander/red diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index d673cdb16d..0623e2f5f9 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -103,11 +103,11 @@ // Can most things breathe? if(trace_gases) continue - if(!(A_gases[/datum/gas/oxygen] && A_gases[/datum/gas/oxygen][MOLES] >= 16)) + if(A_gases[/datum/gas/oxygen] >= 16) continue if(A_gases[/datum/gas/plasma]) continue - if(A_gases[/datum/gas/carbon_dioxide] && A_gases[/datum/gas/carbon_dioxide][MOLES] >= 10) + if(A_gases[/datum/gas/carbon_dioxide] >= 10) continue // Aim for goldilocks temperatures and pressure diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 8a5f0f9439..b0a78211b0 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -191,3 +191,18 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE + +/obj/item/clothing/gloves/krav_maga/combatglovesplus + name = "combat gloves plus" + desc = "These tactical gloves are fireproof and shock resistant, and using nanochip technology it teaches you the powers of krav maga." + icon_state = "black" + item_state = "blackglovesplus" + siemens_coefficient = 0 + permeability_coefficient = 0.05 + strip_delay = 80 + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + heat_protection = HANDS + max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT + resistance_flags = NONE + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index 4a15afd672..035e5ac833 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -179,7 +179,7 @@ /obj/item/twohanded/bostaff/attack(mob/target, mob/living/user) add_fingerprint(user) - if((user.has_trait(TRAIT_CLUMSY)) && prob(50)) + if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) to_chat(user, "You club yourself over the head with [src].") user.Knockdown(60) if(ishuman(user)) diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 4021d11128..06857c0f55 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -125,3 +125,11 @@ /datum/mood_event/surgery description = "HE'S CUTTING ME OPEN!!\n" mood_change = -8 + +/datum/mood_event/sad_empath + description = "Someone seems upset...\n" + mood_change = -2 + timeout = 600 + +/datum/mood_event/sad_empath/add_effects(mob/sadtarget) + description = "[sadtarget.name] seems upset...\n" diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 2422c5ea56..051a548d1d 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -33,6 +33,11 @@ mood_change = 2 timeout = 2400 +/datum/mood_event/bshonk + description = "Quantum mechanics can be fun and silly, too! Honk!\n" + mood_change = 6 + timeout = 4800 + /datum/mood_event/perform_cpr description = "It feels good to save a life.\n" mood_change = 6 @@ -70,3 +75,27 @@ description = "There is something soothing about this music.\n" mood_change = 3 timeout = 600 + +/datum/mood_event/betterhug + description = "Someone was very nice to me.\n" + mood_change = 3 + timeout = 3000 + +/datum/mood_event/betterhug/add_effects(mob/friend) + description = "[friend.name] was very nice to me.\n" + +/datum/mood_event/besthug + description = "Someone is great to be around, they make me feel so happy!\n" + mood_change = 5 + timeout = 3000 + +/datum/mood_event/besthug/add_effects(mob/friend) + description = "[friend.name] is great to be around, [friend.p_they()] makes me feel so happy!\n" + +/datum/mood_event/happy_empath + description = "Someone seems happy!\n" + mood_change = 2 + timeout = 600 + +/datum/mood_event/happy_empath/add_effects(var/mob/happytarget) + description = "[happytarget.name]'s happiness is infectious!\n" diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index e114a43736..461c221ff8 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -86,12 +86,12 @@ /datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner) if(..()) return - owner.add_trait(TRAIT_CLUMSY, GENETIC_MUTATION) + ADD_TRAIT(owner, TRAIT_CLUMSY, GENETIC_MUTATION) /datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner) if(..()) return - owner.remove_trait(TRAIT_CLUMSY, GENETIC_MUTATION) + REMOVE_TRAIT(owner, TRAIT_CLUMSY, GENETIC_MUTATION) //Tourettes causes you to randomly stand in place and shout. @@ -125,12 +125,12 @@ /datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner) if(..()) return - owner.add_trait(TRAIT_DEAF, GENETIC_MUTATION) + ADD_TRAIT(owner, TRAIT_DEAF, GENETIC_MUTATION) /datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner) if(..()) return - owner.remove_trait(TRAIT_DEAF, GENETIC_MUTATION) + REMOVE_TRAIT(owner, TRAIT_DEAF, GENETIC_MUTATION) //Monified turns you into a monkey. diff --git a/code/datums/mutations/cold_resistance.dm b/code/datums/mutations/cold_resistance.dm index 6c3ac2982d..3d8fbababa 100644 --- a/code/datums/mutations/cold_resistance.dm +++ b/code/datums/mutations/cold_resistance.dm @@ -17,14 +17,14 @@ /datum/mutation/human/cold_resistance/on_acquiring(mob/living/carbon/human/owner) if(..()) return - owner.add_trait(TRAIT_RESISTCOLD, "cold_resistance") -// owner.add_trait(TRAIT_RESISTLOWPRESSURE, "cold_resistance") CITADEL CHANGE + ADD_TRAIT(owner, TRAIT_RESISTCOLD, "cold_resistance") +// ADD_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "cold_resistance") CITADEL CHANGE /datum/mutation/human/cold_resistance/on_losing(mob/living/carbon/human/owner) if(..()) return - owner.remove_trait(TRAIT_RESISTCOLD, "cold_resistance") -// owner.remove_trait(TRAIT_RESISTLOWPRESSURE, "cold_resistance") CITADEL CHANGE + REMOVE_TRAIT(owner, TRAIT_RESISTCOLD, "cold_resistance") +// REMOVE_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "cold_resistance") CITADEL CHANGE /datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner) if(owner.getFireLoss()) diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm index 7bcd056fab..0c760f4620 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -11,8 +11,8 @@ /datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner) if(..()) return - owner.add_trait(TRAIT_STUNIMMUNE, TRAIT_HULK) - owner.add_trait(TRAIT_PUSHIMMUNE, TRAIT_HULK) + ADD_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK) + ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK) owner.update_body_parts() SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "hulk", /datum/mood_event/hulk) @@ -28,8 +28,8 @@ /datum/mutation/human/hulk/on_losing(mob/living/carbon/human/owner) if(..()) return - owner.remove_trait(TRAIT_STUNIMMUNE, TRAIT_HULK) - owner.remove_trait(TRAIT_PUSHIMMUNE, TRAIT_HULK) + REMOVE_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK) + REMOVE_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK) owner.update_body_parts() SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "hulk") diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm index 3f303535ce..5c718cf554 100644 --- a/code/datums/mutations/speech.dm +++ b/code/datums/mutations/speech.dm @@ -30,12 +30,12 @@ /datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner) if(..()) return - owner.add_trait(TRAIT_MUTE, GENETIC_MUTATION) + ADD_TRAIT(owner, TRAIT_MUTE, GENETIC_MUTATION) /datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner) if(..()) return - owner.remove_trait(TRAIT_MUTE, GENETIC_MUTATION) + REMOVE_TRAIT(owner, TRAIT_MUTE, GENETIC_MUTATION) /datum/mutation/human/smile diff --git a/code/datums/saymode.dm b/code/datums/saymode.dm index ed6edd11ab..c4f485653e 100644 --- a/code/datums/saymode.dm +++ b/code/datums/saymode.dm @@ -27,7 +27,7 @@ switch(M.lingcheck()) if (LINGHIVE_LING) var/mob/living/L = M - if (!L.has_trait(CHANGELING_HIVEMIND_MUTE)) + if (!HAS_TRAIT(L, CHANGELING_HIVEMIND_MUTE)) to_chat(M, msg) if(LINGHIVE_LINK) to_chat(M, msg) @@ -35,7 +35,7 @@ if(prob(40)) to_chat(M, "We can faintly sense an outsider trying to communicate through the hivemind...") if(LINGHIVE_LING) - if (user.has_trait(CHANGELING_HIVEMIND_MUTE)) + if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE)) to_chat(user, "The poison in the air hinders our ability to interact with the hivemind.") return FALSE var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) @@ -52,7 +52,7 @@ to_chat(M, msg) if(LINGHIVE_LING) var/mob/living/L = M - if (!L.has_trait(CHANGELING_HIVEMIND_MUTE)) + if (!HAS_TRAIT(L, CHANGELING_HIVEMIND_MUTE)) to_chat(M, msg) if(LINGHIVE_OUTSIDER) if(prob(40)) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index dd8ee1b166..0512977d1a 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -465,13 +465,13 @@ /datum/status_effect/hippocraticOath/on_apply() //Makes the user passive, it's in their oath not to harm! - owner.add_trait(TRAIT_PACIFISM, "hippocraticOath") + ADD_TRAIT(owner, TRAIT_PACIFISM, "hippocraticOath") var/datum/atom_hud/H = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] H.add_hud_to(owner) return ..() /datum/status_effect/hippocraticOath/on_remove() - owner.remove_trait(TRAIT_PACIFISM, "hippocraticOath") + REMOVE_TRAIT(owner, TRAIT_PACIFISM, "hippocraticOath") var/datum/atom_hud/H = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] H.remove_hud_from(owner) diff --git a/code/datums/traits/_quirk.dm b/code/datums/traits/_quirk.dm index 963afacec3..cc6dd8db3f 100644 --- a/code/datums/traits/_quirk.dm +++ b/code/datums/traits/_quirk.dm @@ -21,7 +21,7 @@ to_chat(quirk_holder, gain_text) quirk_holder.roundstart_quirks += src if(mob_trait) - quirk_holder.add_trait(mob_trait, ROUNDSTART_TRAIT) + ADD_TRAIT(quirk_holder, mob_trait, ROUNDSTART_TRAIT) START_PROCESSING(SSquirks, src) add() if(spawn_effects) @@ -35,7 +35,7 @@ to_chat(quirk_holder, lose_text) quirk_holder.roundstart_quirks -= src if(mob_trait) - quirk_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT, TRUE) + REMOVE_TRAIT(quirk_holder, mob_trait, ROUNDSTART_TRAIT) SSquirks.quirk_objects -= src return ..() @@ -43,8 +43,8 @@ quirk_holder.roundstart_quirks -= src to_mob.roundstart_quirks += src if(mob_trait) - quirk_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT) - to_mob.add_trait(mob_trait, ROUNDSTART_TRAIT) + REMOVE_TRAIT(quirk_holder, mob_trait, ROUNDSTART_TRAIT) + ADD_TRAIT(to_mob, mob_trait, ROUNDSTART_TRAIT) quirk_holder = to_mob on_transfer() @@ -111,7 +111,7 @@ Use this as a guideline mob_trait = TRAIT_NEARSIGHT ///This define is in __DEFINES/traits.dm and is the actual "trait" that the game tracks - ///You'll need to use "has_trait(X, sources)" checks around the code to check this; for instance, the Ageusia trait is checked in taste code + ///You'll need to use "HAS_TRAIT_FROM(src, X, sources)" checks around the code to check this; for instance, the Ageusia trait is checked in taste code ///If you need help finding where to put it, the declaration finder on GitHub is the best way to locate it gain_text = "Things far away from you start looking blurry." diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index 513115b194..300a1264eb 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -35,6 +35,14 @@ lose_text = "You no longer feel like drinking would ease your pain." medical_record_text = "Patient has unusually efficient liver metabolism and can slowly regenerate wounds by drinking alcoholic beverages." +/datum/quirk/empath + name = "Empath" + desc = "Whether it's a sixth sense or careful study of body language, it only takes you a quick glance at someone to understand how they feel." + value = 2 + mob_trait = TRAIT_EMPATH + gain_text = "You feel in tune with those around you." + lose_text = "You feel isolated from others." + /datum/quirk/freerunning name = "Freerunning" desc = "You're great at quick moves! You can climb tables more quickly." @@ -43,6 +51,15 @@ gain_text = "You feel lithe on your feet!" lose_text = "You feel clumsy again." +/datum/quirk/friendly + name = "Friendly" + desc = "You give the best hugs, especially when you're in the right mood." + value = 1 + mob_trait = TRAIT_FRIENDLY + gain_text = "You want to hug someone." + lose_text = "You no longer feel compelled to hug others." + mood_quirk = TRUE + /datum/quirk/jolly name = "Jolly" desc = "You sometimes just feel happy, for no reason at all." diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm index 4fc30de473..f70e3a3c68 100644 --- a/code/datums/traits/neutral.dm +++ b/code/datums/traits/neutral.dm @@ -84,3 +84,21 @@ /datum/quirk/monochromatic/remove() if(quirk_holder) quirk_holder.remove_client_colour(/datum/client_colour/monochrome) + +/datum/quirk/crocrin_immunity + name = "Crocin Immunity" + desc = "You're one of the few people in the galaxy who are genetically immune to Crocin and Hexacrocin products and their addictive properties! However, you can still get brain damage from Hexacrocin addiction." + mob_trait = TRAIT_CROCRIN_IMMUNE + value = 0 + gain_text = "You feel more prudish." + lose_text = "You don't feel as prudish as before." + medical_record_text = "Patient exhibits a special gene that makes them immune to Crocin and Hexacrocin." + +/datum/quirk/assblastusa + name = "Buns of Steel" + desc = "You've never skipped ass day. With this trait, you are completely immune to all forms of ass slapping and anyone who tries to slap your rock hard ass usually gets a broken hand." + mob_trait = TRAIT_ASSBLASTUSA + value = 0 + medical_record_text = "Patient never skipped ass day." + gain_text = "Your ass rivals those of golems." + lose_text = "Your butt feels more squishy and slappable." \ No newline at end of file diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm index 0906a7e053..f3b8118087 100644 --- a/code/datums/weather/weather_types/radiation_storm.dm +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -33,7 +33,7 @@ if(prob(40)) if(ishuman(L)) var/mob/living/carbon/human/H = L - if(H.dna && !H.has_trait(TRAIT_RADIMMUNE)) + if(H.dna && !HAS_TRAIT(H, TRAIT_RADIMMUNE)) if(prob(max(0,100-resist))) H.randmuti() if(prob(50)) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 48596a0b6d..81e2371f9a 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -6,7 +6,6 @@ var/flags_1 = NONE var/interaction_flags_atom = NONE - var/container_type = NONE var/datum/reagents/reagents = null //This atom's HUD (med/sec, etc) images. Associative list. @@ -203,16 +202,16 @@ return is_refillable() && is_drainable() /atom/proc/is_injectable(allowmobs = TRUE) - return reagents && (container_type & (INJECTABLE | REFILLABLE)) + return reagents && (reagents.reagents_holder_flags & (INJECTABLE | REFILLABLE)) /atom/proc/is_drawable(allowmobs = TRUE) - return reagents && (container_type & (DRAWABLE | DRAINABLE)) + return reagents && (reagents.reagents_holder_flags & (DRAWABLE | DRAINABLE)) /atom/proc/is_refillable() - return reagents && (container_type & REFILLABLE) + return reagents && (reagents.reagents_holder_flags & REFILLABLE) /atom/proc/is_drainable() - return reagents && (container_type & DRAINABLE) + return reagents && (reagents.reagents_holder_flags & DRAINABLE) /atom/proc/AllowDrop() @@ -261,7 +260,7 @@ to_chat(user, desc) if(reagents) - if(container_type & TRANSPARENT) + if(reagents.reagents_holder_flags & TRANSPARENT) to_chat(user, "It contains:") if(reagents.reagent_list.len) if(user.can_see_reagents()) //Show each individual reagent @@ -274,7 +273,7 @@ to_chat(user, "[total_volume] units of various reagents") else to_chat(user, "Nothing.") - else if(container_type & AMOUNT_VISIBLE) + else if(reagents.reagents_holder_flags & AMOUNT_VISIBLE) if(reagents.total_volume) to_chat(user, "It has [reagents.total_volume] unit\s left.") else diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index e56f6d366c..c37c120b93 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -31,6 +31,7 @@ var/atom/movable/pulling var/grab_state = 0 var/throwforce = 0 + var/can_be_z_moved = TRUE /atom/movable/vv_edit_var(var_name, var_value) var/static/list/banned_edits = list("step_x", "step_y", "step_size") diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 3af43ffb78..8506a4133a 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -100,7 +100,7 @@ //helper for getting the appropriate health status /proc/RoundHealth(mob/living/M) - if(M.stat == DEAD || (M.has_trait(TRAIT_FAKEDEATH))) + if(M.stat == DEAD || (HAS_TRAIT(M, TRAIT_FAKEDEATH))) return "health-100" //what's our health? it doesn't matter, we're dead, or faking var/maxi_health = M.maxHealth if(iscarbon(M) && M.health < 0) @@ -172,7 +172,7 @@ var/image/holder = hud_list[STATUS_HUD] var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size - if(stat == DEAD || (has_trait(TRAIT_FAKEDEATH))) + if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) holder.icon_state = "huddead" else holder.icon_state = "hudhealthy" @@ -182,9 +182,9 @@ var/icon/I = icon(icon, icon_state, dir) var/virus_threat = check_virus() holder.pixel_y = I.Height() - world.icon_size - if(has_trait(TRAIT_XENO_HOST)) + if(HAS_TRAIT(src, TRAIT_XENO_HOST)) holder.icon_state = "hudxeno" - else if(stat == DEAD || (has_trait(TRAIT_FAKEDEATH))) + else if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) if(tod) var/tdelta = round(world.time - timeofdeath) if(tdelta < (DEFIB_TIME_LIMIT * 10)) @@ -242,7 +242,7 @@ var/icon/IC = icon(icon, icon_state, dir) holder.pixel_y = IC.Height() - world.icon_size holder.icon_state = "hud_imp_chem" - if(has_trait(TRAIT_MINDSHIELD)) + if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) holder = hud_list[IMPLOYAL_HUD] var/icon/IC = icon(icon, icon_state, dir) holder.pixel_y = IC.Height() - world.icon_size diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index d6513b5d40..a24d846f15 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -64,7 +64,7 @@ Credit where due: return FALSE if(isliving(M)) var/mob/living/L = M - if(L.has_trait(TRAIT_MINDSHIELD)) + if(HAS_TRAIT(L, TRAIT_MINDSHIELD)) return FALSE if(ishuman(M) || isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab) || istype(M, /mob/camera/eminence)) return TRUE @@ -131,7 +131,7 @@ Credit where due: config_tag = "clockwork_cult" antag_flag = ROLE_SERVANT_OF_RATVAR false_report_weight = 10 - required_players = 30 + required_players = 35 required_enemies = 3 recommended_enemies = 5 enemy_minimum_age = 7 diff --git a/code/game/gamemodes/clown_ops/clown_ops.dm b/code/game/gamemodes/clown_ops/clown_ops.dm index 12d3106c8d..a666b57afd 100644 --- a/code/game/gamemodes/clown_ops/clown_ops.dm +++ b/code/game/gamemodes/clown_ops/clown_ops.dm @@ -62,5 +62,6 @@ /datum/outfit/syndicate/clownop/leader name = "Clown Operative Leader - Basic" id = /obj/item/card/id/syndicate/nuke_leader + gloves = /obj/item/clothing/gloves/krav_maga/combatglovesplus r_hand = /obj/item/nuclear_challenge/clownops command_radio = TRUE diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 7b492e3a95..8f091b6372 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -26,7 +26,7 @@ return FALSE else return FALSE - if(M.has_trait(TRAIT_MINDSHIELD) || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M) || !M.client) + if(HAS_TRAIT(M, TRAIT_MINDSHIELD) || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M) || !M.client) return FALSE //can't convert machines, shielded, braindead, or ratvar's dogs return TRUE diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index d76552982c..615d55a818 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -137,6 +137,7 @@ /datum/outfit/syndicate/leader name = "Syndicate Leader - Basic" id = /obj/item/card/id/syndicate/nuke_leader + gloves = /obj/item/clothing/gloves/krav_maga/combatglovesplus r_hand = /obj/item/nuclear_challenge command_radio = TRUE diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm index 6603bb3604..e56495d808 100644 --- a/code/game/gamemodes/objective_items.dm +++ b/code/game/gamemodes/objective_items.dm @@ -124,7 +124,7 @@ /datum/objective_item/steal/plasma/check_special_completion(obj/item/tank/T) var/target_amount = text2num(name) var/found_amount = 0 - found_amount += T.air_contents.gases[/datum/gas/plasma] ? T.air_contents.gases[/datum/gas/plasma][MOLES] : 0 + found_amount += T.air_contents.gases[/datum/gas/plasma] return found_amount>=target_amount diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 7137f28185..aa363428fb 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -151,6 +151,22 @@ if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len) for(var/datum/reagent/R in mob_occupant.reagents.reagent_list) data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume)) + if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner. + var/mob/living/carbon/C = mob_occupant + var/blood_id = C.get_blood_id() + if(blood_id) + data["occupant"]["blood"] = list() // We can start populating this list. + var/blood_type = C.dna.blood_type + if(blood_id != "blood") // special blood substance + var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id] + if(R) + blood_type = R.name + else + blood_type = blood_id + data["occupant"]["blood"]["maxBloodVolume"] = BLOOD_VOLUME_NORMAL + data["occupant"]["blood"]["currentBloodVolume"] = C.blood_volume + data["occupant"]["blood"]["dangerBloodVolume"] = BLOOD_VOLUME_SAFE + data["occupant"]["blood"]["bloodType"] = blood_type return data /obj/machinery/sleeper/ui_act(action, params) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 7e75dc8e8e..36a5c6ede4 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -50,6 +50,8 @@ radio.canhear_range = 0 radio.recalculateChannels() + update_icon() + /obj/machinery/clonepod/Destroy() go_out() QDEL_NULL(radio) @@ -151,7 +153,6 @@ if(clonemind.damnation_type) //Can't clone the damned. INVOKE_ASYNC(src, .proc/horrifyingsound) mess = TRUE - icon_state = "pod_g" update_icon() return FALSE @@ -179,14 +180,13 @@ clonename = "clone ([rand(1,999)])" H.real_name = clonename - icon_state = "pod_1" //Get the clone body ready maim_clone(H) - H.add_trait(TRAIT_STABLEHEART, "cloning") - H.add_trait(TRAIT_EMOTEMUTE, "cloning") - H.add_trait(TRAIT_MUTE, "cloning") - H.add_trait(TRAIT_NOBREATH, "cloning") - H.add_trait(TRAIT_NOCRITDAMAGE, "cloning") + ADD_TRAIT(H, TRAIT_STABLEHEART, "cloning") + ADD_TRAIT(H, TRAIT_EMOTEMUTE, "cloning") + ADD_TRAIT(H, TRAIT_MUTE, "cloning") + ADD_TRAIT(H, TRAIT_NOBREATH, "cloning") + ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, "cloning") H.Unconscious(80) clonemind.transfer_to(H) @@ -278,10 +278,10 @@ else if (!mob_occupant || mob_occupant.loc != src) occupant = null - if (!mess && !panel_open) - icon_state = "pod_0" use_power(200) + update_icon() + //Let's unlock this early I guess. Might be too early, needs tweaking. /obj/machinery/clonepod/attackby(obj/item/W, mob/user, params) if(!(occupant || mess)) @@ -355,17 +355,17 @@ mess = FALSE new /obj/effect/gibspawner/generic(get_turf(src)) audible_message("You hear a splat.") - icon_state = "pod_0" + update_icon() return if(!mob_occupant) return - mob_occupant.remove_trait(TRAIT_STABLEHEART, "cloning") - mob_occupant.remove_trait(TRAIT_EMOTEMUTE, "cloning") - mob_occupant.remove_trait(TRAIT_MUTE, "cloning") - mob_occupant.remove_trait(TRAIT_NOCRITDAMAGE, "cloning") - mob_occupant.remove_trait(TRAIT_NOBREATH, "cloning") + REMOVE_TRAIT(mob_occupant, TRAIT_STABLEHEART, "cloning") + REMOVE_TRAIT(mob_occupant, TRAIT_EMOTEMUTE, "cloning") + REMOVE_TRAIT(mob_occupant, TRAIT_MUTE, "cloning") + REMOVE_TRAIT(mob_occupant, TRAIT_NOCRITDAMAGE, "cloning") + REMOVE_TRAIT(mob_occupant, TRAIT_NOBREATH, "cloning") if(grab_ghost_when == CLONER_MATURE_CLONE) mob_occupant.grab_ghost() @@ -373,7 +373,7 @@ mob_occupant.flash_act() occupant.forceMove(T) - icon_state = "pod_0" + update_icon() mob_occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest. for(var/fl in unattached_flesh) qdel(fl) @@ -389,7 +389,7 @@ technician, as your warranty may be affected.") mess = TRUE maim_clone(mob_occupant) //Remove every bit that's grown back so far to drop later, also destroys bits that haven't grown yet - icon_state = "pod_g" + update_icon() if(mob_occupant.mind != clonemind) clonemind.transfer_to(mob_occupant) mob_occupant.grab_ghost() // We really just want to make you suffer. @@ -452,7 +452,7 @@ // brain function, they also have no limbs or internal organs. - if(!H.has_trait(TRAIT_NODISMEMBER)) + if(!HAS_TRAIT(H, TRAIT_NODISMEMBER)) var/static/list/zones = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) for(var/zone in zones) var/obj/item/bodypart/BP = H.get_bodypart(zone) @@ -471,6 +471,54 @@ flesh_number = unattached_flesh.len +#define CRYOMOBS 'icons/obj/cryo_mobs.dmi' + +/obj/machinery/clonepod/update_icon() + cut_overlays() + + if(mess) + icon_state = "pod_g" + var/image/gib1 = image(CRYOMOBS, "gibup") + var/image/gib2 = image(CRYOMOBS, "gibdown") + gib1.pixel_y = 27 + round(sin(world.time) * 3) + gib1.pixel_x = round(sin(world.time * 3)) + gib2.pixel_y = 27 + round(cos(world.time) * 3) + gib2.pixel_x = round(cos(world.time * 3)) + add_overlay(gib2) + add_overlay(gib1) + add_overlay("cover-on") + + else if(occupant) + icon_state = "pod_1" + + var/image/occupant_overlay + var/completion = (flesh_number - unattached_flesh.len) / flesh_number + + if(unattached_flesh.len <= 0) + occupant_overlay = image(occupant.icon, occupant.icon_state) + occupant_overlay.copy_overlays(occupant) + else + occupant_overlay = image(CRYOMOBS, "clone_meat") + var/matrix/tform = matrix() + tform.Scale(completion) + tform.Turn(cos(world.time * 2) * 3) + occupant_overlay.transform = tform + occupant_overlay.appearance_flags = 0 + + occupant_overlay.dir = SOUTH + occupant_overlay.pixel_y = 27 + round(sin(world.time) * 3) + occupant_overlay.pixel_x = round(sin(world.time * 3)) + + add_overlay(occupant_overlay) + add_overlay("cover-on") + else + icon_state = "pod_0" + + if(panel_open) + icon_state = "pod_0_maintenance" + + add_overlay("panel") + /* * Manual -- A big ol' manual. */ diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 1f262c0979..13d5cff3b8 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1,3 +1,8 @@ +#define ARCADE_WEIGHT_TRICK 4 +#define ARCADE_WEIGHT_USELESS 2 +#define ARCADE_WEIGHT_RARE 1 + + /obj/machinery/computer/arcade name = "random arcade" desc = "random arcade machine" @@ -6,55 +11,66 @@ icon_screen = "invaders" clockwork = TRUE //it'd look weird var/list/prizes = list( - /obj/item/storage/box/snappops = 8, - /obj/item/toy/talking/AI = 8, - /obj/item/toy/talking/codex_gigas = 8, - /obj/item/clothing/under/syndicate/tacticool = 8, - /obj/item/toy/sword = 8, - /obj/item/toy/gun = 8, - /obj/item/gun/ballistic/shotgun/toy/crossbow = 8, - /obj/item/storage/box/fakesyndiesuit = 8, - /obj/item/storage/crayons = 8, - /obj/item/toy/spinningtoy = 8, - /obj/item/toy/prize/ripley = 4, - /obj/item/toy/prize/fireripley = 4, - /obj/item/toy/prize/deathripley = 4, - /obj/item/toy/prize/gygax = 4, - /obj/item/toy/prize/durand = 4, - /obj/item/toy/prize/honk = 4, - /obj/item/toy/prize/marauder = 4, - /obj/item/toy/prize/seraph = 4, - /obj/item/toy/prize/mauler = 4, - /obj/item/toy/prize/odysseus = 4, - /obj/item/toy/prize/phazon = 4, - /obj/item/toy/prize/reticence = 4, - /obj/item/toy/cards/deck = 8, - /obj/item/toy/nuke = 8, - /obj/item/toy/minimeteor = 8, - /obj/item/toy/redbutton = 8, - /obj/item/toy/talking/owl = 8, - /obj/item/toy/talking/griffin = 8, - /obj/item/coin/antagtoken = 8, - /obj/item/stack/tile/fakespace/loaded = 8, - /obj/item/stack/tile/fakepit/loaded = 8, - /obj/item/toy/toy_xeno = 8, - /obj/item/storage/box/actionfigure = 4, - /obj/item/restraints/handcuffs/fake = 8, - /obj/item/grenade/chem_grenade/glitter/pink = 4, - /obj/item/grenade/chem_grenade/glitter/blue = 4, - /obj/item/grenade/chem_grenade/glitter/white = 4, - /obj/item/toy/eightball = 8, - /obj/item/toy/windupToolbox = 8, - /obj/item/toy/clockwork_watch = 8, - /obj/item/toy/toy_dagger = 8, - /obj/item/extendohand/acme = 4, - /obj/item/hot_potato/harmless/toy = 4, - /obj/item/card/emagfake = 4, - /obj/item/clothing/shoes/wheelys = 8, - /obj/item/clothing/shoes/kindleKicks = 8, - /obj/item/storage/belt/military/snack = 8, - /obj/item/toy/plush/random = 450 - )//plushies have a 0.6 chance + /obj/item/toy/balloon = ARCADE_WEIGHT_USELESS, + /obj/item/toy/beach_ball = ARCADE_WEIGHT_USELESS, + /obj/item/toy/cattoy = ARCADE_WEIGHT_USELESS, + /obj/item/toy/clockwork_watch = ARCADE_WEIGHT_TRICK, + /obj/item/toy/dummy = ARCADE_WEIGHT_TRICK, + /obj/item/toy/eightball = ARCADE_WEIGHT_USELESS, + /obj/item/toy/eightball/haunted = ARCADE_WEIGHT_RARE, + /obj/item/storage/box/actionfigure = ARCADE_WEIGHT_USELESS, + /obj/item/toy/foamblade = ARCADE_WEIGHT_TRICK, + /obj/item/toy/gun = ARCADE_WEIGHT_TRICK, + /obj/item/toy/gun/justicar = ARCADE_WEIGHT_TRICK, + /obj/item/toy/gun/m41 = ARCADE_WEIGHT_TRICK, + /obj/item/toy/katana = ARCADE_WEIGHT_TRICK, + /obj/item/toy/minimeteor = ARCADE_WEIGHT_TRICK, + /obj/item/toy/nuke = ARCADE_WEIGHT_TRICK, + /obj/item/toy/plush/random = ARCADE_WEIGHT_USELESS, + /obj/item/toy/redbutton = ARCADE_WEIGHT_TRICK, + /obj/item/toy/spinningtoy = ARCADE_WEIGHT_TRICK, + /obj/item/toy/sword = ARCADE_WEIGHT_TRICK, + /obj/item/toy/sword/cx = ARCADE_WEIGHT_TRICK, + /obj/item/toy/sword/darksabre = ARCADE_WEIGHT_TRICK, + /obj/item/toy/talking/AI = ARCADE_WEIGHT_USELESS, + /obj/item/toy/talking/codex_gigas = ARCADE_WEIGHT_USELESS, + /obj/item/toy/talking/griffin = ARCADE_WEIGHT_USELESS, + /obj/item/toy/talking/owl = ARCADE_WEIGHT_USELESS, + /obj/item/toy/toy_dagger = ARCADE_WEIGHT_TRICK, + /obj/item/toy/toy_xeno = ARCADE_WEIGHT_TRICK, + /obj/item/toy/windupToolbox = ARCADE_WEIGHT_TRICK, + + /obj/item/twohanded/dualsaber/toy = ARCADE_WEIGHT_RARE, + /mob/living/simple_animal/bot/secbot/grievous/toy = ARCADE_WEIGHT_RARE, + /obj/item/clothing/mask/facehugger/toy = ARCADE_WEIGHT_RARE, + /obj/item/gun/ballistic/automatic/toy/pistol/unrestricted = ARCADE_WEIGHT_TRICK, + /obj/item/hot_potato/harmless/toy = ARCADE_WEIGHT_RARE, + /obj/item/twohanded/dualsaber/toy = ARCADE_WEIGHT_RARE, + /obj/item/twohanded/hypereutactic/toy = ARCADE_WEIGHT_RARE, + /obj/item/twohanded/hypereutactic/toy/rainbow = ARCADE_WEIGHT_RARE, + + /obj/item/storage/box/snappops = ARCADE_WEIGHT_TRICK, + /obj/item/clothing/under/syndicate/tacticool = ARCADE_WEIGHT_TRICK, + /obj/item/gun/ballistic/shotgun/toy/crossbow = ARCADE_WEIGHT_TRICK, + /obj/item/storage/box/fakesyndiesuit = ARCADE_WEIGHT_TRICK, + /obj/item/storage/crayons = ARCADE_WEIGHT_USELESS, + /obj/item/coin/antagtoken = ARCADE_WEIGHT_USELESS, + /obj/item/stack/tile/fakespace/loaded = ARCADE_WEIGHT_TRICK, + /obj/item/stack/tile/fakepit/loaded = ARCADE_WEIGHT_TRICK, + /obj/item/restraints/handcuffs/fake = ARCADE_WEIGHT_TRICK, + + /obj/item/grenade/chem_grenade/glitter/pink = ARCADE_WEIGHT_TRICK, + /obj/item/grenade/chem_grenade/glitter/blue = ARCADE_WEIGHT_TRICK, + /obj/item/grenade/chem_grenade/glitter/white = ARCADE_WEIGHT_TRICK, + + /obj/item/extendohand/acme = ARCADE_WEIGHT_TRICK, + /obj/item/card/emagfake = ARCADE_WEIGHT_TRICK, + /obj/item/clothing/shoes/wheelys = ARCADE_WEIGHT_RARE, + /obj/item/clothing/shoes/kindleKicks = ARCADE_WEIGHT_RARE, + /obj/item/storage/belt/military/snack = ARCADE_WEIGHT_RARE, + + /obj/item/clothing/mask/fakemoustache/italian = ARCADE_WEIGHT_RARE + ) light_color = LIGHT_COLOR_GREEN @@ -74,7 +90,8 @@ /obj/machinery/computer/arcade/proc/prizevend(mob/user) SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "arcade", /datum/mood_event/arcade) - if(prob(0.0001)) //1 in a million + + if(prob(1) && prob(1) && prob(1)) //Proper 1 in a million new /obj/item/gun/energy/pulse/prize(src) SSmedals.UnlockMedal(MEDAL_PULSE, usr.client) @@ -124,6 +141,8 @@ var/blocked = FALSE //Player cannot attack/heal while set var/turtle = 0 + var/turn_speed = 5 //Measured in deciseconds. + /obj/machinery/computer/arcade/battle/Reset() var/name_action var/name_part1 @@ -172,7 +191,7 @@ if(turtle > 0) turtle-- - sleep(10) + sleep(turn_speed) enemy_hp -= attackamt arcade_action(usr) @@ -185,7 +204,7 @@ updateUsrDialog() turtle++ - sleep(10) + sleep(turn_speed) player_mp -= pointamt player_hp += healamt blocked = TRUE @@ -202,7 +221,7 @@ turtle-- updateUsrDialog() - sleep(10) + sleep(turn_speed) arcade_action(usr) if (href_list["close"]) @@ -211,10 +230,10 @@ else if (href_list["newgame"]) //Reset everything temp = "New Round" - player_hp = 30 - player_mp = 10 - enemy_hp = 45 - enemy_mp = 20 + player_hp = initial(player_hp) + player_mp = initial(player_mp) + enemy_hp = initial(enemy_hp) + enemy_mp = initial(enemy_mp) gameover = FALSE turtle = 0 @@ -260,7 +279,7 @@ if (player_mp <= 0) gameover = TRUE - sleep(10) + sleep(turn_speed) temp = "You have been drained! GAME OVER" playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10) if(obj_flags & EMAGGED) diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 94f5e63afb..cb3cbf2aa6 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -80,9 +80,21 @@ /obj/machinery/computer/atmos_alert/update_icon() ..() + cut_overlays() + SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + var/overlay_state = icon_screen if(stat & (NOPOWER|BROKEN)) + add_overlay("[icon_keyboard]_off") return + add_overlay(icon_keyboard) if(priority_alarms.len) + overlay_state = "alert:2" add_overlay("alert:2") else if(minor_alarms.len) + overlay_state = "alert:1" add_overlay("alert:1") + else + overlay_state = "alert:0" + add_overlay("alert:0") + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir) + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128) diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index baa6fa577e..6576f51e46 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -59,8 +59,8 @@ var/total_moles = air_sample.total_moles() if(total_moles) for(var/gas_id in air_sample.gases) - var/gas_name = air_sample.gases[gas_id][GAS_META][META_GAS_NAME] - signal.data["gases"][gas_name] = air_sample.gases[gas_id][MOLES] / total_moles * 100 + var/gas_name = GLOB.meta_gas_names[gas_id] + signal.data["gases"][gas_name] = air_sample.gases[gas_id] / total_moles * 100 radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 00a5c8941d..39d5c3d56f 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -450,7 +450,7 @@ scantemp = "Subject's brain is not responding to scanning stimuli." playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) return - if((mob_occupant.has_trait(TRAIT_NOCLONE)) && (src.scanner.scan_level < 2)) + if((HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && (src.scanner.scan_level < 2)) scantemp = "Subject no longer contains the fundamental materials required to create a living clone." playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) return diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 09cbb68083..ccc2121929 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -103,7 +103,9 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD) return data_by_z["[z]"] - var/list/results = list() + var/list/results_damaged = list() + var/list/results_undamaged = list() + var/obj/item/clothing/under/U var/obj/item/card/id/I var/turf/pos @@ -114,6 +116,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) var/toxdam var/burndam var/brutedam + var/totaldam var/area var/pos_x var/pos_y @@ -157,11 +160,13 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) toxdam = round(H.getToxLoss(),1) burndam = round(H.getFireLoss(),1) brutedam = round(H.getBruteLoss(),1) + totaldam = oxydam + toxdam + burndam + brutedam else oxydam = null toxdam = null burndam = null brutedam = null + totaldam = 0 if (nanite_sensors || U.sensor_mode >= SENSOR_COORDS) if (!pos) @@ -174,16 +179,26 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) pos_x = null pos_y = null - results[++results.len] = list("name" = name, "assignment" = assignment, "ijob" = ijob, "life_status" = life_status, "oxydam" = oxydam, "toxdam" = toxdam, "burndam" = burndam, "brutedam" = brutedam, "area" = area, "pos_x" = pos_x, "pos_y" = pos_y, "can_track" = H.can_track(null)) + var/total_list = list("name" = name, "assignment" = assignment, "ijob" = ijob, "life_status" = life_status, "oxydam" = oxydam, "toxdam" = toxdam, "burndam" = burndam, "brutedam" = brutedam, "totaldam" = totaldam, "area" = area, "pos_x" = pos_x, "pos_y" = pos_y, "can_track" = H.can_track(null)) - data_by_z["[z]"] = sortTim(results,/proc/sensor_compare) + if(totaldam) + results_damaged[++results_damaged.len] = total_list + else + results_undamaged[++results_undamaged.len] = total_list + + var/list/returning = sortTim(results_damaged,/proc/damage_compare) + sortTim(results_undamaged,/proc/ijob_compare) + + data_by_z["[z]"] = returning last_update["[z]"] = world.time - return results + return returning -/proc/sensor_compare(list/a,list/b) +/proc/ijob_compare(list/a,list/b) return a["ijob"] - b["ijob"] +/proc/damage_compare(list/a,list/b) + return b["totaldam"] - a["totaldam"] + /datum/crewmonitor/ui_act(action,params) var/mob/living/silicon/ai/AI = usr if(!istype(AI)) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 2980c741be..9d49574317 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -76,7 +76,7 @@ if(connected && connected.is_operational()) if(connected.occupant) //set occupant_status message viable_occupant = connected.occupant - if(viable_occupant.has_dna() && !viable_occupant.has_trait(TRAIT_RADIMMUNE) && !viable_occupant.has_trait(TRAIT_NOCLONE) || (connected.scan_level == 3)) //occupant is viable for dna modification + if(viable_occupant.has_dna() && !HAS_TRAIT(viable_occupant, TRAIT_RADIMMUNE) && !HAS_TRAIT(viable_occupant, TRAIT_NOCLONE) || (connected.scan_level == 3)) //occupant is viable for dna modification occupant_status += "[viable_occupant.name] => " switch(viable_occupant.stat) if(CONSCIOUS) @@ -523,7 +523,7 @@ var/mob/living/carbon/viable_occupant = null if(connected) viable_occupant = connected.occupant - if(!istype(viable_occupant) || !viable_occupant.dna || viable_occupant.has_trait(TRAIT_RADIMMUNE) || viable_occupant.has_trait(TRAIT_NOCLONE)) + if(!istype(viable_occupant) || !viable_occupant.dna || HAS_TRAIT(viable_occupant, TRAIT_RADIMMUNE) || HAS_TRAIT(viable_occupant, TRAIT_NOCLONE)) viable_occupant = null return viable_occupant diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 6769244335..36ba4b0c94 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -76,12 +76,23 @@ /obj/machinery/computer/station_alert/update_icon() ..() + cut_overlays() + SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + var/overlay_state = icon_screen if(stat & (NOPOWER|BROKEN)) + add_overlay("[icon_keyboard]_off") return + add_overlay(icon_keyboard) var/active_alarms = FALSE for(var/cat in alarms) var/list/L = alarms[cat] if(L.len) active_alarms = TRUE if(active_alarms) + overlay_state = "alert:2" add_overlay("alert:2") + else + overlay_state = "alert:0" + add_overlay("alert:0") + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir) + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128) diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index 507d6c6f43..7895fb8c9f 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -1,7 +1,7 @@ /obj/machinery/dna_scannernew name = "\improper DNA scanner" desc = "It scans DNA structures." - icon = 'icons/obj/machines/cloning.dmi' + icon = 'icons/obj/Cryogenic2.dmi' icon_state = "scanner" density = TRUE use_power = IDLE_POWER_USE @@ -99,7 +99,7 @@ var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) if(istype(mob_occupant)) if(locate_computer(/obj/machinery/computer/cloning)) - if(!mob_occupant.suiciding && !(mob_occupant.has_trait(TRAIT_NOCLONE)) && !mob_occupant.hellbound) + if(!mob_occupant.suiciding && !(HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && !mob_occupant.hellbound) mob_occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src) // DNA manipulators cannot operate on severed heads or brains diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 0183fcecd4..1081cb5fa7 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -763,7 +763,7 @@ if(ishuman(user) && prob(40) && src.density) var/mob/living/carbon/human/H = user - if((H.has_trait(TRAIT_DUMB)) && Adjacent(user)) + if((HAS_TRAIT(H, TRAIT_DUMB)) && Adjacent(user)) playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) if(!istype(H.head, /obj/item/clothing/head/helmet)) H.visible_message("[user] headbutts the airlock.", \ diff --git a/code/game/machinery/exp_cloner.dm b/code/game/machinery/exp_cloner.dm index 45ac999a6a..e8364d2271 100644 --- a/code/game/machinery/exp_cloner.dm +++ b/code/game/machinery/exp_cloner.dm @@ -42,11 +42,11 @@ icon_state = "pod_1" //Get the clone body ready maim_clone(H) - H.add_trait(TRAIT_STABLEHEART, "cloning") - H.add_trait(TRAIT_EMOTEMUTE, "cloning") - H.add_trait(TRAIT_MUTE, "cloning") - H.add_trait(TRAIT_NOBREATH, "cloning") - H.add_trait(TRAIT_NOCRITDAMAGE, "cloning") + ADD_TRAIT(H, TRAIT_STABLEHEART, "cloning") + ADD_TRAIT(H, TRAIT_EMOTEMUTE, "cloning") + ADD_TRAIT(H, TRAIT_MUTE, "cloning") + ADD_TRAIT(H, TRAIT_NOBREATH, "cloning") + ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, "cloning") H.Unconscious(80) var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone?", null, null, null, 100, H) @@ -268,7 +268,7 @@ scantemp = "Unable to locate valid genetic data." playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) return - if((mob_occupant.has_trait(TRAIT_NOCLONE)) && (src.scanner.scan_level < 2)) + if((HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && (src.scanner.scan_level < 2)) scantemp = "Subject no longer contains the fundamental materials required to create a living clone." playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) return diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 1f40672e05..0042da1c92 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -73,7 +73,7 @@ say("Subject is not organic.") playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1) return - if(!allow_living && !(C.stat == DEAD || C.has_trait(TRAIT_FAKEDEATH))) //I mean, the machines scanners arent advanced enough to tell you're alive + if(!allow_living && !(C.stat == DEAD || HAS_TRAIT(C, TRAIT_FAKEDEATH))) //I mean, the machines scanners arent advanced enough to tell you're alive say("Subject is still alive.") playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1) return diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 03c60be91c..7284b3c738 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -81,6 +81,12 @@ to_chat(usr, "The drip beeps: Warning, incompatible creature!") return + var/mob/living/L + if(isliving(target)) + L = target + if(!L.can_inject(usr, 1)) + return + if(Adjacent(target) && usr.Adjacent(target)) if(beaker) usr.visible_message("[usr] attaches [src] to [target].", "You attach [src] to [target].") diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index 8a0658fd0f..a3250fe1b0 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -10,7 +10,6 @@ icon = 'icons/obj/machines/limbgrower.dmi' icon_state = "limbgrower_idleoff" density = TRUE - container_type = OPENCONTAINER use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 100 @@ -34,7 +33,7 @@ ) /obj/machinery/limbgrower/Initialize() - create_reagents(100) + create_reagents(100, OPENCONTAINER) stored_research = new /datum/techweb/specialized/autounlocking/limbgrower . = ..() diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 911bb76bda..b0204ddeb8 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -485,7 +485,7 @@ threatcount += 4 if(shoot_unloyal) - if (!perp.has_trait(TRAIT_MINDSHIELD)) + if (!HAS_TRAIT(perp, TRAIT_MINDSHIELD)) threatcount += 4 return threatcount diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 94b6eee8aa..927608d3d5 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -15,7 +15,9 @@ /obj/item/gun/energy, /obj/item/melee/baton, /obj/item/ammo_box/magazine/recharge, - /obj/item/modular_computer)) + /obj/item/modular_computer, + /obj/item/gun/ballistic/automatic/magrifle_e, + /obj/item/gun/ballistic/automatic/pistol/mag_e)) /obj/machinery/recharger/RefreshParts() for(var/obj/item/stock_parts/capacitor/C in component_parts) diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index f3d5a664e8..ff40a8539a 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -96,7 +96,7 @@ /obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE) var/list/to_eat - if(istype(AM0, /obj/item)) + if(isitem(AM0)) to_eat = AM0.GetAllContents() else to_eat = list(AM0) @@ -107,7 +107,7 @@ var/atom/movable/AM = i var/obj/item/bodypart/head/as_head = AM var/obj/item/mmi/as_mmi = AM - var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain) + var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || isbrain(AM) if(brain_holder) emergency_stop(AM) else if(isliving(AM)) @@ -115,9 +115,14 @@ crush_living(AM) else emergency_stop(AM) - else if(istype(AM, /obj/item)) - recycle_item(AM) - items_recycled++ + else if(isitem(AM)) + var/obj/O = AM + if(O.resistance_flags & INDESTRUCTIBLE) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) + O.forceMove(loc) + else + recycle_item(AM) + items_recycled++ else playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) AM.forceMove(loc) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 43e8dff2b9..b84db2ca8d 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -63,7 +63,7 @@ storage_type = /obj/item/watertank/atmos /obj/machinery/suit_storage_unit/mining - suit_type = /obj/item/clothing/suit/hooded/explorer + suit_type = /obj/item/clothing/suit/hooded/explorer/standard mask_type = /obj/item/clothing/mask/gas/explorer /obj/machinery/suit_storage_unit/mining/eva diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index 99baad11ae..ba08109427 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -257,8 +257,7 @@ /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Initialize() . = ..() - create_reagents(max_volume) - reagents.set_reacting(FALSE) + create_reagents(max_volume, NO_REACT) syringes = new known_reagents = list("epinephrine"="Epinephrine","charcoal"="Charcoal") processed_reagents = new @@ -274,7 +273,7 @@ /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/critfail() ..() if(reagents) - reagents.set_reacting(TRUE) + DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/mecha/medical/M) if(..()) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 1a3886c3df..80c92c7922 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -421,14 +421,13 @@ if(!istype(T)) return var/datum/gas_mixture/GM = new - GM.add_gas(/datum/gas/plasma) if(prob(10)) - GM.gases[/datum/gas/plasma][MOLES] += 100 + GM.gases[/datum/gas/plasma] += 100 GM.temperature = 1500+T0C //should be enough to start a fire T.visible_message("[src] suddenly disgorges a cloud of heated plasma.") qdel(src) else - GM.gases[/datum/gas/plasma][MOLES] += 5 + GM.gases[/datum/gas/plasma] += 5 GM.temperature = istype(T) ? T.air.return_temperature() : T20C T.visible_message("[src] suddenly disgorges a cloud of plasma.") T.assume_air(GM) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index d5de4a4898..4700dda60d 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -237,9 +237,8 @@ cabin_air = new cabin_air.temperature = T20C cabin_air.volume = 200 - cabin_air.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - cabin_air.gases[/datum/gas/oxygen][MOLES] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) - cabin_air.gases[/datum/gas/nitrogen][MOLES] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.gases[/datum/gas/oxygen] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.gases[/datum/gas/nitrogen] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) return cabin_air /obj/mecha/proc/add_radio() @@ -446,13 +445,13 @@ var/mob/living/L = user if(!Adjacent(target)) if(selected && selected.is_ranged()) - if(L.has_trait(TRAIT_PACIFISM) && selected.harmful) + if(HAS_TRAIT(L, TRAIT_PACIFISM) && selected.harmful) to_chat(user, "You don't want to harm other living beings!") return if(selected.action(target,params)) selected.start_cooldown() else if(selected && selected.is_melee()) - if(isliving(target) && selected.harmful && L.has_trait(TRAIT_PACIFISM)) + if(isliving(target) && selected.harmful && HAS_TRAIT(L, TRAIT_PACIFISM)) to_chat(user, "You don't want to harm other living beings!") return if(selected.action(target,params)) diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 4d2e113749..ef3ba969e9 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -80,6 +80,7 @@ desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE" name = "\improper DEATH-RIPLEY" icon_state = "deathripley" + armor = list("melee" = 40, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) slow_pressure_step_in = 3 opacity=0 lights_power = 7 @@ -194,4 +195,4 @@ cargo -= O else if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. - to_chat(user, "You fail to push [O] out of [src]!") \ No newline at end of file + to_chat(user, "You fail to push [O] out of [src]!") diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 07152b0310..d5aff99f32 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -72,7 +72,7 @@ ..() if(ishuman(O)) var/mob/living/carbon/human/H = O - if(H.shoes && blood_state && bloodiness && !H.has_trait(TRAIT_LIGHT_STEP)) + if(H.shoes && blood_state && bloodiness && !HAS_TRAIT(H, TRAIT_LIGHT_STEP)) var/obj/item/clothing/shoes/S = H.shoes var/add_blood = 0 if(bloodiness >= BLOOD_GAIN_PER_STEP) diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index f1a1655fb4..35f06c2768 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -60,7 +60,7 @@ /obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L) if(istype(L) && has_gravity(loc)) - playsound(loc, 'sound/effects/gib_step.ogg', L.has_trait(TRAIT_LIGHT_STEP) ? 20 : 50, 1) + playsound(loc, 'sound/effects/gib_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 20 : 50, 1) . = ..() /obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions) diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index 34263ef9a4..0a0348ae39 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -3,6 +3,7 @@ desc = "Graffiti. Damn kids." icon = 'icons/effects/crayondecal.dmi' icon_state = "rune1" + plane = GAME_PLANE //makes the graffiti visible over a wall. gender = NEUTER mergeable_decal = FALSE var/do_icon_rotate = TRUE diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 264715e2ac..10ee73915c 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -1,347 +1,347 @@ -// Foam -// Similar to smoke, but slower and mobs absorb its reagent through their exposed skin. -#define ALUMINUM_FOAM 1 -#define IRON_FOAM 2 -#define RESIN_FOAM 3 - - -/obj/effect/particle_effect/foam - name = "foam" - icon_state = "foam" - opacity = 0 - anchored = TRUE - density = FALSE - layer = EDGED_TURF_LAYER - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - var/amount = 3 - animate_movement = 0 - var/metal = 0 - var/lifetime = 40 - var/reagent_divisor = 7 - var/static/list/blacklisted_turfs = typecacheof(list( - /turf/open/space/transit, - /turf/open/chasm, - /turf/open/lava)) - -/obj/effect/particle_effect/foam/firefighting - name = "firefighting foam" - lifetime = 20 //doesn't last as long as normal foam - amount = 0 //no spread - var/absorbed_plasma = 0 - -/obj/effect/particle_effect/foam/firefighting/MakeSlippery() - return - -/obj/effect/particle_effect/foam/firefighting/process() - ..() - - var/turf/open/T = get_turf(src) - var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) - if(hotspot && istype(T) && T.air) - qdel(hotspot) - var/datum/gas_mixture/G = T.air - var/plas_amt = min(30,G.gases[/datum/gas/plasma][MOLES]) //Absorb some plasma - G.gases[/datum/gas/plasma][MOLES] -= plas_amt - absorbed_plasma += plas_amt - if(G.temperature > T20C) - G.temperature = max(G.temperature/2,T20C) - G.garbage_collect() - T.air_update_turf() - -/obj/effect/particle_effect/foam/firefighting/kill_foam() - STOP_PROCESSING(SSfastprocess, src) - - if(absorbed_plasma) - var/obj/effect/decal/cleanable/plasma/P = (locate(/obj/effect/decal/cleanable/plasma) in get_turf(src)) - if(!P) - P = new(loc) - P.reagents.add_reagent("stable_plasma", absorbed_plasma) - - flick("[icon_state]-disolve", src) - QDEL_IN(src, 5) - -/obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L) - if(!istype(L)) - return - L.adjust_fire_stacks(-2) - L.ExtinguishMob() - -/obj/effect/particle_effect/foam/firefighting/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - return - -/obj/effect/particle_effect/foam/metal - name = "aluminium foam" - metal = ALUMINUM_FOAM - icon_state = "mfoam" - -/obj/effect/particle_effect/foam/metal/MakeSlippery() - return - -/obj/effect/particle_effect/foam/metal/smart - name = "smart foam" - -/obj/effect/particle_effect/foam/metal/iron - name = "iron foam" - metal = IRON_FOAM - -/obj/effect/particle_effect/foam/metal/resin - name = "resin foam" - metal = RESIN_FOAM - -/obj/effect/particle_effect/foam/long_life - lifetime = 150 - -/obj/effect/particle_effect/foam/Initialize() - . = ..() - MakeSlippery() - create_reagents(1000) //limited by the size of the reagent holder anyway. - START_PROCESSING(SSfastprocess, src) - playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3) - -/obj/effect/particle_effect/foam/proc/MakeSlippery() - AddComponent(/datum/component/slippery, 100) - -/obj/effect/particle_effect/foam/Destroy() - STOP_PROCESSING(SSfastprocess, src) - return ..() - - -/obj/effect/particle_effect/foam/proc/kill_foam() - STOP_PROCESSING(SSfastprocess, src) - switch(metal) - if(ALUMINUM_FOAM) - new /obj/structure/foamedmetal(get_turf(src)) - if(IRON_FOAM) - new /obj/structure/foamedmetal/iron(get_turf(src)) - if(RESIN_FOAM) - new /obj/structure/foamedmetal/resin(get_turf(src)) - flick("[icon_state]-disolve", src) - QDEL_IN(src, 5) - -/obj/effect/particle_effect/foam/smart/kill_foam() //Smart foam adheres to area borders for walls - STOP_PROCESSING(SSfastprocess, src) - if(metal) - var/turf/T = get_turf(src) - if(isspaceturf(T)) //Block up any exposed space - T.PlaceOnTop(/turf/open/floor/plating/foam) - for(var/direction in GLOB.cardinals) - var/turf/cardinal_turf = get_step(T, direction) - if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf! - new/obj/structure/foamedmetal(T) - break - flick("[icon_state]-disolve", src) - QDEL_IN(src, 5) - -/obj/effect/particle_effect/foam/process() - lifetime-- - if(lifetime < 1) - kill_foam() - return - - var/fraction = 1/initial(reagent_divisor) - for(var/obj/O in range(0,src)) - if(O.type == src.type) - continue - if(isturf(O.loc)) - var/turf/T = O.loc - if(T.intact && O.level == 1) //hidden under the floor - continue - if(lifetime % reagent_divisor) - reagents.reaction(O, VAPOR, fraction) - var/hit = 0 - for(var/mob/living/L in range(0,src)) - hit += foam_mob(L) - if(hit) - lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate. - var/T = get_turf(src) - if(lifetime % reagent_divisor) - reagents.reaction(T, VAPOR, fraction) - - if(--amount < 0) - return - spread_foam() - -/obj/effect/particle_effect/foam/proc/foam_mob(mob/living/L) - if(lifetime<1) - return 0 - if(!istype(L)) - return 0 - var/fraction = 1/initial(reagent_divisor) - if(lifetime % reagent_divisor) - reagents.reaction(L, VAPOR, fraction) - lifetime-- - return 1 - -/obj/effect/particle_effect/foam/proc/spread_foam() - var/turf/t_loc = get_turf(src) - for(var/turf/T in t_loc.GetAtmosAdjacentTurfs()) - var/obj/effect/particle_effect/foam/foundfoam = locate() in T //Don't spread foam where there's already foam! - if(foundfoam) - continue - - if(is_type_in_typecache(T, blacklisted_turfs)) - continue - - for(var/mob/living/L in T) - foam_mob(L) - var/obj/effect/particle_effect/foam/F = new src.type(T) - F.amount = amount - reagents.copy_to(F, (reagents.total_volume)) - F.add_atom_colour(color, FIXED_COLOUR_PRIORITY) - F.metal = metal - - -/obj/effect/particle_effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(prob(max(0, exposed_temperature - 475))) //foam dissolves when heated - kill_foam() - - -/obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - return - - -/////////////////////////////////////////////// -//FOAM EFFECT DATUM -/datum/effect_system/foam_spread - var/amount = 10 // the size of the foam spread. - var/obj/chemholder - effect_type = /obj/effect/particle_effect/foam - var/metal = 0 - - -/datum/effect_system/foam_spread/metal - effect_type = /obj/effect/particle_effect/foam/metal - - -/datum/effect_system/foam_spread/metal/smart - effect_type = /obj/effect/particle_effect/foam/smart - - -/datum/effect_system/foam_spread/long - effect_type = /obj/effect/particle_effect/foam/long_life - -/datum/effect_system/foam_spread/New() - ..() - chemholder = new /obj() - var/datum/reagents/R = new/datum/reagents(1000) - chemholder.reagents = R - R.my_atom = chemholder - -/datum/effect_system/foam_spread/Destroy() - qdel(chemholder) - chemholder = null - return ..() - -/datum/effect_system/foam_spread/set_up(amt=5, loca, datum/reagents/carry = null) - if(isturf(loca)) - location = loca - else - location = get_turf(loca) - - amount = round(sqrt(amt / 2), 1) - carry.copy_to(chemholder, carry.total_volume) - -/datum/effect_system/foam_spread/metal/set_up(amt=5, loca, datum/reagents/carry = null, metaltype) - ..() - metal = metaltype - -/datum/effect_system/foam_spread/start() - var/obj/effect/particle_effect/foam/F = new effect_type(location) - var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list) - chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount) - F.add_atom_colour(foamcolor, FIXED_COLOUR_PRIORITY) - F.amount = amount - F.metal = metal - - -////////////////////////////////////////////////////////// -// FOAM STRUCTURE. Formed by metal foams. Dense and opaque, but easy to break -/obj/structure/foamedmetal - icon = 'icons/effects/effects.dmi' - icon_state = "metalfoam" - density = TRUE - opacity = 1 // changed in New() - anchored = TRUE - layer = EDGED_TURF_LAYER - resistance_flags = FIRE_PROOF | ACID_PROOF - name = "foamed metal" - desc = "A lightweight foamed metal wall." - gender = PLURAL - max_integrity = 20 - CanAtmosPass = ATMOS_PASS_DENSITY - -/obj/structure/foamedmetal/Initialize() - . = ..() - air_update_turf(1) - -/obj/structure/foamedmetal/Move() - var/turf/T = loc - . = ..() - move_update_air(T) - -/obj/structure/foamedmetal/attack_paw(mob/user) - return attack_hand(user) - -/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) - -/obj/structure/foamedmetal/attack_hand(mob/user) - . = ..() - if(.) - return - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - to_chat(user, "You hit [src] but bounce off it!") - playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) - -/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target) - return !density - -/obj/structure/foamedmetal/iron - max_integrity = 50 - icon_state = "ironfoam" - -//Atmos Backpack Resin, transparent, prevents atmos and filters the air -/obj/structure/foamedmetal/resin - name = "\improper ATMOS Resin" - desc = "A lightweight, transparent resin used to suffocate fires, scrub the air of toxins, and restore the air to a safe temperature." - opacity = FALSE - icon_state = "atmos_resin" - alpha = 120 - max_integrity = 10 - -/obj/structure/foamedmetal/resin/Initialize() - . = ..() - if(isopenturf(loc)) - var/turf/open/O = loc - O.ClearWet() - if(O.air) - var/datum/gas_mixture/G = O.air - G.temperature = 293.15 - for(var/obj/effect/hotspot/H in O) - qdel(H) - var/list/G_gases = G.gases - for(var/I in G_gases) - if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen) - continue - G_gases[I][MOLES] = 0 - G.garbage_collect() - O.air_update_turf() - for(var/obj/machinery/atmospherics/components/unary/U in O) - if(!U.welded) - U.welded = TRUE - U.update_icon() - U.visible_message("[U] sealed shut!") - for(var/mob/living/L in O) - L.ExtinguishMob() - for(var/obj/item/Item in O) - Item.extinguish() - -/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return TRUE - . = ..() - -#undef ALUMINUM_FOAM -#undef IRON_FOAM -#undef RESIN_FOAM +// Foam +// Similar to smoke, but slower and mobs absorb its reagent through their exposed skin. +#define ALUMINUM_FOAM 1 +#define IRON_FOAM 2 +#define RESIN_FOAM 3 + + +/obj/effect/particle_effect/foam + name = "foam" + icon_state = "foam" + opacity = 0 + anchored = TRUE + density = FALSE + layer = EDGED_TURF_LAYER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + var/amount = 3 + animate_movement = 0 + var/metal = 0 + var/lifetime = 40 + var/reagent_divisor = 7 + var/static/list/blacklisted_turfs = typecacheof(list( + /turf/open/space/transit, + /turf/open/chasm, + /turf/open/lava)) + +/obj/effect/particle_effect/foam/firefighting + name = "firefighting foam" + lifetime = 20 //doesn't last as long as normal foam + amount = 0 //no spread + var/absorbed_plasma = 0 + +/obj/effect/particle_effect/foam/firefighting/MakeSlippery() + return + +/obj/effect/particle_effect/foam/firefighting/process() + ..() + + var/turf/open/T = get_turf(src) + var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) + if(hotspot && istype(T) && T.air) + qdel(hotspot) + var/datum/gas_mixture/G = T.air + var/plas_amt = min(30,G.gases[/datum/gas/plasma]) //Absorb some plasma + G.gases[/datum/gas/plasma] -= plas_amt + absorbed_plasma += plas_amt + if(G.temperature > T20C) + G.temperature = max(G.temperature/2,T20C) + GAS_GARBAGE_COLLECT(G.gases) + T.air_update_turf() + +/obj/effect/particle_effect/foam/firefighting/kill_foam() + STOP_PROCESSING(SSfastprocess, src) + + if(absorbed_plasma) + var/obj/effect/decal/cleanable/plasma/P = (locate(/obj/effect/decal/cleanable/plasma) in get_turf(src)) + if(!P) + P = new(loc) + P.reagents.add_reagent("stable_plasma", absorbed_plasma) + + flick("[icon_state]-disolve", src) + QDEL_IN(src, 5) + +/obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L) + if(!istype(L)) + return + L.adjust_fire_stacks(-2) + L.ExtinguishMob() + +/obj/effect/particle_effect/foam/firefighting/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + return + +/obj/effect/particle_effect/foam/metal + name = "aluminium foam" + metal = ALUMINUM_FOAM + icon_state = "mfoam" + +/obj/effect/particle_effect/foam/metal/MakeSlippery() + return + +/obj/effect/particle_effect/foam/metal/smart + name = "smart foam" + +/obj/effect/particle_effect/foam/metal/iron + name = "iron foam" + metal = IRON_FOAM + +/obj/effect/particle_effect/foam/metal/resin + name = "resin foam" + metal = RESIN_FOAM + +/obj/effect/particle_effect/foam/long_life + lifetime = 150 + +/obj/effect/particle_effect/foam/Initialize() + . = ..() + MakeSlippery() + create_reagents(1000) //limited by the size of the reagent holder anyway. + START_PROCESSING(SSfastprocess, src) + playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3) + +/obj/effect/particle_effect/foam/proc/MakeSlippery() + AddComponent(/datum/component/slippery, 100) + +/obj/effect/particle_effect/foam/Destroy() + STOP_PROCESSING(SSfastprocess, src) + return ..() + + +/obj/effect/particle_effect/foam/proc/kill_foam() + STOP_PROCESSING(SSfastprocess, src) + switch(metal) + if(ALUMINUM_FOAM) + new /obj/structure/foamedmetal(get_turf(src)) + if(IRON_FOAM) + new /obj/structure/foamedmetal/iron(get_turf(src)) + if(RESIN_FOAM) + new /obj/structure/foamedmetal/resin(get_turf(src)) + flick("[icon_state]-disolve", src) + QDEL_IN(src, 5) + +/obj/effect/particle_effect/foam/smart/kill_foam() //Smart foam adheres to area borders for walls + STOP_PROCESSING(SSfastprocess, src) + if(metal) + var/turf/T = get_turf(src) + if(isspaceturf(T)) //Block up any exposed space + T.PlaceOnTop(/turf/open/floor/plating/foam) + for(var/direction in GLOB.cardinals) + var/turf/cardinal_turf = get_step(T, direction) + if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf! + new/obj/structure/foamedmetal(T) + break + flick("[icon_state]-disolve", src) + QDEL_IN(src, 5) + +/obj/effect/particle_effect/foam/process() + lifetime-- + if(lifetime < 1) + kill_foam() + return + + var/fraction = 1/initial(reagent_divisor) + for(var/obj/O in range(0,src)) + if(O.type == src.type) + continue + if(isturf(O.loc)) + var/turf/T = O.loc + if(T.intact && O.level == 1) //hidden under the floor + continue + if(lifetime % reagent_divisor) + reagents.reaction(O, VAPOR, fraction) + var/hit = 0 + for(var/mob/living/L in range(0,src)) + hit += foam_mob(L) + if(hit) + lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate. + var/T = get_turf(src) + if(lifetime % reagent_divisor) + reagents.reaction(T, VAPOR, fraction) + + if(--amount < 0) + return + spread_foam() + +/obj/effect/particle_effect/foam/proc/foam_mob(mob/living/L) + if(lifetime<1) + return 0 + if(!istype(L)) + return 0 + var/fraction = 1/initial(reagent_divisor) + if(lifetime % reagent_divisor) + reagents.reaction(L, VAPOR, fraction) + lifetime-- + return 1 + +/obj/effect/particle_effect/foam/proc/spread_foam() + var/turf/t_loc = get_turf(src) + for(var/turf/T in t_loc.GetAtmosAdjacentTurfs()) + var/obj/effect/particle_effect/foam/foundfoam = locate() in T //Don't spread foam where there's already foam! + if(foundfoam) + continue + + if(is_type_in_typecache(T, blacklisted_turfs)) + continue + + for(var/mob/living/L in T) + foam_mob(L) + var/obj/effect/particle_effect/foam/F = new src.type(T) + F.amount = amount + reagents.copy_to(F, (reagents.total_volume)) + F.add_atom_colour(color, FIXED_COLOUR_PRIORITY) + F.metal = metal + + +/obj/effect/particle_effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(prob(max(0, exposed_temperature - 475))) //foam dissolves when heated + kill_foam() + + +/obj/effect/particle_effect/foam/metal/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + return + + +/////////////////////////////////////////////// +//FOAM EFFECT DATUM +/datum/effect_system/foam_spread + var/amount = 10 // the size of the foam spread. + var/obj/chemholder + effect_type = /obj/effect/particle_effect/foam + var/metal = 0 + + +/datum/effect_system/foam_spread/metal + effect_type = /obj/effect/particle_effect/foam/metal + + +/datum/effect_system/foam_spread/metal/smart + effect_type = /obj/effect/particle_effect/foam/smart + + +/datum/effect_system/foam_spread/long + effect_type = /obj/effect/particle_effect/foam/long_life + +/datum/effect_system/foam_spread/New() + ..() + chemholder = new /obj() + var/datum/reagents/R = new/datum/reagents(1000) + chemholder.reagents = R + R.my_atom = chemholder + +/datum/effect_system/foam_spread/Destroy() + qdel(chemholder) + chemholder = null + return ..() + +/datum/effect_system/foam_spread/set_up(amt=5, loca, datum/reagents/carry = null) + if(isturf(loca)) + location = loca + else + location = get_turf(loca) + + amount = round(sqrt(amt / 2), 1) + carry.copy_to(chemholder, carry.total_volume) + +/datum/effect_system/foam_spread/metal/set_up(amt=5, loca, datum/reagents/carry = null, metaltype) + ..() + metal = metaltype + +/datum/effect_system/foam_spread/start() + var/obj/effect/particle_effect/foam/F = new effect_type(location) + var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list) + chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount) + F.add_atom_colour(foamcolor, FIXED_COLOUR_PRIORITY) + F.amount = amount + F.metal = metal + + +////////////////////////////////////////////////////////// +// FOAM STRUCTURE. Formed by metal foams. Dense and opaque, but easy to break +/obj/structure/foamedmetal + icon = 'icons/effects/effects.dmi' + icon_state = "metalfoam" + density = TRUE + opacity = 1 // changed in New() + anchored = TRUE + layer = EDGED_TURF_LAYER + resistance_flags = FIRE_PROOF | ACID_PROOF + name = "foamed metal" + desc = "A lightweight foamed metal wall." + gender = PLURAL + max_integrity = 20 + CanAtmosPass = ATMOS_PASS_DENSITY + +/obj/structure/foamedmetal/Initialize() + . = ..() + air_update_turf(1) + +/obj/structure/foamedmetal/Move() + var/turf/T = loc + . = ..() + move_update_air(T) + +/obj/structure/foamedmetal/attack_paw(mob/user) + return attack_hand(user) + +/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) + +/obj/structure/foamedmetal/attack_hand(mob/user) + . = ..() + if(.) + return + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + to_chat(user, "You hit [src] but bounce off it!") + playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) + +/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target) + return !density + +/obj/structure/foamedmetal/iron + max_integrity = 50 + icon_state = "ironfoam" + +//Atmos Backpack Resin, transparent, prevents atmos and filters the air +/obj/structure/foamedmetal/resin + name = "\improper ATMOS Resin" + desc = "A lightweight, transparent resin used to suffocate fires, scrub the air of toxins, and restore the air to a safe temperature." + opacity = FALSE + icon_state = "atmos_resin" + alpha = 120 + max_integrity = 10 + +/obj/structure/foamedmetal/resin/Initialize() + . = ..() + if(isopenturf(loc)) + var/turf/open/O = loc + O.ClearWet() + if(O.air) + var/datum/gas_mixture/G = O.air + G.temperature = 293.15 + for(var/obj/effect/hotspot/H in O) + qdel(H) + var/list/G_gases = G.gases + for(var/I in G_gases) + if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen) + continue + G_gases[I] = 0 + GAS_GARBAGE_COLLECT(G.gases) + O.air_update_turf() + for(var/obj/machinery/atmospherics/components/unary/U in O) + if(!U.welded) + U.welded = TRUE + U.update_icon() + U.visible_message("[U] sealed shut!") + for(var/mob/living/L in O) + L.ExtinguishMob() + for(var/obj/item/Item in O) + Item.extinguish() + +/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return TRUE + . = ..() + +#undef ALUMINUM_FOAM +#undef IRON_FOAM +#undef RESIN_FOAM diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index e8e833890b..79deac475b 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -1,329 +1,328 @@ -///////////////////////////////////////////// -//// SMOKE SYSTEMS -///////////////////////////////////////////// - -/obj/effect/particle_effect/smoke - name = "smoke" - icon = 'icons/effects/96x96.dmi' - icon_state = "smoke" - pixel_x = -32 - pixel_y = -32 - opacity = 0 - layer = FLY_LAYER - anchored = TRUE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - animate_movement = 0 - var/amount = 4 - var/lifetime = 5 - var/opaque = 1 //whether the smoke can block the view when in enough amount - - -/obj/effect/particle_effect/smoke/proc/fade_out(frames = 16) - if(alpha == 0) //Handle already transparent case - return - if(frames == 0) - frames = 1 //We will just assume that by 0 frames, the coder meant "during one frame". - var/step = alpha / frames - for(var/i = 0, i < frames, i++) - alpha -= step - if(alpha < 160) - set_opacity(0) //if we were blocking view, we aren't now because we're fading out - stoplag() - -/obj/effect/particle_effect/smoke/Initialize() - . = ..() - create_reagents(500) - START_PROCESSING(SSobj, src) - - -/obj/effect/particle_effect/smoke/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/effect/particle_effect/smoke/proc/kill_smoke() - STOP_PROCESSING(SSobj, src) - INVOKE_ASYNC(src, .proc/fade_out) - QDEL_IN(src, 10) - -/obj/effect/particle_effect/smoke/process() - lifetime-- - if(lifetime < 1) - kill_smoke() - return 0 - for(var/mob/living/L in range(0,src)) - smoke_mob(L) - return 1 - -/obj/effect/particle_effect/smoke/proc/smoke_mob(mob/living/carbon/C) - if(!istype(C)) - return 0 - if(lifetime<1) - return 0 - if(C.internal != null || C.has_smoke_protection()) - return 0 - if(C.smoke_delay) - return 0 - C.smoke_delay++ - addtimer(CALLBACK(src, .proc/remove_smoke_delay, C), 10) - return 1 - -/obj/effect/particle_effect/smoke/proc/remove_smoke_delay(mob/living/carbon/C) - if(C) - C.smoke_delay = 0 - -/obj/effect/particle_effect/smoke/proc/spread_smoke() - var/turf/t_loc = get_turf(src) - if(!t_loc) - return - var/list/newsmokes = list() - for(var/turf/T in t_loc.GetAtmosAdjacentTurfs()) - var/obj/effect/particle_effect/smoke/foundsmoke = locate() in T //Don't spread smoke where there's already smoke! - if(foundsmoke) - continue - for(var/mob/living/L in T) - smoke_mob(L) - var/obj/effect/particle_effect/smoke/S = new type(T) - reagents.copy_to(S, reagents.total_volume) - S.setDir(pick(GLOB.cardinals)) - S.amount = amount-1 - S.add_atom_colour(color, FIXED_COLOUR_PRIORITY) - S.lifetime = lifetime - if(S.amount>0) - if(opaque) - S.set_opacity(TRUE) - newsmokes.Add(S) - - if(newsmokes.len) - spawn(1) //the smoke spreads rapidly but not instantly - for(var/obj/effect/particle_effect/smoke/SM in newsmokes) - SM.spread_smoke() - - -/datum/effect_system/smoke_spread - var/amount = 10 - effect_type = /obj/effect/particle_effect/smoke - -/datum/effect_system/smoke_spread/set_up(radius = 5, loca) - if(isturf(loca)) - location = loca - else - location = get_turf(loca) - amount = radius - -/datum/effect_system/smoke_spread/start() - if(holder) - location = get_turf(holder) - var/obj/effect/particle_effect/smoke/S = new effect_type(location) - S.amount = amount - if(S.amount) - S.spread_smoke() - - -///////////////////////////////////////////// -// Bad smoke -///////////////////////////////////////////// - -/obj/effect/particle_effect/smoke/bad - lifetime = 8 - -/obj/effect/particle_effect/smoke/bad/smoke_mob(mob/living/carbon/M) - if(..()) - M.drop_all_held_items() - M.adjustOxyLoss(1) - M.emote("cough") - return 1 - -/obj/effect/particle_effect/smoke/bad/CanPass(atom/movable/mover, turf/target) - if(istype(mover, /obj/item/projectile/beam)) - var/obj/item/projectile/beam/B = mover - B.damage = (B.damage/2) - return 1 - - - -/datum/effect_system/smoke_spread/bad - effect_type = /obj/effect/particle_effect/smoke/bad - -///////////////////////////////////////////// -// Nanofrost smoke -///////////////////////////////////////////// - -/obj/effect/particle_effect/smoke/freezing - name = "nanofrost smoke" - color = "#B2FFFF" - opaque = 0 - -/datum/effect_system/smoke_spread/freezing - effect_type = /obj/effect/particle_effect/smoke/freezing - var/blast = 0 - var/temperature = 2 - var/weldvents = TRUE - var/distcheck = TRUE - -/datum/effect_system/smoke_spread/freezing/proc/Chilled(atom/A) - if(isopenturf(A)) - var/turf/open/T = A - if(T.air) - var/datum/gas_mixture/G = T.air - if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air - G.temperature = temperature - T.air_update_turf() - for(var/obj/effect/hotspot/H in T) - qdel(H) - var/list/G_gases = G.gases - if(G_gases[/datum/gas/plasma]) - G.assert_gas(/datum/gas/nitrogen) - G_gases[/datum/gas/nitrogen][MOLES] += (G_gases[/datum/gas/plasma][MOLES]) - G_gases[/datum/gas/plasma][MOLES] = 0 - G.garbage_collect() - if (weldvents) - for(var/obj/machinery/atmospherics/components/unary/U in T) - if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber. - U.welded = TRUE - U.update_icon() - U.visible_message("[U] was frozen shut!") - for(var/mob/living/L in T) - L.ExtinguishMob() - for(var/obj/item/Item in T) - Item.extinguish() - -/datum/effect_system/smoke_spread/freezing/set_up(radius = 5, loca, blast_radius = 0) - ..() - blast = blast_radius - -/datum/effect_system/smoke_spread/freezing/start() - if(blast) - for(var/turf/T in RANGE_TURFS(blast, location)) - Chilled(T) - ..() - -/datum/effect_system/smoke_spread/freezing/decon - temperature = 293.15 - distcheck = FALSE - weldvents = FALSE - - -///////////////////////////////////////////// -// Sleep smoke -///////////////////////////////////////////// - -/obj/effect/particle_effect/smoke/sleeping - color = "#9C3636" - lifetime = 10 - -/obj/effect/particle_effect/smoke/sleeping/smoke_mob(mob/living/carbon/M) - if(..()) - M.Sleeping(200) - M.emote("cough") - return 1 - -/datum/effect_system/smoke_spread/sleeping - effect_type = /obj/effect/particle_effect/smoke/sleeping - -///////////////////////////////////////////// -// Chem smoke -///////////////////////////////////////////// - -/obj/effect/particle_effect/smoke/chem - lifetime = 10 - - -/obj/effect/particle_effect/smoke/chem/process() - if(..()) - var/turf/T = get_turf(src) - var/fraction = 1/initial(lifetime) - for(var/atom/movable/AM in T) - if(AM.type == src.type) - continue - if(T.intact && AM.level == 1) //hidden under the floor - continue - reagents.reaction(AM, TOUCH, fraction) - - reagents.reaction(T, TOUCH, fraction) - return 1 - -/obj/effect/particle_effect/smoke/chem/smoke_mob(mob/living/carbon/M) - if(lifetime<1) - return 0 - if(!istype(M)) - return 0 - var/mob/living/carbon/C = M - if(C.internal != null || C.has_smoke_protection()) - return 0 - var/fraction = 1/initial(lifetime) - reagents.copy_to(C, fraction*reagents.total_volume) - reagents.reaction(M, INGEST, fraction) - return 1 - - - -/datum/effect_system/smoke_spread/chem - var/obj/chemholder - effect_type = /obj/effect/particle_effect/smoke/chem - -/datum/effect_system/smoke_spread/chem/New() - ..() - chemholder = new /obj() - var/datum/reagents/R = new/datum/reagents(500) - chemholder.reagents = R - R.my_atom = chemholder - -/datum/effect_system/smoke_spread/chem/Destroy() - qdel(chemholder) - chemholder = null - return ..() - -/datum/effect_system/smoke_spread/chem/set_up(datum/reagents/carry = null, radius = 1, loca, silent = FALSE) - if(isturf(loca)) - location = loca - else - location = get_turf(loca) - amount = radius - carry.copy_to(chemholder, carry.total_volume) - - if(!silent) - var/contained = "" - for(var/reagent in carry.reagent_list) - contained += " [reagent] " - if(contained) - contained = "\[[contained]\]" - - var/where = "[AREACOORD(location)]" - if(carry.my_atom.fingerprintslast) - var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast) - var/more = "" - if(M) - more = "[ADMIN_LOOKUPFLW(M)] " - message_admins("Smoke: ([ADMIN_VERBOSEJMP(location)])[contained]. Key: [more ? more : carry.my_atom.fingerprintslast].") - log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last touched by [carry.my_atom.fingerprintslast].") - else - message_admins("Smoke: ([ADMIN_VERBOSEJMP(location)])[contained]. No associated key.") - log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.") - - -/datum/effect_system/smoke_spread/chem/start() - var/mixcolor = mix_color_from_reagents(chemholder.reagents.reagent_list) - if(holder) - location = get_turf(holder) - var/obj/effect/particle_effect/smoke/chem/S = new effect_type(location) - - if(chemholder.reagents.total_volume > 1) // can't split 1 very well - chemholder.reagents.copy_to(S, chemholder.reagents.total_volume) - - if(mixcolor) - S.add_atom_colour(mixcolor, FIXED_COLOUR_PRIORITY) // give the smoke color, if it has any to begin with - S.amount = amount - if(S.amount) - S.spread_smoke() //calling process right now so the smoke immediately attacks mobs. - - -///////////////////////////////////////////// -// Transparent smoke -///////////////////////////////////////////// - -//Same as the base type, but the smoke produced is not opaque -/datum/effect_system/smoke_spread/transparent - effect_type = /obj/effect/particle_effect/smoke/transparent - -/obj/effect/particle_effect/smoke/transparent - opaque = FALSE +///////////////////////////////////////////// +//// SMOKE SYSTEMS +///////////////////////////////////////////// + +/obj/effect/particle_effect/smoke + name = "smoke" + icon = 'icons/effects/96x96.dmi' + icon_state = "smoke" + pixel_x = -32 + pixel_y = -32 + opacity = 0 + layer = FLY_LAYER + anchored = TRUE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + animate_movement = 0 + var/amount = 4 + var/lifetime = 5 + var/opaque = 1 //whether the smoke can block the view when in enough amount + + +/obj/effect/particle_effect/smoke/proc/fade_out(frames = 16) + if(alpha == 0) //Handle already transparent case + return + if(frames == 0) + frames = 1 //We will just assume that by 0 frames, the coder meant "during one frame". + var/step = alpha / frames + for(var/i = 0, i < frames, i++) + alpha -= step + if(alpha < 160) + set_opacity(0) //if we were blocking view, we aren't now because we're fading out + stoplag() + +/obj/effect/particle_effect/smoke/Initialize() + . = ..() + create_reagents(500) + START_PROCESSING(SSobj, src) + + +/obj/effect/particle_effect/smoke/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/effect/particle_effect/smoke/proc/kill_smoke() + STOP_PROCESSING(SSobj, src) + INVOKE_ASYNC(src, .proc/fade_out) + QDEL_IN(src, 10) + +/obj/effect/particle_effect/smoke/process() + lifetime-- + if(lifetime < 1) + kill_smoke() + return 0 + for(var/mob/living/L in range(0,src)) + smoke_mob(L) + return 1 + +/obj/effect/particle_effect/smoke/proc/smoke_mob(mob/living/carbon/C) + if(!istype(C)) + return 0 + if(lifetime<1) + return 0 + if(C.internal != null || C.has_smoke_protection()) + return 0 + if(C.smoke_delay) + return 0 + C.smoke_delay++ + addtimer(CALLBACK(src, .proc/remove_smoke_delay, C), 10) + return 1 + +/obj/effect/particle_effect/smoke/proc/remove_smoke_delay(mob/living/carbon/C) + if(C) + C.smoke_delay = 0 + +/obj/effect/particle_effect/smoke/proc/spread_smoke() + var/turf/t_loc = get_turf(src) + if(!t_loc) + return + var/list/newsmokes = list() + for(var/turf/T in t_loc.GetAtmosAdjacentTurfs()) + var/obj/effect/particle_effect/smoke/foundsmoke = locate() in T //Don't spread smoke where there's already smoke! + if(foundsmoke) + continue + for(var/mob/living/L in T) + smoke_mob(L) + var/obj/effect/particle_effect/smoke/S = new type(T) + reagents.copy_to(S, reagents.total_volume) + S.setDir(pick(GLOB.cardinals)) + S.amount = amount-1 + S.add_atom_colour(color, FIXED_COLOUR_PRIORITY) + S.lifetime = lifetime + if(S.amount>0) + if(opaque) + S.set_opacity(TRUE) + newsmokes.Add(S) + + if(newsmokes.len) + spawn(1) //the smoke spreads rapidly but not instantly + for(var/obj/effect/particle_effect/smoke/SM in newsmokes) + SM.spread_smoke() + + +/datum/effect_system/smoke_spread + var/amount = 10 + effect_type = /obj/effect/particle_effect/smoke + +/datum/effect_system/smoke_spread/set_up(radius = 5, loca) + if(isturf(loca)) + location = loca + else + location = get_turf(loca) + amount = radius + +/datum/effect_system/smoke_spread/start() + if(holder) + location = get_turf(holder) + var/obj/effect/particle_effect/smoke/S = new effect_type(location) + S.amount = amount + if(S.amount) + S.spread_smoke() + + +///////////////////////////////////////////// +// Bad smoke +///////////////////////////////////////////// + +/obj/effect/particle_effect/smoke/bad + lifetime = 8 + +/obj/effect/particle_effect/smoke/bad/smoke_mob(mob/living/carbon/M) + if(..()) + M.drop_all_held_items() + M.adjustOxyLoss(1) + M.emote("cough") + return 1 + +/obj/effect/particle_effect/smoke/bad/CanPass(atom/movable/mover, turf/target) + if(istype(mover, /obj/item/projectile/beam)) + var/obj/item/projectile/beam/B = mover + B.damage = (B.damage/2) + return 1 + + + +/datum/effect_system/smoke_spread/bad + effect_type = /obj/effect/particle_effect/smoke/bad + +///////////////////////////////////////////// +// Nanofrost smoke +///////////////////////////////////////////// + +/obj/effect/particle_effect/smoke/freezing + name = "nanofrost smoke" + color = "#B2FFFF" + opaque = 0 + +/datum/effect_system/smoke_spread/freezing + effect_type = /obj/effect/particle_effect/smoke/freezing + var/blast = 0 + var/temperature = 2 + var/weldvents = TRUE + var/distcheck = TRUE + +/datum/effect_system/smoke_spread/freezing/proc/Chilled(atom/A) + if(isopenturf(A)) + var/turf/open/T = A + if(T.air) + var/datum/gas_mixture/G = T.air + if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air + G.temperature = temperature + T.air_update_turf() + for(var/obj/effect/hotspot/H in T) + qdel(H) + var/list/G_gases = G.gases + if(G_gases[/datum/gas/plasma]) + G_gases[/datum/gas/nitrogen] += (G_gases[/datum/gas/plasma]) + G_gases[/datum/gas/plasma] = 0 + GAS_GARBAGE_COLLECT(G.gases) + if (weldvents) + for(var/obj/machinery/atmospherics/components/unary/U in T) + if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber. + U.welded = TRUE + U.update_icon() + U.visible_message("[U] was frozen shut!") + for(var/mob/living/L in T) + L.ExtinguishMob() + for(var/obj/item/Item in T) + Item.extinguish() + +/datum/effect_system/smoke_spread/freezing/set_up(radius = 5, loca, blast_radius = 0) + ..() + blast = blast_radius + +/datum/effect_system/smoke_spread/freezing/start() + if(blast) + for(var/turf/T in RANGE_TURFS(blast, location)) + Chilled(T) + ..() + +/datum/effect_system/smoke_spread/freezing/decon + temperature = 293.15 + distcheck = FALSE + weldvents = FALSE + + +///////////////////////////////////////////// +// Sleep smoke +///////////////////////////////////////////// + +/obj/effect/particle_effect/smoke/sleeping + color = "#9C3636" + lifetime = 10 + +/obj/effect/particle_effect/smoke/sleeping/smoke_mob(mob/living/carbon/M) + if(..()) + M.Sleeping(200) + M.emote("cough") + return 1 + +/datum/effect_system/smoke_spread/sleeping + effect_type = /obj/effect/particle_effect/smoke/sleeping + +///////////////////////////////////////////// +// Chem smoke +///////////////////////////////////////////// + +/obj/effect/particle_effect/smoke/chem + lifetime = 10 + + +/obj/effect/particle_effect/smoke/chem/process() + if(..()) + var/turf/T = get_turf(src) + var/fraction = 1/initial(lifetime) + for(var/atom/movable/AM in T) + if(AM.type == src.type) + continue + if(T.intact && AM.level == 1) //hidden under the floor + continue + reagents.reaction(AM, TOUCH, fraction) + + reagents.reaction(T, TOUCH, fraction) + return 1 + +/obj/effect/particle_effect/smoke/chem/smoke_mob(mob/living/carbon/M) + if(lifetime<1) + return 0 + if(!istype(M)) + return 0 + var/mob/living/carbon/C = M + if(C.internal != null || C.has_smoke_protection()) + return 0 + var/fraction = 1/initial(lifetime) + reagents.copy_to(C, fraction*reagents.total_volume) + reagents.reaction(M, INGEST, fraction) + return 1 + + + +/datum/effect_system/smoke_spread/chem + var/obj/chemholder + effect_type = /obj/effect/particle_effect/smoke/chem + +/datum/effect_system/smoke_spread/chem/New() + ..() + chemholder = new /obj() + var/datum/reagents/R = new/datum/reagents(500) + chemholder.reagents = R + R.my_atom = chemholder + +/datum/effect_system/smoke_spread/chem/Destroy() + qdel(chemholder) + chemholder = null + return ..() + +/datum/effect_system/smoke_spread/chem/set_up(datum/reagents/carry = null, radius = 1, loca, silent = FALSE) + if(isturf(loca)) + location = loca + else + location = get_turf(loca) + amount = radius + carry.copy_to(chemholder, carry.total_volume) + + if(!silent) + var/contained = "" + for(var/reagent in carry.reagent_list) + contained += " [reagent] " + if(contained) + contained = "\[[contained]\]" + + var/where = "[AREACOORD(location)]" + if(carry.my_atom.fingerprintslast) + var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast) + var/more = "" + if(M) + more = "[ADMIN_LOOKUPFLW(M)] " + message_admins("Smoke: ([ADMIN_VERBOSEJMP(location)])[contained]. Key: [more ? more : carry.my_atom.fingerprintslast].") + log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last touched by [carry.my_atom.fingerprintslast].") + else + message_admins("Smoke: ([ADMIN_VERBOSEJMP(location)])[contained]. No associated key.") + log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.") + + +/datum/effect_system/smoke_spread/chem/start() + var/mixcolor = mix_color_from_reagents(chemholder.reagents.reagent_list) + if(holder) + location = get_turf(holder) + var/obj/effect/particle_effect/smoke/chem/S = new effect_type(location) + + if(chemholder.reagents.total_volume > 1) // can't split 1 very well + chemholder.reagents.copy_to(S, chemholder.reagents.total_volume) + + if(mixcolor) + S.add_atom_colour(mixcolor, FIXED_COLOUR_PRIORITY) // give the smoke color, if it has any to begin with + S.amount = amount + if(S.amount) + S.spread_smoke() //calling process right now so the smoke immediately attacks mobs. + + +///////////////////////////////////////////// +// Transparent smoke +///////////////////////////////////////////// + +//Same as the base type, but the smoke produced is not opaque +/datum/effect_system/smoke_spread/transparent + effect_type = /obj/effect/particle_effect/smoke/transparent + +/obj/effect/particle_effect/smoke/transparent + opaque = FALSE diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 12a72685bb..7e8094c9e7 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -170,7 +170,7 @@ if(!victim.client || !istype(victim)) return to_chat(victim, "You feel fast!") - victim.add_trait(TRAIT_GOTTAGOREALLYFAST, "yellow_orb") + ADD_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb") sleep(duration) - victim.remove_trait(TRAIT_GOTTAGOREALLYFAST, "yellow_orb") + REMOVE_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb") to_chat(victim, "You slow down.") diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm index b1bb3e6b4d..65395d534a 100644 --- a/code/game/objects/effects/spawners/bombspawner.dm +++ b/code/game/objects/effects/spawners/bombspawner.dm @@ -1,6 +1,6 @@ #define CELSIUS_TO_KELVIN(T_K) ((T_K) + T0C) -#define OPTIMAL_TEMP_K_PLA_BURN_SCALE(PRESSURE_P,PRESSURE_O,TEMP_O) (((PRESSURE_P) * GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_SPECIFIC_HEAT]) / (((PRESSURE_P) * GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_SPECIFIC_HEAT] + (PRESSURE_O) * GLOB.meta_gas_info[/datum/gas/oxygen][META_GAS_SPECIFIC_HEAT]) / PLASMA_UPPER_TEMPERATURE - (PRESSURE_O) * GLOB.meta_gas_info[/datum/gas/oxygen][META_GAS_SPECIFIC_HEAT] / CELSIUS_TO_KELVIN(TEMP_O))) +#define OPTIMAL_TEMP_K_PLA_BURN_SCALE(PRESSURE_P,PRESSURE_O,TEMP_O) (((PRESSURE_P) * GLOB.meta_gas_specific_heats[/datum/gas/plasma]) / (((PRESSURE_P) * GLOB.meta_gas_specific_heats[/datum/gas/plasma] + (PRESSURE_O) * GLOB.meta_gas_specific_heats[/datum/gas/oxygen]) / PLASMA_UPPER_TEMPERATURE - (PRESSURE_O) * GLOB.meta_gas_specific_heats[/datum/gas/oxygen] / CELSIUS_TO_KELVIN(TEMP_O))) #define OPTIMAL_TEMP_K_PLA_BURN_RATIO(PRESSURE_P,PRESSURE_O,TEMP_O) (CELSIUS_TO_KELVIN(TEMP_O) * PLASMA_OXYGEN_FULLBURN * (PRESSURE_P) / (PRESSURE_O)) /obj/effect/spawner/newbomb @@ -19,12 +19,10 @@ var/obj/item/tank/internals/plasma/PT = new(V) var/obj/item/tank/internals/oxygen/OT = new(V) - PT.air_contents.assert_gas(/datum/gas/plasma) - PT.air_contents.gases[/datum/gas/plasma][MOLES] = pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)) + PT.air_contents.gases[/datum/gas/plasma] = pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)) PT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_p) - OT.air_contents.assert_gas(/datum/gas/oxygen) - OT.air_contents.gases[/datum/gas/oxygen][MOLES] = pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)) + OT.air_contents.gases[/datum/gas/oxygen] = pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)) OT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_o) V.tank_one = PT diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm index 16e13a9fe2..56e47ed6f5 100644 --- a/code/game/objects/empulse.dm +++ b/code/game/objects/empulse.dm @@ -9,7 +9,7 @@ message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ") log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ") - if(heavy_range > 1) + if(heavy_range >= 1) new /obj/effect/temp_visual/emp/pulse(epicenter) if(heavy_range > light_range) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 9ff1b5cf01..69cb247287 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -256,7 +256,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) can_handle_hot = TRUE else if(C.gloves && (C.gloves.max_heat_protection_temperature > 360)) can_handle_hot = TRUE - else if(C.has_trait(TRAIT_RESISTHEAT) || C.has_trait(TRAIT_RESISTHEATHANDS)) + else if(HAS_TRAIT(C, TRAIT_RESISTHEAT) || HAS_TRAIT(C, TRAIT_RESISTHEATHANDS)) can_handle_hot = TRUE if(can_handle_hot) @@ -449,7 +449,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) return 0 /obj/item/proc/eyestab(mob/living/carbon/M, mob/living/carbon/user) - + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, "You don't want to harm [M]!") + return + if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) + M = user var/is_human_victim = 0 var/obj/item/bodypart/affecting = M.get_bodypart(BODY_ZONE_HEAD) if(ishuman(M)) @@ -519,7 +523,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) M.adjust_blurriness(15) if(M.stat != DEAD) to_chat(M, "Your eyes start to bleed profusely!") - if(!(M.has_trait(TRAIT_BLIND) || M.has_trait(TRAIT_NEARSIGHT))) + if(!(HAS_TRAIT(M, TRAIT_BLIND) || HAS_TRAIT(M, TRAIT_NEARSIGHT))) to_chat(M, "You become nearsighted!") M.become_nearsighted(EYE_DAMAGE) if(prob(50)) diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm index d818191055..a8d0bed2aa 100644 --- a/code/game/objects/items/AI_modules.dm +++ b/code/game/objects/items/AI_modules.dm @@ -362,7 +362,7 @@ AI MODULES /obj/item/aiModule/core/full/asimov name = "'Asimov' Core AI Module" law_id = "asimov" - var/subject = "human being" + var/subject = "person of an NT approved crew species" //CITADEL CHANGED FROM HUMANS! /obj/item/aiModule/core/full/asimov/attack_self(var/mob/user as mob) var/targName = stripped_input(user, "Please enter a new subject that asimov is concerned with.", "Asimov to whom?", subject) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 7881c277ff..38d64be99c 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -161,13 +161,18 @@ RLD user.visible_message("[user] sets the RCD to 'Wall' and points it down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide..") return (BRUTELOSS) -/obj/item/construction/rcd/verb/toggle_window_type() - set name = "Toggle Window Type" +/obj/item/construction/rcd/verb/toggle_window_type_verb() + set name = "RCD : Toggle Window Type" set category = "Object" - set src in usr // What does this do? + set src in view(1) + if(!usr.canUseTopic(src, BE_CLOSE)) + return + + toggle_window_type(usr) + +/obj/item/construction/rcd/proc/toggle_window_type(mob/user) var/window_type_name - if (window_type == /obj/structure/window/fulltile) window_type = /obj/structure/window/reinforced/fulltile window_type_name = "reinforced glass" @@ -175,17 +180,14 @@ RLD window_type = /obj/structure/window/fulltile window_type_name = "glass" - to_chat(usr, "You change \the [src]'s window mode to [window_type_name].") + to_chat(user, "You change \the [src]'s window mode to [window_type_name].") -/obj/item/construction/rcd/verb/change_airlock_access() - set name = "Change Airlock Access" - set category = "Object" - set src in usr +/obj/item/construction/rcd/verb/change_airlock_access(mob/user) - if (!ishuman(usr) && !usr.has_unlimited_silicon_privilege) - return ..(usr) + if (!ishuman(user) && !user.has_unlimited_silicon_privilege) + return - var/t1 = text("") + var/t1 = "" if(use_one_access) @@ -216,24 +218,23 @@ RLD t1 += "

Close

\n" - var/datum/browser/popup = new(usr, "airlock_electronics", "Access Control", 900, 500) + var/datum/browser/popup = new(user, "rcd_access", "Access Control", 900, 500) popup.set_content(t1) - popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state)) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) popup.open() - onclose(usr, "airlock") + onclose(user, "rcd_access") /obj/item/construction/rcd/Topic(href, href_list) ..() if (usr.stat || usr.restrained()) return if (href_list["close"]) - usr << browse(null, "window=airlock") + usr << browse(null, "window=rcd_access") return if (href_list["access"]) toggle_access(href_list["access"]) - - change_airlock_access() + change_airlock_access(usr) /obj/item/construction/rcd/proc/toggle_access(acc) if (acc == "all") @@ -253,16 +254,77 @@ RLD if (!conf_access.len) conf_access = null -/obj/item/construction/rcd/verb/change_airlock_setting() - set name = "Change Airlock Setting" - set category = "Object" - set src in usr +/obj/item/construction/rcd/proc/get_airlock_image(airlock_type) + var/obj/machinery/door/airlock/proto = airlock_type + var/ic = initial(proto.icon) + var/mutable_appearance/MA = mutable_appearance(ic, "closed") + if(!initial(proto.glass)) + MA.overlays += "fill_closed" + //Not scaling these down to button size because they look horrible then, instead just bumping up radius. + return MA - var/airlockcat = input(usr, "Select whether the airlock is solid or glass.") in list("Solid", "Glass") +/obj/item/construction/rcd/proc/check_menu(mob/living/user) + if(!istype(user)) + return FALSE + if(user.incapacitated() || !user.Adjacent(src)) + return FALSE + return TRUE + +/obj/item/construction/rcd/proc/change_airlock_setting(mob/user) + if(!user) + return + + var/list/solid_or_glass_choices = list( + "Solid" = get_airlock_image(/obj/machinery/door/airlock), + "Glass" = get_airlock_image(/obj/machinery/door/airlock/glass) + ) + + var/list/solid_choices = list( + "Standard" = get_airlock_image(/obj/machinery/door/airlock), + "Public" = get_airlock_image(/obj/machinery/door/airlock/public), + "Engineering" = get_airlock_image(/obj/machinery/door/airlock/engineering), + "Atmospherics" = get_airlock_image(/obj/machinery/door/airlock/atmos), + "Security" = get_airlock_image(/obj/machinery/door/airlock/security), + "Command" = get_airlock_image(/obj/machinery/door/airlock/command), + "Medical" = get_airlock_image(/obj/machinery/door/airlock/medical), + "Research" = get_airlock_image(/obj/machinery/door/airlock/research), + "Freezer" = get_airlock_image(/obj/machinery/door/airlock/freezer), + "Science" = get_airlock_image(/obj/machinery/door/airlock/science), + "Virology" = get_airlock_image(/obj/machinery/door/airlock/virology), + "Mining" = get_airlock_image(/obj/machinery/door/airlock/mining), + "Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance), + "External" = get_airlock_image(/obj/machinery/door/airlock/external), + "External Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance/external), + "Airtight Hatch" = get_airlock_image(/obj/machinery/door/airlock/hatch), + "Maintenance Hatch" = get_airlock_image(/obj/machinery/door/airlock/maintenance_hatch) + ) + + var/list/glass_choices = list( + "Standard" = get_airlock_image(/obj/machinery/door/airlock/glass), + "Public" = get_airlock_image(/obj/machinery/door/airlock/public/glass), + "Engineering" = get_airlock_image(/obj/machinery/door/airlock/engineering/glass), + "Atmospherics" = get_airlock_image(/obj/machinery/door/airlock/atmos/glass), + "Security" = get_airlock_image(/obj/machinery/door/airlock/security/glass), + "Command" = get_airlock_image(/obj/machinery/door/airlock/command/glass), + "Medical" = get_airlock_image(/obj/machinery/door/airlock/medical/glass), + "Research" = get_airlock_image(/obj/machinery/door/airlock/research/glass), + "Science" = get_airlock_image(/obj/machinery/door/airlock/science/glass), + "Virology" = get_airlock_image(/obj/machinery/door/airlock/virology/glass), + "Mining" = get_airlock_image(/obj/machinery/door/airlock/mining/glass), + "Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance/glass), + "External" = get_airlock_image(/obj/machinery/door/airlock/external/glass), + "External Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance/external/glass) + ) + + var/airlockcat = show_radial_menu(user, src, solid_or_glass_choices, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE) + if(!check_menu(user)) + return switch(airlockcat) if("Solid") if(advanced_airlock_setting == 1) - var/airlockpaint = input(usr, "Select the type of the airlock.") in list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Freezer", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance", "Airtight Hatch", "Maintenance Hatch") + var/airlockpaint = show_radial_menu(user, src, solid_choices, radius = 42, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE) + if(!check_menu(user)) + return switch(airlockpaint) if("Standard") airlock_type = /obj/machinery/door/airlock @@ -305,7 +367,9 @@ RLD if("Glass") if(advanced_airlock_setting == 1) - var/airlockpaint = input(usr, "Select the type of the airlock.") in list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance") + var/airlockpaint = show_radial_menu(user, src , glass_choices, radius = 42, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE) + if(!check_menu(user)) + return switch(airlockpaint) if("Standard") airlock_type = /obj/machinery/door/airlock/glass @@ -356,8 +420,8 @@ RLD playsound(src.loc, 'sound/machines/click.ogg', 50, 1) return TRUE -/obj/item/construction/rcd/New() - ..() +/obj/item/construction/rcd/Initialize() + . = ..() GLOB.rcd_list += src /obj/item/construction/rcd/Destroy() @@ -366,19 +430,46 @@ RLD /obj/item/construction/rcd/attack_self(mob/user) ..() - switch(mode) - if(1) - mode = 2 - to_chat(user, "You change RCD's mode to 'Airlock'.") - if(2) - mode = 3 - to_chat(user, "You change RCD's mode to 'Deconstruct'.") - if(3) - mode = 4 - to_chat(user, "You change RCD's mode to 'Grilles & Windows'.") - if(4) - mode = 1 - to_chat(user, "You change RCD's mode to 'Floor & Walls'.") + var/list/choices = list( + "Airlock" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlock"), + "Deconstruct" = image(icon= 'icons/mob/radial.dmi', icon_state = "delete"), + "Grilles & Windows" = image(icon = 'icons/mob/radial.dmi', icon_state = "grillewindow"), + "Floors & Walls" = image(icon = 'icons/mob/radial.dmi', icon_state = "wallfloor") + ) + if(mode == RCD_AIRLOCK) + choices += list( + "Change Access" = image(icon = 'icons/mob/radial.dmi', icon_state = "access"), + "Change Airlock Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlocktype") + ) + else if(mode == RCD_WINDOWGRILLE) + choices += list( + "Change Window Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "windowtype") + ) + var/choice = show_radial_menu(user,src,choices, custom_check = CALLBACK(src,.proc/check_menu,user)) + if(!check_menu(user)) + return + switch(choice) + if("Floors & Walls") + mode = RCD_FLOORWALL + if("Airlock") + mode = RCD_AIRLOCK + if("Deconstruct") + mode = RCD_DECONSTRUCT + if("Grilles & Windows") + mode = RCD_WINDOWGRILLE + if("Change Access") + change_airlock_access(user) + return + if("Change Airlock Type") + change_airlock_setting(user) + return + if("Change Window Type") + toggle_window_type(user) + return + else + return + playsound(src, 'sound/effects/pop.ogg', 50, 0) + to_chat(user, "You change RCD's mode to '[choice]'.") /obj/item/construction/rcd/proc/target_check(atom/A, mob/user) // only returns true for stuff the device can actually work with if((isturf(A) && A.density && mode==RCD_DECONSTRUCT) || (isturf(A) && !A.density) || (istype(A, /obj/machinery/door/airlock) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/grille) || (istype(A, /obj/structure/window) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/girder)) diff --git a/code/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm index bc1b128c69..cea8165e02 100644 --- a/code/game/objects/items/RCL.dm +++ b/code/game/objects/items/RCL.dm @@ -14,13 +14,14 @@ w_class = WEIGHT_CLASS_NORMAL var/max_amount = 90 var/active = FALSE - actions_types = list(/datum/action/item_action/rcl) + actions_types = list(/datum/action/item_action/rcl_col,/datum/action/item_action/rcl_gui) var/list/colors = list("red", "yellow", "green", "blue", "pink", "orange", "cyan", "white") var/current_color_index = 1 var/ghetto = FALSE lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' var/datum/component/mobhook + var/datum/radial_menu/persistent/wiring_gui_menu /obj/item/twohanded/rcl/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/stack/cable_coil)) @@ -85,7 +86,8 @@ /obj/item/twohanded/rcl/Destroy() QDEL_NULL(loaded) last = null - setActive(FALSE, null) // setactive(FALSE) removes mobhook + QDEL_NULL(mobhook) + QDEL_NULL(wiring_gui_menu) return ..() /obj/item/twohanded/rcl/update_icon() @@ -115,20 +117,28 @@ if(loaded) QDEL_NULL(loaded) loaded = null + QDEL_NULL(wiring_gui_menu) unwield(user) - setActive(wielded, user) + active = wielded return TRUE return FALSE +/obj/item/twohanded/rcl/pickup(mob/user) + ..() + getMobhook(user) + + + /obj/item/twohanded/rcl/dropped(mob/wearer) ..() if(mobhook) - setActive(FALSE, mobhook.parent) + active = FALSE + QDEL_NULL(mobhook) last = null /obj/item/twohanded/rcl/attack_self(mob/user) ..() - setActive(wielded, user) + active = wielded if(!active) last = null else if(!last) @@ -137,17 +147,24 @@ last = C break -/obj/item/twohanded/rcl/proc/setActive(toggle, mob/user) - active = toggle - if (active && user) - if (mobhook && mobhook.parent != user) +obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook) + if(to_hook) + if(mobhook && mobhook.parent != to_hook) QDEL_NULL(mobhook) if (!mobhook) - mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/trigger))) + mobhook = to_hook.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/trigger))) else QDEL_NULL(mobhook) /obj/item/twohanded/rcl/proc/trigger(mob/user) + if(active) + layCable(user) + if(wiring_gui_menu) //update the wire options as you move + wiringGuiUpdate(user) + + +//previous contents of trigger(), lays cable each time the player moves +/obj/item/twohanded/rcl/proc/layCable(mob/user) if(!isturf(user.loc)) return if(is_empty(user, 0)) @@ -156,7 +173,7 @@ if(prob(2) && ghetto) //Give ghetto RCLs a 2% chance to jam, requiring it to be reactviated manually. to_chat(user, "[src]'s wires jam!") - setActive(FALSE, user) + active = FALSE return else if(last) @@ -179,6 +196,91 @@ is_empty(user) //If we've run out, display message update_icon() +//searches the current tile for a stub cable of the same colour +/obj/item/twohanded/rcl/proc/findLinkingCable(mob/user) + var/turf/T + if(!isturf(user.loc)) + return + + T = get_turf(user) + if(T.intact || !T.can_have_cabling()) + return + + for(var/obj/structure/cable/C in T) + if(!C) + continue + if(C.cable_color != GLOB.cable_colors[colors[current_color_index]]) + continue + if(C.d1 == 0) + return C + break + return + + +/obj/item/twohanded/rcl/proc/wiringGuiGenerateChoices(mob/user) + var/fromdir = 0 + var/obj/structure/cable/linkingCable = findLinkingCable(user) + if(linkingCable) + fromdir = linkingCable.d2 + + var/list/wiredirs = list("1","5","4","6","2","10","8","9") + for(var/icondir in wiredirs) + var/dirnum = text2num(icondir) + var/cablesuffix = "[min(fromdir,dirnum)]-[max(fromdir,dirnum)]" + if(fromdir == dirnum) //cables can't loop back on themselves + cablesuffix = "invalid" + var/image/img = image(icon = 'icons/mob/radial.dmi', icon_state = "cable_[cablesuffix]") + img.color = GLOB.cable_colors[colors[current_color_index]] + wiredirs[icondir] = img + return wiredirs + +/obj/item/twohanded/rcl/proc/showWiringGui(mob/user) + var/list/choices = wiringGuiGenerateChoices(user) + + wiring_gui_menu = show_radial_menu_persistent(user, src , choices, select_proc = CALLBACK(src, .proc/wiringGuiReact, user), radius = 42) + +/obj/item/twohanded/rcl/proc/wiringGuiUpdate(mob/user) + if(!wiring_gui_menu) + return + + wiring_gui_menu.entry_animation = FALSE //stop the open anim from playing each time we update + var/list/choices = wiringGuiGenerateChoices(user) + + wiring_gui_menu.change_choices(choices,FALSE) + + +//Callback used to respond to interactions with the wiring menu +/obj/item/twohanded/rcl/proc/wiringGuiReact(mob/living/user,choice) + if(!choice) //close on a null choice (the center button) + QDEL_NULL(wiring_gui_menu) + return + + choice = text2num(choice) + + if(!isturf(user.loc)) + return + if(is_empty(user, 0)) + to_chat(user, "\The [src] is empty!") + return + + var/turf/T = get_turf(user) + if(T.intact || !T.can_have_cabling()) + return + + loaded.item_color = colors[current_color_index] + + var/obj/structure/cable/linkingCable = findLinkingCable(user) + if(linkingCable) + if(choice != linkingCable.d2) + loaded.cable_join(linkingCable, user, FALSE, choice) + last = null + else + last = loaded.place_turf(get_turf(src), user, choice) + + is_empty(user) //If we've run out, display message + + wiringGuiUpdate(user) + /obj/item/twohanded/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff . = ..() @@ -192,12 +294,21 @@ update_icon() /obj/item/twohanded/rcl/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/rcl)) + if(istype(action, /datum/action/item_action/rcl_col)) current_color_index++; if (current_color_index > colors.len) current_color_index = 1 var/cwname = colors[current_color_index] to_chat(user, "Color changed to [cwname]!") + if(loaded) + loaded.item_color= colors[current_color_index] + if(wiring_gui_menu) + wiringGuiUpdate(user) + else if(istype(action, /datum/action/item_action/rcl_gui)) + if(wiring_gui_menu) //The menu is already open, close it + QDEL_NULL(wiring_gui_menu) + else //open the menu + showWiringGui(user) /obj/item/twohanded/rcl/ghetto actions_types = list() diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index 41ddc22106..0549ebc474 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -331,7 +331,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( //make sure what we're clicking is valid for the current category var/static/list/make_pipe_whitelist if(!make_pipe_whitelist) - make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe)) + make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe, /obj/structure/window, /obj/structure/grille)) var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist)) . = FALSE diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index ab877ff97a..699efaac2e 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -59,7 +59,7 @@ /obj/item/areaeditor/blueprints/attack_self(mob/user) . = ..() if(!legend) - var/area/A = get_area() + var/area/A = get_area(user) if(get_area_type() == AREA_STATION) . += "

According to \the [src], you are now in \"[html_encode(A.name)]\".

" . += "

Change area name

" @@ -140,12 +140,10 @@ legend = FALSE -/obj/item/areaeditor/proc/get_area() - var/turf/T = get_turf(usr) - var/area/A = T.loc - return A -/obj/item/areaeditor/proc/get_area_type(area/A = get_area()) +/obj/item/areaeditor/proc/get_area_type(area/A) + if(!A) + A = get_area(usr) if(A.outdoors) return AREA_SPACE var/list/SPECIALS = list( @@ -183,7 +181,7 @@ return "" /obj/item/areaeditor/proc/edit_area() - var/area/A = get_area() + var/area/A = get_area(usr) var/prevname = "[A.name]" var/str = stripped_input(usr,"New area name:", "Area Creation", "", MAX_NAME_LEN) if(!str || !length(str) || str==prevname) //cancel diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm index a8f5894b7c..80fc0f43fd 100644 --- a/code/game/objects/items/body_egg.dm +++ b/code/game/objects/items/body_egg.dm @@ -16,7 +16,7 @@ /obj/item/organ/body_egg/Insert(var/mob/living/carbon/M, special = 0) ..() - owner.add_trait(TRAIT_XENO_HOST, TRAIT_GENERIC) + ADD_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC) START_PROCESSING(SSobj, src) owner.med_hud_set_status() INVOKE_ASYNC(src, .proc/AddInfectionImages, owner) @@ -24,7 +24,7 @@ /obj/item/organ/body_egg/Remove(var/mob/living/carbon/M, special = 0) STOP_PROCESSING(SSobj, src) if(owner) - owner.remove_trait(TRAIT_XENO_HOST, TRAIT_GENERIC) + REMOVE_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC) owner.med_hud_set_status() INVOKE_ASYNC(src, .proc/RemoveInfectionImages, owner) ..() diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 30b1ca3399..96bbe759ca 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -105,7 +105,7 @@ if(isturf(A)) return - if(istype(A,/obj/item/storage/lockbox)) + if(istype(A,/obj/item/storage/lockbox) || istype(A, /obj/item/storage/pod)) A.emag_act(user) uses = max(uses - 1, 0) if(!uses) diff --git a/code/game/objects/items/charter.dm b/code/game/objects/items/charter.dm index c550a0c872..5ed719ff94 100644 --- a/code/game/objects/items/charter.dm +++ b/code/game/objects/items/charter.dm @@ -37,10 +37,10 @@ to_chat(user, "You're still waiting for approval from your employers about your proposed name change, it'd be best to wait for now.") return - var/new_name = stripped_input(user, message="What do you want to name \ + var/new_name = html_decode(stripped_input(user, message="What do you want to name \ [station_name()]? Keep in mind particularly terrible names may be \ rejected by your employers, while names using the standard format, \ - will automatically be accepted.", max_length=MAX_CHARTER_LEN) + will automatically be accepted.", max_length=MAX_CHARTER_LEN)) if(response_timer_id) to_chat(user, "You're still waiting for approval from your employers about your proposed name change, it'd be best to wait for now.") diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index f7c37715aa..344e7c5472 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -248,9 +248,8 @@ /obj/effect/chrono_field/return_air() //we always have nominal air and temperature var/datum/gas_mixture/GM = new - GM.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - GM.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD - GM.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD + GM.gases[/datum/gas/oxygen] = MOLES_O2STANDARD + GM.gases[/datum/gas/nitrogen] = MOLES_N2STANDARD GM.temperature = T20C return GM diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 1ad7974fc1..d64f5b57b8 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -102,7 +102,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon_state = "cigoff" throw_speed = 0.5 item_state = "cigoff" - container_type = INJECTABLE w_class = WEIGHT_CLASS_TINY body_parts_covered = null grind_results = list() @@ -123,8 +122,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/cigarette/Initialize() . = ..() - create_reagents(chem_volume) - reagents.set_reacting(FALSE) // so it doesn't react until you light it + create_reagents(chem_volume, INJECTABLE | NO_REACT) // so it doesn't react until you light it if(list_reagents) reagents.add_reagent_list(list_reagents) if(starts_lit) @@ -184,7 +182,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM qdel(src) return // allowing reagents to react after being lit - reagents.set_reacting(TRUE) + DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) reagents.handle_reactions() icon_state = icon_on item_state = icon_on @@ -325,7 +323,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM list_reagents = list("space_drugs" = 15, "lipolicide" = 35) /obj/item/clothing/mask/cigarette/rollie/mindbreaker - list_reagents = list("mindbreaker" = 35, "lipolicide" = 15) + list_reagents = list("mindbreaker" = 35, "lipolicide" = 15) /obj/item/cigbutt/roach name = "roach" @@ -720,8 +718,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/vape/Initialize(mapload, param_color) . = ..() - create_reagents(chem_volume) - reagents.set_reacting(FALSE) // so it doesn't react until you light it + DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) reagents.add_reagent("nicotine", 50) if(!icon_state) if(!param_color) @@ -790,13 +787,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(reagents.total_volume > 0) to_chat(user, "You empty [src] of all reagents.") reagents.clear_reagents() - return /obj/item/clothing/mask/vape/equipped(mob/user, slot) if(slot == SLOT_WEAR_MASK) if(!screw) to_chat(user, "You start puffing on the vape.") - reagents.set_reacting(TRUE) + DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) START_PROCESSING(SSobj, src) else //it will not start if the vape is opened. to_chat(user, "You need to close the cap first!") @@ -804,7 +800,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/vape/dropped(mob/user) var/mob/living/carbon/C = user if(C.get_item_by_slot(SLOT_WEAR_MASK) == src) - reagents.set_reacting(FALSE) + ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) STOP_PROCESSING(SSobj, src) /obj/item/clothing/mask/vape/proc/hand_reagents()//had to rename to avoid duplicate error diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 26f8a73cb3..99d6c874e8 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -68,6 +68,8 @@ var/pre_noise = FALSE var/post_noise = FALSE + var/datum/team/gang/gang //For marking territory. + var/gang_tag_delay = 30 //this is the delay for gang mode tag applications on anything that gang = true on. /obj/item/toy/crayon/suicide_act(mob/user) user.visible_message("[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!") @@ -252,7 +254,7 @@ cost = 0 if(ishuman(user)) var/mob/living/carbon/human/H = user - if (H.has_trait(TRAIT_TAGGER)) + if (HAS_TRAIT(H, TRAIT_TAGGER)) cost *= 0.5 var/charges_used = use_charges(user, cost) if(!charges_used) @@ -288,6 +290,13 @@ else if(drawing in numerals) temp = "number" + // If a gang member is using a gang spraycan, it'll behave differently + var/gang_mode = FALSE + if(gang && user.mind && user.mind.has_antag_datum(/datum/antagonist/gang)) //Heres a check. + gang_mode = TRUE // No more runtimes if a non-gang member sprays a gang can, it just works like normal cans. + // discontinue if the area isn't valid for tagging because gang "honour" + if(gang_mode && (!can_claim_for_gang(user, target))) + return var/graf_rot if(drawing in oriented) @@ -310,20 +319,22 @@ clicky = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) if(!instant) - to_chat(user, "You start drawing a [temp] on the [target.name]...") + to_chat(user, "You start drawing a [temp] on the [target.name]...") if(pre_noise) audible_message("You hear spraying.") playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5) - var/takes_time = !instant + var/takes_time = !instant //For order purposes, since I'm maximum bad. + if(gang_mode) + takes_time = TRUE var/wait_time = 50 if(paint_mode == PAINT_LARGE_HORIZONTAL) wait_time *= 3 - if(takes_time) - if(!do_after(user, 50, target = target)) + if(takes_time) //This is what deteremines the time it takes to spray a tag in gang mode. 50 is Default. + if(!do_after(user, gang_tag_delay, target = target)) //25 is a good number, but we have gang_tag_delay var now. return if(length(text_buffer)) @@ -332,26 +343,34 @@ var/list/turf/affected_turfs = list() + if(actually_paints) - switch(paint_mode) - if(PAINT_NORMAL) - var/obj/effect/decal/cleanable/crayon/C = new(target, paint_color, drawing, temp, graf_rot) - C.add_hiddenprint(user) - C.pixel_x = clickx - C.pixel_y = clicky - affected_turfs += target - if(PAINT_LARGE_HORIZONTAL) - var/turf/left = locate(target.x-1,target.y,target.z) - var/turf/right = locate(target.x+1,target.y,target.z) - if(is_type_in_list(left, validSurfaces) && is_type_in_list(right, validSurfaces)) - var/obj/effect/decal/cleanable/crayon/C = new(left, paint_color, drawing, temp, graf_rot, PAINT_LARGE_HORIZONTAL_ICON) + if(gang_mode) + // Double check it wasn't tagged in the meanwhile. + if(!can_claim_for_gang(user, target)) + return + tag_for_gang(user, target) + affected_turfs += target + else + switch(paint_mode) + if(PAINT_NORMAL) + var/obj/effect/decal/cleanable/crayon/C = new(target, paint_color, drawing, temp, graf_rot) C.add_hiddenprint(user) - affected_turfs += left - affected_turfs += right + C.pixel_x = clickx + C.pixel_y = clicky affected_turfs += target - else - to_chat(user, "There isn't enough space to paint!") - return + if(PAINT_LARGE_HORIZONTAL) + var/turf/left = locate(target.x-1,target.y,target.z) + var/turf/right = locate(target.x+1,target.y,target.z) + if(is_type_in_list(left, validSurfaces) && is_type_in_list(right, validSurfaces)) + var/obj/effect/decal/cleanable/crayon/C = new(left, paint_color, drawing, temp, graf_rot, PAINT_LARGE_HORIZONTAL_ICON) + C.add_hiddenprint(user) + affected_turfs += left + affected_turfs += right + affected_turfs += target + else + to_chat(user, "There isn't enough space to paint!") + return if(!instant) to_chat(user, "You finish drawing \the [temp].") @@ -373,6 +392,52 @@ reagents.trans_to(t, ., volume_multiplier) check_empty(user) + +//////////////Gang mode stuff///////////////// +/obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target) + // Check area validity. + // Reject space, player-created areas, and non-station z-levels. + var/area/A = get_area(target) + if(!A || (!is_station_level(A.z)) || !A.valid_territory) + to_chat(user, "[A] is unsuitable for tagging.") + return FALSE + + var/spraying_over = FALSE + for(var/G in target) + var/obj/effect/decal/cleanable/crayon/gang/gangtag = G + if(istype(gangtag)) + var/datum/antagonist/gang/GA = user.mind.has_antag_datum(/datum/antagonist/gang) + if(gangtag.gang != GA.gang) + spraying_over = TRUE + break + + var/occupying_gang = territory_claimed(A, user) + if(occupying_gang && !spraying_over) + to_chat(user, "[A] has already been tagged by the [occupying_gang] gang! You must get rid of or spray over the old tag first!") + return FALSE + + // If you pass the gauntlet of checks, you're good to proceed + return TRUE + +/obj/item/toy/crayon/proc/territory_claimed(area/territory, mob/user) + for(var/datum/team/gang/G in GLOB.gangs) + if(territory.type in (G.territories|G.new_territories)) + . = G.name + break + +/obj/item/toy/crayon/proc/tag_for_gang(mob/user, atom/target) + //Delete any old markings on this tile, including other gang tags + for(var/obj/effect/decal/cleanable/crayon/old_marking in target) + qdel(old_marking) + + var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) + var/area/territory = get_area(target) + + new /obj/effect/decal/cleanable/crayon/gang(target,G.gang,"graffiti",0,user) // Heres the gang tag. + to_chat(user, "You tagged [territory] for your gang!") +/////////////////Gang end//////////////////// + + /obj/item/toy/crayon/attack(mob/M, mob/user) if(edible && (M == user)) to_chat(user, "You take a bite of the [src.name]. Delicious!") @@ -524,6 +589,7 @@ is_capped = TRUE self_contained = FALSE // Don't disappear when they're empty can_change_colour = TRUE + gang = TRUE //Gang check is true for all things upon the honored hierarchy of spraycans, except those that are FALSE. validSurfaces = list(/turf/open/floor, /turf/closed/wall) reagent_contents = list("welding_fuel" = 1, "ethanol" = 1) @@ -669,6 +735,7 @@ icon_capped = "deathcan2_cap" icon_uncapped = "deathcan2" use_overlays = FALSE + gang = FALSE volume_multiplier = 25 charges = 100 @@ -683,6 +750,7 @@ icon_capped = "clowncan2_cap" icon_uncapped = "clowncan2" use_overlays = FALSE + gang = FALSE reagent_contents = list("lube" = 1, "banana" = 1) volume_multiplier = 5 @@ -695,6 +763,7 @@ icon_capped = "mimecan_cap" icon_uncapped = "mimecan" use_overlays = FALSE + gang = FALSE can_change_colour = FALSE paint_color = "#FFFFFF" //RGB @@ -703,6 +772,26 @@ post_noise = FALSE reagent_contents = list("nothing" = 1, "mutetoxin" = 1) +/obj/item/toy/crayon/spraycan/gang + charges = 20 // Charges back to 20, which is the default value for them. + gang = TRUE + gang_tag_delay = 15 //Its 50% faster than a regular spraycan, for tagging. After-all they did spend points/meet the boss. + + pre_noise = FALSE + post_noise = TRUE // Its even more stealthy just a tad. + +/obj/item/toy/crayon/spraycan/gang/Initialize(loc, datum/team/gang/G) + ..() + if(G) + gang = G + paint_color = G.color + update_icon() + +/obj/item/toy/crayon/spraycan/gang/examine(mob/user) + . = ..() + if(user.mind && user.mind.has_antag_datum(/datum/antagonist/gang) || isobserver(user)) + to_chat(user, "This spraycan has been specially modified with a stage 2 nozzle kit, making it faster.") + #undef RANDOM_GRAFFITI #undef RANDOM_LETTER #undef RANDOM_NUMBER diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 034363be7d..55e75b3992 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -444,11 +444,12 @@ /obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H) var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain) - return (!H.suiciding && !(H.has_trait(TRAIT_NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain) + return (!H.suiciding && !(HAS_TRAIT(H, TRAIT_NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain) /obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H) - if(defib.pullshocksafely && isliving(H.pulledby)) - H.visible_message("The defibrillator safely discharges the excessive charge into the floor!") + if(req_defib) + if(defib.pullshocksafely && isliving(H.pulledby)) + H.visible_message("The defibrillator safely discharges the excessive charge into the floor!") else var/mob/living/M = H.pulledby if(M.electrocute_act(30, src)) @@ -542,7 +543,20 @@ user.visible_message("[user] begins to place [src] on [H]'s chest.", "You begin to place [src] on [H]'s chest...") busy = TRUE update_icon() - if(do_after(user, 30 - defib.primetime, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process + + var/primetimer + var/primetimer2 + var/deathtimer + if(req_defib) + primetimer = 30 - defib.primetime //I swear to god if I find shit like this elsewhere + primetimer2 = 20 - defib.primetime + deathtimer = DEFIB_TIME_LOSS * defib.timedeath + else + primetimer = 30 + primetimer2 = 20 + deathtimer = DEFIB_TIME_LOSS * 10 + + if(do_after(user, primetimer, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process user.visible_message("[user] places [src] on [H]'s chest.", "You place [src] on [H]'s chest.") playsound(src, 'sound/machines/defib_charge.ogg', 75, 0) var/tplus = world.time - H.timeofdeath @@ -550,10 +564,10 @@ // (in deciseconds) // brain damage starts setting in on the patient after // some time left rotting - var/tloss = DEFIB_TIME_LOSS * defib.timedeath + var/tloss = deathtimer var/total_burn = 0 var/total_brute = 0 - if(do_after(user, 20 - defib.primetime, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total + if(do_after(user, primetimer2, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total for(var/obj/item/carried_item in H.contents) if(istype(carried_item, /obj/item/clothing/suit/space)) if((!combat && !req_defib) || (req_defib && !defib.combat)) @@ -571,7 +585,7 @@ shock_touching(30, H) var/failed - if (H.suiciding || (H.has_trait(TRAIT_NOCLONE))) + if (H.suiciding || (HAS_TRAIT(H, TRAIT_NOCLONE))) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile." else if (H.hellbound) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existence. Further attempts futile." @@ -613,8 +627,9 @@ if(tplus > tloss) H.adjustBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150) log_combat(user, H, "revived", defib) - if(defib.healdisk) - H.heal_overall_damage(25, 25) + if(req_defib) + if(defib.healdisk) + H.heal_overall_damage(25, 25) if(req_defib) defib.deductcharge(revivecost) cooldown = 1 @@ -698,12 +713,12 @@ req_defib = FALSE /////////////////////////////////////////// -/////////Dedibrillators Disks////////////// +/////////Defibrillator Disks////////////// /////////////////////////////////////////// /obj/item/disk/medical name = "Defibrillator Upgrade Disk" - desc = "A blank defibrillator disk..." + desc = "A blank upgrade disk, made for a defibrillator" icon = 'modular_citadel/icons/obj/defib_disks.dmi' icon_state = "upgrade_disk" item_state = "heal_disk" @@ -711,25 +726,25 @@ /obj/item/disk/medical/defib_heal name = "Defibrillator Healing Disk" - desc = "A disk alowing for grater amounts of healing" + desc = "An upgrade which increases the healing power of the defibrillator" icon_state = "heal_disk" materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000) /obj/item/disk/medical/defib_shock name = "Defibrillator Anti-Shock Disk" - desc = "A disk that helps agains shocking anyone, other then the intented target" + desc = "A safety upgrade that guarantees only the patient will get shocked" icon_state = "zap_disk" materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000) /obj/item/disk/medical/defib_decay name = "Defibrillator Body-Decay Extender Disk" - desc = "A disk that helps defibrillators revive the longer decayed" + desc = "An upgrade allowing the defibrillator to work on more decayed bodies" icon_state = "body_disk" materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 16000, MAT_SILVER = 6000, MAT_TITANIUM = 2000) /obj/item/disk/medical/defib_speed - name = "Defibrllator Pre-Primer Disk" - desc = "A disk that cuts the time charg time in half for defibrillator use" + name = "Defibrillator Fast Charge Disk" + desc = "An upgrade to the defibrillator capacitors, which let it charge faster" icon_state = "fast_disk" materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_GOLD = 26000, MAT_SILVER = 26000) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 7d3d36c5b2..48b21d58bd 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -358,9 +358,9 @@ GLOBAL_LIST_EMPTY(PDAs) if (total_moles) for(var/id in env_gases) - var/gas_level = env_gases[id][MOLES]/total_moles + var/gas_level = env_gases[id]/total_moles if(gas_level > 0) - dat += "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_level*100, 0.01)]%
" + dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100, 0.01)]%
" dat += "Temperature: [round(environment.temperature-T0C)]°C
" dat += "
" diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index fc268e2b3e..1a733fbff2 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -31,7 +31,7 @@ var/remote_door_id = "" - var/bot_access_flags = 0 //Bit flags. Selection: SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT + var/bot_access_flags = 0 //Bit flags. Selection: SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT var/spam_enabled = 0 //Enables "Send to All" Option var/obj/item/pda/host_pda = null @@ -65,7 +65,7 @@ name = "\improper BreatheDeep cartridge" icon_state = "cart-a" access = CART_ATMOS | CART_DRONEPHONE - bot_access_flags = FLOOR_BOT + bot_access_flags = FLOOR_BOT | FIRE_BOT /obj/item/cartridge/medical name = "\improper Med-U cartridge" @@ -112,7 +112,7 @@ /obj/item/cartridge/roboticist name = "\improper B.O.O.P. Remote Control cartridge" desc = "Packed with heavy duty triple-bot interlink!" - bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT + bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT access = CART_DRONEPHONE /obj/item/cartridge/signal @@ -160,7 +160,7 @@ name = "\improper Power-On DELUXE cartridge" icon_state = "cart-ce" access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_ENGINE | CART_ATMOS | CART_DRONEPHONE - bot_access_flags = FLOOR_BOT + bot_access_flags = FLOOR_BOT | FIRE_BOT /obj/item/cartridge/cmo name = "\improper Med-U DELUXE cartridge" @@ -172,7 +172,7 @@ name = "\improper Signal Ace DELUXE cartridge" icon_state = "cart-rd" access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_REAGENT_SCANNER | CART_ATMOS | CART_DRONEPHONE - bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT + bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT /obj/item/cartridge/rd/Initialize() . = ..() @@ -183,7 +183,7 @@ desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime, Clown, and Syndie) icon_state = "cart-c" access = ~(CART_CLOWN | CART_MIME | CART_REMOTE_DOOR) - bot_access_flags = SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT + bot_access_flags = SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT spam_enabled = 1 /obj/item/cartridge/captain/New() diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index cbbd7a387a..40f2059d25 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -52,7 +52,7 @@ add_fingerprint(user) if(istype(M) && on && user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH)) - if((user.has_trait(TRAIT_CLUMSY) || user.has_trait(TRAIT_DUMB)) && prob(50)) //too dumb to use flashlight properly + if((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50)) //too dumb to use flashlight properly return ..() //just hit them in the head if(!user.IsAdvancedToolUser()) @@ -86,7 +86,7 @@ else user.visible_message("[user] directs [src] to [M]'s eyes.", \ "You direct [src] to [M]'s eyes.") - if(M.stat == DEAD || (M.has_trait(TRAIT_BLIND)) || !M.flash_act(visual = 1)) //mob is dead or fully blind + if(M.stat == DEAD || (HAS_TRAIT(M, TRAIT_BLIND)) || !M.flash_act(visual = 1)) //mob is dead or fully blind to_chat(user, "[M]'s pupils don't react to the light!") else if(M.dna && M.dna.check_mutation(XRAY)) //mob has X-ray vision to_chat(user, "[M]'s pupils give an eerie glow!") diff --git a/code/game/objects/items/devices/instruments.dm b/code/game/objects/items/devices/instruments.dm index c5ed5fb601..661d38ce6b 100644 --- a/code/game/objects/items/devices/instruments.dm +++ b/code/game/objects/items/devices/instruments.dm @@ -54,7 +54,7 @@ /obj/item/instrument/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/musicaltuner)) var/mob/living/carbon/human/H = user - if (H.has_trait(TRAIT_MUSICIAN)) + if (HAS_TRAIT(H, TRAIT_MUSICIAN)) if (!tune_time) H.visible_message("[H] tunes the [src] to perfection!", "You tune the [src] to perfection!") tune_time = 300 diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 632c2c4221..7baea7f488 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -69,7 +69,7 @@ if (!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") return - if(user.has_trait(TRAIT_NOGUNS)) + if(HAS_TRAIT(user, TRAIT_NOGUNS)) to_chat(user, "Your fingers can't press the button!") return if(ishuman(user)) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 5a68a8423a..9f52b4c1ac 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -95,13 +95,15 @@ SLIME SCANNER /obj/item/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user) // Clumsiness/brain damage check - if ((user.has_trait(TRAIT_CLUMSY) || user.has_trait(TRAIT_DUMB)) && prob(50)) + if ((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50)) to_chat(user, "You stupidly try to analyze the floor's vitals!") user.visible_message("[user] has analyzed the floor's vitals!") - to_chat(user, "Analyzing results for The floor:\n\tOverall status: Healthy") - to_chat(user, "Key: Suffocation/Toxin/Burn/Brute") - to_chat(user, "\tDamage specifics: 0-0-0-0") - to_chat(user, "Body temperature: ???") + var/msg = "*---------*\nAnalyzing results for The floor:\n\tOverall status: Healthy\n" + msg += "Key: Suffocation/Toxin/Burn/Brute\n" + msg += "\tDamage specifics: 0-0-0-0\n" + msg += "Body temperature: ???\n" + msg += "*---------*" + to_chat(user, msg) return user.visible_message("[user] has analyzed [M]'s vitals.") @@ -125,7 +127,7 @@ SLIME SCANNER var/brute_loss = M.getBruteLoss() var/mob_status = (M.stat == DEAD ? "Deceased" : "[round(M.health/M.maxHealth,0.01)*100] % healthy") - if(M.has_trait(TRAIT_FAKEDEATH) && !advanced) + if(HAS_TRAIT(M, TRAIT_FAKEDEATH) && !advanced) mob_status = "Deceased" oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss @@ -136,31 +138,31 @@ SLIME SCANNER if(H.undergoing_liver_failure() && H.stat != DEAD) to_chat(user, "Subject is suffering from liver failure: Apply Corazone and begin a liver transplant immediately!") - to_chat(user, "Analyzing results for [M]:\n\tOverall status: [mob_status]") + var/msg = "*---------*\nAnalyzing results for [M]:\n\tOverall status: [mob_status]\n" // Damage descriptions if(brute_loss > 10) - to_chat(user, "\t[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected.") + msg += "\t[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected.\n" if(fire_loss > 10) - to_chat(user, "\t[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected.") + msg += "\t[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected.\n" if(oxy_loss > 10) - to_chat(user, "\t[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.") + msg += "\t[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.\n" if(tox_loss > 10) - to_chat(user, "\t[tox_loss > 50 ? "Severe" : "Minor"] amount of toxin damage detected.") + msg += "\t[tox_loss > 50 ? "Severe" : "Minor"] amount of toxin damage detected.\n" if(M.getStaminaLoss()) - to_chat(user, "\tSubject appears to be suffering from fatigue.") + msg += "\tSubject appears to be suffering from fatigue.\n" if(advanced) - to_chat(user, "\tFatigue Level: [M.getStaminaLoss()]%.") + msg += "\tFatigue Level: [M.getStaminaLoss()]%.\n" if (M.getCloneLoss()) - to_chat(user, "\tSubject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage.") + msg += "\tSubject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage.\n" if(advanced) - to_chat(user, "\tCellular Damage Level: [M.getCloneLoss()].") + msg += "\tCellular Damage Level: [M.getCloneLoss()].\n" if (M.getBrainLoss() >= 200 || !M.getorgan(/obj/item/organ/brain)) - to_chat(user, "\tSubject's brain function is non-existent.") + msg += "\tSubject's brain function is non-existent.\n" else if (M.getBrainLoss() >= 120) - to_chat(user, "\tSevere brain damage detected. Subject likely to have mental traumas.") + msg += "\tSevere brain damage detected. Subject likely to have mental traumas.\n" else if (M.getBrainLoss() >= 45) - to_chat(user, "\tBrain damage detected.") + msg += "\tBrain damage detected.\n" if(iscarbon(M)) var/mob/living/carbon/C = M if(LAZYLEN(C.get_traumas())) @@ -176,83 +178,83 @@ SLIME SCANNER trauma_desc += "permanent " trauma_desc += B.scan_desc trauma_text += trauma_desc - to_chat(user, "\tCerebral traumas detected: subject appears to be suffering from [english_list(trauma_text)].") + msg += "\tCerebral traumas detected: subject appears to be suffering from [english_list(trauma_text)].\n" if(C.roundstart_quirks.len) - to_chat(user, "\tSubject has the following physiological traits: [C.get_trait_string()].") + msg += "\tSubject has the following physiological traits: [C.get_trait_string()].\n" if(advanced) - to_chat(user, "\tBrain Activity Level: [(200 - M.getBrainLoss())/2]%.") + msg += "\tBrain Activity Level: [(200 - M.getBrainLoss())/2]%.\n" if (M.radiation) - to_chat(user, "\tSubject is irradiated.") + msg += "\tSubject is irradiated.\n" if(advanced) - to_chat(user, "\tRadiation Level: [M.radiation]%.") + msg += "\tRadiation Level: [M.radiation]%.\n" if(advanced && M.hallucinating()) - to_chat(user, "\tSubject is hallucinating.") + msg += "\tSubject is hallucinating.\n" //Eyes and ears if(advanced) if(iscarbon(M)) var/mob/living/carbon/C = M var/obj/item/organ/ears/ears = C.getorganslot(ORGAN_SLOT_EARS) - to_chat(user, "\t==EAR STATUS==") + msg += "\t==EAR STATUS==\n" if(istype(ears)) var/healthy = TRUE - if(C.has_trait(TRAIT_DEAF, GENETIC_MUTATION)) + if(HAS_TRAIT_FROM(C, TRAIT_DEAF, GENETIC_MUTATION)) healthy = FALSE - to_chat(user, "\tSubject is genetically deaf.") - else if(C.has_trait(TRAIT_DEAF)) + msg += "\tSubject is genetically deaf.\n" + else if(HAS_TRAIT(C, TRAIT_DEAF)) healthy = FALSE - to_chat(user, "\tSubject is deaf.") + msg += "\tSubject is deaf.\n" else if(ears.ear_damage) - to_chat(user, "\tSubject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.") + msg += "\tSubject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.\n" healthy = FALSE if(ears.deaf) - to_chat(user, "\tSubject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf.") + msg += "\tSubject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf.\n" healthy = FALSE if(healthy) - to_chat(user, "\tHealthy.") + msg += "\tHealthy.\n" else - to_chat(user, "\tSubject does not have ears.") + msg += "\tSubject does not have ears.\n" var/obj/item/organ/eyes/eyes = C.getorganslot(ORGAN_SLOT_EYES) - to_chat(user, "\t==EYE STATUS==") + msg += "\t==EYE STATUS==\n" if(istype(eyes)) var/healthy = TRUE - if(C.has_trait(TRAIT_BLIND)) - to_chat(user, "\tSubject is blind.") + if(HAS_TRAIT(C, TRAIT_BLIND)) + msg += "\tSubject is blind.\n" healthy = FALSE - if(C.has_trait(TRAIT_NEARSIGHT)) - to_chat(user, "\tSubject is nearsighted.") + if(HAS_TRAIT(C, TRAIT_NEARSIGHT)) + msg += "\tSubject is nearsighted.\n" healthy = FALSE if(eyes.eye_damage > 30) - to_chat(user, "\tSubject has severe eye damage.") + msg += "\tSubject has severe eye damage.\n" healthy = FALSE else if(eyes.eye_damage > 20) - to_chat(user, "\tSubject has significant eye damage.") + msg += "\tSubject has significant eye damage.\n" healthy = FALSE else if(eyes.eye_damage) - to_chat(user, "\tSubject has minor eye damage.") + msg += "\tSubject has minor eye damage.\n" healthy = FALSE if(healthy) - to_chat(user, "\tHealthy.") + msg += "\tHealthy.\n" else - to_chat(user, "\tSubject does not have eyes.") + msg += "\tSubject does not have eyes.\n" if(ishuman(M)) var/mob/living/carbon/human/H = M var/ldamage = H.return_liver_damage() if(ldamage > 10) - to_chat(user, "\t[ldamage > 45 ? "Severe" : "Minor"] liver damage detected.") + msg += "\t[ldamage > 45 ? "Severe" : "Minor"] liver damage detected.\n" // Body part damage report if(iscarbon(M) && mode == 1) 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) - to_chat(user, "\tDamage: Brute-Burn-Toxin-Suffocation\n\t\tSpecifics: [brute_loss]-[fire_loss]-[tox_loss]-[oxy_loss]") + msg += "\tDamage: Brute-Burn-Toxin-Suffocation\n\t\tSpecifics: [brute_loss]-[fire_loss]-[tox_loss]-[oxy_loss]\n" for(var/obj/item/bodypart/org in damaged) - to_chat(user, "\t\t[capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]-[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]") + msg += "\t\t[capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]-[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]\n" // Species and body temperature if(ishuman(M)) @@ -282,20 +284,22 @@ SLIME SCANNER else if (S.mutantstomach != initial(S.mutantstomach)) mutant = TRUE - to_chat(user, "Species: [S.name][mutant ? "-derived mutant" : ""]") - to_chat(user, "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)") + msg += "Species: [H.dna.custom_species ? H.dna.custom_species : S.name] Base: [S.name]\n" + if(mutant) + msg += "Subject has mutations present." + 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 || ((M.has_trait(TRAIT_FAKEDEATH)) && !advanced))) - to_chat(user, "Time of Death: [M.tod]") + if(M.tod && (M.stat == DEAD || ((HAS_TRAIT(M, TRAIT_FAKEDEATH)) && !advanced))) + msg += "Time of Death: [M.tod]\n" var/tdelta = round(world.time - M.timeofdeath) if(tdelta < (DEFIB_TIME_LIMIT * 10)) - to_chat(user, "Subject died [DisplayTimeText(tdelta)] ago, defibrillation may be possible!") + msg += "Subject died [DisplayTimeText(tdelta)] ago, defibrillation may be possible!\n" for(var/thing in M.diseases) var/datum/disease/D = thing if(!(D.visibility_flags & HIDDEN_SCANNER)) - to_chat(user, "Warning: [D.form] detected\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]") + msg += "Warning: [D.form] detected\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]\n" // Blood Level if(M.has_dna()) @@ -305,7 +309,7 @@ SLIME SCANNER if(ishuman(C)) var/mob/living/carbon/human/H = C if(H.bleed_rate) - to_chat(user, "Subject is bleeding!") + msg += "Subject is bleeding!\n" var/blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100) var/blood_type = C.dna.blood_type if(blood_id != "blood")//special blood substance @@ -315,36 +319,41 @@ SLIME SCANNER else blood_type = blood_id if(C.blood_volume <= BLOOD_VOLUME_SAFE && C.blood_volume > BLOOD_VOLUME_OKAY) - to_chat(user, "LOW blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]") + msg += "LOW blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]\n" else if(C.blood_volume <= BLOOD_VOLUME_OKAY) - to_chat(user, "CRITICAL blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]") + msg += "CRITICAL blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]\n" else - to_chat(user, "Blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]") + msg += "Blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]\n" var/cyberimp_detect for(var/obj/item/organ/cyberimp/CI in C.internal_organs) if(CI.status == ORGAN_ROBOTIC && !CI.syndicate_implant) cyberimp_detect += "[C.name] is modified with a [CI.name].
" if(cyberimp_detect) - to_chat(user, "Detected cybernetic modifications:") - to_chat(user, "[cyberimp_detect]") + msg += "Detected cybernetic modifications:\n" + msg += "[cyberimp_detect]\n" + 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" if(M.reagents.reagent_list.len) - to_chat(user, "Subject contains the following reagents:") + msg += "Subject contains the following reagents:\n" for(var/datum/reagent/R in M.reagents.reagent_list) - to_chat(user, "[R.volume] units of [R.name][R.overdosed == 1 ? " - OVERDOSING" : "."]") + msg += "[R.volume] units of [R.name][R.overdosed == 1 ? " - OVERDOSING" : ".
"]\n" else - to_chat(user, "Subject contains no reagents.") + msg += "Subject contains no reagents.\n" if(M.reagents.addiction_list.len) - to_chat(user, "Subject is addicted to the following reagents:") + msg += "Subject is addicted to the following reagents:\n" for(var/datum/reagent/R in M.reagents.addiction_list) - to_chat(user, "[R.name]") + msg += "[R.name]\n" else - to_chat(user, "Subject is not addicted to any reagents.") + msg += "Subject is not addicted to any reagents.\n" + msg += "*---------*
" + to_chat(user, msg) /obj/item/healthanalyzer/verb/toggle_mode() set name = "Switch Verbosity" @@ -419,39 +428,38 @@ SLIME SCANNER if(total_moles) var/list/env_gases = environment.gases - environment.assert_gases(arglist(GLOB.hardcoded_gases)) - var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles - var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles - var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles - var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles + var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles + var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles + var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles + var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles if(abs(n2_concentration - N2STANDARD) < 20) - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen][MOLES], 0.01)] mol)") + to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen], 0.01)] mol)") else - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen][MOLES], 0.01)] mol)") + to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen], 0.01)] mol)") if(abs(o2_concentration - O2STANDARD) < 2) - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 0.01)] mol)") + to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen], 0.01)] mol)") else - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 0.01)] mol)") + to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen], 0.01)] mol)") if(co2_concentration > 0.01) - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 0.01)] mol)") + to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide], 0.01)] mol)") else - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 0.01)] mol)") + to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide], 0.01)] mol)") if(plasma_concentration > 0.005) - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 0.01)] mol)") + to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma], 0.01)] mol)") else - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 0.01)] mol)") + to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma], 0.01)] mol)") - environment.garbage_collect() + GAS_GARBAGE_COLLECT(environment.gases) for(var/id in env_gases) if(id in GLOB.hardcoded_gases) continue - var/gas_concentration = env_gases[id][MOLES]/total_moles - to_chat(user, "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(env_gases[id][MOLES], 0.01)] mol)") + var/gas_concentration = env_gases[id]/total_moles + to_chat(user, "[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(env_gases[id], 0.01)] mol)") to_chat(user, "Temperature: [round(environment.temperature-T0C, 0.01)] °C ([round(environment.temperature, 0.01)] K)") /obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens @@ -541,8 +549,8 @@ SLIME SCANNER var/list/cached_gases = air_contents.gases for(var/id in cached_gases) - var/gas_concentration = cached_gases[id][MOLES]/total_moles - to_chat(user, "[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(cached_gases[id][MOLES], 0.01)] mol)") + var/gas_concentration = cached_gases[id]/total_moles + to_chat(user, "[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(cached_gases[id], 0.01)] mol)") to_chat(user, "Temperature: [round(temperature - T0C,0.01)] °C ([round(temperature, 0.01)] K)") else diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm index d5ac5d9c52..10c81e9dbb 100644 --- a/code/game/objects/items/dna_injector.dm +++ b/code/game/objects/items/dna_injector.dm @@ -31,7 +31,7 @@ /obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user) prepare() - if(M.has_dna() && !M.has_trait(TRAIT_RADIMMUNE) && !M.has_trait(TRAIT_NOCLONE)) + if(M.has_dna() && !HAS_TRAIT(M, TRAIT_RADIMMUNE) && !HAS_TRAIT(M, TRAIT_NOCLONE)) M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2)) var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]" for(var/datum/mutation/human/HM in remove_mutations) @@ -313,7 +313,7 @@ to_chat(user, "You can't modify [M]'s DNA while [M.p_theyre()] dead.") return FALSE - if(M.has_dna() && !(M.has_trait(TRAIT_NOCLONE))) + if(M.has_dna() && !(HAS_TRAIT(M, TRAIT_NOCLONE))) M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2)) var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]" var/endtime = world.time+duration diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index e0d6b553fd..882a50b3ba 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -15,7 +15,6 @@ attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed") dog_fashion = /datum/dog_fashion/back resistance_flags = FIRE_PROOF - container_type = AMOUNT_VISIBLE var/max_water = 50 var/last_use = 1 var/chem = "water" @@ -56,7 +55,7 @@ /obj/item/extinguisher/Initialize() . = ..() - create_reagents(max_water) + create_reagents(max_water, AMOUNT_VISIBLE) reagents.add_reagent(chem, max_water) @@ -71,6 +70,10 @@ sprite_name = "foam_extinguisher" precision = TRUE +/obj/item/extinguisher/proc/refill() + create_reagents(max_water, AMOUNT_VISIBLE) + reagents.add_reagent(chem, max_water) + /obj/item/extinguisher/suicide_act(mob/living/carbon/user) if (!safety && (reagents.total_volume >= 1)) user.visible_message("[user] puts the nozzle to [user.p_their()] mouth. It looks like [user.p_theyre()] trying to extinguish the spark of life!") @@ -183,7 +186,7 @@ W.reagents = R R.my_atom = W reagents.trans_to(W,1) - + //Make em move dat ass, hun addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_particles, water_particles), 2) @@ -243,3 +246,12 @@ user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "You quietly empty out \the [src] using its release valve.") +//firebot assembly +/obj/item/extinguisher/attackby(obj/O, mob/user, params) + if(istype(O, /obj/item/bodypart/l_arm/robot) || istype(O, /obj/item/bodypart/r_arm/robot)) + to_chat(user, "You add [O] to [src].") + qdel(O) + qdel(src) + user.put_in_hands(new /obj/item/bot_assembly/firebot) + else + ..() diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index 2635955a15..fd51ecf26b 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -205,7 +205,7 @@ //Transfer 5% of current tank air contents to turf var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount) if(air_transfer.gases[/datum/gas/plasma]) - air_transfer.gases[/datum/gas/plasma][MOLES] *= 5 + air_transfer.gases[/datum/gas/plasma] *= 5 target.assume_air(air_transfer) //Burn it based on transfered gas target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) diff --git a/code/game/objects/items/grenades/grenade.dm b/code/game/objects/items/grenades/grenade.dm index 32e06eb9b4..28d8739369 100644 --- a/code/game/objects/items/grenades/grenade.dm +++ b/code/game/objects/items/grenades/grenade.dm @@ -33,7 +33,7 @@ qdel(src) /obj/item/grenade/proc/clown_check(mob/living/carbon/human/user) - var/clumsy = user.has_trait(TRAIT_CLUMSY) + var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY) if(clumsy && (clumsy_check == GRENADE_CLUMSY_FUMBLE)) if(prob(50)) to_chat(user, "Huh? How does this thing work?") diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 1f3019fe65..5e19577b46 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -44,7 +44,7 @@ if(!istype(C)) return - if(iscarbon(user) && (user.has_trait(TRAIT_CLUMSY) && prob(50))) + if(iscarbon(user) && (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))) to_chat(user, "Uh... how do those things work?!") apply_cuffs(user,user) return diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 0b61bba471..03dc7e8120 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -248,7 +248,9 @@ if(SSreligion.holy_weapon_type) return var/obj/item/nullrod/holy_weapon - var/list/holy_weapons_list = typesof(/obj/item/nullrod) + var/list/holy_weapons_list = typesof(/obj/item/nullrod) + list( + /obj/item/melee/transforming/energy/sword/cx/chaplain + ) var/list/display_names = list() for(var/V in holy_weapons_list) var/obj/item/nullrod/rodtype = V @@ -544,6 +546,9 @@ /obj/item/nullrod/pride_hammer icon_state = "pride" + item_state = "pride" + lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' name = "Pride-struck Hammer" desc = "It resonates an aura of Pride." force = 16 @@ -551,7 +556,7 @@ w_class = 4 slot_flags = ITEM_SLOT_BACK attack_verb = list("attacked", "smashed", "crushed", "splattered", "cracked") - hitsound = 'sound/weapons/blade1.ogg' + hitsound = 'sound/weapons/resonator_blast.ogg' /obj/item/nullrod/pride_hammer/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity) . = ..() diff --git a/code/game/objects/items/implants/implant_chem.dm b/code/game/objects/items/implants/implant_chem.dm index b9c85c0728..c6c8be1a83 100644 --- a/code/game/objects/items/implants/implant_chem.dm +++ b/code/game/objects/items/implants/implant_chem.dm @@ -2,7 +2,6 @@ name = "chem implant" desc = "Injects things." icon_state = "reagents" - container_type = OPENCONTAINER activated = FALSE /obj/item/implant/chem/get_data() @@ -23,7 +22,7 @@ /obj/item/implant/chem/Initialize() . = ..() - create_reagents(50) + create_reagents(50, OPENCONTAINER) GLOB.tracked_chem_implants += src /obj/item/implant/chem/Destroy() diff --git a/code/game/objects/items/implants/implant_mindshield.dm b/code/game/objects/items/implants/implant_mindshield.dm index 2c197eb7ec..b9907cbfca 100644 --- a/code/game/objects/items/implants/implant_mindshield.dm +++ b/code/game/objects/items/implants/implant_mindshield.dm @@ -1,6 +1,7 @@ /obj/item/implant/mindshield name = "mindshield implant" desc = "Protects against brainwashing." + resistance_flags = INDESTRUCTIBLE activated = 0 /obj/item/implant/mindshield/get_data() @@ -19,14 +20,14 @@ /obj/item/implant/mindshield/implant(mob/living/target, mob/user, silent = FALSE) if(..()) if(!target.mind) - target.add_trait(TRAIT_MINDSHIELD, "implant") + ADD_TRAIT(target, TRAIT_MINDSHIELD, "implant") target.sec_hud_set_implants() return TRUE if(target.mind.has_antag_datum(/datum/antagonist/brainwashed)) target.mind.remove_antag_datum(/datum/antagonist/brainwashed) - if(target.mind.has_antag_datum(/datum/antagonist/rev/head) || target.mind.unconvertable) + if(target.mind.has_antag_datum(/datum/antagonist/rev/head) || target.mind.unconvertable || target.mind.has_antag_datum(/datum/antagonist/gang/boss)) if(!silent) target.visible_message("[target] seems to resist the implant!", "You feel something interfering with your mental conditioning, but you resist it!") var/obj/item/implanter/I = loc @@ -37,15 +38,18 @@ I.update_icon() return FALSE + var/datum/antagonist/gang/gang = target.mind.has_antag_datum(/datum/antagonist/gang) var/datum/antagonist/rev/rev = target.mind.has_antag_datum(/datum/antagonist/rev) if(rev) rev.remove_revolutionary(FALSE, user) + if(gang) + target.mind.remove_antag_datum(/datum/antagonist/gang) if(!silent) if(target.mind in SSticker.mode.cult) to_chat(target, "You feel something interfering with your mental conditioning, but you resist it!") else to_chat(target, "You feel a sense of peace and security. You are now protected from brainwashing.") - target.add_trait(TRAIT_MINDSHIELD, "implant") + ADD_TRAIT(target, TRAIT_MINDSHIELD, "implant") target.sec_hud_set_implants() return TRUE return FALSE @@ -54,7 +58,7 @@ if(..()) if(isliving(target)) var/mob/living/L = target - L.remove_trait(TRAIT_MINDSHIELD, "implant") + REMOVE_TRAIT(L, TRAIT_MINDSHIELD, "implant") L.sec_hud_set_implants() if(target.stat != DEAD && !silent) to_chat(target, "Your mind suddenly feels terribly vulnerable. You are no longer safe from brainwashing.") diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm index 24ee6d0966..889f702ee7 100644 --- a/code/game/objects/items/implants/implant_misc.dm +++ b/code/game/objects/items/implants/implant_misc.dm @@ -33,17 +33,8 @@ /obj/item/implant/adrenalin/activate() . = ..() uses-- + imp_in.do_adrenaline(150, TRUE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "omnizine" = 10, "stimulants" = 10), "You feel a sudden surge of energy!") to_chat(imp_in, "You feel a sudden surge of energy!") - imp_in.SetStun(0) - imp_in.SetKnockdown(0) - imp_in.SetUnconscious(0) - imp_in.adjustStaminaLoss(-75) - imp_in.lying = 0 - imp_in.update_canmove() - - imp_in.reagents.add_reagent("synaptizine", 10) - imp_in.reagents.add_reagent("omnizine", 10) - imp_in.reagents.add_reagent("stimulants", 10) if(!uses) qdel(src) diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index 36c79bd454..781e1fa562 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -185,7 +185,7 @@ objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120) message_admins("[ADMIN_LOOKUPFLW(user)] set brainwash machine objective to '[objective]'.") log_game("[key_name(user)] set brainwash machine objective to '[objective]'.") - if(C.has_trait(TRAIT_MINDSHIELD)) + if(HAS_TRAIT(C, TRAIT_MINDSHIELD)) return FALSE brainwash(C, objective) message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index 730a459ed4..bbd2e67464 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -12,6 +12,7 @@ var/cell_type = /obj/item/stock_parts/cell/high var/obj/item/stock_parts/cell/cell var/recharging = FALSE + var/gun_charger = FALSE /obj/item/inducer/Initialize() . = ..() @@ -104,7 +105,7 @@ var/obj/item/stock_parts/cell/C = A.get_cell() var/obj/O var/coefficient = 1 - if(istype(A, /obj/item/gun/energy)) + if(istype(A, /obj/item/gun/energy) && gun_charger != TRUE) to_chat(user,"Error unable to interface with device") return FALSE if(istype(A, /obj)) @@ -181,3 +182,26 @@ /obj/item/inducer/sci/Initialize() . = ..() update_icon() + +/obj/item/inducer/sci/combat + icon_state = "inducer-combat" + item_state = "inducer-combat" + w_class = WEIGHT_CLASS_BULKY + slot_flags = SLOT_BELT + desc = "A tool for inductively charging internal power cells. This one has been modified and upgraded to be able to charge into guns as well as normal electronics." + cell_type = /obj/item/stock_parts/cell/hyper + powertransfer = 1300 + opened = FALSE + gun_charger = TRUE + +/obj/item/inducer/sci/combat/dry + cell_type = null + opened = TRUE + +/obj/item/inducer/sci/combat/dry/Initialize() //Just in case + . = ..() + update_icon() + +/obj/item/inducer/sci/combat/Initialize() + . = ..() + update_icon() diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 11d6f264b8..ef2aa825e7 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -49,8 +49,6 @@ forkload = null else if(user.zone_selected == BODY_ZONE_PRECISE_EYES) - if(user.has_trait(TRAIT_CLUMSY) && prob(50)) - M = user return eyestab(M,user) else return ..() @@ -79,8 +77,6 @@ /obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user) if(user.zone_selected == BODY_ZONE_PRECISE_EYES) - if(user.has_trait(TRAIT_CLUMSY) && prob(50)) - M = user return eyestab(M,user) else return ..() diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm index 6194c4d9ca..02d0a1c36a 100644 --- a/code/game/objects/items/manuals.dm +++ b/code/game/objects/items/manuals.dm @@ -37,7 +37,7 @@

It really is that easy! Good luck! - + "} @@ -344,14 +344,14 @@ author = "Sir John Rose" title = "Barman Recipes: Mixing Drinks and Changing Lives" page_link = "Guide_to_food_and_drinks" - + /obj/item/book/manual/wiki/robotics_cyborgs name = "Robotics for Dummies" icon_state = "borgbook" author = "XISC" title = "Robotics for Dummies" page_link = "Guide_to_robotics" - + /obj/item/book/manual/wiki/research_and_development name = "Research and Development 101" icon_state = "rdbook" @@ -401,7 +401,7 @@ author = "the City-state of Atmosia" title = "Lexica Atmosia" page_link = "Guide_to_Atmospherics" - + /obj/item/book/manual/wiki/medicine name = "Medical Space Compendium, Volume 638" icon_state = "book8" @@ -441,7 +441,7 @@ H.dropItemToGround(W) if(prob(50)) step(W, pick(GLOB.alldirs)) - H.add_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) + ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC) H.bleed_rate = 5 H.gib_animation() sleep(3) diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 3a35f4d8ef..9162f3ed91 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -156,7 +156,7 @@ return //CIT CHANGE - ditto add_fingerprint(user) - if((user.has_trait(TRAIT_CLUMSY)) && prob(50)) + if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) to_chat(user, "You club yourself over the head.") user.Knockdown(60 * force) if(ishuman(user)) @@ -283,7 +283,7 @@ else var/turf/T = get_turf(src) if(!isspaceturf(T)) - consume_turf(T) + shard.consume_turf(T) /obj/item/melee/supermatter_sword/afterattack(target, mob/user, proximity_flag) . = ..() @@ -330,18 +330,7 @@ else if(!isturf(target)) shard.Bumped(target) else - consume_turf(target) - -/obj/item/melee/supermatter_sword/proc/consume_turf(turf/T) - var/oldtype = T.type - var/turf/newT = T.ScrapeAway() - if(newT.type == oldtype) - return - playsound(T, 'sound/effects/supermatter.ogg', 50, 1) - T.visible_message("[T] smacks into [src] and rapidly flashes to ash.",\ - "You hear a loud crack as you are washed with a wave of heat.") - shard.Consume() - T.CalculateAdjacentTurfs() + shard.consume_turf(target) /obj/item/melee/supermatter_sword/add_blood_DNA(list/blood_dna) return FALSE diff --git a/code/game/objects/items/melee/transforming.dm b/code/game/objects/items/melee/transforming.dm index 74eb048d8a..0d39e6c847 100644 --- a/code/game/objects/items/melee/transforming.dm +++ b/code/game/objects/items/melee/transforming.dm @@ -82,6 +82,6 @@ to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") /obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user) - if(clumsy_check && user.has_trait(TRAIT_CLUMSY) && prob(50)) + if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) to_chat(user, "You accidentally cut yourself with [src], like a doofus!") user.take_bodypart_damage(5,5) diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 703de902b6..9528bf94ba 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -591,10 +591,22 @@ desc = "An adorable stuffed toy that resembles a slime. It is practically just a hacky sack." icon_state = "plushie_slime" item_state = "plushie_slime" - attack_verb = list("blorbled", "slimed", "absorbed") + attack_verb = list("blorbled", "slimed", "absorbed", "glomped") squeak_override = list('sound/effects/blobattack.ogg' = 1) gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy +/obj/item/toy/plush/slimeplushie/annie + desc = "An adorable stuffed toy that resembles a slimey crewmember." + icon_state = "annie" + item_state = "annie" + +/obj/item/toy/plush/slimeplushie/paxton + desc = "An adorable stuffed toy that resembles a slimey crewmember." + icon_state = "paxton" + item_state = "paxton" + attack_verb = list("CQC'd", "jabroni'd", "powergamed", "robusted", "cakehatted") + gender = MALE + /obj/item/toy/plush/awakenedplushie name = "awakened plushie" desc = "An ancient plushie that has grown enlightened to the true nature of reality." @@ -635,6 +647,13 @@ attack_verb = list("lit", "flickered", "flashed") squeak_override = list('sound/weapons/magout.ogg' = 1) +/obj/item/toy/plush/box + name = "cardboard plushie" + desc = "A toy box plushie, it holds cotten. Only a baddie would place a bomb through the postal system..." + icon_state = "box" + item_state = "box" + attack_verb = list("open", "closed", "packed", "hidden", "rigged", "bombed", "sent", "gave") + /obj/item/toy/plush/borgplushie name = "robot plushie" desc = "An adorable stuffed toy of a robot." @@ -659,6 +678,12 @@ icon_state = "neeb" item_state = "neeb" +/obj/item/toy/plush/borgplushie/bhijn + desc = "An adorable stuffed toy of a IPC." + icon_state = "bhijn" + item_state = "bhijn" + attack_verb = list("closed", "reworked", "merged") + /obj/item/toy/plush/bird name = "bird plushie" desc = "An adorable stuffed plushie that resembles an avian." @@ -728,6 +753,10 @@ icon_state = "pavel" item_state = "pavel" +/obj/item/toy/plush/mammal/mason + icon_state = "mason" + item_state = "mason" + /obj/item/toy/plush/mammal/oten icon_state = "oten" item_state = "oten" @@ -736,6 +765,10 @@ icon_state = "ray" item_state = "ray" +/obj/item/toy/plush/mammal/redtail + icon_state = "redtail" + item_state = "redtail" + /obj/item/toy/plush/mammal/dawud icon_state = "dawud" item_state = "dawud" @@ -743,6 +776,7 @@ /obj/item/toy/plush/mammal/edgar icon_state = "edgar" item_state = "edgar" + attack_verb = list("collared", "tricked", "headpatted") /obj/item/toy/plush/mammal/frank icon_state = "frank" @@ -777,6 +811,16 @@ icon_state = "zed" item_state = "zed" +/obj/item/toy/plush/mammal/justin + icon_state = "justin" + item_state = "justin" + attack_verb = list("buttslapped", "fixed") + +/obj/item/toy/plush/mammal/reece + icon_state = "reece" + item_state = "reece" + attack_verb = list("healed", "cured", "demoted") + /obj/item/toy/plush/mammal/dog desc = "An adorable stuffed toy that resembles a canine." icon_state = "katlin" @@ -816,6 +860,13 @@ icon_state = "flynn" item_state = "flynn" +/obj/item/toy/plush/mammal/dog/fritz + icon_state = "fritz" + item_state = "fritz" + attack_verb = list("barked", "boofed", "shotgun'd") + obj_flags = UNIQUE_RENAME + unique_reskin = list("Goodboye" = "fritz", "Badboye" = "fritz_bad") + /obj/item/toy/plush/catgirl name = "feline plushie" desc = "An adorable stuffed toy that resembles a feline." @@ -840,6 +891,12 @@ icon_state = "drew" item_state = "drew" +/obj/item/toy/plush/catgirl/trilby + desc = "A masked stuffed toy that resembles a feline scientist." + icon_state = "trilby" + item_state = "trilby" + attack_verb = list("pred", "coded", "remembered") + /obj/item/toy/plush/catgirl/fermis name = "medcat plushie" desc = "An affectionate stuffed toy that resembles a certain medcat, comes complete with battery operated wagging tail!! You get the impression she's cheering you on to to find happiness and be kind to people." diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index d37ec0376a..bd301c36f7 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -150,7 +150,7 @@ if(tank && !tank.air_contents.remove(gasPerThrow * pressureSetting)) to_chat(user, "\The [src] lets out a weak hiss and doesn't react!") return - if(user.has_trait(TRAIT_CLUMSY) && prob(75) && clumsyCheck && iscarbon(user)) + if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(75) && clumsyCheck && iscarbon(user)) var/mob/living/carbon/C = user C.visible_message("[C] loses [C.p_their()] grip on [src], causing it to go off!", "[src] slips out of your hands and goes off!") C.dropItemToGround(src, TRUE) diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm index a80aa1be60..8582725cda 100644 --- a/code/game/objects/items/religion.dm +++ b/code/game/objects/items/religion.dm @@ -187,7 +187,7 @@ inspiration_available = FALSE /obj/item/banner/command/check_inspiration(mob/living/carbon/human/H) - return H.has_trait(TRAIT_MINDSHIELD) //Command is stalwart but rewards their allies. + return HAS_TRAIT(H, TRAIT_MINDSHIELD) //Command is stalwart but rewards their allies. /datum/crafting_recipe/command_banner name = "Command Banner" diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 1171bd7bf7..b641e15d90 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -91,7 +91,7 @@ return (active) /obj/item/shield/energy/attack_self(mob/living/carbon/human/user) - if(clumsy_check && user.has_trait(TRAIT_CLUMSY) && prob(50)) + if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) to_chat(user, "You beat yourself in the head with [src].") user.take_bodypart_damage(5) active = !active @@ -153,3 +153,16 @@ slot_flags = null to_chat(user, "[src] can now be concealed.") add_fingerprint(user) + +/obj/item/shield/makeshift + name = "metal shield" + desc = "A large shield made of wired and welded sheets of metal. The handle is made of cloth and leather making it unwieldy." + armor = list("melee" = 25, "bullet" = 25, "laser" = 5, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 80) + lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' + item_state = "makeshift_shield" + materials = list(MAT_METAL = 18000) + slot_flags = null + block_chance = 25 + force = 5 + throwforce = 7 diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index d3a3ecd5ef..cf967e25ba 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -281,12 +281,12 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( var/hit_hand = ((user.active_hand_index % 2 == 0) ? "r_" : "l_") + "arm" if(ishuman(user)) var/mob/living/carbon/human/H = user - if(!H.gloves && !H.has_trait(TRAIT_PIERCEIMMUNE)) // golems, etc + if(!H.gloves && !HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) // golems, etc to_chat(H, "[src] cuts into your hand!") H.apply_damage(force*0.5, BRUTE, hit_hand) else if(ismonkey(user)) var/mob/living/carbon/monkey/M = user - if(!M.has_trait(TRAIT_PIERCEIMMUNE)) + if(!HAS_TRAIT(M, TRAIT_PIERCEIMMUNE)) to_chat(M, "[src] cuts into your hand!") M.apply_damage(force*0.5, BRUTE, hit_hand) @@ -312,7 +312,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( /obj/item/shard/Crossed(mob/living/L) if(istype(L) && has_gravity(loc)) - if(L.has_trait(TRAIT_LIGHT_STEP)) + if(HAS_TRAIT(L, TRAIT_LIGHT_STEP)) playsound(loc, 'sound/effects/glass_step.ogg', 30, 1) else playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index e63ddd1c02..050e4f7b15 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -252,7 +252,8 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \ new/datum/stack_recipe("empty sandbag", /obj/item/emptysandbag, 4), \ null, \ - new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1), \ + new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1),\ + new/datum/stack_recipe("white gloves", /obj/item/clothing/gloves/color/white, 1),\ new/datum/stack_recipe("black gloves", /obj/item/clothing/gloves/color/black, 3), \ null, \ new/datum/stack_recipe("blindfold", /obj/item/clothing/glasses/sunglasses/blindfold, 2), \ @@ -281,16 +282,38 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ */ GLOBAL_LIST_INIT(cardboard_recipes, list ( \ new/datum/stack_recipe("box", /obj/item/storage/box), \ + new/datum/stack_recipe("sec box", /obj/item/storage/box/seclooking), \ new/datum/stack_recipe("light tubes", /obj/item/storage/box/lights/tubes), \ new/datum/stack_recipe("light bulbs", /obj/item/storage/box/lights/bulbs), \ new/datum/stack_recipe("mouse traps", /obj/item/storage/box/mousetraps), \ + new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \ + new/datum/stack_recipe("power cell", /obj/item/storage/box/cells), \ + new/datum/stack_recipe("02", /obj/item/storage/box/otwo), \ + null, \ + new/datum/stack_recipe("lethal ammo box", /obj/item/storage/box/lethalshot), \ + new/datum/stack_recipe("rubber shot ammo box", /obj/item/storage/box/rubbershot), \ + new/datum/stack_recipe("bean bag ammo box", /obj/item/storage/box/beanbag), \ + new/datum/stack_recipe("12g ammo box", /obj/item/storage/box/lethalslugs), \ + new/datum/stack_recipe("stun slug ammo box", /obj/item/storage/box/stunslug), \ + new/datum/stack_recipe("tech shell ammo box", /obj/item/storage/box/techsslug), \ + new/datum/stack_recipe("incendiary ammo box", /obj/item/storage/box/fireshot), \ + new/datum/stack_recipe("firing pins", /obj/item/storage/box/firingpins), \ + new/datum/stack_recipe("loose ammo", /obj/item/storage/box/ammoshells), \ + null, \ new/datum/stack_recipe("cardborg suit", /obj/item/clothing/suit/cardborg, 3), \ new/datum/stack_recipe("cardborg helmet", /obj/item/clothing/head/cardborg), \ - new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \ new/datum/stack_recipe("folder", /obj/item/folder), \ new/datum/stack_recipe("large box", /obj/structure/closet/cardboard, 4), \ new/datum/stack_recipe("cardboard cutout", /obj/item/cardboard_cutout, 5), \ -)) + null, \ + new/datum/stack_recipe("colored brown", /obj/item/storage/box/brown), \ + new/datum/stack_recipe("colored green", /obj/item/storage/box/green), \ + new/datum/stack_recipe("colored red", /obj/item/storage/box/blue), \ + new/datum/stack_recipe("colored blue", /obj/item/storage/box/red), \ + new/datum/stack_recipe("colored yellow", /obj/item/storage/box/yellow), \ + new/datum/stack_recipe("colored pink", /obj/item/storage/box/pink), \ + new/datum/stack_recipe("colored purple", /obj/item/storage/box/purple), \ + )) /obj/item/stack/sheet/cardboard //BubbleWrap //it's cardboard you fuck name = "cardboard" @@ -382,8 +405,8 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \ GLOBAL_LIST_INIT(brass_recipes, list ( \ new/datum/stack_recipe("wall gear", /obj/structure/destructible/clockwork/wall_gear, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \ null, - new/datum/stack_recipe("pinion airlock", /obj/machinery/door/airlock/clockwork, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ - new/datum/stack_recipe("brass pinion airlock", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("brass pinion airlock", /obj/machinery/door/airlock/clockwork, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("brass pinion airlock - windowed", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \ null, new/datum/stack_recipe("directional brass window", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ @@ -392,11 +415,14 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \ null, new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("sender - mech sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("sender - lever", /obj/structure/destructible/clockwork/trap/trigger/lever, 1, time = 10, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("sender - repeater", /obj/structure/destructible/clockwork/trap/trigger/repeater, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ null, new/datum/stack_recipe("receiver - brass skewer", /obj/structure/destructible/clockwork/trap/brass_skewer, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_ADJACENT), \ new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \ + new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \ + )) /obj/item/stack/tile/brass diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 25fc96c251..8178f0390a 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -28,7 +28,6 @@ STR.max_w_class = WEIGHT_CLASS_NORMAL STR.max_items = 21 - /* * Backpack Types */ @@ -48,6 +47,13 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 50) component_type = /datum/component/storage/concrete/bluespace/bag_of_holding +/obj/item/storage/backpack/holding/satchel + name = "satchel of holding" + desc = "A satchel that opens into a localized pocket of Blue Space." + icon_state = "holdingsat" + item_state = "holdingsat" + species_exception = list(/datum/species/angel) + /obj/item/storage/backpack/holding/ComponentInitialize() . = ..() GET_COMPONENT(STR, /datum/component/storage) @@ -237,6 +243,18 @@ icon_state = "satchel-explorer" item_state = "securitypack" +/obj/item/storage/backpack/satchel/bone + name = "bone satchel" + desc = "A bone satchel fashend with watcher wings and large bones from goliath. Can be worn on the belt." + icon = 'icons/obj/mining.dmi' + icon_state = "goliath_saddle" + slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT + +/obj/item/storage/backpack/satchel/bone/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_combined_w_class = 10 + /obj/item/storage/backpack/satchel/cap name = "captain's satchel" desc = "An exclusive satchel for Nanotrasen officers." @@ -440,6 +458,8 @@ new /obj/item/clothing/suit/straight_jacket(src) new /obj/item/clothing/mask/muzzle(src) new /obj/item/mmi/syndie(src) + new /obj/item/implantcase(src) + new /obj/item/implanter(src) /obj/item/storage/backpack/duffelbag/syndie/surgery_adv name = "advanced surgery duffel bag" @@ -457,6 +477,8 @@ new /obj/item/clothing/suit/straight_jacket(src) new /obj/item/clothing/mask/muzzle(src) new /obj/item/mmi/syndie(src) + new /obj/item/implantcase(src) + new /obj/item/implanter(src) /obj/item/storage/backpack/duffelbag/syndie/ammo name = "ammunition duffel bag" diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index b95d6a897e..c2d5ca50be 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -109,7 +109,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", to_chat(user, "You don't have the dexterity to do this!") return - if (user.has_trait(TRAIT_CLUMSY) && prob(50)) + if (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) to_chat(user, "[src] slips out of your hand and hits your head.") user.take_bodypart_damage(10) user.Unconscious(400) diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index c8e96d0b28..ffeef0c8df 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -14,9 +14,11 @@ * ID and security PDA cart boxes, * Handcuff, mousetrap, and pillbottle boxes, * Snap-pops and matchboxes, - * Replacement light boxes. - * Action Figure Boxes - * Various paper bags. + * Replacement light boxes, + * Ammo types, + * Action Figure Boxes, + * Various paper bags, + * Colored boxes * * For syndicate call-ins see uplink_kits.dm */ @@ -74,7 +76,6 @@ return 0 return ..() - //Disk boxes /obj/item/storage/box/disks name = "diskette box" @@ -84,7 +85,6 @@ for(var/i in 1 to 7) new /obj/item/disk/data(src) - /obj/item/storage/box/disks_plantgene name = "plant data disks box" illustration = "disk_kit" @@ -117,7 +117,6 @@ new /obj/item/crowbar/red(src) new /obj/item/reagent_containers/hypospray/medipen(src) - // Engineer survival box /obj/item/storage/box/engineer/PopulateContents() new /obj/item/clothing/mask/breath(src) @@ -143,6 +142,29 @@ ..() // we want the regular stuff too new /obj/item/radio/off(src) +/obj/item/storage/box/seclooking + icon_state = "secbox" + illustration = null + +/obj/item/storage/box/cells + name = "box of powercells" + desc = "Contains powercells." + illustration = "power_cell" + +/obj/item/storage/box/ammoshells + name = "box of loose ammo" + desc = "Contains loose ammo." + illustration = "loose_ammo" + +/obj/item/storage/box/otwo + name = "box of o2 supplies" + desc = "Contains o2 supplies." + illustration = "02" + +/obj/item/storage/box/otwo/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/tank/internals/emergency_oxygen/engi(src) + /obj/item/storage/box/gloves name = "box of latex gloves" desc = "Contains sterile latex gloves." @@ -261,7 +283,6 @@ new /obj/item/assembly/flash/handheld(src) new /obj/item/screwdriver(src) - /obj/item/storage/box/teargas name = "box of tear gas grenades (WARNING)" desc = "WARNING: These devices are extremely dangerous and can cause blindness and skin irritation." @@ -465,7 +486,7 @@ /obj/item/storage/box/firingpins name = "box of standard firing pins" desc = "A box full of standard firing pins, to allow newly-developed firearms to operate." - illustration = "id" + illustration = "firing_pins" /obj/item/storage/box/firingpins/PopulateContents() for(var/i in 1 to 5) @@ -474,7 +495,7 @@ /obj/item/storage/box/lasertagpins name = "box of laser tag firing pins" desc = "A box full of laser tag firing pins, to allow newly-developed firearms to require wearing brightly coloured plastic armor before being able to be used." - illustration = "id" + illustration = "firing_pins" /obj/item/storage/box/lasertagpins/PopulateContents() for(var/i in 1 to 3) @@ -615,7 +636,6 @@ for(var/i in 1 to 7) new /obj/item/light/bulb(src) - /obj/item/storage/box/deputy name = "box of deputy armbands" desc = "To be issued to those authorized to act as deputy of security." @@ -721,6 +741,46 @@ for(var/i in 1 to 6) new /obj/item/ammo_casing/shotgun/beanbag(src) +/obj/item/storage/box/lethalslugs + name = "box of 12g shotgun slugs" + desc = "A box full of lethal 12g slug, designed for riot shotguns." + icon_state = "12g_box" + illustration = null + +/obj/item/storage/box/lethalslugs/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/projectile/bullet/shotgun_slug(src) + +/obj/item/storage/box/stunslug + name = "box of stun slugs" + desc = "A box full of stun 12g slugs." + icon_state = "stunslug_box" + illustration = null + +/obj/item/storage/box/stunslug/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/projectile/bullet/shotgun_stunslug(src) + +/obj/item/storage/box/techsslug + name = "box of tech shotgun shells" + desc = "A box full of tech shotgun shells." + icon_state = "techslug_box" + illustration = null + +/obj/item/storage/box/techsslug/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/ammo_casing/shotgun/techshell(src) + +/obj/item/storage/box/fireshot + name = "box of incendiary ammo" + desc = "A box full of tech incendiary ammo." + icon_state = "fireshot_box" + illustration = null + +/obj/item/storage/box/techsslug/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/ammo_casing/shotgun/incendiary(src) + /obj/item/storage/box/actionfigure name = "box of action figures" desc = "The latest set of collectable action figures." @@ -731,6 +791,19 @@ var/randomFigure = pick(subtypesof(/obj/item/toy/figure)) new randomFigure(src) +/obj/item/storage/box/mechfigures + name = "box of mech figures" + desc = "The latest set of collectable mech figures." + icon_state = "box" + +/obj/item/storage/box/mechfigures/PopulateContents() + for(var/i in 1 to 4) + var/randomFigure = pick(subtypesof(/obj/item/toy/prize/)) + new randomFigure(src) + + + + #define NODESIGN "None" #define NANOTRASEN "NanotrasenStandard" #define SYNDI "SyndiSnacks" @@ -966,7 +1039,6 @@ for(var/i in 1 to 7) new /obj/item/reagent_containers/pill/patch/silver_sulf(src) - /obj/item/storage/box/fountainpens name = "box of fountain pens" @@ -1025,3 +1097,32 @@ new /obj/item/stock_parts/matter_bin/bluespace(src) new /obj/item/stock_parts/matter_bin/bluespace(src) new /obj/item/stock_parts/matter_bin/bluespace(src) + +//Colored boxes. +/obj/item/storage/box/green + icon_state = "box_green" + illustration = null + +/obj/item/storage/box/blue + icon_state = "box_blue" + illustration = null + +/obj/item/storage/box/purple + icon_state = "box_purple" + illustration = null + +/obj/item/storage/box/red + icon_state = "box_red" + illustration = null + +/obj/item/storage/box/yellow + icon_state = "box_yellow" + illustration = null + +/obj/item/storage/box/brown + icon_state = "box_brown" + illustration = null + +/obj/item/storage/box/pink + icon_state = "box_pink" + illustration = null diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index cc1c07aa02..f4f386b7d0 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -27,6 +27,14 @@ for(var/i in 1 to 6) new /obj/item/paper(folder) +/obj/item/storage/briefcase/crafted + desc = "Hand crafted suitcase made of leather and cloth." + force = 6 + max_integrity = 50 + +/obj/item/storage/briefcase/crafted/PopulateContents() + return //So we dont spawn items + /obj/item/storage/briefcase/lawyer folder_path = /obj/item/folder/blue diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 079feec17a..1a666ce921 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -122,7 +122,7 @@ new /obj/item/reagent_containers/pill/antirad(src) new /obj/item/reagent_containers/food/drinks/bottle/vodka(src) new /obj/item/healthanalyzer(src) - + /obj/item/storage/firstaid/o2 name = "oxygen deprivation treatment kit" @@ -312,3 +312,11 @@ /obj/item/storage/pill_bottle/mutarad/PopulateContents() for(var/i in 1 to 7) new /obj/item/reagent_containers/pill/mutarad(src) + +/obj/item/storage/pill_bottle/penis_enlargement + name = "penis enlargement pills" + desc = "You want penis enlargement pills?" + +/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/reagent_containers/pill/penis_enlargement(src) diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index eb9fc86516..9b8d2b4a21 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -208,3 +208,38 @@ new/obj/item/stack/cable_coil/orange(src) new/obj/item/stack/cable_coil/cyan(src) new/obj/item/stack/cable_coil/white(src) + +/obj/item/storage/toolbox/gold_real + name = "golden toolbox" + desc = "A larger then normal toolbox made of gold plated plastitanium." + item_state = "gold" + icon_state = "gold" + has_latches = FALSE + force = 16 // Less then a spear + throwforce = 14 + throw_speed = 5 + throw_range = 10 + +/obj/item/storage/toolbox/gold_real/PopulateContents() + new /obj/item/screwdriver/nuke(src) + new /obj/item/wrench(src) + new /obj/item/weldingtool/largetank(src) + new /obj/item/crowbar/red(src) + new /obj/item/wirecutters(src, "red") + new /obj/item/multitool/ai_detect(src) + new /obj/item/clothing/gloves/combat(src) + +/obj/item/storage/toolbox/gold_real/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_combined_w_class = 40 + STR.max_items = 12 + +/obj/item/storage/toolbox/gold_fake // used in crafting + name = "golden toolbox" + desc = "A gold plated toolbox, fancy and harmless do to the gold plating being on cardboard!" + icon_state = "gold" + item_state = "gold" + has_latches = FALSE + force = 0 + throwforce = 0 diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index c0e81a7949..bf7c71dddb 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -1,3 +1,5 @@ +#define STUNBATON_CHARGE_LENIENCY 0.3 + /obj/item/melee/baton name = "stunbaton" desc = "A stun baton for incapacitating people with." @@ -13,7 +15,7 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) var/stunforce = 140 - var/status = 0 + var/status = FALSE var/obj/item/stock_parts/cell/cell var/hitcost = 1000 var/throw_hit_chance = 35 @@ -44,17 +46,30 @@ /obj/item/melee/baton/loaded //this one starts with a cell pre-installed. preload_cell_type = /obj/item/stock_parts/cell/high -/obj/item/melee/baton/proc/deductcharge(chrgdeductamt) - if(cell) - //Note this value returned is significant, as it will determine - //if a stun is applied or not - . = cell.use(chrgdeductamt) - if(status && cell.charge < hitcost) - //we're below minimum, turn off - status = 0 - update_icon() - playsound(loc, "sparks", 75, 1, -1) +/obj/item/melee/baton/proc/deductcharge(chrgdeductamt, chargecheck = TRUE) + if(!cell) + switch_status(FALSE, TRUE) + return FALSE + //Note this value returned is significant, as it will determine + //if a stun is applied or not + . = cell.use(chrgdeductamt) + if(status && (!. || (chargecheck && cell.charge < hitcost * STUNBATON_CHARGE_LENIENCY))) + //we're below minimum, turn off + switch_status(FALSE) +/obj/item/melee/baton/proc/switch_status(new_status = FALSE, silent = FALSE) + if(status != new_status) + status = new_status + if(!silent) + playsound(loc, "sparks", 75, 1, -1) + if(status) + START_PROCESSING(SSobj, src) + else + STOP_PROCESSING(SSobj, src) + update_icon() + +/obj/item/melee/baton/process() + deductcharge(hitcost * 0.004, FALSE) /obj/item/melee/baton/update_icon() if(status) @@ -77,7 +92,7 @@ if(cell) to_chat(user, "[src] already has a cell.") else - if(C.maxcharge < hitcost) + if(C.maxcharge < hitcost * STUNBATON_CHARGE_LENIENCY) to_chat(user, "[src] requires a higher capacity cell.") return if(!user.transferItemToLoc(W, src)) @@ -92,31 +107,25 @@ cell.forceMove(get_turf(src)) cell = null to_chat(user, "You remove the cell from [src].") - status = 0 - update_icon() + switch_status(FALSE, TRUE) else return ..() /obj/item/melee/baton/attack_self(mob/user) - if(cell && cell.charge > hitcost) - status = !status + if(cell && cell.charge > hitcost * STUNBATON_CHARGE_LENIENCY) + switch_status(!status) to_chat(user, "[src] is now [status ? "on" : "off"].") - playsound(loc, "sparks", 75, 1, -1) else - status = 0 + switch_status(FALSE, TRUE) if(!cell) to_chat(user, "[src] does not have a power source!") else to_chat(user, "[src] is out of charge.") - update_icon() add_fingerprint(user) /obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user) - if(status && user.has_trait(TRAIT_CLUMSY) && prob(50)) - user.visible_message("[user] accidentally hits [user.p_them()]self with [src]!", \ - "You accidentally hit yourself with [src]!") - user.Knockdown(stunforce*3) - deductcharge(hitcost) + if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) + clowning_around(user) return if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)//CIT CHANGE - makes it impossible to baton in stamina softcrit @@ -153,17 +162,21 @@ var/mob/living/carbon/human/H = L if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that playsound(L, 'sound/weapons/genhit.ogg', 50, 1) - return 0 + return FALSE + var/stunpwr = stunforce if(iscyborg(loc)) var/mob/living/silicon/robot/R = loc - if(!R || !R.cell || !R.cell.use(hitcost)) - return 0 + if(!istype(R) || !R.cell || !R.cell.use(hitcost)) + return FALSE else - if(!deductcharge(hitcost)) - return 0 + var/stuncharge = cell.charge + if(!deductcharge(hitcost, FALSE)) + stunpwr *= round(stuncharge/hitcost) + if(stunpwr < stunforce * STUNBATON_CHARGE_LENIENCY) + return FALSE - L.Knockdown(stunforce) - L.adjustStaminaLoss(stunforce*0.1, affected_zone = (istype(user) ? user.zone_selected : BODY_ZONE_CHEST))//CIT CHANGE - makes stunbatons deal extra staminaloss. Todo: make this also deal pain when pain gets implemented. + L.Knockdown(stunpwr) + L.adjustStaminaLoss(stunpwr*0.1, affected_zone = (istype(user) ? user.zone_selected : BODY_ZONE_CHEST))//CIT CHANGE - makes stunbatons deal extra staminaloss. Todo: make this also deal pain when pain gets implemented. L.apply_effect(EFFECT_STUTTER, stunforce) SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK) if(user) @@ -180,11 +193,18 @@ H.forcesay(GLOB.hit_appends) - return 1 + return TRUE + +/obj/item/melee/baton/proc/clowning_around(mob/living/user) + user.visible_message("[user] accidentally hits [user.p_them()]self with [src]!", \ + "You accidentally hit yourself with [src]!") + user.Knockdown(stunforce*3) + deductcharge(hitcost) /obj/item/melee/baton/emp_act(severity) . = ..() if (!(. & EMP_PROTECT_SELF)) + switch_status(FALSE) deductcharge(1000 / severity) //Makeshift stun baton. Replacement for stun gloves. @@ -202,12 +222,15 @@ hitcost = 2000 throw_hit_chance = 10 slot_flags = ITEM_SLOT_BACK - var/obj/item/assembly/igniter/sparkler = 0 + var/obj/item/assembly/igniter/sparkler /obj/item/melee/baton/cattleprod/Initialize() . = ..() sparkler = new (src) + sparkler.activate_cooldown = 5 /obj/item/melee/baton/cattleprod/baton_stun() - if(sparkler.activate()) - ..() + sparkler?.activate() + . = ..() + +#undef STUNBATON_CHARGE_LENIENCY \ No newline at end of file diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index b3ee748d13..2e8074f656 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -17,8 +17,7 @@ /obj/item/tank/jetpack/New() ..() if(gas_type) - air_contents.assert_gas(gas_type) - air_contents.gases[gas_type][MOLES] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) + air_contents.gases[gas_type] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) ion_trail = new ion_trail.set_up(src) @@ -33,7 +32,6 @@ else toggle_internals(user) - /obj/item/tank/jetpack/proc/cycle(mob/user) if(user.incapacitated()) return @@ -48,7 +46,6 @@ var/datum/action/A = X A.UpdateButtonIcon() - /obj/item/tank/jetpack/proc/turn_on() on = TRUE icon_state = "[initial(icon_state)]-on" @@ -91,7 +88,7 @@ desc = "A jetpack made from two air tanks, a fire extinguisher and some atmospherics equipment. It doesn't look like it can hold much." icon_state = "jetpack-improvised" item_state = "jetpack-sec" - volume = 20 //normal jetpacks have 70 volume + volume = 30 //normal jetpacks have 70 volume gas_type = null //it starts empty full_speed = FALSE //moves at hardsuit jetpack speeds @@ -119,8 +116,10 @@ /obj/item/tank/jetpack/void name = "void jetpack (oxygen)" desc = "It works well in a void." + volume = 60 icon_state = "jetpack-void" item_state = "jetpack-void" + full_speed = FALSE //Old pre-hardsuit tech /obj/item/tank/jetpack/oxygen name = "jetpack (oxygen)" @@ -133,7 +132,7 @@ desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks." icon_state = "jetpack-mini" item_state = "jetpack-mini" - volume = 40 + volume = 50 throw_range = 7 w_class = WEIGHT_CLASS_NORMAL @@ -152,8 +151,6 @@ icon_state = "jetpack-sec" item_state = "jetpack-sec" - - /obj/item/tank/jetpack/carbondioxide name = "jetpack (carbon dioxide)" desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals." @@ -162,7 +159,6 @@ distribute_pressure = 0 gas_type = /datum/gas/carbon_dioxide - /obj/item/tank/jetpack/suit name = "hardsuit jetpack upgrade" desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment." @@ -221,7 +217,6 @@ return ..() - //Return a jetpack that the mob can use //Back worn jetpacks, hardsuit internal packs, and so on. //Used in Process_Spacemove() and wherever you want to check for/get a jetpack diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm index f4eb763847..c16762467e 100644 --- a/code/game/objects/items/tanks/tank_types.dm +++ b/code/game/objects/items/tanks/tank_types.dm @@ -21,8 +21,7 @@ /obj/item/tank/internals/oxygen/New() ..() - air_contents.assert_gas(/datum/gas/oxygen) - air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -49,9 +48,8 @@ /obj/item/tank/internals/anesthetic/New() ..() - air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide) - air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD + air_contents.gases[/datum/gas/nitrous_oxide] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD return /* @@ -67,9 +65,8 @@ /obj/item/tank/internals/air/New() ..() - air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gases[/datum/gas/nitrogen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD + air_contents.gases[/datum/gas/nitrogen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD return @@ -87,8 +84,7 @@ /obj/item/tank/internals/plasma/New() ..() - air_contents.assert_gas(/datum/gas/plasma) - air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params) @@ -106,7 +102,7 @@ /obj/item/tank/internals/plasma/full/New() ..() // Plasma asserted in parent - air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -124,13 +120,12 @@ /obj/item/tank/internals/plasmaman/New() ..() - air_contents.assert_gas(/datum/gas/plasma) - air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/tank/internals/plasmaman/full/New() ..() // Plasma asserted in parent - air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -144,7 +139,7 @@ /obj/item/tank/internals/plasmaman/belt/full/New() ..() // Plasma asserted in parent - air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -166,8 +161,7 @@ /obj/item/tank/internals/emergency_oxygen/New() ..() - air_contents.assert_gas(/datum/gas/oxygen) - air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/tank/internals/emergency_oxygen/engi diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index cdeb972ca1..1245b7de94 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -128,7 +128,7 @@ H.dropItemToGround(W) if(prob(50)) step(W, pick(GLOB.alldirs)) - H.add_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) + ADD_TRAIT(H, TRAIT_DISFIGURED, TRAIT_GENERIC) H.bleed_rate = 5 H.gib_animation() sleep(3) diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 6d1ffe9eae..8f2b85098d 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -18,7 +18,7 @@ /obj/item/watertank/Initialize() . = ..() - create_reagents(volume) + create_reagents(volume, OPENCONTAINER) noz = make_noz() /obj/item/watertank/ui_action_click(mob/user) @@ -113,7 +113,6 @@ possible_transfer_amounts = list(25,50,100) volume = 500 item_flags = NOBLUDGEON | ABSTRACT // don't put in storage - container_type = OPENCONTAINER slot_flags = 0 var/obj/item/watertank/tank @@ -335,7 +334,7 @@ var/usage_ratio = 5 //5 unit added per 1 removed var/injection_amount = 1 amount_per_transfer_from_this = 5 - container_type = OPENCONTAINER + reagent_flags = OPENCONTAINER spillable = FALSE possible_transfer_amounts = list(5,10,15) diff --git a/code/game/objects/items/teleprod.dm b/code/game/objects/items/teleprod.dm index fd9972f427..c514e5e926 100644 --- a/code/game/objects/items/teleprod.dm +++ b/code/game/objects/items/teleprod.dm @@ -6,27 +6,23 @@ item_state = "teleprod" slot_flags = null -/obj/item/melee/baton/cattleprod/teleprod/attack(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit - ..() - if(status && user.has_trait(TRAIT_CLUMSY) && prob(50)) - user.visible_message("[user] accidentally hits [user.p_them()]self with [src]!", \ - "You accidentally hit yourself with [src]!") - if(do_teleport(user, get_turf(user), 50))//honk honk - SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK) - user.Knockdown(stunforce*3) - deductcharge(hitcost) - else - SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK) - user.Knockdown(stunforce*3) - deductcharge(hitcost/4) +/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit + . = ..() + if(!. || !istype(M) || M.anchored) return else - if(status) - if(!istype(M) && M.anchored) - return . - else - SEND_SIGNAL(M, COMSIG_LIVING_MINOR_SHOCK) - do_teleport(M, get_turf(M), 15) + SEND_SIGNAL(M, COMSIG_LIVING_MINOR_SHOCK) + do_teleport(M, get_turf(M), 15) + +/obj/item/melee/baton/cattleprod/teleprod/clowning_around(mob/living/user) + user.visible_message("[user] accidentally hits [user.p_them()]self with [src]!", \ + "You accidentally hit yourself with [src]!") + SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK) + user.Knockdown(stunforce*3) + if(do_teleport(user, get_turf(user), 50)) + deductcharge(hitcost) + else + deductcharge(hitcost * 0.25) /obj/item/melee/baton/cattleprod/attackby(obj/item/I, mob/user, params)//handles sticking a crystal onto a stunprod to make a teleprod if(istype(I, /obj/item/stack/ore/bluespace_crystal)) diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 2e8cb569a6..217b53c928 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -75,11 +75,6 @@ return ..() if(user.zone_selected != BODY_ZONE_PRECISE_EYES && user.zone_selected != BODY_ZONE_HEAD) return ..() - if(user.has_trait(TRAIT_PACIFISM)) - to_chat(user, "You don't want to harm [M]!") - return - if(user.has_trait(TRAIT_CLUMSY) && prob(50)) - M = user return eyestab(M,user) /obj/item/screwdriver/brass @@ -103,7 +98,7 @@ /obj/item/screwdriver/abductor/get_belt_overlay() return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_nuke") - + /obj/item/screwdriver/power name = "hand drill" desc = "A simple powered hand drill. It's fitted with a screw bit." diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 7b976a6289..54f199969f 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -266,10 +266,10 @@ status = !status if(status) to_chat(user, "You resecure [src] and close the fuel tank.") - container_type = NONE + DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) else to_chat(user, "[src] can now be attached, modified, and refuelled.") - container_type = OPENCONTAINER + ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) add_fingerprint(user) /obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index f0a233fea6..bf63a96f05 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -290,6 +290,8 @@ var/hacked = FALSE var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD var/list/possible_colors = list("red", "blue", "green", "purple") + total_mass = 0.375 //Survival flashlights typically weigh around 5 ounces. + var/total_mass_on = 3.4 //The typical medieval sword, on the other hand, weighs roughly 3 pounds. //Values copied from the regular e-sword /obj/item/twohanded/dualsaber/suicide_act(mob/living/carbon/user) if(wielded) @@ -348,7 +350,7 @@ unwield() return ..() - if(user.has_trait(TRAIT_CLUMSY) && (wielded) && prob(40)) + if(HAS_TRAIT(user, TRAIT_CLUMSY) && (wielded) && prob(40)) impale(user) return if((wielded) && prob(50)) @@ -387,6 +389,7 @@ if(wielded) sharpness = IS_SHARP w_class = w_class_on + total_mass = total_mass_on hitsound = 'sound/weapons/blade1.ogg' START_PROCESSING(SSobj, src) set_light(brightness_on) @@ -394,6 +397,7 @@ /obj/item/twohanded/dualsaber/unwield() //Specific unwield () to switch hitsounds. sharpness = initial(sharpness) w_class = initial(w_class) + total_mass = initial(total_mass) ..() hitsound = "swing_hit" STOP_PROCESSING(SSobj, src) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 294611c1f1..ccc703296e 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -115,10 +115,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/claymore/highlander/pickup(mob/living/user) to_chat(user, "The power of Scotland protects you! You are shielded from all stuns and knockdowns.") user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!") - user.add_trait(TRAIT_IGNORESLOWDOWN, HIGHLANDER) + user.ignore_slowdown(HIGHLANDER) /obj/item/claymore/highlander/dropped(mob/living/user) - user.remove_trait(TRAIT_IGNORESLOWDOWN, HIGHLANDER) + user.unignore_slowdown(HIGHLANDER) if(!QDELETED(src)) qdel(src) //If this ever happens, it's because you lost an arm @@ -225,6 +225,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/katana/cursed slot_flags = null + item_flags = NODROP /obj/item/katana/suicide_act(mob/user) user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") @@ -499,6 +500,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 w_class = WEIGHT_CLASS_HUGE var/homerun_ready = 0 var/homerun_able = 0 + total_mass = 2.7 //a regular wooden major league baseball bat weighs somewhere between 2 to 3.4 pounds, according to google /obj/item/melee/baseball_bat/homerun name = "home run bat" diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 6221416db8..2db2cd08d8 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -241,6 +241,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e //what happens when the obj's health is below integrity_failure level. /obj/proc/obj_break(damage_flag) + SEND_SIGNAL(src, COMSIG_OBJ_BREAK, damage_flag) return //what happens when the obj's integrity reaches zero. diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 68c4ffeee8..5f21862c17 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -71,7 +71,7 @@ adjusted_climb_time *= 2 if(isalien(user)) adjusted_climb_time *= 0.25 //aliens are terrifyingly fast - if(user.has_trait(TRAIT_FREERUNNING)) //do you have any idea how fast I am??? + if(HAS_TRAIT(user, TRAIT_FREERUNNING)) //do you have any idea how fast I am??? adjusted_climb_time *= 0.8 structureclimber = user if(do_mob(user, user, adjusted_climb_time)) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index a6a6c5f699..cbdb0750e2 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -86,7 +86,7 @@ to_chat(user, "Alt-click to [locked ? "unlock" : "lock"].") if(isliving(user)) var/mob/living/L = user - if(L.has_trait(TRAIT_SKITTISH)) + if(HAS_TRAIT(L, TRAIT_SKITTISH)) to_chat(user, "Ctrl-Shift-click [src] to jump inside.") /obj/structure/closet/CanPass(atom/movable/mover, turf/target) @@ -416,7 +416,7 @@ togglelock(user) /obj/structure/closet/CtrlShiftClick(mob/living/user) - if(!user.has_trait(TRAIT_SKITTISH)) + if(!HAS_TRAIT(user, TRAIT_SKITTISH)) return ..() if(!user.canUseTopic(src) || !isturf(user.loc)) return diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index cc9b002fa8..54b9d650d5 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -5,7 +5,6 @@ icon_state = "cart" anchored = FALSE density = TRUE - container_type = OPENCONTAINER //copypaste sorry var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite var/obj/item/storage/bag/trash/mybag = null @@ -18,7 +17,7 @@ /obj/structure/janitorialcart/Initialize() . = ..() - create_reagents(100) + create_reagents(100, OPENCONTAINER) /obj/structure/janitorialcart/proc/wet_mop(obj/item/mop, mob/user) if(reagents.total_volume < 1) diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index 7fe9700470..e56cf3b09d 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -4,13 +4,12 @@ icon = 'icons/obj/janitor.dmi' icon_state = "mopbucket" density = TRUE - container_type = OPENCONTAINER var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite /obj/structure/mopbucket/Initialize() . = ..() - create_reagents(100) + create_reagents(100, OPENCONTAINER) /obj/structure/mopbucket/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/mop)) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 695395afd2..09e5510d62 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -182,7 +182,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an for(var/mob/living/M in compiled) var/mob/living/mob_occupant = get_mob_or_brainmob(M) - if(mob_occupant.client && !mob_occupant.suiciding && !(mob_occupant.has_trait(TRAIT_NOCLONE)) && !mob_occupant.hellbound) + if(mob_occupant.client && !mob_occupant.suiciding && !(HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && !mob_occupant.hellbound) icon_state = "morgue4" // Cloneable if(mob_occupant.stat == DEAD && beeper) if(world.time > next_beep) diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 6d3f498a8c..0e2f951f38 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -1,6 +1,6 @@ #define MUSICIAN_HEARCHECK_MINDELAY 4 -#define MUSIC_MAXLINES 300 +#define MUSIC_MAXLINES 600 #define MUSIC_MAXLINECHARS 50 /datum/song diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm index 815dd9de6d..65ffb7e2e5 100644 --- a/code/game/objects/structures/petrified_statue.dm +++ b/code/game/objects/structures/petrified_statue.dm @@ -17,7 +17,7 @@ L.buckled.unbuckle_mob(L,force=1) L.visible_message("[L]'s skin rapidly turns to marble!", "Your body freezes up! Can't... move... can't... think...") L.forceMove(src) - L.add_trait(TRAIT_MUTE, STATUE_MUTE) + ADD_TRAIT(L, TRAIT_MUTE, STATUE_MUTE) L.faction += "mimic" //Stops mimics from instaqdeling people in statues L.status_flags |= GODMODE obj_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues @@ -59,7 +59,7 @@ if(petrified_mob) petrified_mob.status_flags &= ~GODMODE petrified_mob.forceMove(loc) - petrified_mob.remove_trait(TRAIT_MUTE, STATUE_MUTE) + REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_MUTE) petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob petrified_mob.faction -= "mimic" petrified_mob = null diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index 6015cf9f4a..c386726f34 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -152,8 +152,8 @@ pod_moving = 0 if(!QDELETED(pod)) var/datum/gas_mixture/floor_mixture = loc.return_air() - floor_mixture.archive() - pod.air_contents.archive() + ARCHIVE_TEMPERATURE(floor_mixture) + ARCHIVE_TEMPERATURE(pod.air_contents) pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on air_update_turf() diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index 03082cd4ba..ee46538be1 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -11,9 +11,8 @@ /obj/structure/transit_tube_pod/Initialize() . = ..() - air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - air_contents.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD - air_contents.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD + air_contents.gases[/datum/gas/oxygen] = MOLES_O2STANDARD + air_contents.gases[/datum/gas/nitrogen] = MOLES_N2STANDARD air_contents.temperature = T20C diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index f108a536d2..e441ccd6cc 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -297,15 +297,14 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( continue var/list/S_gases = S.air.gases for(var/id in S_gases) - ASSERT_GAS(id, total) - total_gases[id][MOLES] += S_gases[id][MOLES] + total_gases[id] += S_gases[id] total.temperature += S.air.temperature air.copy_from(total) var/list/air_gases = air.gases for(var/id in air_gases) - air_gases[id][MOLES] /= turf_count //Averages contents of the turfs, ignoring walls and the like + air_gases[id] /= turf_count //Averages contents of the turfs, ignoring walls and the like air.temperature /= turf_count SSair.add_to_active(src) diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index 63b5f4b160..cff219c63e 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -7,6 +7,9 @@ var/wet var/footstep = null + var/barefootstep = null + var/clawfootstep = null + var/heavyfootstep = null /turf/open/ComponentInitialize() . = ..() @@ -27,6 +30,9 @@ icon = 'icons/turf/floors.dmi' icon_state = "floor" footstep = FOOTSTEP_FLOOR + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY tiled_dirt = TRUE /turf/open/indestructible/Melt() @@ -42,6 +48,9 @@ /turf/open/indestructible/sound name = "squeaky floor" footstep = null + barefootstep = null + clawfootstep = null + heavyfootstep = null var/sound /turf/open/indestructible/sound/Entered(var/mob/AM) @@ -61,6 +70,10 @@ icon = 'icons/turf/floors.dmi' icon_state = "cobble" baseturfs = /turf/open/indestructible/cobble + footstep = FOOTSTEP_FLOOR + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY tiled_dirt = FALSE /turf/open/indestructible/necropolis @@ -71,6 +84,9 @@ baseturfs = /turf/open/indestructible/necropolis initial_gas_mix = LAVALAND_DEFAULT_ATMOS footstep = FOOTSTEP_LAVA + barefootstep = FOOTSTEP_LAVA + clawfootstep = FOOTSTEP_LAVA + heavyfootstep = FOOTSTEP_LAVA tiled_dirt = FALSE /turf/open/indestructible/necropolis/Initialize() @@ -108,6 +124,9 @@ desc = "A floor made of invulnerable notebook paper." icon_state = "paperfloor" footstep = null + barefootstep = null + clawfootstep = null + heavyfootstep = null tiled_dirt = FALSE /turf/open/indestructible/binary @@ -116,6 +135,9 @@ baseturfs = /turf/open/indestructible/binary icon_state = "binary" footstep = null + barefootstep = null + clawfootstep = null + heavyfootstep = null /turf/open/indestructible/airblock icon_state = "bluespace" @@ -128,6 +150,9 @@ icon_state = "reebe" baseturfs = /turf/open/indestructible/clock_spawn_room footstep = FOOTSTEP_PLATING + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/indestructible/clock_spawn_room/Entered() ..() @@ -289,9 +314,8 @@ /turf/open/rad_act(pulse_strength) . = ..() if (air.gases[/datum/gas/carbon_dioxide] && air.gases[/datum/gas/oxygen]) - pulse_strength = min(pulse_strength,air.gases[/datum/gas/carbon_dioxide][MOLES]*1000,air.gases[/datum/gas/oxygen][MOLES]*2000) //Ensures matter is conserved properly - air.gases[/datum/gas/carbon_dioxide][MOLES]=max(air.gases[/datum/gas/carbon_dioxide][MOLES]-(pulse_strength/1000),0) - air.gases[/datum/gas/oxygen][MOLES]=max(air.gases[/datum/gas/oxygen][MOLES]-(pulse_strength/2000),0) - air.assert_gas(/datum/gas/pluoxium) - air.gases[/datum/gas/pluoxium][MOLES]+=(pulse_strength/4000) - air.garbage_collect() + pulse_strength = min(pulse_strength,air.gases[/datum/gas/carbon_dioxide]*1000,air.gases[/datum/gas/oxygen]*2000) //Ensures matter is conserved properly + air.gases[/datum/gas/carbon_dioxide]=max(air.gases[/datum/gas/carbon_dioxide]-(pulse_strength/1000),0) + air.gases[/datum/gas/oxygen]=max(air.gases[/datum/gas/oxygen]-(pulse_strength/2000),0) + air.gases[/datum/gas/pluoxium]+=(pulse_strength/4000) + GAS_GARBAGE_COLLECT(air.gases) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 4523cc5b67..b00efc7ed6 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -7,6 +7,9 @@ baseturfs = /turf/open/floor/plating footstep = FOOTSTEP_FLOOR + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY var/icon_regular_floor = "floor" //used to remember what icon the tile should have by default var/icon_plating = "plating" diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index fc1dec2acb..7b45aa1fbb 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -13,6 +13,9 @@ floor_tile = /obj/item/stack/tile/wood broken_states = list("wood-broken", "wood-broken2", "wood-broken3", "wood-broken4", "wood-broken5", "wood-broken6", "wood-broken7") footstep = FOOTSTEP_WOOD + barefootstep = FOOTSTEP_WOOD_BAREFOOT + clawfootstep = FOOTSTEP_WOOD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY tiled_dirt = FALSE /turf/open/floor/wood/examine(mob/user) @@ -73,6 +76,9 @@ flags_1 = NONE bullet_bounce_sound = null footstep = FOOTSTEP_GRASS + barefootstep = FOOTSTEP_GRASS + clawfootstep = FOOTSTEP_GRASS + heavyfootstep = FOOTSTEP_GENERIC_HEAVY var/ore_type = /obj/item/stack/ore/glass var/turfverb = "uproot" tiled_dirt = FALSE @@ -103,6 +109,9 @@ slowdown = 2 bullet_sizzle = TRUE footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/floor/grass/snow/try_replace_tile(obj/item/stack/tile/T, mob/user, params) return @@ -136,6 +145,9 @@ turfverb = "dig up" slowdown = 0 footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/floor/grass/fakebasalt/Initialize() . = ..() @@ -156,6 +168,9 @@ flags_1 = NONE bullet_bounce_sound = null footstep = FOOTSTEP_CARPET + barefootstep = FOOTSTEP_CARPET_BAREFOOT + clawfootstep = FOOTSTEP_CARPET_BAREFOOT + heavyfootstep = FOOTSTEP_GENERIC_HEAVY tiled_dirt = FALSE /turf/open/floor/carpet/examine(mob/user) diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 91744f3fa8..bff955086c 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -141,6 +141,9 @@ icon_state = "plating" baseturfs = /turf/open/floor/clockwork footstep = FOOTSTEP_PLATING + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY var/uses_overlay = TRUE var/obj/effect/clockwork/overlay/floor/realappearence diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index e783b8a9a0..036f54c710 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -13,6 +13,9 @@ intact = FALSE baseturfs = /turf/open/space footstep = FOOTSTEP_PLATING + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY var/attachment_holes = TRUE diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm index c33612c9bc..d9966ee55c 100644 --- a/code/game/turfs/simulated/floor/plating/asteroid.dm +++ b/code/game/turfs/simulated/floor/plating/asteroid.dm @@ -10,6 +10,9 @@ icon_plating = "asteroid" postdig_icon_change = TRUE footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY var/environment_type = "asteroid" var/turf_type = /turf/open/floor/plating/asteroid //Because caves do whacky shit to revert to normal var/floor_variance = 20 //probability floor has a different icon state @@ -333,6 +336,9 @@ icon_plating = "snow-ice" environment_type = "snow_cavern" footstep = FOOTSTEP_FLOOR + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/floor/plating/asteroid/snow/ice/burn_tile() return FALSE diff --git a/code/game/turfs/simulated/floor/plating/dirt.dm b/code/game/turfs/simulated/floor/plating/dirt.dm index dc865634f4..b9bcc0937b 100644 --- a/code/game/turfs/simulated/floor/plating/dirt.dm +++ b/code/game/turfs/simulated/floor/plating/dirt.dm @@ -9,6 +9,9 @@ planetary_atmos = TRUE attachment_holes = FALSE footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY tiled_dirt = FALSE /turf/open/floor/plating/dirt/dark diff --git a/code/game/turfs/simulated/floor/plating/misc_plating.dm b/code/game/turfs/simulated/floor/plating/misc_plating.dm index f86ab3c03c..15b039193d 100644 --- a/code/game/turfs/simulated/floor/plating/misc_plating.dm +++ b/code/game/turfs/simulated/floor/plating/misc_plating.dm @@ -47,6 +47,9 @@ planetary_atmos = TRUE attachment_holes = FALSE footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY tiled_dirt = FALSE /turf/open/floor/plating/ashplanet/Initialize() @@ -79,6 +82,9 @@ layer = MID_TURF_LAYER canSmoothWith = list(/turf/open/floor/plating/ashplanet/rocky, /turf/closed) footstep = FOOTSTEP_FLOOR + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/floor/plating/ashplanet/wateryrock gender = PLURAL @@ -87,6 +93,9 @@ icon_state = "wateryrock" slowdown = 2 footstep = FOOTSTEP_FLOOR + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/floor/plating/ashplanet/wateryrock/Initialize() icon_state = "[icon_state][rand(1, 9)]" @@ -100,6 +109,9 @@ attachment_holes = FALSE bullet_bounce_sound = null footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/floor/plating/beach/try_replace_tile(obj/item/stack/tile/T, mob/user, params) return @@ -141,6 +153,9 @@ name = "iron sand" desc = "Like sand, but more metal." footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/floor/plating/ironsand/Initialize() . = ..() @@ -165,6 +180,9 @@ attachment_holes = FALSE bullet_sizzle = TRUE footstep = FOOTSTEP_FLOOR + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/floor/plating/ice/Initialize() . = ..() @@ -202,6 +220,9 @@ attachment_holes = FALSE planetary_atmos = TRUE footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY /turf/open/floor/plating/snowed/cavern initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120" diff --git a/code/game/turfs/simulated/floor/reinf_floor.dm b/code/game/turfs/simulated/floor/reinf_floor.dm index e677de8c5c..1a477d5d9a 100644 --- a/code/game/turfs/simulated/floor/reinf_floor.dm +++ b/code/game/turfs/simulated/floor/reinf_floor.dm @@ -7,6 +7,9 @@ heat_capacity = INFINITY floor_tile = /obj/item/stack/rods footstep = FOOTSTEP_PLATING + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY tiled_dirt = FALSE /turf/open/floor/engine/examine(mob/user) diff --git a/code/game/turfs/simulated/lava.dm b/code/game/turfs/simulated/lava.dm index b9e355b122..e24736ecf3 100644 --- a/code/game/turfs/simulated/lava.dm +++ b/code/game/turfs/simulated/lava.dm @@ -13,6 +13,9 @@ bullet_bounce_sound = 'sound/items/welder2.ogg' footstep = FOOTSTEP_LAVA + barefootstep = FOOTSTEP_LAVA + clawfootstep = FOOTSTEP_LAVA + heavyfootstep = FOOTSTEP_LAVA /turf/open/lava/ex_act(severity, target) contents_explosion(severity, target) diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index f40f74787a..8efac31f65 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -77,6 +77,19 @@ return ..() +/turf/closed/wall/clockwork/try_destroy(obj/item/I, mob/user, turf/T) + if(!heated) + return ..() + if(!istype(I, /obj/item/pickaxe/drill/jackhammer)) + return FALSE + to_chat(user, "You begin to smash though [src]...") + if(!do_after(user, 70, TRUE, src)) + return FALSE + I.play_tool_sound(src) + visible_message("[user] smashes through [src] with [I]!", "You hear the grinding of metal.") + dismantle_wall() + return TRUE + /turf/closed/wall/clockwork/ReplaceWithLattice() ..() for(var/obj/structure/lattice/L in src) diff --git a/code/game/turfs/simulated/water.dm b/code/game/turfs/simulated/water.dm index b46dd1d06c..708ca230b1 100644 --- a/code/game/turfs/simulated/water.dm +++ b/code/game/turfs/simulated/water.dm @@ -12,3 +12,6 @@ bullet_bounce_sound = null //needs a splashing sound one day. footstep = FOOTSTEP_WATER + barefootstep = FOOTSTEP_WATER + clawfootstep = FOOTSTEP_WATER + heavyfootstep = FOOTSTEP_WATER diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 3e7968a9d7..9ebe8f3c19 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -134,7 +134,7 @@ if ((!(A) || src != A.loc)) return - if(destination_z && destination_x && destination_y) + if(destination_z && destination_x && destination_y && !(A.pulledby || !A.can_be_z_moved)) var/tx = destination_x var/ty = destination_y var/turf/DT = locate(tx, ty, destination_z) @@ -157,8 +157,10 @@ A.forceMove(DT) if(AM) var/turf/T = get_step(A.loc,turn(A.dir, 180)) + AM.can_be_z_moved = FALSE AM.forceMove(T) A.start_pulling(AM) + AM.can_be_z_moved = TRUE //now we're on the new z_level, proceed the space drifting stoplag()//Let a diagonal move finish, if necessary diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index afe275f9b9..032c5b6511 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -112,6 +112,8 @@ LC.handlecable(C, user) return C.loaded.place_turf(src, user) + if(C.wiring_gui_menu) + C.wiringGuiUpdate(user) C.is_empty(user) /turf/attackby(obj/item/C, mob/user, params) diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm index 1e207909bd..1672310567 100644 --- a/code/modules/admin/antag_panel.dm +++ b/code/modules/admin/antag_panel.dm @@ -80,7 +80,7 @@ GLOBAL_VAR(antag_prototypes) var/list/result = list() if(!current) result += "No body!" - if(current && current.has_trait(TRAIT_MINDSHIELD)) + if(current && HAS_TRAIT(current, TRAIT_MINDSHIELD)) result += "Mindshielded" //Move these to mob if(iscyborg(current)) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 226f2a5456..6fa118ab7f 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -903,6 +903,13 @@ else dat += "Alien" + //Gang + if(jobban_isbanned(M, ROLE_GANG) || isbanned_dept) + dat += "Gang" + else + dat += "Gang" + + //Other Roles (black) dat += "" dat += "" @@ -974,7 +981,7 @@ if("ghostroles") joblist += list(ROLE_PAI, ROLE_POSIBRAIN, ROLE_DRONE , ROLE_DEATHSQUAD, ROLE_LAVALAND, ROLE_SENTIENCE) if("teamantags") - joblist += list(ROLE_OPERATIVE, ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ABDUCTOR, ROLE_ALIEN) + joblist += list(ROLE_OPERATIVE, ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ABDUCTOR, ROLE_ALIEN, ROLE_GANG) if("convertantags") joblist += list(ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ALIEN) if("otherroles") diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm index 3056b459d8..97a799824b 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm @@ -217,3 +217,7 @@ /proc/_step_away(ref, trg, max) step_away(ref, trg, max) +/proc/_instantiate_at(thing, location) + new thing(location) + + diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 67b33afcc6..57dc357859 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -841,8 +841,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(Rad.anchored) if(!Rad.loaded_tank) var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad) - Plasma.air_contents.assert_gas(/datum/gas/plasma) - Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70 + Plasma.air_contents.gases[/datum/gas/plasma] = 70 Rad.drainratio = 0 Rad.loaded_tank = Plasma Plasma.forceMove(Rad) diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index 39aff33953..b19b2a91d8 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -9,10 +9,9 @@ var/list/lines = list("[AREACOORD(target)]: [env.temperature] K ([env.temperature - T0C] C), [env.return_pressure()] kPa[(burning)?(", burning"):(null)]") for(var/id in env_gases) - var/gas = env_gases[id] - var/moles = gas[MOLES] + var/moles = env_gases[id] if (moles >= 0.00001) - lines += "[gas[GAS_META][META_GAS_NAME]]: [moles] mol" + lines += "[GLOB.meta_gas_names[id]]: [moles] mol" to_chat(usr, lines.Join("\n")) /client/proc/air_status(turf/target) diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 72da825e0c..3996cabe48 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -150,6 +150,42 @@ message_admins("[key_name_admin(src)] set the round end sound to [S]") SSblackbox.record_feedback("tally", "admin_verb", 1, "Set Round End Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/play_web_sound_manual() + set category = "Fun" + set name = "Manual Play Internet Sound" + if(!check_rights(R_SOUNDS)) + return + + var/web_sound_input = input("Enter youtube-dl fetched content URL (supported sites only, leave blank to stop playing)", "Send youtube-dl media link") as text|null + if(!istext(web_sound_input)) + return + web_sound_input = trim(web_sound_input) + if(!length(web_sound_input)) + log_admin("[key_name(src)] stopped web sound") + message_admins("[key_name(src)] stopped web sound") + for(var/m in GLOB.player_list) + var/mob/M = m + var/client/C = M.client + if((C.prefs.toggles & SOUND_MIDI) && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded) + C.chatOutput.stopMusic() + return + var/freq = input(usr, "What frequency would you like the sound to play at?",, 1) as null|num + if(!freq) + return + if(web_sound_input && !findtext(web_sound_input, GLOB.is_http_protocol)) + to_chat(src, "BLOCKED: Content URL not using http(s) protocol") + to_chat(src, "The media provider returned a content URL that isn't using the HTTP or HTTPS protocol") + return + + SSblackbox.record_feedback("nested tally", "played_url_manual", 1, list("[ckey]", "[web_sound_input]")) + log_admin("[key_name(src)] manually played web sound: [web_sound_input]") + message_admins("[key_name(src)] manually played web sound: HREF") + for(var/m in GLOB.player_list) + var/mob/M = m + var/client/C = M.client + if((C.prefs.toggles & SOUND_MIDI) && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded) + C.chatOutput.sendMusic(web_sound_input, freq) + /client/proc/stop_sounds() set category = "Debug" set name = "Stop All Playing Sounds" diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index da1b404ea5..968c2d1e2f 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -34,14 +34,14 @@ deity = "Nar'Sie" else if(isliving(usr)) var/mob/living/L = usr - if(L.has_trait(TRAIT_SPIRITUAL)) + if(HAS_TRAIT(L, TRAIT_SPIRITUAL)) cross.icon_state = "holylight" font_color = "blue" prayer_type = "SPIRITUAL PRAYER" - + var/msg_tmp = msg msg = "[icon2html(cross, GLOB.admins)][prayer_type][deity ? " (to [deity])" : ""]: [ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]: [msg]" - + for(var/client/C in GLOB.admins) if(C.prefs.chat_toggles & CHAT_PRAYER) to_chat(C, msg) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 808c48e002..f74b31760d 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1249,7 +1249,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(!check_rights(R_ADMIN) || !check_rights(R_FUN)) return - var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_ROD, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING) + var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD) var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list @@ -1294,6 +1294,9 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(!puzzle_imprison(target)) to_chat(usr,"Imprisonment failed!") return + if(ADMIN_PUNISHMENT_PIE) + var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/creamy = new(get_turf(target)) + creamy.splat(target) var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]." message_admins(msg) diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index 3fa1020000..ca491d8cab 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -108,10 +108,7 @@ to_chat(loc, "Combat injection is still recharging.") return var/mob/living/carbon/human/M = loc - M.adjustStaminaLoss(-75) - M.SetUnconscious(0) - M.SetStun(0) - M.SetKnockdown(0) + M.do_adrenaline(150, FALSE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "omnizine" = 10), "You feel a sudden surge of energy!") combat_cooldown = 0 START_PROCESSING(SSobj, src) @@ -503,6 +500,7 @@ Congratulations! You are now trained for invasive xenobiology research!"} L.lastattacker = user.real_name L.lastattackerckey = user.ckey + L.adjustStaminaLoss(35) //because previously it took 5-6 hits to actually "incapacitate" someone for the purposes of the sleep inducement L.Knockdown(140) L.apply_effect(EFFECT_STUTTER, 7) SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK) diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm index 969590402c..8a3ff2186a 100644 --- a/code/modules/antagonists/abductor/equipment/gland.dm +++ b/code/modules/antagonists/abductor/equipment/gland.dm @@ -272,10 +272,10 @@ /obj/item/organ/heart/gland/electric/Insert(mob/living/carbon/M, special = 0) ..() - owner.add_trait(TRAIT_SHOCKIMMUNE, ORGAN_TRAIT) + ADD_TRAIT(owner, TRAIT_SHOCKIMMUNE, ORGAN_TRAIT) /obj/item/organ/heart/gland/electric/Remove(mob/living/carbon/M, special = 0) - owner.remove_trait(TRAIT_SHOCKIMMUNE, ORGAN_TRAIT) + REMOVE_TRAIT(owner, TRAIT_SHOCKIMMUNE, ORGAN_TRAIT) ..() /obj/item/organ/heart/gland/electric/activate() diff --git a/code/modules/antagonists/blob/blob/blobs/core.dm b/code/modules/antagonists/blob/blob/blobs/core.dm index e048aa7665..81792ca4f6 100644 --- a/code/modules/antagonists/blob/blob/blobs/core.dm +++ b/code/modules/antagonists/blob/blob/blobs/core.dm @@ -4,7 +4,7 @@ icon_state = "blank_blob" desc = "A huge, pulsating yellow mass." max_integrity = 400 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 90) + armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 5, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 90) // Last stand explosion_block = 6 point_return = -1 health_regen = 0 //we regen in Life() instead of when pulsed diff --git a/code/modules/antagonists/blob/blob/blobs/factory.dm b/code/modules/antagonists/blob/blob/blobs/factory.dm index 3d955036b0..284a43562e 100644 --- a/code/modules/antagonists/blob/blob/blobs/factory.dm +++ b/code/modules/antagonists/blob/blob/blobs/factory.dm @@ -6,6 +6,7 @@ max_integrity = 200 health_regen = 1 point_return = 25 + armor = list("melee" = 10, "bullet" = 20, "laser" = 15, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) var/list/spores = list() var/mob/living/simple_animal/hostile/blob/blobbernaut/naut = null var/max_spores = 3 diff --git a/code/modules/antagonists/blob/blob/blobs/resource.dm b/code/modules/antagonists/blob/blob/blobs/resource.dm index 5024d0984c..76aecf717d 100644 --- a/code/modules/antagonists/blob/blob/blobs/resource.dm +++ b/code/modules/antagonists/blob/blob/blobs/resource.dm @@ -5,6 +5,7 @@ desc = "A thin spire of slightly swaying tendrils." max_integrity = 60 point_return = 15 + armor = list("melee" = 10, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) var/resource_delay = 0 /obj/structure/blob/resource/scannerreport() diff --git a/code/modules/antagonists/blob/blob/blobs/shield.dm b/code/modules/antagonists/blob/blob/blobs/shield.dm index a83f4294b2..33e7e4392f 100644 --- a/code/modules/antagonists/blob/blob/blobs/shield.dm +++ b/code/modules/antagonists/blob/blob/blobs/shield.dm @@ -8,7 +8,8 @@ explosion_block = 3 point_return = 4 atmosblock = TRUE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list("melee" = 25, "bullet" = 25, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + var/weakened /obj/structure/blob/shield/scannerreport() if(atmosblock) @@ -20,14 +21,20 @@ /obj/structure/blob/shield/update_icon() ..() - if(obj_integrity <= 75) + if(obj_integrity <= 70) icon_state = "blob_shield_damaged" name = "weakened strong blob" desc = "A wall of twitching tendrils." atmosblock = FALSE + if(!weakened) + armor = armor.setRating("melee" = 15, "bullet" = 15, "laser" = 5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + weakened = TRUE else icon_state = initial(icon_state) name = initial(name) desc = initial(desc) atmosblock = TRUE - air_update_turf(1) + if(weakened) + armor = armor.setRating("melee" = 25, "bullet" = 25, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + weakened = FALSE + air_update_turf(1) \ No newline at end of file diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 7e0ae3c08c..5b0be336ff 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -169,7 +169,7 @@ to_chat(owner.current, "We have reached our capacity for abilities.") return - if(owner.current.has_trait(TRAIT_DEATHCOMA))//To avoid potential exploits by buying new powers while in stasis, which clears your verblist. + if(HAS_TRAIT(owner.current, TRAIT_DEATHCOMA))//To avoid potential exploits by buying new powers while in stasis, which clears your verblist. to_chat(owner.current, "We lack the energy to evolve new abilities right now.") return @@ -239,7 +239,7 @@ if(verbose) to_chat(user, "[target] is not compatible with our biology.") return - if((target.has_trait(TRAIT_NOCLONE)) || (target.has_trait(TRAIT_NOCLONE))) + if((HAS_TRAIT(target, TRAIT_NOCLONE)) || (HAS_TRAIT(target, TRAIT_NOCLONE))) if(verbose) to_chat(user, "DNA of [target] is ruined beyond usability!") return diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm index 1d4f15ec9d..c5334265fb 100644 --- a/code/modules/antagonists/changeling/changeling_power.dm +++ b/code/modules/antagonists/changeling/changeling_power.dm @@ -68,7 +68,7 @@ if(req_stat < user.stat) to_chat(user, "We are incapacitated.") return 0 - if((user.has_trait(TRAIT_DEATHCOMA)) && (!ignores_fakedeath)) + if((HAS_TRAIT(user, TRAIT_DEATHCOMA)) && (!ignores_fakedeath)) to_chat(user, "We are incapacitated.") return 0 return 1 diff --git a/code/modules/antagonists/changeling/powers/adrenaline.dm b/code/modules/antagonists/changeling/powers/adrenaline.dm index ede14a23c9..a9d85d0fed 100644 --- a/code/modules/antagonists/changeling/powers/adrenaline.dm +++ b/code/modules/antagonists/changeling/powers/adrenaline.dm @@ -12,13 +12,5 @@ //Recover from stuns. /obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user) - to_chat(user, "Energy rushes through us.[user.lying ? " We arise." : ""]") - user.SetSleeping(0) - user.SetUnconscious(0) - user.SetStun(0) - user.SetKnockdown(0) - user.reagents.add_reagent("changelingadrenaline", 10) - user.reagents.add_reagent("changelinghaste", 2) //For a really quick burst of speed - user.adjustStaminaLoss(-75) + user.do_adrenaline(100, FALSE, 70, 0, TRUE, list("epinephrine" = 3, "changelingmeth" = 10, "mannitol" = 10, "omnizine" = 10, "changelingadrenaline" = 5), "Energy rushes through us.") return TRUE - diff --git a/code/modules/antagonists/changeling/powers/fakedeath.dm b/code/modules/antagonists/changeling/powers/fakedeath.dm index c19eb50e7f..346d948c79 100644 --- a/code/modules/antagonists/changeling/powers/fakedeath.dm +++ b/code/modules/antagonists/changeling/powers/fakedeath.dm @@ -33,7 +33,7 @@ RV.action.Grant(user) /obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/living/user) - if(user.has_trait(TRAIT_DEATHCOMA, "changeling")) + if(HAS_TRAIT_FROM(user, TRAIT_DEATHCOMA, "changeling")) to_chat(user, "We are already reviving.") return if(!user.stat) //Confirmation for living changelings if they want to fake their death diff --git a/code/modules/antagonists/changeling/powers/hivemind.dm b/code/modules/antagonists/changeling/powers/hivemind.dm index b72123da6f..1d7382d947 100644 --- a/code/modules/antagonists/changeling/powers/hivemind.dm +++ b/code/modules/antagonists/changeling/powers/hivemind.dm @@ -10,10 +10,10 @@ action_background_icon_state = "bg_ling" /obj/effect/proc_holder/changeling/hivemind_comms/sting_action(var/mob/living/user) - if (user.has_trait(CHANGELING_HIVEMIND_MUTE)) + if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE)) to_chat(user, "The poison in the air hinders our ability to interact with the hivemind.") return - var/input = stripped_input(usr, "Please choose a message to transmit.", "Changeling Hivemind", "") + var/input = html_decode(stripped_input(usr, "Please choose a message to transmit.", "Changeling Hivemind", "")) user.say(".g[input]") /obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(mob/user, is_respec) @@ -47,7 +47,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank) action_background_icon_state = "bg_ling" /obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/living/user) - if (user.has_trait(CHANGELING_HIVEMIND_MUTE)) + if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE)) to_chat(user, "The poison in the air hinders our ability to interact with the hivemind.") return var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) @@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank) /obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user) if(!..()) return - if (user.has_trait(CHANGELING_HIVEMIND_MUTE)) + if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE)) to_chat(user, "The poison in the air hinders our ability to interact with the hivemind.") return var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index 3d6c766307..ede3c2fc58 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -344,9 +344,8 @@ if(isitem(target)) var/obj/item/I = target if(!I.anchored) - to_chat(firer, "You pull [I] towards yourself.") - H.throw_mode_on() - I.throw_at(H, 10, 2) + to_chat(firer, "You pull [I] right into your grasp.") + H.put_in_hands(I) //Because throwing it is goofy as fuck and unreliable. If you land the tentacle despite the penalties to accuracy, you should have your reward. . = 1 else if(isliving(target)) diff --git a/code/modules/antagonists/changeling/powers/revive.dm b/code/modules/antagonists/changeling/powers/revive.dm index 514b7603fd..3404765628 100644 --- a/code/modules/antagonists/changeling/powers/revive.dm +++ b/code/modules/antagonists/changeling/powers/revive.dm @@ -37,7 +37,7 @@ if(!.) return - if(user.has_trait(CHANGELING_DRAIN) || ((user.stat != DEAD) && !(user.has_trait(TRAIT_DEATHCOMA)))) + if(HAS_TRAIT(user, CHANGELING_DRAIN) || ((user.stat != DEAD) && !(HAS_TRAIT(user, TRAIT_DEATHCOMA)))) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) changeling.purchasedpowers -= src return FALSE diff --git a/code/modules/antagonists/changeling/powers/strained_muscles.dm b/code/modules/antagonists/changeling/powers/strained_muscles.dm index 4e8b8adbd1..baeed8b0b2 100644 --- a/code/modules/antagonists/changeling/powers/strained_muscles.dm +++ b/code/modules/antagonists/changeling/powers/strained_muscles.dm @@ -19,7 +19,7 @@ if(active) to_chat(user, "Our muscles tense and strengthen.") else - user.remove_trait(TRAIT_GOTTAGOFAST, "changeling_muscles") + REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles") to_chat(user, "Our muscles relax.") if(stacks >= 10) to_chat(user, "We collapse in exhaustion.") @@ -32,12 +32,12 @@ /obj/effect/proc_holder/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user) while(active) - user.add_trait(TRAIT_GOTTAGOFAST, "changeling_muscles") + ADD_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles") if(user.stat != CONSCIOUS || user.staminaloss >= 90) active = !active to_chat(user, "Our muscles relax without the energy to strengthen them.") user.Knockdown(40) - user.remove_trait(TRAIT_GOTTAGOFAST, "changeling_muscles") + REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles") break stacks++ diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index b9abf76fd1..5a701d8a96 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -64,11 +64,11 @@ /obj/effect/proc_holder/changeling/sting/transformation name = "Transformation Sting" desc = "We silently sting a human, injecting a retrovirus that forces them to transform." - helptext = "The victim will transform much like a changeling would. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + helptext = "The victim will transform much like a changeling would. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human. This ability is loud, and might cause our blood to react violently to heat." sting_icon = "sting_transform" chemical_cost = 50 dna_cost = 3 - loudness = 1 + loudness = 2 var/datum/changelingprofile/selected_dna = null action_icon = 'icons/mob/actions/actions_changeling.dmi' action_icon_state = "ling_sting_transform" @@ -91,7 +91,7 @@ /obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target) if(!..()) return - if((target.has_trait(TRAIT_HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits)) + if((HAS_TRAIT(target, TRAIT_HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits)) to_chat(user, "Our sting appears ineffective against its DNA.") return 0 return 1 @@ -134,7 +134,7 @@ return if(isliving(target)) var/mob/living/L = target - if((L.has_trait(TRAIT_HUSK)) || !L.has_dna()) + if((HAS_TRAIT(L, TRAIT_HUSK)) || !L.has_dna()) to_chat(user, "Our sting appears ineffective against its DNA.") return 0 return 1 diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm index d7ae0c7fc6..ec712f2eec 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm @@ -44,12 +44,13 @@ /obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and fabricator clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture." - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard) + quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \ + /datum/clockwork_scripture/create_object/stargazer) maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more actions_types = list() -/obj/item/clockwork/slab/cyborg/engineer //two scriptures, plus a fabricator - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transmission) +/obj/item/clockwork/slab/cyborg/engineer //three scriptures, plus a fabricator + quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/stargazer) /obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \ @@ -61,12 +62,12 @@ /obj/item/clockwork/slab/cyborg/peacekeeper //two scriptures, plus a spear quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/hateful_manacles, /datum/clockwork_scripture/ranged_ability/judicial_marker) -/obj/item/clockwork/slab/cyborg/janitor //five scriptures, plus a fabricator +/obj/item/clockwork/slab/cyborg/janitor //six scriptures, plus a fabricator quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \ - /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor) + /datum/clockwork_scripture/create_object/stargazer, /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor) -/obj/item/clockwork/slab/cyborg/service //five scriptures, plus xray vision - quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, \ +/obj/item/clockwork/slab/cyborg/service //six scriptures, plus xray vision + quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant,/datum/clockwork_scripture/create_object/stargazer, \ /datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/clockwork_obelisk) /obj/item/clockwork/slab/cyborg/miner //two scriptures, plus a spear and xray vision diff --git a/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm b/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm index 51521ada24..9d241148b4 100644 --- a/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm +++ b/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm @@ -32,7 +32,7 @@ if(ishuman(loc)) var/mob/living/carbon/human/H = loc if(src == H.glasses && !up) - if(H.has_trait(TRAIT_BLIND)) + if(HAS_TRAIT(H, TRAIT_BLIND)) to_chat(H, "\"You're blind, idiot. Stop embarrassing yourself.\"") return if(blind_cultist(H)) @@ -76,7 +76,7 @@ ..() if(slot != SLOT_GLASSES || up) return - if(user.has_trait(TRAIT_BLIND)) + if(HAS_TRAIT(user, TRAIT_BLIND)) to_chat(user, "\"You're blind, idiot. Stop embarrassing yourself.\"" ) return if(blind_cultist(user)) //Cultists instantly go blind @@ -115,11 +115,11 @@ var/obj/item/clothing/glasses/wraith_spectacles/WS = L.glasses desc = "[glasses_right && !WS.up ? "":""]You are [glasses_right ? "":"not "]wearing wraith spectacles[glasses_right && !WS.up ? "!":"."]
\ You have taken [W.eye_damage_done] eye damage from them.
" - if(L.has_trait(TRAIT_NEARSIGHT)) + if(HAS_TRAIT(L, TRAIT_NEARSIGHT)) desc += "You are nearsighted!
" else if(glasses_right && !WS.up) desc += "You will become nearsighted at [W.nearsight_breakpoint] eye damage.
" - if(L.has_trait(TRAIT_BLIND)) + if(HAS_TRAIT(L, TRAIT_BLIND)) desc += "You are blind!" else if(glasses_right && !WS.up) desc += "You will become blind at [W.blind_breakpoint] eye damage." @@ -153,18 +153,18 @@ qdel(src) /datum/status_effect/wraith_spectacles/proc/apply_eye_damage(mob/living/carbon/human/H) - if(H.has_trait(TRAIT_BLIND)) + if(HAS_TRAIT(H, TRAIT_BLIND)) return H.adjust_eye_damage(0.5) eye_damage_done += 0.5 if(eye_damage_done >= 20) H.adjust_blurriness(2) if(eye_damage_done >= nearsight_breakpoint) - if(!H.has_trait(TRAIT_NEARSIGHT)) + if(!HAS_TRAIT(H, TRAIT_NEARSIGHT)) to_chat(H, "Your vision doubles, then trembles. Darkness begins to close in. You can't keep this up!") H.become_nearsighted(EYE_DAMAGE) if(eye_damage_done >= blind_breakpoint) - if(!H.has_trait(TRAIT_BLIND)) + if(!HAS_TRAIT(H, TRAIT_BLIND)) to_chat(H, "A piercing white light floods your vision. Suddenly, all goes dark!") H.become_blind(EYE_DAMAGE) diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm index 6415d9f91a..552a747651 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm @@ -2,6 +2,32 @@ // DRIVERS // ///////////// +//Stargazer: Creates a stargazer, a cheap power generator that utilizes starlight. +/datum/clockwork_scripture/create_object/stargazer + descname = "Generates Power From Starlight" + name = "Stargazer" + desc = "Forms a weak structure that generates power every second while within three tiles of starlight." + invocations = list("Capture their inferior light for us!") + channel_time = 50 + power_cost = 200 + object_path = /obj/structure/destructible/clockwork/stargazer + creator_message = "You form a stargazer, which will generate power near starlight." + observer_message = "A large lantern-shaped machine forms!" + usage_tip = "For obvious reasons, make sure to place this near a window or somewhere else that can see space!" + tier = SCRIPTURE_DRIVER + one_per_tile = TRUE + primary_component = HIEROPHANT_ANSIBLE + sort_priority = 1 + quickbind = TRUE + quickbind_desc = "Creates a stargazer, which generates power when near starlight." + +/datum/clockwork_scripture/create_object/stargazer/check_special_requirements() + var/area/A = get_area(invoker) + if(A.outdoors || A.map_name == "Space" || !A.blob_allowed) + to_chat(invoker, "Stargazers can't be built off-station.") + return + return ..() + //Integration Cog: Creates an integration cog that can be inserted into APCs to passively siphon power. /datum/clockwork_scripture/create_object/integration_cog @@ -18,7 +44,7 @@ tier = SCRIPTURE_DRIVER space_allowed = TRUE primary_component = HIEROPHANT_ANSIBLE - sort_priority = 1 + sort_priority = 2 important = TRUE quickbind = TRUE quickbind_desc = "Creates an integration cog, which can be used to siphon power from an open APC." @@ -39,7 +65,7 @@ tier = SCRIPTURE_DRIVER one_per_tile = TRUE primary_component = HIEROPHANT_ANSIBLE - sort_priority = 2 + sort_priority = 3 quickbind = TRUE quickbind_desc = "Creates a Sigil of Transgression, which will briefly stun and slow the next non-Servant to cross it." @@ -59,7 +85,7 @@ tier = SCRIPTURE_DRIVER one_per_tile = TRUE primary_component = HIEROPHANT_ANSIBLE - sort_priority = 3 + sort_priority = 4 quickbind = TRUE quickbind_desc = "Creates a Sigil of Submission, which will convert non-Servants that remain on it." @@ -76,7 +102,7 @@ usage_tip = "The light can be used from up to two tiles away. Damage taken will GREATLY REDUCE the stun's duration." tier = SCRIPTURE_DRIVER primary_component = BELLIGERENT_EYE - sort_priority = 4 + sort_priority = 5 slab_overlay = "volt" ranged_type = /obj/effect/proc_holder/slab/kindle ranged_message = "You charge the clockwork slab with divine energy.\n\ @@ -100,7 +126,7 @@ usage_tip = "The manacles are about as strong as zipties, and break when removed." tier = SCRIPTURE_DRIVER primary_component = BELLIGERENT_EYE - sort_priority = 5 + sort_priority = 6 ranged_type = /obj/effect/proc_holder/slab/hateful_manacles slab_overlay = "hateful_manacles" ranged_message = "You charge the clockwork slab with divine energy.\n\ @@ -124,7 +150,7 @@ usage_tip = "You cannot reactivate Vanguard while still shielded by it." tier = SCRIPTURE_DRIVER primary_component = VANGUARD_COGWHEEL - sort_priority = 6 + sort_priority = 7 quickbind = TRUE quickbind_desc = "Allows you to temporarily have quickly regenerating stamina and absorb stuns. All stuns absorbed will affect you when disabled." @@ -156,7 +182,7 @@ usage_tip = "The Compromise is very fast to invoke, and will remove holy water from the target Servant." tier = SCRIPTURE_DRIVER primary_component = VANGUARD_COGWHEEL - sort_priority = 7 + sort_priority = 8 quickbind = TRUE quickbind_desc = "Allows you to convert a Servant's brute, burn, and oxygen damage to half toxin damage.
Click your slab to disable." slab_overlay = "compromise" @@ -180,7 +206,7 @@ usage_tip = "This can't be used while on Reebe, for obvious reasons." tier = SCRIPTURE_DRIVER primary_component = GEIS_CAPACITOR - sort_priority = 8 + sort_priority = 9 important = TRUE quickbind = TRUE quickbind_desc = "Returns you to Reebe." @@ -238,7 +264,7 @@ tier = SCRIPTURE_DRIVER space_allowed = TRUE primary_component = GEIS_CAPACITOR - sort_priority = 9 + sort_priority = 10 important = TRUE quickbind = TRUE quickbind_desc = "Creates a new Clockwork Slab." @@ -259,6 +285,6 @@ tier = SCRIPTURE_DRIVER space_allowed = TRUE primary_component = GEIS_CAPACITOR - sort_priority = 10 + sort_priority = 11 quickbind = TRUE quickbind_desc = "Creates a pair of Wraith Spectacles, which grant true sight but cause gradual vision loss." diff --git a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm index 8dfadb60bc..df0083e845 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm @@ -110,7 +110,7 @@ if(!(BI.resistance_flags & ON_FIRE)) BI.fire_act() continue - if(is_servant_of_ratvar(L) || (L.has_trait(TRAIT_BLIND)) || L.anti_magic_check(TRUE, TRUE)) + if(is_servant_of_ratvar(L) || (HAS_TRAIT(L, TRAIT_BLIND)) || L.anti_magic_check(TRUE, TRUE)) continue if(L.stat || L.lying) continue diff --git a/code/modules/antagonists/clockcult/clock_structures/stargazer.dm b/code/modules/antagonists/clockcult/clock_structures/stargazer.dm new file mode 100644 index 0000000000..57f83c55aa --- /dev/null +++ b/code/modules/antagonists/clockcult/clock_structures/stargazer.dm @@ -0,0 +1,70 @@ +#define STARGAZER_RANGE 3 //How many tiles the stargazer can see out to +#define STARGAZER_POWER 7 //How many watts will be produced per second when the stargazer sees starlight + +//Stargazer: A very fragile but cheap generator that creates power from starlight. +/obj/structure/destructible/clockwork/stargazer + name = "stargazer" + desc = "A large lantern-shaped machine made of thin brass. It looks fragile." + clockwork_desc = "A lantern-shaped generator that produces power when near starlight." + icon_state = "stargazer" + unanchored_icon = "stargazer_unwrenched" + max_integrity = 40 + construction_value = 5 + layer = WALL_OBJ_LAYER + break_message = "The stargazer's fragile body shatters into pieces!" + resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + light_color = "#DAAA18" + var/star_light_star_bright = FALSE //If this stargazer can see starlight + +/obj/structure/destructible/clockwork/stargazer/Initialize() + . = ..() + START_PROCESSING(SSprocessing, src) + +/obj/structure/destructible/clockwork/stargazer/Destroy() + STOP_PROCESSING(SSprocessing, src) + . = ..() + +/obj/structure/destructible/clockwork/stargazer/examine(mob/user) + ..() + if(is_servant_of_ratvar(user)) + to_chat(user, "Generates [DisplayPower(STARGAZER_POWER)] per second while viewing starlight within [STARGAZER_RANGE] tiles.") + if(star_light_star_bright) + to_chat(user, "[is_servant_of_ratvar(user) ? "It can see starlight!" : "It's shining brilliantly!"]") + +/obj/structure/destructible/clockwork/stargazer/process() + star_light_star_bright = check_starlight() + if(star_light_star_bright) + adjust_clockwork_power(STARGAZER_POWER) + +/obj/structure/destructible/clockwork/stargazer/update_anchored(mob/living/user, damage) + . = ..() + star_light_star_bright = check_starlight() + +/obj/structure/destructible/clockwork/stargazer/proc/check_starlight() + var/old_status = star_light_star_bright + var/has_starlight + if(!anchored) + has_starlight = FALSE + else + for(var/turf/T in view(3, src)) + if(isspaceturf(T)) + has_starlight = TRUE + break + if(has_starlight && anchored) + var/area/A = get_area(src) + if(A.outdoors || A.map_name == "Space" || !A.blob_allowed) + has_starlight = FALSE + if(old_status != has_starlight) + if(has_starlight) + visible_message("[src] hums and shines brilliantly!") + playsound(src, 'sound/machines/clockcult/stargazer_activate.ogg', 50, TRUE) + add_overlay("stargazer_light") + set_light(1.5, 5) + else + if(anchored) //We lost visibility somehow + visible_message("[src] flickers, and falls dark.") + else + visible_message("[src] whooshes quietly as it slides into a less bulky form.") + cut_overlays() + set_light(0) + return has_starlight diff --git a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm new file mode 100644 index 0000000000..3eac1b9fef --- /dev/null +++ b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm @@ -0,0 +1,20 @@ +//Mech sensor: Activates when stepped on by a mech +/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech + name = "mech sensor" + desc = "A thin plate of brass, barely visible but clearly distinct." + clockwork_desc = "A trigger that will activate when a mech controlled by a non-servant runs across it." + max_integrity = 5 + icon_state = "pressure_sensor" + alpha = 75 + +/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech/Crossed(atom/movable/AM) + + if(!istype(AM,/obj/mecha/)) + return + + var/obj/mecha/M = AM + if(M.occupant && is_servant_of_ratvar(M.occupant)) + return + audible_message("*click*") + playsound(src, 'sound/items/screwdriver2.ogg', 50, TRUE) + activate() \ No newline at end of file diff --git a/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm b/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm index 6312228447..ebfb219c9a 100644 --- a/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm +++ b/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm @@ -68,7 +68,14 @@ mouse_opacity = MOUSE_OPACITY_OPAQUE //So players can interact with the tile it's on to pull them off buckle_mob(squirrel, TRUE) else - visible_message("A massive brass spike erupts from the ground!") + var/obj/mecha/M = locate() in get_turf(src) + if(M) + M.take_damage(50,BRUTE,"melee") + M.visible_message("A massive brass spike erupts from the ground, penetrating \the [M] and shattering the trap into pieces!") + addtimer(CALLBACK(src, .proc/take_damage, max_integrity), 1) + else + visible_message("A massive brass spike erupts from the ground!") + playsound(src, 'sound/machines/clockcult/brass_skewer.ogg', 75, FALSE) icon_state = "[initial(icon_state)]_extended" density = TRUE //Skewers are one-use only diff --git a/code/modules/antagonists/clockcult/clock_structures/traps/power_null.dm b/code/modules/antagonists/clockcult/clock_structures/traps/power_null.dm new file mode 100644 index 0000000000..6c8477ab5b --- /dev/null +++ b/code/modules/antagonists/clockcult/clock_structures/traps/power_null.dm @@ -0,0 +1,17 @@ +/obj/structure/destructible/clockwork/trap/power_nullifier + name = "power nullifier" + desc = "A well hidden set of wires and connections." + clockwork_desc = "When triggered, it sets off a 3x3 emp pulse with the center suffering a stronger pulse." + icon_state = "electric_trap" + break_message = "The power nullifier sparks, then slowly crumbles to debris!" + max_integrity = 40 + density = FALSE + var/activated = FALSE + +/obj/structure/destructible/clockwork/trap/power_nullifier/activate() + if(!activated) + activated = TRUE + empulse(get_turf(src),1,1,TRUE) + +/obj/structure/destructible/clockwork/trap/power_nullifier/emp_act(var/strength=1) + activate() diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index c8d59f54a8..32442ee72c 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -13,7 +13,7 @@ var/give_equipment = FALSE var/datum/team/cult/cult_team - + /datum/antagonist/cult/get_team() return cult_team @@ -115,7 +115,7 @@ cult_team.rise(current) if(cult_team.cult_ascendent) cult_team.ascend(current) - + /datum/antagonist/cult/remove_innate_effects(mob/living/mob_override) . = ..() var/mob/living/current = owner.current @@ -131,7 +131,7 @@ var/mob/living/carbon/human/H = current H.eye_color = initial(H.eye_color) H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) - H.remove_trait(CULT_EYES) + REMOVE_TRAIT(H, TRAIT_CULT_EYES, "valid_cultist") H.update_body() H.cut_overlays() H.regenerate_icons() @@ -220,12 +220,12 @@ throwing.Remove(current) current.update_action_buttons_icon() current.remove_status_effect(/datum/status_effect/cult_master) - + if(ishuman(current)) var/mob/living/carbon/human/H = current H.eye_color = initial(H.eye_color) H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) - H.remove_trait(CULT_EYES) + REMOVE_TRAIT(H, TRAIT_CULT_EYES, "valid_cultist") H.cut_overlays() H.regenerate_icons() @@ -241,7 +241,31 @@ var/reckoning_complete = FALSE var/cult_risen = FALSE var/cult_ascendent = FALSE - + +/datum/team/cult/New() + . = ..() + START_PROCESSING(SSprocessing, src) + +/datum/team/cult/Destroy() + STOP_PROCESSING(SSprocessing, src) + return ..() + +/datum/team/cult/process() + if(SSticker.current_state == GAME_STATE_FINISHED) + return + var/datum/objective/sacrifice/sac_objective = locate() in objectives + if(!sac_objective || sac_objective.check_completion()) + return + var/datum/mind/sacrificial = sac_objective.get_target() + var/mob/living/sac_current = sacrificial.current + if(!sacrificial || !sac_current) //target is gone for good but not sacrified. + sort_sacrifice(TRUE) + return + if(QDELETED(sac_objective.target_current) || sac_objective.target_current != sac_current) //target is now a different mob (monkey, simple mob) + sac_objective.sac_image = sac_current.get_sac_image() + sac_objective.target_current = sac_current + sac_objective.update_explanation_text() + /datum/team/cult/proc/check_size() if(cult_ascendent) return @@ -262,7 +286,7 @@ to_chat(B.current, "The veil weakens as your cult grows, your eyes begin to glow...") addtimer(CALLBACK(src, .proc/rise, B.current), 200) cult_risen = TRUE - + if(ratio > CULT_ASCENDENT && !cult_ascendent) for(var/datum/mind/B in members) if(B.current) @@ -270,16 +294,16 @@ to_chat(B.current, "Your cult is ascendent and the red harvest approaches - you cannot hide your true nature for much longer!!") addtimer(CALLBACK(src, .proc/ascend, B.current), 200) cult_ascendent = TRUE - - + + /datum/team/cult/proc/rise(cultist) if(ishuman(cultist)) var/mob/living/carbon/human/H = cultist H.eye_color = "f00" H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) - H.add_trait(CULT_EYES) + ADD_TRAIT(H, TRAIT_CULT_EYES, "valid_cultist") H.update_body() - + /datum/team/cult/proc/ascend(cultist) if(ishuman(cultist)) var/mob/living/carbon/human/H = cultist @@ -289,48 +313,68 @@ /datum/team/cult/proc/setup_objectives() //SAC OBJECTIVE , todo: move this to objective internals + sort_sacrifice() + //SUMMON OBJECTIVE + var/datum/objective/eldergod/summon_objective = new() + summon_objective.team = src + objectives += summon_objective + +/datum/team/cult/proc/sort_sacrifice(replacement = FALSE) + var/list/target_candidates = list() - var/datum/objective/sacrifice/sac_objective = new - sac_objective.team = src + + var/datum/objective/sacrifice/sac_objective = locate() in GLOB.objectives + if(!sac_objective) + sac_objective = new + sac_objective.team = src for(var/mob/living/carbon/human/player in GLOB.player_list) if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && !is_convertable_to_cult(player) && player.stat != DEAD) target_candidates += player.mind - if(target_candidates.len == 0) + if(!length(target_candidates)) message_admins("Cult Sacrifice: Could not find unconvertible target, checking for convertible target.") for(var/mob/living/carbon/human/player in GLOB.player_list) if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && player.stat != DEAD) target_candidates += player.mind + listclearnulls(target_candidates) - if(LAZYLEN(target_candidates)) - sac_objective.target = pick(target_candidates) - sac_objective.update_explanation_text() + if(!LAZYLEN(target_candidates)) + message_admins("Cult Sacrifice: Could not find unconvertible or convertible target. Proceeding to next stage!") + sac_objective.sacced = TRUE + return + var/datum/mind/new_target = pick(target_candidates) + if(replacement) + for(var/datum/mind/H in members) + if(H.current) + to_chat(H.current, "Nar'Sie murmurs, [sac_objective.target] is beyond your reach. Sacrifice [new_target] instead...") + sac_objective.target = new_target + sac_objective.target_current = new_target.current + sac_objective.update_explanation_text() - var/datum/job/sacjob = SSjob.GetJob(sac_objective.target.assigned_role) - var/datum/preferences/sacface = sac_objective.target.current.client.prefs - var/icon/reshape = get_flat_human_icon(null, sacjob, sacface, list(SOUTH)) - reshape.Shift(SOUTH, 4) - reshape.Shift(EAST, 1) - reshape.Crop(7,4,26,31) - reshape.Crop(-5,-3,26,30) - sac_objective.sac_image = reshape + sac_objective.sac_image = sac_objective.target_current.get_sac_image() + objectives += sac_objective - objectives += sac_objective - else - message_admins("Cult Sacrifice: Could not find unconvertible or convertible target. WELP!") +/mob/proc/get_sac_image() + var/icon/reshape = icon(icon, icon_state, SOUTH) + reshape.Shift(SOUTH, 4) + reshape.Shift(EAST, 1) + reshape.Crop(7,4,26,31) + reshape.Crop(-5,-3,26,30) +/mob/living/carbon/human/get_sac_image() + var/datum/job/sacjob = SSjob.GetJob(mind.assigned_role) + var/datum/preferences/sacface = client.prefs + var/icon/reshape = get_flat_human_icon(null, sacjob, sacface, list(SOUTH)) + reshape.Shift(SOUTH, 4) + reshape.Shift(EAST, 1) + reshape.Crop(7,4,26,31) + reshape.Crop(-5,-3,26,30) - //SUMMON OBJECTIVE - - var/datum/objective/eldergod/summon_objective = new() - summon_objective.team = src - objectives += summon_objective - - /datum/objective/sacrifice var/sacced = FALSE var/sac_image + var/mob/living/target_current /datum/objective/sacrifice/check_completion() return sacced || completed diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 0a949174b0..6bef6fd021 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -211,8 +211,6 @@ else return FALSE - - /datum/action/innate/cult/spin2win name = "Geometer's Fury" desc = "You draw on the power of the sword's ancient runes, spinning it wildly around you as you become immune to most attacks." @@ -267,7 +265,6 @@ return . = ..() - /obj/item/clothing/head/culthood name = "ancient cultist hood" icon_state = "culthood" @@ -294,7 +291,6 @@ heat_protection = CHEST|GROIN|LEGS|ARMS max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT - /obj/item/clothing/head/culthood/alt name = "cultist hood" desc = "An armored hood worn by the followers of Nar'Sie." @@ -313,7 +309,6 @@ /obj/item/clothing/suit/cultrobes/alt/ghost item_flags = NODROP | DROPDEL - /obj/item/clothing/head/magus name = "magus helm" icon_state = "magus" @@ -529,7 +524,12 @@ "The shuttle's custodian was found washing the windows with their own blood.", "A shuttle engineer began screaming 'DEATH IS NOT THE END' and ripped out wires until an arc flash seared off her flesh.", "A shuttle inspector started laughing madly over the radio and then threw herself into an engine turbine.", + "An assistant was found on the shuttle.", + "A medical officer was found pouring out several blood bags onto the shuttle's instrument panels, before slitting both wrists open and screaming 'DEATH IS NOT THE END'.", + "A fuel technician was found replacing the fuel with his blood.", + "All the lights aboard the shuttle turned a crimson red before blowing out..", "The shuttle dispatcher was found dead with bloody symbols carved into their flesh.", + "An engine turbine began leaking blood when it was powered on.", "The shuttle's transponder is emitting the encoded message 'FEAR THE OLD BLOOD' in lieu of its assigned identification signal.") var/message = pick_n_take(curses) message += " The shuttle will be delayed by three minutes." @@ -990,6 +990,6 @@ continue throw_at(Next, 3, 1, D.thrower) return - throw_at(D.thrower, 7, 1, D.thrower) + throw_at(D.thrower, 7, 1, null) else ..() diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 8a3f81fc01..2f3a039e70 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -123,7 +123,7 @@ structure_check() searches for nearby cultist structures required for the invoca continue if(ishuman(L)) var/mob/living/carbon/human/H = L - if((H.has_trait(TRAIT_MUTE)) || H.silent) + if((HAS_TRAIT(H, TRAIT_MUTE)) || H.silent) continue if(L.stat) continue @@ -246,18 +246,18 @@ structure_check() searches for nearby cultist structures required for the invoca return 0 to_chat(convertee, "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \ and something evil takes root.") - to_chat(convertee, "Do you wish to embrace the Geometer of Blood? Click here to stop resisting the truth. Or you could choose to continue resisting...") + to_chat(convertee, "Do you wish to embrace the Geometer of Blood? Click here to become a follower of Nar'sie. Or you could choose to continue resisting and suffer a fate worse than death...") currentconversionman = convertee conversiontimeout = world.time + (10 SECONDS) convertee.Stun(100) - convertee.add_trait(TRAIT_MUTE, "conversionrune") + ADD_TRAIT(convertee, TRAIT_MUTE, "conversionrune") conversionresult = FALSE while(world.time < conversiontimeout && convertee && !conversionresult) stoplag(1) currentconversionman = null if(!convertee) return FALSE - convertee.remove_trait(TRAIT_MUTE, "conversionrune") + REMOVE_TRAIT(convertee, TRAIT_MUTE, "conversionrune") if(get_turf(convertee) != get_turf(src)) return FALSE if(!conversionresult) diff --git a/code/modules/antagonists/highlander/highlander.dm b/code/modules/antagonists/highlander/highlander.dm index 1fa37f3a51..c0246ba978 100644 --- a/code/modules/antagonists/highlander/highlander.dm +++ b/code/modules/antagonists/highlander/highlander.dm @@ -7,11 +7,11 @@ /datum/antagonist/highlander/apply_innate_effects(mob/living/mob_override) var/mob/living/L = owner.current || mob_override - L.add_trait(TRAIT_NOGUNS, "highlander") + ADD_TRAIT(L, TRAIT_NOGUNS, "highlander") /datum/antagonist/highlander/remove_innate_effects(mob/living/mob_override) var/mob/living/L = owner.current || mob_override - L.remove_trait(TRAIT_NOGUNS, "highlander") + REMOVE_TRAIT(L, TRAIT_NOGUNS, "highlander") /datum/antagonist/highlander/proc/forge_objectives() var/datum/objective/steal/steal_objective = new diff --git a/code/modules/antagonists/overthrow/overthrow_converter.dm b/code/modules/antagonists/overthrow/overthrow_converter.dm index c94a838165..23599bd01b 100644 --- a/code/modules/antagonists/overthrow/overthrow_converter.dm +++ b/code/modules/antagonists/overthrow/overthrow_converter.dm @@ -37,7 +37,7 @@ if(M == user) to_chat(user,"You cannot convert yourself!") return - if(M.has_trait(TRAIT_MINDSHIELD)) + if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) to_chat(user, "This mind is too strong to convert, try to remove whatever is protecting it first!") return M.visible_message("[user] is attempting to implant [M].") diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index 90df57f48b..e10d83ffb7 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -17,7 +17,7 @@ return FALSE if(new_owner.unconvertable) return FALSE - if(new_owner.current && new_owner.current.has_trait(TRAIT_MINDSHIELD)) + if(new_owner.current && HAS_TRAIT(new_owner.current, TRAIT_MINDSHIELD)) return FALSE /datum/antagonist/rev/apply_innate_effects(mob/living/mob_override) diff --git a/code/modules/antagonists/traitor/IAA/internal_affairs.dm b/code/modules/antagonists/traitor/IAA/internal_affairs.dm index 5213c679ca..051bf74705 100644 --- a/code/modules/antagonists/traitor/IAA/internal_affairs.dm +++ b/code/modules/antagonists/traitor/IAA/internal_affairs.dm @@ -130,6 +130,7 @@ if(!owner.current||owner.current.stat==DEAD) return to_chat(owner.current, " Target eliminated: [victim.name]") + LAZYINITLIST(targets_stolen) for(var/objective_ in victim.objectives) if(istype(objective_, /datum/objective/assassinate/internal)) var/datum/objective/assassinate/internal/objective = objective_ diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 67527b2e91..1e7a9b7c15 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -27,6 +27,7 @@ var/datum/wires/connected = null var/next_activate = 0 //When we're next allowed to activate - for spam control + var/activate_cooldown = 3 SECONDS /obj/item/assembly/get_part_rating() return 1 @@ -78,7 +79,7 @@ /obj/item/assembly/proc/activate() if(QDELETED(src) || !secured || (next_activate > world.time)) return FALSE - next_activate = world.time + 30 + next_activate = world.time + activate_cooldown return TRUE diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index d40666babb..8ec93f978f 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -1,203 +1,202 @@ -/obj/item/onetankbomb - name = "bomb" - icon = 'icons/obj/tank.dmi' - item_state = "assembly" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - throwforce = 5 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 2 - throw_range = 4 - flags_1 = CONDUCT_1 - var/status = FALSE //0 - not readied //1 - bomb finished with welder - var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device - var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank - -/obj/item/onetankbomb/IsSpecialAssembly() - return TRUE - -/obj/item/onetankbomb/examine(mob/user) - bombtank.examine(user) - -/obj/item/onetankbomb/update_icon() - cut_overlays() - if(bombtank) - icon = bombtank.icon - icon_state = bombtank.icon_state - if(bombassembly) - add_overlay(bombassembly.icon_state) - copy_overlays(bombassembly) - add_overlay("bomb_assembly") - -/obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I) - to_chat(user, "You disassemble [src]!") - if(bombassembly) - bombassembly.forceMove(drop_location()) - bombassembly.master = null - bombassembly = null - if(bombtank) - bombtank.forceMove(drop_location()) - bombtank.master = null - bombtank = null - qdel(src) - return TRUE - -/obj/item/onetankbomb/welder_act(mob/living/user, obj/item/I) - . = FALSE - if(status) - to_chat(user, "[bombtank] already has a pressure hole!") - return - if(!I.tool_start_check(user, amount=0)) - return - if(I.use_tool(src, user, 0, volume=40)) - status = TRUE - GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]" - message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]") - to_chat(user, "A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.") - add_fingerprint(user) - return TRUE - - -/obj/item/onetankbomb/analyzer_act(mob/living/user, obj/item/I) - bombtank.analyzer_act(user, I) - -/obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly - bombassembly.attack_self(user, TRUE) - add_fingerprint(user) - return - -/obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here. - audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*") - playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) - sleep(10) - if(QDELETED(src)) - return - if(status) - bombtank.ignite() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file - else - bombtank.release() - -//Assembly / attached device memes - -/obj/item/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps - . = ..() - if(bombassembly) - bombassembly.Crossed(AM) - -/obj/item/onetankbomb/on_found(mob/finder) //for mousetraps - if(bombassembly) - bombassembly.on_found(finder) - -/obj/item/onetankbomb/attack_hand() //also for mousetraps - . = ..() - if(.) - return - if(bombassembly) - bombassembly.attack_hand() - -/obj/item/onetankbomb/Move() - . = ..() - if(bombassembly) - bombassembly.setDir(dir) - bombassembly.Move() - -/obj/item/onetankbomb/dropped() - . = ..() - if(bombassembly) - bombassembly.dropped() - - - - -// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ---------- - -//Bomb assembly proc. This turns assembly+tank into a bomb -/obj/item/tank/proc/bomb_assemble(obj/item/assembly_holder/assembly, mob/living/user) - //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it - if(isigniter(assembly.a_left) == isigniter(assembly.a_right)) - return - - if((src in user.get_equipped_items(TRUE)) && !user.canUnEquip(src)) - to_chat(user, "[src] is stuck to you!") - return - - if(!user.canUnEquip(assembly)) - to_chat(user, "[assembly] is stuck to your hand!") - return - - var/obj/item/onetankbomb/bomb = new - user.transferItemToLoc(src, bomb) - user.transferItemToLoc(assembly, bomb) - - bomb.bombassembly = assembly //Tell the bomb about its assembly part - assembly.master = bomb //Tell the assembly about its new owner - - bomb.bombtank = src //Same for tank - master = bomb - - forceMove(bomb) - bomb.update_icon() - - user.put_in_hands(bomb) //Equips the bomb if possible, or puts it on the floor. - to_chat(user, "You attach [assembly] to [src].") - return - -/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode - air_contents.assert_gases(/datum/gas/plasma, /datum/gas/oxygen) - var/fuel_moles = air_contents.gases[/datum/gas/plasma][MOLES] + air_contents.gases[/datum/gas/oxygen][MOLES]/6 - air_contents.garbage_collect() - var/datum/gas_mixture/bomb_mixture = air_contents.copy() - var/strength = 1 - - var/turf/ground_zero = get_turf(loc) - - if(master) - qdel(master) - qdel(src) - - if(bomb_mixture.temperature > (T0C + 400)) - strength = (fuel_moles/15) - - if(strength >=1) - explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1)) - else if(strength >=0.5) - explosion(ground_zero, 0, 1, 2, 4) - else if(strength >=0.2) - explosion(ground_zero, -1, 0, 1, 2) - else - ground_zero.assume_air(bomb_mixture) - ground_zero.hotspot_expose(1000, 125) - - else if(bomb_mixture.temperature > (T0C + 250)) - strength = (fuel_moles/20) - - if(strength >=1) - explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1)) - else if (strength >=0.5) - explosion(ground_zero, -1, 0, 1, 2) - else - ground_zero.assume_air(bomb_mixture) - ground_zero.hotspot_expose(1000, 125) - - else if(bomb_mixture.temperature > (T0C + 100)) - strength = (fuel_moles/25) - - if (strength >=1) - explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1)) - else - ground_zero.assume_air(bomb_mixture) - ground_zero.hotspot_expose(1000, 125) - - else - ground_zero.assume_air(bomb_mixture) - ground_zero.hotspot_expose(1000, 125) - - ground_zero.air_update_turf() - -/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out. - var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles()) - var/turf/T = get_turf(src) - if(!T) - return - T.assume_air(removed) - air_update_turf() +/obj/item/onetankbomb + name = "bomb" + icon = 'icons/obj/tank.dmi' + item_state = "assembly" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + throwforce = 5 + w_class = WEIGHT_CLASS_NORMAL + throw_speed = 2 + throw_range = 4 + flags_1 = CONDUCT_1 + var/status = FALSE //0 - not readied //1 - bomb finished with welder + var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device + var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank + +/obj/item/onetankbomb/IsSpecialAssembly() + return TRUE + +/obj/item/onetankbomb/examine(mob/user) + bombtank.examine(user) + +/obj/item/onetankbomb/update_icon() + cut_overlays() + if(bombtank) + icon = bombtank.icon + icon_state = bombtank.icon_state + if(bombassembly) + add_overlay(bombassembly.icon_state) + copy_overlays(bombassembly) + add_overlay("bomb_assembly") + +/obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I) + to_chat(user, "You disassemble [src]!") + if(bombassembly) + bombassembly.forceMove(drop_location()) + bombassembly.master = null + bombassembly = null + if(bombtank) + bombtank.forceMove(drop_location()) + bombtank.master = null + bombtank = null + qdel(src) + return TRUE + +/obj/item/onetankbomb/welder_act(mob/living/user, obj/item/I) + . = FALSE + if(status) + to_chat(user, "[bombtank] already has a pressure hole!") + return + if(!I.tool_start_check(user, amount=0)) + return + if(I.use_tool(src, user, 0, volume=40)) + status = TRUE + GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]" + message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]") + to_chat(user, "A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.") + add_fingerprint(user) + return TRUE + + +/obj/item/onetankbomb/analyzer_act(mob/living/user, obj/item/I) + bombtank.analyzer_act(user, I) + +/obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly + bombassembly.attack_self(user, TRUE) + add_fingerprint(user) + return + +/obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here. + audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*") + playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) + sleep(10) + if(QDELETED(src)) + return + if(status) + bombtank.ignite() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file + else + bombtank.release() + +//Assembly / attached device memes + +/obj/item/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps + . = ..() + if(bombassembly) + bombassembly.Crossed(AM) + +/obj/item/onetankbomb/on_found(mob/finder) //for mousetraps + if(bombassembly) + bombassembly.on_found(finder) + +/obj/item/onetankbomb/attack_hand() //also for mousetraps + . = ..() + if(.) + return + if(bombassembly) + bombassembly.attack_hand() + +/obj/item/onetankbomb/Move() + . = ..() + if(bombassembly) + bombassembly.setDir(dir) + bombassembly.Move() + +/obj/item/onetankbomb/dropped() + . = ..() + if(bombassembly) + bombassembly.dropped() + + + + +// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ---------- + +//Bomb assembly proc. This turns assembly+tank into a bomb +/obj/item/tank/proc/bomb_assemble(obj/item/assembly_holder/assembly, mob/living/user) + //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it + if(isigniter(assembly.a_left) == isigniter(assembly.a_right)) + return + + if((src in user.get_equipped_items(TRUE)) && !user.canUnEquip(src)) + to_chat(user, "[src] is stuck to you!") + return + + if(!user.canUnEquip(assembly)) + to_chat(user, "[assembly] is stuck to your hand!") + return + + var/obj/item/onetankbomb/bomb = new + user.transferItemToLoc(src, bomb) + user.transferItemToLoc(assembly, bomb) + + bomb.bombassembly = assembly //Tell the bomb about its assembly part + assembly.master = bomb //Tell the assembly about its new owner + + bomb.bombtank = src //Same for tank + master = bomb + + forceMove(bomb) + bomb.update_icon() + + user.put_in_hands(bomb) //Equips the bomb if possible, or puts it on the floor. + to_chat(user, "You attach [assembly] to [src].") + return + +/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode + var/fuel_moles = air_contents.gases[/datum/gas/plasma] + air_contents.gases[/datum/gas/oxygen]/6 + GAS_GARBAGE_COLLECT(air_contents.gases) + var/datum/gas_mixture/bomb_mixture = air_contents.copy() + var/strength = 1 + + var/turf/ground_zero = get_turf(loc) + + if(master) + qdel(master) + qdel(src) + + if(bomb_mixture.temperature > (T0C + 400)) + strength = (fuel_moles/15) + + if(strength >=1) + explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1)) + else if(strength >=0.5) + explosion(ground_zero, 0, 1, 2, 4) + else if(strength >=0.2) + explosion(ground_zero, -1, 0, 1, 2) + else + ground_zero.assume_air(bomb_mixture) + ground_zero.hotspot_expose(1000, 125) + + else if(bomb_mixture.temperature > (T0C + 250)) + strength = (fuel_moles/20) + + if(strength >=1) + explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1)) + else if (strength >=0.5) + explosion(ground_zero, -1, 0, 1, 2) + else + ground_zero.assume_air(bomb_mixture) + ground_zero.hotspot_expose(1000, 125) + + else if(bomb_mixture.temperature > (T0C + 100)) + strength = (fuel_moles/25) + + if (strength >=1) + explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1)) + else + ground_zero.assume_air(bomb_mixture) + ground_zero.hotspot_expose(1000, 125) + + else + ground_zero.assume_air(bomb_mixture) + ground_zero.hotspot_expose(1000, 125) + + ground_zero.air_update_turf() + +/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out. + var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles()) + var/turf/T = get_turf(src) + if(!T) + return + T.assume_air(removed) + air_update_turf() diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm index ad83ed8c13..b1aa63c242 100644 --- a/code/modules/assembly/flash.dm +++ b/code/modules/assembly/flash.dm @@ -43,7 +43,7 @@ holder.update_icon() /obj/item/assembly/flash/proc/clown_check(mob/living/carbon/human/user) - if(user.has_trait(TRAIT_CLUMSY) && prob(50)) + if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) flash_carbon(user, user, 15, 0) return FALSE return TRUE diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 58a3a5349a..a2a9fb0105 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -18,7 +18,7 @@ if(!armed) if(ishuman(usr)) var/mob/living/carbon/human/user = usr - if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50)) + if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) to_chat(user, "Your hand slips, setting off the trigger!") pulse(FALSE) update_icon() @@ -38,7 +38,7 @@ var/obj/item/bodypart/affecting = null if(ishuman(target)) var/mob/living/carbon/human/H = target - if(H.has_trait(TRAIT_PIERCEIMMUNE)) + if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) playsound(src, 'sound/effects/snap.ogg', 50, TRUE) armed = FALSE update_icon() @@ -70,7 +70,7 @@ if(!armed) to_chat(user, "You arm [src].") else - if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50)) + if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) var/which_hand = BODY_ZONE_PRECISE_L_HAND if(!(user.active_hand_index % 2)) which_hand = BODY_ZONE_PRECISE_R_HAND @@ -87,7 +87,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/assembly/mousetrap/attack_hand(mob/living/carbon/human/user) if(armed) - if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50)) + if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) var/which_hand = BODY_ZONE_PRECISE_L_HAND if(!(user.active_hand_index % 2)) which_hand = BODY_ZONE_PRECISE_R_HAND diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 8959029b9b..8ba703d7fa 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -58,18 +58,12 @@ Send Signal
Frequency/Code for signaler:
Frequency: -- -- [format_frequency(src.frequency)] -+ -+
+Set
Code: -- -- [src.code] -+ -+
+Set
[t1] "} user << browse(dat, "window=radio") @@ -85,17 +79,23 @@ Code: onclose(usr, "radio") return - if (href_list["freq"]) - var/new_frequency = (frequency + text2num(href_list["freq"])) - if(new_frequency < MIN_FREE_FREQ || new_frequency > MAX_FREE_FREQ) - new_frequency = sanitize_frequency(new_frequency) - set_frequency(new_frequency) + if (href_list["set"]) - if(href_list["code"]) - src.code += text2num(href_list["code"]) - src.code = round(src.code) - src.code = min(100, src.code) - src.code = max(1, src.code) + if(href_list["set"] == "freq") + var/new_freq = input(usr, "Input a new signalling frequency", "Remote Signaller Frequency", format_frequency(frequency)) as num|null + if(!usr.canUseTopic(src, BE_CLOSE)) + return + new_freq = unformat_frequency(new_freq) + new_freq = sanitize_frequency(new_freq, TRUE) + set_frequency(new_freq) + + if(href_list["set"] == "code") + var/new_code = input(usr, "Input a new signalling code", "Remote Signaller Code", code) as num|null + if(!usr.canUseTopic(src, BE_CLOSE)) + return + new_code = round(new_code) + new_code = CLAMP(new_code, 1, 100) + code = new_code if(href_list["send"]) spawn( 0 ) @@ -206,4 +206,4 @@ Code: /obj/item/assembly/signaler/cyborg/attackby(obj/item/W, mob/user, params) return /obj/item/assembly/signaler/cyborg/screwdriver_act(mob/living/user, obj/item/I) - return + return \ No newline at end of file diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm index bf5d8efb13..d1da05e42d 100644 --- a/code/modules/atmospherics/environmental/LINDA_fire.dm +++ b/code/modules/atmospherics/environmental/LINDA_fire.dm @@ -14,9 +14,9 @@ if(!air_contents) return 0 - var/oxy = air_contents.gases[/datum/gas/oxygen] ? air_contents.gases[/datum/gas/oxygen][MOLES] : 0 - var/tox = air_contents.gases[/datum/gas/plasma] ? air_contents.gases[/datum/gas/plasma][MOLES] : 0 - var/trit = air_contents.gases[/datum/gas/tritium] ? air_contents.gases[/datum/gas/tritium][MOLES] : 0 + var/oxy = air_contents.gases[/datum/gas/oxygen] + var/tox = air_contents.gases[/datum/gas/plasma] + var/trit = air_contents.gases[/datum/gas/tritium] if(active_hotspot) if(soh) if((tox > 0.5 || trit > 0.5) && oxy > 0.5) @@ -162,7 +162,7 @@ color = list(LERP(0.3, 1, 1-greyscale_fire) * heat_r,0.3 * heat_g * greyscale_fire,0.3 * heat_b * greyscale_fire, 0.59 * heat_r * greyscale_fire,LERP(0.59, 1, 1-greyscale_fire) * heat_g,0.59 * heat_b * greyscale_fire, 0.11 * heat_r * greyscale_fire,0.11 * heat_g * greyscale_fire,LERP(0.11, 1, 1-greyscale_fire) * heat_b, 0,0,0) alpha = heat_a -#define INSUFFICIENT(path) (!location.air.gases[path] || location.air.gases[path][MOLES] < 0.5) +#define INSUFFICIENT(path) (location.air.gases[path] < 0.5) /obj/effect/hotspot/process() if(just_spawned) just_spawned = FALSE @@ -184,7 +184,7 @@ return //Not enough to burn - if(((!location.air.gases[/datum/gas/plasma] || location.air.gases[/datum/gas/plasma][MOLES] < 0.5) && (!location.air.gases[/datum/gas/tritium] || location.air.gases[/datum/gas/tritium][MOLES] < 0.5)) || location.air.gases[/datum/gas/oxygen][MOLES] < 0.5) + if((location.air.gases[/datum/gas/plasma] < 0.5 && location.air.gases[/datum/gas/tritium] < 0.5) || location.air.gases[/datum/gas/oxygen] < 0.5) qdel(src) return diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index 45bb47ab58..ea555c9489 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -88,7 +88,7 @@ temperature_archived = temperature /turf/open/archive() - air.archive() + ARCHIVE_TEMPERATURE(air) archived_cycle = SSair.times_fired temperature_archived = temperature @@ -121,10 +121,9 @@ if (nonoverlaying_gases[id]) continue var/gas = gases[id] - var/gas_meta = gas[GAS_META] - var/gas_overlay = gas_meta[META_GAS_OVERLAY] - if(gas_overlay && gas[MOLES] > gas_meta[META_GAS_MOLES_VISIBLE]) - . += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(gas[MOLES] / MOLES_GAS_VISIBLE_STEP, 1))] + var/gas_overlay = GLOB.meta_gas_overlays[id] + if(gas_overlay && gas > GLOB.meta_gas_visibility[id]) + . += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(gas / MOLES_GAS_VISIBLE_STEP, 1))] /proc/typecache_of_gases_with_no_overlays() . = list() @@ -215,7 +214,7 @@ if (planet_atmos) //share our air with the "atmosphere" "above" the turf var/datum/gas_mixture/G = new G.copy_from_turf(src) - G.archive() + ARCHIVE_TEMPERATURE(G) if(our_air.compare(G)) if(!our_excited_group) var/datum/excited_group/EG = new @@ -232,6 +231,11 @@ atmos_cooldown = cached_atmos_cooldown +/turf/open/space/process_cell(fire_count) //dumb hack to prevent space pollution + . = ..() + var/datum/gas_mixture/immutable/I = space_gas + I.after_process_cell() + /turf/proc/process_cell_reaction() SSair.remove_from_react_queue(src) @@ -327,7 +331,7 @@ A.merge(T.air) for(var/id in A_gases) - A_gases[id][MOLES] /= turflen + A_gases[id] /= turflen for(var/t in turf_list) var/turf/open/T = t diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 0304946111..9858db2abb 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -5,82 +5,38 @@ What are the archived variables for? */ #define MINIMUM_HEAT_CAPACITY 0.0003 #define MINIMUM_MOLE_COUNT 0.01 -#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that - once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ -GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm -GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) - -/proc/init_gaslist_cache() - . = list() - for(var/id in GLOB.meta_gas_info) - var/list/cached_gas = new(3) - - .[id] = cached_gas - - cached_gas[MOLES] = 0 - cached_gas[ARCHIVE] = 0 - cached_gas[GAS_META] = GLOB.meta_gas_info[id] +//Unomos - global list inits for all of the meta gas lists. +//This setup allows procs to only look at one list instead of trying to dig around in lists-within-lists +GLOBAL_LIST_INIT(meta_gas_specific_heats, meta_gas_heat_list()) +GLOBAL_LIST_INIT(meta_gas_names, meta_gas_name_list()) +GLOBAL_LIST_INIT(meta_gas_visibility, meta_gas_visibility_list()) +GLOBAL_LIST_INIT(meta_gas_overlays, meta_gas_overlay_list()) +GLOBAL_LIST_INIT(meta_gas_dangers, meta_gas_danger_list()) +GLOBAL_LIST_INIT(meta_gas_ids, meta_gas_id_list()) +GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list()) /datum/gas_mixture - var/list/gases + var/list/gases = list() var/temperature = 0 //kelvins var/tmp/temperature_archived = 0 var/volume = CELL_VOLUME //liters var/last_share = 0 - var/list/reaction_results + var/list/reaction_results = list() var/list/analyzer_results //used for analyzer feedback - not initialized until its used var/gc_share = FALSE // Whether to call garbage_collect() on the sharer during shares, used for immutable mixtures /datum/gas_mixture/New(volume) - gases = new if (!isnull(volume)) src.volume = volume - reaction_results = new - -//listmos procs -//use the macros in performance intensive areas. for their definitions, refer to code/__DEFINES/atmospherics.dm - - //assert_gas(gas_id) - used to guarantee that the gas list for this id exists in gas_mixture.gases. - //Must be used before adding to a gas. May be used before reading from a gas. -/datum/gas_mixture/proc/assert_gas(gas_id) - ASSERT_GAS(gas_id, src) - - //assert_gases(args) - shorthand for calling ASSERT_GAS() once for each gas type. -/datum/gas_mixture/proc/assert_gases() - for(var/id in args) - ASSERT_GAS(id, src) - - //add_gas(gas_id) - similar to assert_gas(), but does not check for an existing - //gas list for this id. This can clobber existing gases. - //Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas(). -/datum/gas_mixture/proc/add_gas(gas_id) - ADD_GAS(gas_id, gases) - - //add_gases(args) - shorthand for calling add_gas() once for each gas_type. -/datum/gas_mixture/proc/add_gases() - var/cached_gases = gases - for(var/id in args) - ADD_GAS(id, cached_gases) - - //garbage_collect() - removes any gas list which is empty. - //If called with a list as an argument, only removes gas lists with IDs from that list. - //Must be used after subtracting from a gas. Must be used after assert_gas() - //if assert_gas() was called only to read from the gas. - //By removing empty gases, processing speed is increased. -/datum/gas_mixture/proc/garbage_collect(list/tocheck) - var/list/cached_gases = gases - for(var/id in (tocheck || cached_gases)) - if(QUANTIZE(cached_gases[id][MOLES]) <= 0 && QUANTIZE(cached_gases[id][ARCHIVE]) <= 0) - cached_gases -= id //PV = nRT -/datum/gas_mixture/proc/heat_capacity(data = MOLES) //joules per kelvin +/datum/gas_mixture/proc/heat_capacity() //joules per kelvin var/list/cached_gases = gases + var/list/cached_gasheats = GLOB.meta_gas_specific_heats . = 0 for(var/id in cached_gases) - var/gas_data = cached_gases[id] - . += gas_data[data] * gas_data[GAS_META][META_GAS_SPECIFIC_HEAT] + . += cached_gases[id] * cached_gasheats[id] /datum/gas_mixture/turf/heat_capacity() . = ..() @@ -108,10 +64,6 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) /datum/gas_mixture/proc/thermal_energy() //joules return THERMAL_ENERGY(src) //see code/__DEFINES/atmospherics.dm; use the define in performance critical areas -/datum/gas_mixture/proc/archive() - //Update archived versions of variables - //Returns: 1 in all cases - /datum/gas_mixture/proc/merge(datum/gas_mixture/giver) //Merges all air from giver into self. Deletes giver. //Returns: 1 if we are mutable, 0 otherwise @@ -156,14 +108,6 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) //Performs various reactions such as combustion or fusion (LOL) //Returns: 1 if any reaction took place; 0 otherwise -/datum/gas_mixture/archive() - var/list/cached_gases = gases - - temperature_archived = temperature - for(var/id in cached_gases) - cached_gases[id][ARCHIVE] = cached_gases[id][MOLES] - - return 1 /datum/gas_mixture/merge(datum/gas_mixture/giver) if(!giver) @@ -181,8 +125,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) var/list/giver_gases = giver.gases //gas transfer for(var/giver_id in giver_gases) - ASSERT_GAS(giver_id, src) - cached_gases[giver_id][MOLES] += giver_gases[giver_id][MOLES] + cached_gases[giver_id] += giver_gases[giver_id] return 1 @@ -198,10 +141,9 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) removed.temperature = temperature for(var/id in cached_gases) - ADD_GAS(id, removed.gases) - removed_gases[id][MOLES] = QUANTIZE((cached_gases[id][MOLES] / sum) * amount) - cached_gases[id][MOLES] -= removed_gases[id][MOLES] - garbage_collect() + removed_gases[id] = QUANTIZE((cached_gases[id] / sum) * amount) + cached_gases[id] -= removed_gases[id] + GAS_GARBAGE_COLLECT(gases) return removed @@ -216,11 +158,10 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) removed.temperature = temperature for(var/id in cached_gases) - ADD_GAS(id, removed.gases) - removed_gases[id][MOLES] = QUANTIZE(cached_gases[id][MOLES] * ratio) - cached_gases[id][MOLES] -= removed_gases[id][MOLES] + removed_gases[id] = QUANTIZE(cached_gases[id] * ratio) + cached_gases[id] -= removed_gases[id] - garbage_collect() + GAS_GARBAGE_COLLECT(gases) return removed @@ -231,8 +172,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) copy.temperature = temperature for(var/id in cached_gases) - ADD_GAS(id, copy.gases) - copy_gases[id][MOLES] = cached_gases[id][MOLES] + copy_gases[id] = cached_gases[id] return copy @@ -243,8 +183,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) temperature = sample.temperature for(var/id in sample_gases) - ASSERT_GAS(id,src) - cached_gases[id][MOLES] = sample_gases[id][MOLES] + cached_gases[id] = sample_gases[id] //remove all gases not in the sample cached_gases &= sample_gases @@ -272,8 +211,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) var/path = id if(!ispath(path)) path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around - ADD_GAS(path, gases) - gases[path][MOLES] = text2num(gas[id]) + gases[path] = text2num(gas[id]) return 1 /datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4) @@ -296,26 +234,25 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) var/moved_moles = 0 var/abs_moved_moles = 0 + //we're gonna define these vars outside of this for loop because as it turns out, var declaration is pricy + var/delta + var/gas_heat_capacity + //and also cache this shit rq because that results in sanic speed for reasons byond explanation + var/list/cached_gasheats = GLOB.meta_gas_specific_heats //GAS TRANSFER - for(var/id in sharer_gases - cached_gases) // create gases not in our cache - ADD_GAS(id, gases) - for(var/id in cached_gases) // transfer gases - ASSERT_GAS(id, sharer) + for(var/id in cached_gases | sharer_gases) // transfer gases - var/gas = cached_gases[id] - var/sharergas = sharer_gases[id] - - var/delta = QUANTIZE(gas[ARCHIVE] - sharergas[ARCHIVE])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures + delta = QUANTIZE(cached_gases[id] - sharer_gases[id])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/gas_heat_capacity = delta * gas[GAS_META][META_GAS_SPECIFIC_HEAT] + gas_heat_capacity = delta * cached_gasheats[id] if(delta > 0) heat_capacity_self_to_sharer += gas_heat_capacity else heat_capacity_sharer_to_self -= gas_heat_capacity //subtract here instead of adding the absolute value because we know that delta is negative. - gas[MOLES] -= delta - sharergas[MOLES] += delta + cached_gases[id] -= delta + sharer_gases[id] += delta moved_moles += delta abs_moved_moles += abs(delta) @@ -338,11 +275,8 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.1) // <10% change in sharer heat capacity temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT) - if(length(cached_gases ^ sharer_gases)) //if all gases were present in both mixtures, we know that no gases are 0 - garbage_collect(cached_gases - sharer_gases) //any gases the sharer had, we are guaranteed to have. gases that it didn't have we are not. - sharer.garbage_collect(sharer_gases - cached_gases) //the reverse is equally true if (initial(sharer.gc_share)) - sharer.garbage_collect() + GAS_GARBAGE_COLLECT(sharer.gases) if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) var/our_moles TOTAL_MOLES(cached_gases,our_moles) @@ -356,8 +290,8 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) sharer_temperature = sharer.temperature_archived var/temperature_delta = temperature_archived - sharer_temperature if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity(ARCHIVE) - sharer_heat_capacity = sharer_heat_capacity || sharer.heat_capacity(ARCHIVE) + var/self_heat_capacity = heat_capacity() + sharer_heat_capacity = sharer_heat_capacity || sharer.heat_capacity() if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*temperature_delta* \ @@ -376,9 +310,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) for(var/id in cached_gases | sample_gases) // compare gases from either mixture var/gas_moles = cached_gases[id] - gas_moles = gas_moles ? gas_moles[MOLES] : 0 var/sample_moles = sample_gases[id] - sample_moles = sample_moles ? sample_moles[MOLES] : 0 var/delta = abs(gas_moles - sample_moles) if(delta > MINIMUM_MOLES_DELTA_TO_MOVE && \ delta > gas_moles * MINIMUM_AIR_RATIO_TO_MOVE) @@ -425,7 +357,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) for(var/id in min_reqs) if (id == "TEMP" || id == "ENER") continue - if(!cached_gases[id] || cached_gases[id][MOLES] < min_reqs[id]) + if(cached_gases[id] < min_reqs[id]) continue reaction_loop //at this point, all minimum requirements for the reaction are satisfied. @@ -449,7 +381,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) if (. & STOP_REACTIONS) break if(.) - garbage_collect() + GAS_GARBAGE_COLLECT(gases) if(temperature < TCMB) //just for safety temperature = TCMB diff --git a/code/modules/atmospherics/gasmixtures/gas_types.dm b/code/modules/atmospherics/gasmixtures/gas_types.dm index 9dcf8c3145..d628826b01 100644 --- a/code/modules/atmospherics/gasmixtures/gas_types.dm +++ b/code/modules/atmospherics/gasmixtures/gas_types.dm @@ -1,33 +1,66 @@ GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/plasma)) //the main four gases, which were at one time hardcoded GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/pluoxium, /datum/gas/stimulum, /datum/gas/nitryl))) //unable to react amongst themselves -/proc/meta_gas_list() - . = subtypesof(/datum/gas) - for(var/gas_path in .) - var/list/gas_info = new(7) - var/datum/gas/gas = gas_path - - gas_info[META_GAS_SPECIFIC_HEAT] = initial(gas.specific_heat) - gas_info[META_GAS_NAME] = initial(gas.name) - gas_info[META_GAS_MOLES_VISIBLE] = initial(gas.moles_visible) - if(initial(gas.moles_visible) != null) - gas_info[META_GAS_OVERLAY] = new /list(FACTOR_GAS_VISIBLE_MAX) - for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX) - gas_info[META_GAS_OVERLAY][i] = new /obj/effect/overlay/gas(initial(gas.gas_overlay), i * 255 / FACTOR_GAS_VISIBLE_MAX) - gas_info[META_GAS_FUSION_POWER] = initial(gas.fusion_power) - gas_info[META_GAS_DANGER] = initial(gas.dangerous) - gas_info[META_GAS_ID] = initial(gas.id) - .[gas_path] = gas_info - /proc/gas_id2path(id) - var/list/meta_gas = GLOB.meta_gas_info + var/list/meta_gas = GLOB.meta_gas_ids if(id in meta_gas) return id for(var/path in meta_gas) - if(meta_gas[path][META_GAS_ID] == id) + if(meta_gas[path] == id) return path return "" +//Unomos - oh god oh fuck oh shit oh lord have mercy this is messy as fuck oh god +//my addiction to seeing better performance numbers isn't healthy, kids +//you see this shit, children? +//i am not a good idol. don't take after me. +//this is literally worse than my alcohol addiction +/proc/meta_gas_heat_list() + . = subtypesof(/datum/gas) + for(var/gas_path in .) + var/datum/gas/gas = gas_path + .[gas_path] = initial(gas.specific_heat) + +/proc/meta_gas_name_list() + . = subtypesof(/datum/gas) + for(var/gas_path in .) + var/datum/gas/gas = gas_path + .[gas_path] = initial(gas.name) + +/proc/meta_gas_visibility_list() + . = subtypesof(/datum/gas) + for(var/gas_path in .) + var/datum/gas/gas = gas_path + .[gas_path] = initial(gas.moles_visible) + +/proc/meta_gas_overlay_list() + . = subtypesof(/datum/gas) + for(var/gas_path in .) + var/datum/gas/gas = gas_path + .[gas_path] = 0 //gotta make sure if(GLOB.meta_gas_overlays[gaspath]) doesn't break + if(initial(gas.moles_visible) != null) + .[gas_path] = new /list(FACTOR_GAS_VISIBLE_MAX) + for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX) + .[gas_path][i] = new /obj/effect/overlay/gas(initial(gas.gas_overlay), i * 255 / FACTOR_GAS_VISIBLE_MAX) + +/proc/meta_gas_danger_list() + . = subtypesof(/datum/gas) + for(var/gas_path in .) + var/datum/gas/gas = gas_path + .[gas_path] = initial(gas.dangerous) + +/proc/meta_gas_id_list() + . = subtypesof(/datum/gas) + for(var/gas_path in .) + var/datum/gas/gas = gas_path + .[gas_path] = initial(gas.id) + +/proc/meta_gas_fusion_list() + . = subtypesof(/datum/gas) + for(var/gas_path in .) + var/datum/gas/gas = gas_path + .[gas_path] = initial(gas.fusion_power) + /*||||||||||||||/----------\||||||||||||||*\ ||||||||||||||||[GAS DATUMS]|||||||||||||||| ||||||||||||||||\__________/|||||||||||||||| diff --git a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm index 08f64b5f4a..53f7ede3e6 100644 --- a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm +++ b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm @@ -7,22 +7,18 @@ /datum/gas_mixture/immutable/New() ..() - garbage_collect() - -/datum/gas_mixture/immutable/garbage_collect() temperature = initial_temperature temperature_archived = initial_temperature gases.Cut() -/datum/gas_mixture/immutable/archive() - return 1 //nothing changes, so we do nothing and the archive is successful - /datum/gas_mixture/immutable/merge() return 0 //we're immutable. /datum/gas_mixture/immutable/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4) . = ..(sharer, 0) - garbage_collect() + temperature = initial_temperature + temperature_archived = initial_temperature + gases.Cut() /datum/gas_mixture/immutable/react() return 0 //we're immutable. @@ -43,6 +39,10 @@ . = ..() temperature = initial_temperature +/datum/gas_mixture/immutable/proc/after_process_cell() + temperature = initial_temperature + temperature_archived = initial_temperature + gases.Cut() //used by space tiles /datum/gas_mixture/immutable/space @@ -62,10 +62,13 @@ /datum/gas_mixture/immutable/cloner initial_temperature = T20C -/datum/gas_mixture/immutable/cloner/garbage_collect() +/datum/gas_mixture/immutable/cloner/New() ..() - ADD_GAS(/datum/gas/nitrogen, gases) - gases[/datum/gas/nitrogen][MOLES] = MOLES_O2STANDARD + MOLES_N2STANDARD + gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD + +/datum/gas_mixture/immutable/cloner/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4) + . = ..(sharer, 0) + gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD /datum/gas_mixture/immutable/cloner/heat_capacity() return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20 diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 84ad1e9258..46ad4f26b7 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -60,7 +60,7 @@ if(location && location.freon_gas_act()) . = REACTING else if(location && location.water_vapor_gas_act()) - air.gases[/datum/gas/water_vapor][MOLES] -= MOLES_GAS_VISIBLE + air.gases[/datum/gas/water_vapor] -= MOLES_GAS_VISIBLE . = REACTING //tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic @@ -86,21 +86,20 @@ var/turf/open/location = isturf(holder) ? holder : null var/burned_fuel = 0 - if(cached_gases[/datum/gas/oxygen][MOLES] < cached_gases[/datum/gas/tritium][MOLES]) - burned_fuel = cached_gases[/datum/gas/oxygen][MOLES]/TRITIUM_BURN_OXY_FACTOR - cached_gases[/datum/gas/tritium][MOLES] -= burned_fuel + if(cached_gases[/datum/gas/oxygen] < cached_gases[/datum/gas/tritium]) + burned_fuel = cached_gases[/datum/gas/oxygen]/TRITIUM_BURN_OXY_FACTOR + cached_gases[/datum/gas/tritium] -= burned_fuel else - burned_fuel = cached_gases[/datum/gas/tritium][MOLES]*TRITIUM_BURN_TRIT_FACTOR - cached_gases[/datum/gas/tritium][MOLES] -= cached_gases[/datum/gas/tritium][MOLES]/TRITIUM_BURN_TRIT_FACTOR - cached_gases[/datum/gas/oxygen][MOLES] -= cached_gases[/datum/gas/tritium][MOLES] + burned_fuel = cached_gases[/datum/gas/tritium]*TRITIUM_BURN_TRIT_FACTOR + cached_gases[/datum/gas/tritium] -= cached_gases[/datum/gas/tritium]/TRITIUM_BURN_TRIT_FACTOR + cached_gases[/datum/gas/oxygen] -= cached_gases[/datum/gas/tritium] if(burned_fuel) energy_released += FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR) - ASSERT_GAS(/datum/gas/water_vapor, air) //oxygen+more-or-less hydrogen=H2O - cached_gases[/datum/gas/water_vapor][MOLES] += burned_fuel/TRITIUM_BURN_OXY_FACTOR + cached_gases[/datum/gas/water_vapor] += burned_fuel/TRITIUM_BURN_OXY_FACTOR cached_results["fire"] += burned_fuel @@ -157,23 +156,21 @@ temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) if(temperature_scale > 0) oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale - if(cached_gases[/datum/gas/oxygen][MOLES] / cached_gases[/datum/gas/plasma][MOLES] > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium. + if(cached_gases[/datum/gas/oxygen] / cached_gases[/datum/gas/plasma] > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium. super_saturation = TRUE - if(cached_gases[/datum/gas/oxygen][MOLES] > cached_gases[/datum/gas/plasma][MOLES]*PLASMA_OXYGEN_FULLBURN) - plasma_burn_rate = (cached_gases[/datum/gas/plasma][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA + if(cached_gases[/datum/gas/oxygen] > cached_gases[/datum/gas/plasma]*PLASMA_OXYGEN_FULLBURN) + plasma_burn_rate = (cached_gases[/datum/gas/plasma]*temperature_scale)/PLASMA_BURN_RATE_DELTA else - plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA + plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY) - plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/oxygen][MOLES]/oxygen_burn_rate) //Ensures matter is conserved properly - cached_gases[/datum/gas/plasma][MOLES] = QUANTIZE(cached_gases[/datum/gas/plasma][MOLES] - plasma_burn_rate) - cached_gases[/datum/gas/oxygen][MOLES] = QUANTIZE(cached_gases[/datum/gas/oxygen][MOLES] - (plasma_burn_rate * oxygen_burn_rate)) + plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma],cached_gases[/datum/gas/oxygen]/oxygen_burn_rate) //Ensures matter is conserved properly + cached_gases[/datum/gas/plasma] = QUANTIZE(cached_gases[/datum/gas/plasma] - plasma_burn_rate) + cached_gases[/datum/gas/oxygen] = QUANTIZE(cached_gases[/datum/gas/oxygen] - (plasma_burn_rate * oxygen_burn_rate)) if (super_saturation) - ASSERT_GAS(/datum/gas/tritium,air) - cached_gases[/datum/gas/tritium][MOLES] += plasma_burn_rate + cached_gases[/datum/gas/tritium] += plasma_burn_rate else - ASSERT_GAS(/datum/gas/carbon_dioxide,air) - cached_gases[/datum/gas/carbon_dioxide][MOLES] += plasma_burn_rate + cached_gases[/datum/gas/carbon_dioxide] += plasma_burn_rate energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate) @@ -231,21 +228,21 @@ var/old_heat_capacity = air.heat_capacity() var/reaction_energy = 0 - var/mediation = FUSION_MEDIATION_FACTOR*(air.heat_capacity()-(cached_gases[/datum/gas/plasma][MOLES]*cached_gases[/datum/gas/plasma][GAS_META][META_GAS_SPECIFIC_HEAT]))/(air.total_moles()-cached_gases[/datum/gas/plasma][MOLES]) //This is the average specific heat of the mixture,not including plasma. + var/mediation = FUSION_MEDIATION_FACTOR*(air.heat_capacity()-(cached_gases[/datum/gas/plasma]*GLOB.meta_gas_specific_heats[/datum/gas/plasma]))/(air.total_moles()-cached_gases[/datum/gas/plasma]) //This is the average specific heat of the mixture,not including plasma. - var/gases_fused = air.total_moles() - cached_gases[/datum/gas/plasma][MOLES] - var/plasma_differential = (cached_gases[/datum/gas/plasma][MOLES] - gases_fused) / air.total_moles() + var/gases_fused = air.total_moles() - cached_gases[/datum/gas/plasma] + var/plasma_differential = (cached_gases[/datum/gas/plasma] - gases_fused) / air.total_moles() var/reaction_efficiency = FUSION_EFFICIENCY_BASE ** -((plasma_differential ** 2) / FUSION_EFFICIENCY_DIVISOR) //https://www.desmos.com/calculator/6jjx3vdrvx var/gas_power = 0 for (var/gas_id in cached_gases) - gas_power += reaction_efficiency * (cached_gases[gas_id][GAS_META][META_GAS_FUSION_POWER]*cached_gases[gas_id][MOLES]) + gas_power += reaction_efficiency * (GLOB.meta_gas_fusions[gas_id]*cached_gases[gas_id]) var/power_ratio = gas_power/mediation cached_scan_results[id] = power_ratio //used for analyzer feedback for (var/gas_id in cached_gases) //and now we fuse - cached_gases[gas_id][MOLES] = 0 + cached_gases[gas_id] = 0 var/radiation_power = (FUSION_RADIATION_FACTOR * power_ratio) / (power_ratio + FUSION_RADIATION_CONSTANT) //https://www.desmos.com/calculator/4i1f296phl var/zap_power = ((FUSION_ZAP_POWER_ASYMPTOTE * power_ratio) / (power_ratio + FUSION_ZAP_POWER_CONSTANT)) + FUSION_ZAP_POWER_BASE //https://www.desmos.com/calculator/n0zkdpxnrr @@ -255,33 +252,30 @@ if (power_ratio > FUSION_SUPER_TIER_THRESHOLD) //power ratio 50+: SUPER TIER. The gases become so energized that they fuse into a ton of tritium, which is pretty nice! Until you consider the fact that everything just exploded, the canister is probably going to break and you're irradiated. reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_SUPER * (power_ratio / FUSION_ENERGY_DIVISOR_SUPER) - cached_gases[/datum/gas/tritium][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_TRITIUM //60% of the gas is converted to energy, 40% to trit + cached_gases[/datum/gas/tritium] += gases_fused * FUSION_GAS_CREATION_FACTOR_TRITIUM //60% of the gas is converted to energy, 40% to trit fusion_prepare_to_die_edition_rng = 100 //Wait a minute.. do_explosion = TRUE zap_range = FUSION_ZAP_RANGE_SUPER else if (power_ratio > FUSION_HIGH_TIER_THRESHOLD) //power ratio 20-50; High tier. The reaction is so energized that it fuses into a small amount of stimulum, and some pluoxium. Very dangerous, but super cool and super useful. reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_HIGH * (power_ratio / FUSION_ENERGY_DIVISOR_HIGH) - air.assert_gases(/datum/gas/stimulum, /datum/gas/pluoxium) - cached_gases[/datum/gas/stimulum][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_STIM //40% of the gas is converted to energy, 60% to stim and pluox - cached_gases[/datum/gas/pluoxium][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_PLUOX + cached_gases[/datum/gas/stimulum] += gases_fused * FUSION_GAS_CREATION_FACTOR_STIM //40% of the gas is converted to energy, 60% to stim and pluox + cached_gases[/datum/gas/pluoxium] += gases_fused * FUSION_GAS_CREATION_FACTOR_PLUOX fusion_prepare_to_die_edition_rng = power_ratio //Now we're getting into dangerous territory do_explosion = TRUE zap_range = FUSION_ZAP_RANGE_HIGH else if (power_ratio > FUSION_MID_TIER_THRESHOLD) //power_ratio 5 to 20; Mediation is overpowered, fusion reaction starts to break down. reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_MID * (power_ratio / FUSION_ENERGY_DIVISOR_MID) - air.assert_gases(/datum/gas/nitryl,/datum/gas/nitrous_oxide) - cached_gases[/datum/gas/nitryl][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_NITRYL //20% of the gas is converted to energy, 80% to nitryl and N2O - cached_gases[/datum/gas/nitrous_oxide][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_N2O + cached_gases[/datum/gas/nitryl] += gases_fused * FUSION_GAS_CREATION_FACTOR_NITRYL //20% of the gas is converted to energy, 80% to nitryl and N2O + cached_gases[/datum/gas/nitrous_oxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_N2O fusion_prepare_to_die_edition_rng = power_ratio * FUSION_MID_TIER_RAD_PROB_FACTOR //Still unlikely, but don't stand next to the reaction unprotected zap_range = FUSION_ZAP_RANGE_MID else //power ratio 0 to 5; Gas power is overpowered. Fusion isn't nearly as powerful. reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_LOW * (power_ratio / FUSION_ENERGY_DIVISOR_LOW) - air.assert_gases(/datum/gas/bz, /datum/gas/carbon_dioxide) - cached_gases[/datum/gas/bz][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_BZ //10% of the gas is converted to energy, 90% to BZ and CO2 - cached_gases[/datum/gas/carbon_dioxide][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_CO2 + cached_gases[/datum/gas/bz] += gases_fused * FUSION_GAS_CREATION_FACTOR_BZ //10% of the gas is converted to energy, 90% to BZ and CO2 + cached_gases[/datum/gas/carbon_dioxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_CO2 fusion_prepare_to_die_edition_rng = power_ratio * FUSION_LOW_TIER_RAD_PROB_FACTOR //Low, but still something to look out for zap_range = FUSION_ZAP_RANGE_LOW @@ -322,14 +316,13 @@ var/temperature = air.temperature var/old_heat_capacity = air.heat_capacity() - var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),cached_gases[/datum/gas/oxygen][MOLES],cached_gases[/datum/gas/nitrogen][MOLES]) + var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),cached_gases[/datum/gas/oxygen],cached_gases[/datum/gas/nitrogen]) var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY - ASSERT_GAS(/datum/gas/nitryl,air) - if ((cached_gases[/datum/gas/oxygen][MOLES] - heat_efficency < 0 )|| (cached_gases[/datum/gas/nitrogen][MOLES] - heat_efficency < 0)) //Shouldn't produce gas from nothing. + if ((cached_gases[/datum/gas/oxygen] - heat_efficency < 0 )|| (cached_gases[/datum/gas/nitrogen] - heat_efficency < 0)) //Shouldn't produce gas from nothing. return NO_REACTION - cached_gases[/datum/gas/oxygen][MOLES] -= heat_efficency - cached_gases[/datum/gas/nitrogen][MOLES] -= heat_efficency - cached_gases[/datum/gas/nitryl][MOLES] += heat_efficency*2 + cached_gases[/datum/gas/oxygen] -= heat_efficency + cached_gases[/datum/gas/nitrogen] -= heat_efficency + cached_gases[/datum/gas/nitryl] += heat_efficency*2 if(energy_used > 0) var/new_heat_capacity = air.heat_capacity() @@ -355,14 +348,13 @@ var/pressure = air.return_pressure() var/old_heat_capacity = air.heat_capacity() - var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/nitrous_oxide][MOLES],1))),cached_gases[/datum/gas/nitrous_oxide][MOLES],cached_gases[/datum/gas/plasma][MOLES]/2) + var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma]/cached_gases[/datum/gas/nitrous_oxide],1))),cached_gases[/datum/gas/nitrous_oxide],cached_gases[/datum/gas/plasma]/2) var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED - if ((cached_gases[/datum/gas/nitrous_oxide][MOLES] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma][MOLES] - (2*reaction_efficency) < 0)) //Shouldn't produce gas from nothing. + if ((cached_gases[/datum/gas/nitrous_oxide] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma] - (2*reaction_efficency) < 0)) //Shouldn't produce gas from nothing. return NO_REACTION - ASSERT_GAS(/datum/gas/bz,air) - cached_gases[/datum/gas/bz][MOLES] += reaction_efficency - cached_gases[/datum/gas/nitrous_oxide][MOLES] -= reaction_efficency - cached_gases[/datum/gas/plasma][MOLES] -= 2*reaction_efficency + cached_gases[/datum/gas/bz] += reaction_efficency + cached_gases[/datum/gas/nitrous_oxide] -= reaction_efficency + cached_gases[/datum/gas/plasma] -= 2*reaction_efficency if(energy_released > 0) @@ -388,16 +380,15 @@ var/list/cached_gases = air.gases var/old_heat_capacity = air.heat_capacity() - var/heat_scale = min(air.temperature/STIMULUM_HEAT_SCALE,cached_gases[/datum/gas/tritium][MOLES],cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/nitryl][MOLES]) + var/heat_scale = min(air.temperature/STIMULUM_HEAT_SCALE,cached_gases[/datum/gas/tritium],cached_gases[/datum/gas/plasma],cached_gases[/datum/gas/nitryl]) var/stim_energy_change = heat_scale + STIMULUM_FIRST_RISE*(heat_scale**2) - STIMULUM_FIRST_DROP*(heat_scale**3) + STIMULUM_SECOND_RISE*(heat_scale**4) - STIMULUM_ABSOLUTE_DROP*(heat_scale**5) - ASSERT_GAS(/datum/gas/stimulum,air) - if ((cached_gases[/datum/gas/tritium][MOLES] - heat_scale < 0 )|| (cached_gases[/datum/gas/plasma][MOLES] - heat_scale < 0) || (cached_gases[/datum/gas/nitryl][MOLES] - heat_scale < 0)) //Shouldn't produce gas from nothing. + if ((cached_gases[/datum/gas/tritium] - heat_scale < 0 )|| (cached_gases[/datum/gas/plasma] - heat_scale < 0) || (cached_gases[/datum/gas/nitryl] - heat_scale < 0)) //Shouldn't produce gas from nothing. return NO_REACTION - cached_gases[/datum/gas/stimulum][MOLES]+= heat_scale/10 - cached_gases[/datum/gas/tritium][MOLES] -= heat_scale - cached_gases[/datum/gas/plasma][MOLES] -= heat_scale - cached_gases[/datum/gas/nitryl][MOLES] -= heat_scale + cached_gases[/datum/gas/stimulum]+= heat_scale/10 + cached_gases[/datum/gas/tritium] -= heat_scale + cached_gases[/datum/gas/plasma] -= heat_scale + cached_gases[/datum/gas/nitryl] -= heat_scale if(stim_energy_change) var/new_heat_capacity = air.heat_capacity() @@ -418,15 +409,14 @@ /datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air) var/list/cached_gases = air.gases - air.assert_gases(/datum/gas/hypernoblium,/datum/gas/bz) var/old_heat_capacity = air.heat_capacity() - var/nob_formed = min((cached_gases[/datum/gas/nitrogen][MOLES]+cached_gases[/datum/gas/tritium][MOLES])/100,cached_gases[/datum/gas/tritium][MOLES]/10,cached_gases[/datum/gas/nitrogen][MOLES]/20) - var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz][MOLES],1))) - if ((cached_gases[/datum/gas/tritium][MOLES] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen][MOLES] - 20*nob_formed < 0)) + var/nob_formed = min((cached_gases[/datum/gas/nitrogen]+cached_gases[/datum/gas/tritium])/100,cached_gases[/datum/gas/tritium]/10,cached_gases[/datum/gas/nitrogen]/20) + var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz],1))) + if ((cached_gases[/datum/gas/tritium] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen] - 20*nob_formed < 0)) return NO_REACTION - cached_gases[/datum/gas/tritium][MOLES] -= 10*nob_formed - cached_gases[/datum/gas/nitrogen][MOLES] -= 20*nob_formed - cached_gases[/datum/gas/hypernoblium][MOLES]+= nob_formed + cached_gases[/datum/gas/tritium] -= 10*nob_formed + cached_gases[/datum/gas/nitrogen] -= 20*nob_formed + cached_gases[/datum/gas/hypernoblium]+= nob_formed if (nob_formed) @@ -449,14 +439,13 @@ /datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder) var/list/cached_gases = air.gases // As the name says it, it needs to be dry - if(cached_gases[/datum/gas/water_vapor] && cached_gases[/datum/gas/water_vapor][MOLES]/air.total_moles() > 0.1) + if(cached_gases[/datum/gas/water_vapor] && cached_gases[/datum/gas/water_vapor]/air.total_moles() > 0.1) return //Replace miasma with oxygen - var/cleaned_air = min(cached_gases[/datum/gas/miasma][MOLES], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20) - cached_gases[/datum/gas/miasma][MOLES] -= cleaned_air - ASSERT_GAS(/datum/gas/oxygen,air) - cached_gases[/datum/gas/oxygen][MOLES] += cleaned_air + var/cleaned_air = min(cached_gases[/datum/gas/miasma], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20) + cached_gases[/datum/gas/miasma] -= cleaned_air + cached_gases[/datum/gas/oxygen] += cleaned_air //Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable air.temperature += cleaned_air * 0.002 diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 0a7b76cc79..6ea571935b 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -1,880 +1,880 @@ -/datum/tlv - var/min2 - var/min1 - var/max1 - var/max2 - -/datum/tlv/New(min2 as num, min1 as num, max1 as num, max2 as num) - if(min2) src.min2 = min2 - if(min1) src.min1 = min1 - if(max1) src.max1 = max1 - if(max2) src.max2 = max2 - -/datum/tlv/proc/get_danger_level(val as num) - if(max2 != -1 && val >= max2) - return 2 - if(min2 != -1 && val <= min2) - return 2 - if(max1 != -1 && val >= max1) - return 1 - if(min1 != -1 && val <= min1) - return 1 - return 0 - -/datum/tlv/no_checks - min2 = -1 - min1 = -1 - max1 = -1 - max2 = -1 - -/datum/tlv/dangerous - min2 = -1 - min1 = -1 - max1 = 0.2 - max2 = 0.5 - -/obj/item/electronics/airalarm - name = "air alarm electronics" - icon_state = "airalarm_electronics" - -/obj/item/wallframe/airalarm - name = "air alarm frame" - desc = "Used for building Air Alarms." - icon = 'icons/obj/monitors.dmi' - icon_state = "alarm_bitem" - result_path = /obj/machinery/airalarm - -#define AALARM_MODE_SCRUBBING 1 -#define AALARM_MODE_VENTING 2 //makes draught -#define AALARM_MODE_PANIC 3 //like siphon, but stronger (enables widenet) -#define AALARM_MODE_REPLACEMENT 4 //sucks off all air, then refill and swithes to scrubbing -#define AALARM_MODE_OFF 5 -#define AALARM_MODE_FLOOD 6 //Emagged mode; turns off scrubbers and pressure checks on vents -#define AALARM_MODE_SIPHON 7 //Scrubbers suck air -#define AALARM_MODE_CONTAMINATED 8 //Turns on all filtering and widenet scrubbing. -#define AALARM_MODE_REFILL 9 //just like normal, but with triple the air output - -#define AALARM_REPORT_TIMEOUT 100 - -#define AALARM_OVERLAY_OFF "alarm_off" -#define AALARM_OVERLAY_GREEN "alarm_green" -#define AALARM_OVERLAY_WARN "alarm_amber" -#define AALARM_OVERLAY_DANGER "alarm_red" - -/obj/machinery/airalarm - name = "air alarm" - desc = "A machine that monitors atmosphere levels. Goes off if the area is dangerous." - icon = 'icons/obj/monitors.dmi' - icon_state = "alarm0" - use_power = IDLE_POWER_USE - idle_power_usage = 4 - active_power_usage = 8 - power_channel = ENVIRON - req_access = list(ACCESS_ATMOSPHERICS) - max_integrity = 250 - integrity_failure = 80 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) - resistance_flags = FIRE_PROOF - - var/danger_level = 0 - var/mode = AALARM_MODE_SCRUBBING - - var/locked = TRUE - var/aidisabled = 0 - var/shorted = 0 - var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone - var/brightness_on = 1 - - var/frequency = FREQ_ATMOS_CONTROL - var/alarm_frequency = FREQ_ATMOS_ALARMS - var/datum/radio_frequency/radio_connection - - var/list/TLV = list( // Breathable air. - "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa - "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), - /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa - /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), - /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), - /datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5), - /datum/gas/plasma = new/datum/tlv/dangerous, - /datum/gas/nitrous_oxide = new/datum/tlv/dangerous, - /datum/gas/bz = new/datum/tlv/dangerous, - /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic - /datum/gas/water_vapor = new/datum/tlv/dangerous, - /datum/gas/tritium = new/datum/tlv/dangerous, - /datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects - /datum/gas/nitryl = new/datum/tlv/dangerous, - /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires - ) - -/obj/machinery/airalarm/server // No checks here. - TLV = list( - "pressure" = new/datum/tlv/no_checks, - "temperature" = new/datum/tlv/no_checks, - /datum/gas/oxygen = new/datum/tlv/no_checks, - /datum/gas/nitrogen = new/datum/tlv/no_checks, - /datum/gas/carbon_dioxide = new/datum/tlv/no_checks, - /datum/gas/miasma = new/datum/tlv/no_checks, - /datum/gas/plasma = new/datum/tlv/no_checks, - /datum/gas/nitrous_oxide = new/datum/tlv/no_checks, - /datum/gas/bz = new/datum/tlv/no_checks, - /datum/gas/hypernoblium = new/datum/tlv/no_checks, - /datum/gas/water_vapor = new/datum/tlv/no_checks, - /datum/gas/tritium = new/datum/tlv/no_checks, - /datum/gas/stimulum = new/datum/tlv/no_checks, - /datum/gas/nitryl = new/datum/tlv/no_checks, - /datum/gas/pluoxium = new/datum/tlv/no_checks - ) - -/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures. - TLV = list( - "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa - "temperature" = new/datum/tlv(T0C-73.15, T0C-63.15, T0C, T0C+10), - /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa - /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), - /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), - /datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5), - /datum/gas/plasma = new/datum/tlv/dangerous, - /datum/gas/nitrous_oxide = new/datum/tlv/dangerous, - /datum/gas/bz = new/datum/tlv/dangerous, - /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic - /datum/gas/water_vapor = new/datum/tlv/dangerous, - /datum/gas/tritium = new/datum/tlv/dangerous, - /datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects - /datum/gas/nitryl = new/datum/tlv/dangerous, - /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires - ) - -/obj/machinery/airalarm/unlocked - locked = FALSE - -/obj/machinery/airalarm/engine - name = "engine air alarm" - locked = FALSE - req_access = null - req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_ENGINE) - -/obj/machinery/airalarm/mixingchamber - name = "chamber air alarm" - locked = FALSE - req_access = null - req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_TOX, ACCESS_TOX_STORAGE) - -/obj/machinery/airalarm/all_access - name = "all-access air alarm" - desc = "This particular atmos control unit appears to have no access restrictions." - locked = FALSE - req_access = null - req_one_access = null - -/obj/machinery/airalarm/syndicate //general syndicate access - req_access = list(ACCESS_SYNDICATE) - -/obj/machinery/airalarm/directional/north //Pixel offsets get overwritten on New() - dir = SOUTH - pixel_y = 24 - -/obj/machinery/airalarm/directional/south - dir = NORTH - pixel_y = -24 - -/obj/machinery/airalarm/directional/east - dir = WEST - pixel_x = 24 - -/obj/machinery/airalarm/directional/west - dir = EAST - pixel_x = -24 - -//all air alarms in area are connected via magic -/area - var/list/air_vent_names = list() - var/list/air_scrub_names = list() - var/list/air_vent_info = list() - var/list/air_scrub_info = list() - -/obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) - . = ..() - wires = new /datum/wires/airalarm(src) - - if(ndir) - setDir(ndir) - - if(nbuild) - buildstage = 0 - panel_open = TRUE - pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) - pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0 - - if(name == initial(name)) - name = "[get_area_name(src)] Air Alarm" - - power_change() - set_frequency(frequency) - -/obj/machinery/airalarm/Destroy() - SSradio.remove_object(src, frequency) - qdel(wires) - wires = null - return ..() - -/obj/machinery/airalarm/examine(mob/user) - . = ..() - switch(buildstage) - if(0) - to_chat(user, "It is missing air alarm electronics.") - if(1) - to_chat(user, "It is missing wiring.") - if(2) - to_chat(user, "Alt-click to [locked ? "unlock" : "lock"] the interface.") - -/obj/machinery/airalarm/ui_status(mob/user) - if(user.has_unlimited_silicon_privilege && aidisabled) - to_chat(user, "AI control has been disabled.") - else if(!shorted) - return ..() - return UI_CLOSE - -/obj/machinery/airalarm/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "airalarm", name, 440, 650, master_ui, state) - ui.open() - -/obj/machinery/airalarm/ui_data(mob/user) - var/data = list( - "locked" = locked, - "siliconUser" = user.has_unlimited_silicon_privilege, - "emagged" = (obj_flags & EMAGGED ? 1 : 0), - "danger_level" = danger_level, - ) - - var/area/A = get_area(src) - data["atmos_alarm"] = A.atmosalm - data["fire_alarm"] = A.fire - - var/turf/T = get_turf(src) - var/datum/gas_mixture/environment = T.return_air() - var/datum/tlv/cur_tlv - - data["environment_data"] = list() - var/pressure = environment.return_pressure() - cur_tlv = TLV["pressure"] - data["environment_data"] += list(list( - "name" = "Pressure", - "value" = pressure, - "unit" = "kPa", - "danger_level" = cur_tlv.get_danger_level(pressure) - )) - var/temperature = environment.temperature - cur_tlv = TLV["temperature"] - data["environment_data"] += list(list( - "name" = "Temperature", - "value" = temperature, - "unit" = "K ([round(temperature - T0C, 0.1)]C)", - "danger_level" = cur_tlv.get_danger_level(temperature) - )) - var/total_moles = environment.total_moles() - var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume - for(var/gas_id in environment.gases) - if(!(gas_id in TLV)) // We're not interested in this gas, it seems. - continue - cur_tlv = TLV[gas_id] - data["environment_data"] += list(list( - "name" = environment.gases[gas_id][GAS_META][META_GAS_NAME], - "value" = environment.gases[gas_id][MOLES] / total_moles * 100, - "unit" = "%", - "danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id][MOLES] * partial_pressure) - )) - - if(!locked || user.has_unlimited_silicon_privilege) - data["vents"] = list() - for(var/id_tag in A.air_vent_names) - var/long_name = A.air_vent_names[id_tag] - var/list/info = A.air_vent_info[id_tag] - if(!info || info["frequency"] != frequency) - continue - data["vents"] += list(list( - "id_tag" = id_tag, - "long_name" = sanitize(long_name), - "power" = info["power"], - "checks" = info["checks"], - "excheck" = info["checks"]&1, - "incheck" = info["checks"]&2, - "direction" = info["direction"], - "external" = info["external"], - "internal" = info["internal"], - "extdefault"= (info["external"] == ONE_ATMOSPHERE), - "intdefault"= (info["internal"] == 0) - )) - data["scrubbers"] = list() - for(var/id_tag in A.air_scrub_names) - var/long_name = A.air_scrub_names[id_tag] - var/list/info = A.air_scrub_info[id_tag] - if(!info || info["frequency"] != frequency) - continue - data["scrubbers"] += list(list( - "id_tag" = id_tag, - "long_name" = sanitize(long_name), - "power" = info["power"], - "scrubbing" = info["scrubbing"], - "widenet" = info["widenet"], - "filter_types" = info["filter_types"] - )) - data["mode"] = mode - data["modes"] = list() - data["modes"] += list(list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0)) - data["modes"] += list(list("name" = "Contaminated - Scrubs out ALL contaminants quickly","mode" = AALARM_MODE_CONTAMINATED, "selected" = mode == AALARM_MODE_CONTAMINATED, "danger" = 0)) - data["modes"] += list(list("name" = "Draught - Siphons out air while replacing", "mode" = AALARM_MODE_VENTING, "selected" = mode == AALARM_MODE_VENTING, "danger" = 0)) - data["modes"] += list(list("name" = "Refill - Triple vent output", "mode" = AALARM_MODE_REFILL, "selected" = mode == AALARM_MODE_REFILL, "danger" = 1)) - data["modes"] += list(list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 1)) - data["modes"] += list(list("name" = "Siphon - Siphons air out of the room", "mode" = AALARM_MODE_SIPHON, "selected" = mode == AALARM_MODE_SIPHON, "danger" = 1)) - data["modes"] += list(list("name" = "Panic Siphon - Siphons air out of the room quickly","mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1)) - data["modes"] += list(list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0)) - if(obj_flags & EMAGGED) - data["modes"] += list(list("name" = "Flood - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FLOOD, "selected" = mode == AALARM_MODE_FLOOD, "danger" = 1)) - - var/datum/tlv/selected - var/list/thresholds = list() - - selected = TLV["pressure"] - thresholds += list(list("name" = "Pressure", "settings" = list())) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min2", "selected" = selected.min2)) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min1", "selected" = selected.min1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max1", "selected" = selected.max1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max2", "selected" = selected.max2)) - - selected = TLV["temperature"] - thresholds += list(list("name" = "Temperature", "settings" = list())) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min2", "selected" = selected.min2)) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min1", "selected" = selected.min1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1)) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2)) - - for(var/gas_id in GLOB.meta_gas_info) - if(!(gas_id in TLV)) // We're not interested in this gas, it seems. - continue - selected = TLV[gas_id] - thresholds += list(list("name" = GLOB.meta_gas_info[gas_id][META_GAS_NAME], "settings" = list())) - thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2)) - thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1)) - thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1)) - thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max2", "selected" = selected.max2)) - - data["thresholds"] = thresholds - return data - -/obj/machinery/airalarm/ui_act(action, params) - if(..() || buildstage != 2) - return - if((locked && !usr.has_unlimited_silicon_privilege) || (usr.has_unlimited_silicon_privilege && aidisabled)) - return - var/device_id = params["id_tag"] - switch(action) - if("lock") - if(usr.has_unlimited_silicon_privilege && !wires.is_cut(WIRE_IDSCAN)) - locked = !locked - . = TRUE - if("power", "toggle_filter", "widenet", "scrubbing") - send_signal(device_id, list("[action]" = params["val"]), usr) - . = TRUE - if("excheck") - send_signal(device_id, list("checks" = text2num(params["val"])^1), usr) - . = TRUE - if("incheck") - send_signal(device_id, list("checks" = text2num(params["val"])^2), usr) - . = TRUE - if("set_external_pressure", "set_internal_pressure") - var/area/A = get_area(src) - var/target = input("New target pressure:", name, A.air_vent_info[device_id][(action == "set_external_pressure" ? "external" : "internal")]) as num|null - if(!isnull(target) && !..()) - send_signal(device_id, list("[action]" = target), usr) - . = TRUE - if("reset_external_pressure") - send_signal(device_id, list("reset_external_pressure"), usr) - . = TRUE - if("reset_internal_pressure") - send_signal(device_id, list("reset_internal_pressure"), usr) - . = TRUE - if("threshold") - var/env = params["env"] - if(text2path(env)) - env = text2path(env) - - var/name = params["var"] - var/datum/tlv/tlv = TLV[env] - if(isnull(tlv)) - return - var/value = input("New [name] for [env]:", name, tlv.vars[name]) as num|null - if(!isnull(value) && !..()) - if(value < 0) - tlv.vars[name] = -1 - else - tlv.vars[name] = round(value, 0.01) - investigate_log(" treshold value for [env]:[name] was set to [value] by [key_name(usr)]",INVESTIGATE_ATMOS) - . = TRUE - if("mode") - mode = text2num(params["mode"]) - investigate_log("was turned to [get_mode_name(mode)] mode by [key_name(usr)]",INVESTIGATE_ATMOS) - apply_mode() - . = TRUE - if("alarm") - var/area/A = get_area(src) - if(A.atmosalert(2, src)) - post_alert(2) - . = TRUE - if("reset") - var/area/A = get_area(src) - if(A.atmosalert(0, src)) - post_alert(0) - . = TRUE - update_icon() - -/obj/machinery/airalarm/proc/reset(wire) - switch(wire) - if(WIRE_POWER) - if(!wires.is_cut(WIRE_POWER)) - shorted = FALSE - update_icon() - if(WIRE_AI) - if(!wires.is_cut(WIRE_AI)) - aidisabled = FALSE - - -/obj/machinery/airalarm/proc/shock(mob/user, prb) - if((stat & (NOPOWER))) // unpowered, no shock - return 0 - if(!prob(prb)) - return 0 //you lucked out, no shock for you - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() //sparks always. - if (electrocute_mob(user, get_area(src), src, 1, TRUE)) - return 1 - else - return 0 - -/obj/machinery/airalarm/proc/refresh_all() - var/area/A = get_area(src) - for(var/id_tag in A.air_vent_names) - var/list/I = A.air_vent_info[id_tag] - if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) - continue - send_signal(id_tag, list("status")) - for(var/id_tag in A.air_scrub_names) - var/list/I = A.air_scrub_info[id_tag] - if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) - continue - send_signal(id_tag, list("status")) - -/obj/machinery/airalarm/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, RADIO_TO_AIRALARM) - -/obj/machinery/airalarm/proc/send_signal(target, list/command, mob/user)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise - if(!radio_connection) - return 0 - - var/datum/signal/signal = new(command) - signal.data["tag"] = target - signal.data["sigtype"] = "command" - signal.data["user"] = user - radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM) - - return 1 - -/obj/machinery/airalarm/proc/get_mode_name(mode_value) - switch(mode_value) - if(AALARM_MODE_SCRUBBING) - return "Filtering" - if(AALARM_MODE_CONTAMINATED) - return "Contaminated" - if(AALARM_MODE_VENTING) - return "Draught" - if(AALARM_MODE_REFILL) - return "Refill" - if(AALARM_MODE_PANIC) - return "Panic Siphon" - if(AALARM_MODE_REPLACEMENT) - return "Cycle" - if(AALARM_MODE_SIPHON) - return "Siphon" - if(AALARM_MODE_OFF) - return "Off" - if(AALARM_MODE_FLOOD) - return "Flood" - -/obj/machinery/airalarm/proc/apply_mode() - var/area/A = get_area(src) - switch(mode) - if(AALARM_MODE_SCRUBBING) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma), - "scrubbing" = 1, - "widenet" = 0, - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE - )) - if(AALARM_MODE_CONTAMINATED) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "set_filters" = list( - /datum/gas/carbon_dioxide, - /datum/gas/miasma, - /datum/gas/plasma, - /datum/gas/water_vapor, - /datum/gas/hypernoblium, - /datum/gas/nitrous_oxide, - /datum/gas/nitryl, - /datum/gas/tritium, - /datum/gas/bz, - /datum/gas/stimulum, - /datum/gas/pluoxium - ), - "scrubbing" = 1, - "widenet" = 1, - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE - )) - if(AALARM_MODE_VENTING) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "widenet" = 0, - "scrubbing" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE*2 - )) - if(AALARM_MODE_REFILL) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma), - "scrubbing" = 1, - "widenet" = 0, - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE * 3 - )) - if(AALARM_MODE_PANIC, - AALARM_MODE_REPLACEMENT) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "widenet" = 1, - "scrubbing" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 0 - )) - if(AALARM_MODE_SIPHON) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 1, - "widenet" = 0, - "scrubbing" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 0 - )) - - if(AALARM_MODE_OFF) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 0 - )) - if(AALARM_MODE_FLOOD) - for(var/device_id in A.air_scrub_names) - send_signal(device_id, list( - "power" = 0 - )) - for(var/device_id in A.air_vent_names) - send_signal(device_id, list( - "power" = 1, - "checks" = 2, - "set_internal_pressure" = 0 - )) - -/obj/machinery/airalarm/update_icon() - set_light(0) - cut_overlays() - SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) - if(stat & NOPOWER) - icon_state = "alarm0" - return - - if(stat & BROKEN) - icon_state = "alarmx" - return - - if(panel_open) - switch(buildstage) - if(2) - icon_state = "alarmx" - if(1) - icon_state = "alarm_b2" - if(0) - icon_state = "alarm_b1" - return - - icon_state = "alarm1" - var/overlay_state = AALARM_OVERLAY_OFF - var/area/A = get_area(src) - switch(max(danger_level, A.atmosalm)) - if(0) - add_overlay(AALARM_OVERLAY_GREEN) - overlay_state = AALARM_OVERLAY_GREEN - light_color = LIGHT_COLOR_PALEBLUE - set_light(brightness_on) - if(1) - add_overlay(AALARM_OVERLAY_WARN) - overlay_state = AALARM_OVERLAY_WARN - light_color = LIGHT_COLOR_LAVA - set_light(brightness_on) - if(2) - add_overlay(AALARM_OVERLAY_DANGER) - overlay_state = AALARM_OVERLAY_DANGER - light_color = LIGHT_COLOR_RED - set_light(brightness_on) - - SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) - update_light() - -/obj/machinery/airalarm/process() - if((stat & (NOPOWER|BROKEN)) || shorted) - return - - var/turf/location = get_turf(src) - if(!location) - return - - var/datum/tlv/cur_tlv - - var/datum/gas_mixture/environment = location.return_air() - var/list/env_gases = environment.gases - var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume - - cur_tlv = TLV["pressure"] - var/environment_pressure = environment.return_pressure() - var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure) - - cur_tlv = TLV["temperature"] - var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature) - - var/gas_dangerlevel = 0 - for(var/gas_id in env_gases) - if(!(gas_id in TLV)) // We're not interested in this gas, it seems. - continue - cur_tlv = TLV[gas_id] - gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(env_gases[gas_id][MOLES] * partial_pressure)) - - environment.garbage_collect() - - var/old_danger_level = danger_level - danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel) - - if(old_danger_level != danger_level) - apply_danger_level() - if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05) - mode = AALARM_MODE_SCRUBBING - apply_mode() - - return - - -/obj/machinery/airalarm/proc/post_alert(alert_level) - var/datum/radio_frequency/frequency = SSradio.return_frequency(alarm_frequency) - - if(!frequency) - return - - var/datum/signal/alert_signal = new(list( - "zone" = get_area_name(src), - "type" = "Atmospheric" - )) - if(alert_level==2) - alert_signal.data["alert"] = "severe" - else if (alert_level==1) - alert_signal.data["alert"] = "minor" - else if (alert_level==0) - alert_signal.data["alert"] = "clear" - - frequency.post_signal(src, alert_signal, range = -1) - -/obj/machinery/airalarm/proc/apply_danger_level() - var/area/A = get_area(src) - - var/new_area_danger_level = 0 - for(var/obj/machinery/airalarm/AA in A) - if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted) - new_area_danger_level = max(new_area_danger_level,AA.danger_level) - if(A.atmosalert(new_area_danger_level,src)) //if area was in normal state or if area was in alert state - post_alert(new_area_danger_level) - - update_icon() - -/obj/machinery/airalarm/attackby(obj/item/W, mob/user, params) - switch(buildstage) - if(2) - if(istype(W, /obj/item/wirecutters) && panel_open && wires.is_all_cut()) - W.play_tool_sound(src) - to_chat(user, "You cut the final wires.") - new /obj/item/stack/cable_coil(loc, 5) - buildstage = 1 - update_icon() - return - else if(istype(W, /obj/item/screwdriver)) // Opening that Air Alarm up. - W.play_tool_sound(src) - panel_open = !panel_open - to_chat(user, "The wires have been [panel_open ? "exposed" : "unexposed"].") - update_icon() - return - else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda))// trying to unlock the interface with an ID card - togglelock(user) - else if(panel_open && is_wire_tool(W)) - wires.interact(user) - return - if(1) - if(istype(W, /obj/item/crowbar)) - user.visible_message("[user.name] removes the electronics from [src.name].",\ - "You start prying out the circuit...") - W.play_tool_sound(src) - if (W.use_tool(src, user, 20)) - if (buildstage == 1) - to_chat(user, "You remove the air alarm electronics.") - new /obj/item/electronics/airalarm( src.loc ) - playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) - buildstage = 0 - update_icon() - return - - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/cable = W - if(cable.get_amount() < 5) - to_chat(user, "You need five lengths of cable to wire the air alarm!") - return - user.visible_message("[user.name] wires the air alarm.", \ - "You start wiring the air alarm...") - if (do_after(user, 20, target = src)) - if (cable.get_amount() >= 5 && buildstage == 1) - cable.use(5) - to_chat(user, "You wire the air alarm.") - wires.repair() - aidisabled = 0 - locked = FALSE - mode = 1 - shorted = 0 - post_alert(0) - buildstage = 2 - update_icon() - return - if(0) - if(istype(W, /obj/item/electronics/airalarm)) - if(user.temporarilyRemoveItemFromInventory(W)) - to_chat(user, "You insert the circuit.") - buildstage = 1 - update_icon() - qdel(W) - return - - if(istype(W, /obj/item/electroadaptive_pseudocircuit)) - var/obj/item/electroadaptive_pseudocircuit/P = W - if(!P.adapt_circuit(user, 25)) - return - user.visible_message("[user] fabricates a circuit and places it into [src].", \ - "You adapt an air alarm circuit and slot it into the assembly.") - buildstage = 1 - update_icon() - return - - if(istype(W, /obj/item/wrench)) - to_chat(user, "You detach \the [src] from the wall.") - W.play_tool_sound(src) - new /obj/item/wallframe/airalarm( user.loc ) - qdel(src) - return - - return ..() - -/obj/machinery/airalarm/AltClick(mob/user) - ..() - if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) - return - else - togglelock(user) - -/obj/machinery/airalarm/proc/togglelock(mob/living/user) - if(stat & (NOPOWER|BROKEN)) - to_chat(user, "It does nothing!") - else - if(src.allowed(usr) && !wires.is_cut(WIRE_IDSCAN)) - locked = !locked - updateUsrDialog() - to_chat(user, "You [ locked ? "lock" : "unlock"] the air alarm interface.") - else - to_chat(user, "Access denied.") - return - -/obj/machinery/airalarm/power_change() - ..() - if(stat & NOPOWER) - set_light(0) - update_icon() - -/obj/machinery/airalarm/emag_act(mob/user) - if(obj_flags & EMAGGED) - return - obj_flags |= EMAGGED - visible_message("Sparks fly out of [src]!", "You emag [src], disabling its safeties.") - playsound(src, "sparks", 50, 1) - -/obj/machinery/airalarm/obj_break(damage_flag) - ..() - update_icon() - set_light(0) - -/obj/machinery/airalarm/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - new /obj/item/stack/sheet/metal(loc, 2) - var/obj/item/I = new /obj/item/electronics/airalarm(loc) - if(!disassembled) - I.obj_integrity = I.max_integrity * 0.5 - new /obj/item/stack/cable_coil(loc, 3) - qdel(src) - -#undef AALARM_MODE_SCRUBBING -#undef AALARM_MODE_VENTING -#undef AALARM_MODE_PANIC -#undef AALARM_MODE_REPLACEMENT -#undef AALARM_MODE_OFF -#undef AALARM_MODE_FLOOD -#undef AALARM_MODE_SIPHON -#undef AALARM_MODE_CONTAMINATED -#undef AALARM_MODE_REFILL -#undef AALARM_REPORT_TIMEOUT +/datum/tlv + var/min2 + var/min1 + var/max1 + var/max2 + +/datum/tlv/New(min2 as num, min1 as num, max1 as num, max2 as num) + if(min2) src.min2 = min2 + if(min1) src.min1 = min1 + if(max1) src.max1 = max1 + if(max2) src.max2 = max2 + +/datum/tlv/proc/get_danger_level(val as num) + if(max2 != -1 && val >= max2) + return 2 + if(min2 != -1 && val <= min2) + return 2 + if(max1 != -1 && val >= max1) + return 1 + if(min1 != -1 && val <= min1) + return 1 + return 0 + +/datum/tlv/no_checks + min2 = -1 + min1 = -1 + max1 = -1 + max2 = -1 + +/datum/tlv/dangerous + min2 = -1 + min1 = -1 + max1 = 0.2 + max2 = 0.5 + +/obj/item/electronics/airalarm + name = "air alarm electronics" + icon_state = "airalarm_electronics" + +/obj/item/wallframe/airalarm + name = "air alarm frame" + desc = "Used for building Air Alarms." + icon = 'icons/obj/monitors.dmi' + icon_state = "alarm_bitem" + result_path = /obj/machinery/airalarm + +#define AALARM_MODE_SCRUBBING 1 +#define AALARM_MODE_VENTING 2 //makes draught +#define AALARM_MODE_PANIC 3 //like siphon, but stronger (enables widenet) +#define AALARM_MODE_REPLACEMENT 4 //sucks off all air, then refill and swithes to scrubbing +#define AALARM_MODE_OFF 5 +#define AALARM_MODE_FLOOD 6 //Emagged mode; turns off scrubbers and pressure checks on vents +#define AALARM_MODE_SIPHON 7 //Scrubbers suck air +#define AALARM_MODE_CONTAMINATED 8 //Turns on all filtering and widenet scrubbing. +#define AALARM_MODE_REFILL 9 //just like normal, but with triple the air output + +#define AALARM_REPORT_TIMEOUT 100 + +#define AALARM_OVERLAY_OFF "alarm_off" +#define AALARM_OVERLAY_GREEN "alarm_green" +#define AALARM_OVERLAY_WARN "alarm_amber" +#define AALARM_OVERLAY_DANGER "alarm_red" + +/obj/machinery/airalarm + name = "air alarm" + desc = "A machine that monitors atmosphere levels. Goes off if the area is dangerous." + icon = 'icons/obj/monitors.dmi' + icon_state = "alarm0" + use_power = IDLE_POWER_USE + idle_power_usage = 4 + active_power_usage = 8 + power_channel = ENVIRON + req_access = list(ACCESS_ATMOSPHERICS) + max_integrity = 250 + integrity_failure = 80 + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + resistance_flags = FIRE_PROOF + + var/danger_level = 0 + var/mode = AALARM_MODE_SCRUBBING + + var/locked = TRUE + var/aidisabled = 0 + var/shorted = 0 + var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone + var/brightness_on = 1 + + var/frequency = FREQ_ATMOS_CONTROL + var/alarm_frequency = FREQ_ATMOS_ALARMS + var/datum/radio_frequency/radio_connection + + var/list/TLV = list( // Breathable air. + "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa + "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), + /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa + /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), + /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), + /datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5), + /datum/gas/plasma = new/datum/tlv/dangerous, + /datum/gas/nitrous_oxide = new/datum/tlv/dangerous, + /datum/gas/bz = new/datum/tlv/dangerous, + /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic + /datum/gas/water_vapor = new/datum/tlv/dangerous, + /datum/gas/tritium = new/datum/tlv/dangerous, + /datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects + /datum/gas/nitryl = new/datum/tlv/dangerous, + /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires + ) + +/obj/machinery/airalarm/server // No checks here. + TLV = list( + "pressure" = new/datum/tlv/no_checks, + "temperature" = new/datum/tlv/no_checks, + /datum/gas/oxygen = new/datum/tlv/no_checks, + /datum/gas/nitrogen = new/datum/tlv/no_checks, + /datum/gas/carbon_dioxide = new/datum/tlv/no_checks, + /datum/gas/miasma = new/datum/tlv/no_checks, + /datum/gas/plasma = new/datum/tlv/no_checks, + /datum/gas/nitrous_oxide = new/datum/tlv/no_checks, + /datum/gas/bz = new/datum/tlv/no_checks, + /datum/gas/hypernoblium = new/datum/tlv/no_checks, + /datum/gas/water_vapor = new/datum/tlv/no_checks, + /datum/gas/tritium = new/datum/tlv/no_checks, + /datum/gas/stimulum = new/datum/tlv/no_checks, + /datum/gas/nitryl = new/datum/tlv/no_checks, + /datum/gas/pluoxium = new/datum/tlv/no_checks + ) + +/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures. + TLV = list( + "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa + "temperature" = new/datum/tlv(T0C-73.15, T0C-63.15, T0C, T0C+10), + /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa + /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), + /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), + /datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5), + /datum/gas/plasma = new/datum/tlv/dangerous, + /datum/gas/nitrous_oxide = new/datum/tlv/dangerous, + /datum/gas/bz = new/datum/tlv/dangerous, + /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic + /datum/gas/water_vapor = new/datum/tlv/dangerous, + /datum/gas/tritium = new/datum/tlv/dangerous, + /datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects + /datum/gas/nitryl = new/datum/tlv/dangerous, + /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000) // Unlike oxygen, pluoxium does not fuel plasma/tritium fires + ) + +/obj/machinery/airalarm/unlocked + locked = FALSE + +/obj/machinery/airalarm/engine + name = "engine air alarm" + locked = FALSE + req_access = null + req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_ENGINE) + +/obj/machinery/airalarm/mixingchamber + name = "chamber air alarm" + locked = FALSE + req_access = null + req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_TOX, ACCESS_TOX_STORAGE) + +/obj/machinery/airalarm/all_access + name = "all-access air alarm" + desc = "This particular atmos control unit appears to have no access restrictions." + locked = FALSE + req_access = null + req_one_access = null + +/obj/machinery/airalarm/syndicate //general syndicate access + req_access = list(ACCESS_SYNDICATE) + +/obj/machinery/airalarm/directional/north //Pixel offsets get overwritten on New() + dir = SOUTH + pixel_y = 24 + +/obj/machinery/airalarm/directional/south + dir = NORTH + pixel_y = -24 + +/obj/machinery/airalarm/directional/east + dir = WEST + pixel_x = 24 + +/obj/machinery/airalarm/directional/west + dir = EAST + pixel_x = -24 + +//all air alarms in area are connected via magic +/area + var/list/air_vent_names = list() + var/list/air_scrub_names = list() + var/list/air_vent_info = list() + var/list/air_scrub_info = list() + +/obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) + . = ..() + wires = new /datum/wires/airalarm(src) + + if(ndir) + setDir(ndir) + + if(nbuild) + buildstage = 0 + panel_open = TRUE + pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) + pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0 + + if(name == initial(name)) + name = "[get_area_name(src)] Air Alarm" + + power_change() + set_frequency(frequency) + +/obj/machinery/airalarm/Destroy() + SSradio.remove_object(src, frequency) + qdel(wires) + wires = null + return ..() + +/obj/machinery/airalarm/examine(mob/user) + . = ..() + switch(buildstage) + if(0) + to_chat(user, "It is missing air alarm electronics.") + if(1) + to_chat(user, "It is missing wiring.") + if(2) + to_chat(user, "Alt-click to [locked ? "unlock" : "lock"] the interface.") + +/obj/machinery/airalarm/ui_status(mob/user) + if(user.has_unlimited_silicon_privilege && aidisabled) + to_chat(user, "AI control has been disabled.") + else if(!shorted) + return ..() + return UI_CLOSE + +/obj/machinery/airalarm/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "airalarm", name, 440, 650, master_ui, state) + ui.open() + +/obj/machinery/airalarm/ui_data(mob/user) + var/data = list( + "locked" = locked, + "siliconUser" = user.has_unlimited_silicon_privilege, + "emagged" = (obj_flags & EMAGGED ? 1 : 0), + "danger_level" = danger_level, + ) + + var/area/A = get_area(src) + data["atmos_alarm"] = A.atmosalm + data["fire_alarm"] = A.fire + + var/turf/T = get_turf(src) + var/datum/gas_mixture/environment = T.return_air() + var/datum/tlv/cur_tlv + + data["environment_data"] = list() + var/pressure = environment.return_pressure() + cur_tlv = TLV["pressure"] + data["environment_data"] += list(list( + "name" = "Pressure", + "value" = pressure, + "unit" = "kPa", + "danger_level" = cur_tlv.get_danger_level(pressure) + )) + var/temperature = environment.temperature + cur_tlv = TLV["temperature"] + data["environment_data"] += list(list( + "name" = "Temperature", + "value" = temperature, + "unit" = "K ([round(temperature - T0C, 0.1)]C)", + "danger_level" = cur_tlv.get_danger_level(temperature) + )) + var/total_moles = environment.total_moles() + var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume + for(var/gas_id in environment.gases) + if(!(gas_id in TLV)) // We're not interested in this gas, it seems. + continue + cur_tlv = TLV[gas_id] + data["environment_data"] += list(list( + "name" = GLOB.meta_gas_names[gas_id], + "value" = environment.gases[gas_id] / total_moles * 100, + "unit" = "%", + "danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id] * partial_pressure) + )) + + if(!locked || user.has_unlimited_silicon_privilege) + data["vents"] = list() + for(var/id_tag in A.air_vent_names) + var/long_name = A.air_vent_names[id_tag] + var/list/info = A.air_vent_info[id_tag] + if(!info || info["frequency"] != frequency) + continue + data["vents"] += list(list( + "id_tag" = id_tag, + "long_name" = sanitize(long_name), + "power" = info["power"], + "checks" = info["checks"], + "excheck" = info["checks"]&1, + "incheck" = info["checks"]&2, + "direction" = info["direction"], + "external" = info["external"], + "internal" = info["internal"], + "extdefault"= (info["external"] == ONE_ATMOSPHERE), + "intdefault"= (info["internal"] == 0) + )) + data["scrubbers"] = list() + for(var/id_tag in A.air_scrub_names) + var/long_name = A.air_scrub_names[id_tag] + var/list/info = A.air_scrub_info[id_tag] + if(!info || info["frequency"] != frequency) + continue + data["scrubbers"] += list(list( + "id_tag" = id_tag, + "long_name" = sanitize(long_name), + "power" = info["power"], + "scrubbing" = info["scrubbing"], + "widenet" = info["widenet"], + "filter_types" = info["filter_types"] + )) + data["mode"] = mode + data["modes"] = list() + data["modes"] += list(list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0)) + data["modes"] += list(list("name" = "Contaminated - Scrubs out ALL contaminants quickly","mode" = AALARM_MODE_CONTAMINATED, "selected" = mode == AALARM_MODE_CONTAMINATED, "danger" = 0)) + data["modes"] += list(list("name" = "Draught - Siphons out air while replacing", "mode" = AALARM_MODE_VENTING, "selected" = mode == AALARM_MODE_VENTING, "danger" = 0)) + data["modes"] += list(list("name" = "Refill - Triple vent output", "mode" = AALARM_MODE_REFILL, "selected" = mode == AALARM_MODE_REFILL, "danger" = 1)) + data["modes"] += list(list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 1)) + data["modes"] += list(list("name" = "Siphon - Siphons air out of the room", "mode" = AALARM_MODE_SIPHON, "selected" = mode == AALARM_MODE_SIPHON, "danger" = 1)) + data["modes"] += list(list("name" = "Panic Siphon - Siphons air out of the room quickly","mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1)) + data["modes"] += list(list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0)) + if(obj_flags & EMAGGED) + data["modes"] += list(list("name" = "Flood - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FLOOD, "selected" = mode == AALARM_MODE_FLOOD, "danger" = 1)) + + var/datum/tlv/selected + var/list/thresholds = list() + + selected = TLV["pressure"] + thresholds += list(list("name" = "Pressure", "settings" = list())) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min2", "selected" = selected.min2)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min1", "selected" = selected.min1)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max1", "selected" = selected.max1)) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max2", "selected" = selected.max2)) + + selected = TLV["temperature"] + thresholds += list(list("name" = "Temperature", "settings" = list())) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min2", "selected" = selected.min2)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min1", "selected" = selected.min1)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1)) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2)) + + for(var/gas_id in GLOB.meta_gas_names) + if(!(gas_id in TLV)) // We're not interested in this gas, it seems. + continue + selected = TLV[gas_id] + thresholds += list(list("name" = GLOB.meta_gas_names[gas_id], "settings" = list())) + thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2)) + thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1)) + thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1)) + thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max2", "selected" = selected.max2)) + + data["thresholds"] = thresholds + return data + +/obj/machinery/airalarm/ui_act(action, params) + if(..() || buildstage != 2) + return + if((locked && !usr.has_unlimited_silicon_privilege) || (usr.has_unlimited_silicon_privilege && aidisabled)) + return + var/device_id = params["id_tag"] + switch(action) + if("lock") + if(usr.has_unlimited_silicon_privilege && !wires.is_cut(WIRE_IDSCAN)) + locked = !locked + . = TRUE + if("power", "toggle_filter", "widenet", "scrubbing") + send_signal(device_id, list("[action]" = params["val"]), usr) + . = TRUE + if("excheck") + send_signal(device_id, list("checks" = text2num(params["val"])^1), usr) + . = TRUE + if("incheck") + send_signal(device_id, list("checks" = text2num(params["val"])^2), usr) + . = TRUE + if("set_external_pressure", "set_internal_pressure") + var/area/A = get_area(src) + var/target = input("New target pressure:", name, A.air_vent_info[device_id][(action == "set_external_pressure" ? "external" : "internal")]) as num|null + if(!isnull(target) && !..()) + send_signal(device_id, list("[action]" = target), usr) + . = TRUE + if("reset_external_pressure") + send_signal(device_id, list("reset_external_pressure"), usr) + . = TRUE + if("reset_internal_pressure") + send_signal(device_id, list("reset_internal_pressure"), usr) + . = TRUE + if("threshold") + var/env = params["env"] + if(text2path(env)) + env = text2path(env) + + var/name = params["var"] + var/datum/tlv/tlv = TLV[env] + if(isnull(tlv)) + return + var/value = input("New [name] for [env]:", name, tlv.vars[name]) as num|null + if(!isnull(value) && !..()) + if(value < 0) + tlv.vars[name] = -1 + else + tlv.vars[name] = round(value, 0.01) + investigate_log(" treshold value for [env]:[name] was set to [value] by [key_name(usr)]",INVESTIGATE_ATMOS) + . = TRUE + if("mode") + mode = text2num(params["mode"]) + investigate_log("was turned to [get_mode_name(mode)] mode by [key_name(usr)]",INVESTIGATE_ATMOS) + apply_mode() + . = TRUE + if("alarm") + var/area/A = get_area(src) + if(A.atmosalert(2, src)) + post_alert(2) + . = TRUE + if("reset") + var/area/A = get_area(src) + if(A.atmosalert(0, src)) + post_alert(0) + . = TRUE + update_icon() + +/obj/machinery/airalarm/proc/reset(wire) + switch(wire) + if(WIRE_POWER) + if(!wires.is_cut(WIRE_POWER)) + shorted = FALSE + update_icon() + if(WIRE_AI) + if(!wires.is_cut(WIRE_AI)) + aidisabled = FALSE + + +/obj/machinery/airalarm/proc/shock(mob/user, prb) + if((stat & (NOPOWER))) // unpowered, no shock + return 0 + if(!prob(prb)) + return 0 //you lucked out, no shock for you + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(5, 1, src) + s.start() //sparks always. + if (electrocute_mob(user, get_area(src), src, 1, TRUE)) + return 1 + else + return 0 + +/obj/machinery/airalarm/proc/refresh_all() + var/area/A = get_area(src) + for(var/id_tag in A.air_vent_names) + var/list/I = A.air_vent_info[id_tag] + if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) + continue + send_signal(id_tag, list("status")) + for(var/id_tag in A.air_scrub_names) + var/list/I = A.air_scrub_info[id_tag] + if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) + continue + send_signal(id_tag, list("status")) + +/obj/machinery/airalarm/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + radio_connection = SSradio.add_object(src, frequency, RADIO_TO_AIRALARM) + +/obj/machinery/airalarm/proc/send_signal(target, list/command, mob/user)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise + if(!radio_connection) + return 0 + + var/datum/signal/signal = new(command) + signal.data["tag"] = target + signal.data["sigtype"] = "command" + signal.data["user"] = user + radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM) + + return 1 + +/obj/machinery/airalarm/proc/get_mode_name(mode_value) + switch(mode_value) + if(AALARM_MODE_SCRUBBING) + return "Filtering" + if(AALARM_MODE_CONTAMINATED) + return "Contaminated" + if(AALARM_MODE_VENTING) + return "Draught" + if(AALARM_MODE_REFILL) + return "Refill" + if(AALARM_MODE_PANIC) + return "Panic Siphon" + if(AALARM_MODE_REPLACEMENT) + return "Cycle" + if(AALARM_MODE_SIPHON) + return "Siphon" + if(AALARM_MODE_OFF) + return "Off" + if(AALARM_MODE_FLOOD) + return "Flood" + +/obj/machinery/airalarm/proc/apply_mode() + var/area/A = get_area(src) + switch(mode) + if(AALARM_MODE_SCRUBBING) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma), + "scrubbing" = 1, + "widenet" = 0, + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE + )) + if(AALARM_MODE_CONTAMINATED) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "set_filters" = list( + /datum/gas/carbon_dioxide, + /datum/gas/miasma, + /datum/gas/plasma, + /datum/gas/water_vapor, + /datum/gas/hypernoblium, + /datum/gas/nitrous_oxide, + /datum/gas/nitryl, + /datum/gas/tritium, + /datum/gas/bz, + /datum/gas/stimulum, + /datum/gas/pluoxium + ), + "scrubbing" = 1, + "widenet" = 1, + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE + )) + if(AALARM_MODE_VENTING) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "widenet" = 0, + "scrubbing" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE*2 + )) + if(AALARM_MODE_REFILL) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma), + "scrubbing" = 1, + "widenet" = 0, + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE * 3 + )) + if(AALARM_MODE_PANIC, + AALARM_MODE_REPLACEMENT) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "widenet" = 1, + "scrubbing" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 0 + )) + if(AALARM_MODE_SIPHON) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 1, + "widenet" = 0, + "scrubbing" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 0 + )) + + if(AALARM_MODE_OFF) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 0 + )) + if(AALARM_MODE_FLOOD) + for(var/device_id in A.air_scrub_names) + send_signal(device_id, list( + "power" = 0 + )) + for(var/device_id in A.air_vent_names) + send_signal(device_id, list( + "power" = 1, + "checks" = 2, + "set_internal_pressure" = 0 + )) + +/obj/machinery/airalarm/update_icon() + set_light(0) + cut_overlays() + SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + if(stat & NOPOWER) + icon_state = "alarm0" + return + + if(stat & BROKEN) + icon_state = "alarmx" + return + + if(panel_open) + switch(buildstage) + if(2) + icon_state = "alarmx" + if(1) + icon_state = "alarm_b2" + if(0) + icon_state = "alarm_b1" + return + + icon_state = "alarm1" + var/overlay_state = AALARM_OVERLAY_OFF + var/area/A = get_area(src) + switch(max(danger_level, A.atmosalm)) + if(0) + add_overlay(AALARM_OVERLAY_GREEN) + overlay_state = AALARM_OVERLAY_GREEN + light_color = LIGHT_COLOR_PALEBLUE + set_light(brightness_on) + if(1) + add_overlay(AALARM_OVERLAY_WARN) + overlay_state = AALARM_OVERLAY_WARN + light_color = LIGHT_COLOR_LAVA + set_light(brightness_on) + if(2) + add_overlay(AALARM_OVERLAY_DANGER) + overlay_state = AALARM_OVERLAY_DANGER + light_color = LIGHT_COLOR_RED + set_light(brightness_on) + + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) + update_light() + +/obj/machinery/airalarm/process() + if((stat & (NOPOWER|BROKEN)) || shorted) + return + + var/turf/location = get_turf(src) + if(!location) + return + + var/datum/tlv/cur_tlv + + var/datum/gas_mixture/environment = location.return_air() + var/list/env_gases = environment.gases + var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume + + cur_tlv = TLV["pressure"] + var/environment_pressure = environment.return_pressure() + var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure) + + cur_tlv = TLV["temperature"] + var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature) + + var/gas_dangerlevel = 0 + for(var/gas_id in env_gases) + if(!(gas_id in TLV)) // We're not interested in this gas, it seems. + continue + cur_tlv = TLV[gas_id] + gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(env_gases[gas_id] * partial_pressure)) + + GAS_GARBAGE_COLLECT(environment.gases) + + var/old_danger_level = danger_level + danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel) + + if(old_danger_level != danger_level) + apply_danger_level() + if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05) + mode = AALARM_MODE_SCRUBBING + apply_mode() + + return + + +/obj/machinery/airalarm/proc/post_alert(alert_level) + var/datum/radio_frequency/frequency = SSradio.return_frequency(alarm_frequency) + + if(!frequency) + return + + var/datum/signal/alert_signal = new(list( + "zone" = get_area_name(src), + "type" = "Atmospheric" + )) + if(alert_level==2) + alert_signal.data["alert"] = "severe" + else if (alert_level==1) + alert_signal.data["alert"] = "minor" + else if (alert_level==0) + alert_signal.data["alert"] = "clear" + + frequency.post_signal(src, alert_signal, range = -1) + +/obj/machinery/airalarm/proc/apply_danger_level() + var/area/A = get_area(src) + + var/new_area_danger_level = 0 + for(var/obj/machinery/airalarm/AA in A) + if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted) + new_area_danger_level = max(new_area_danger_level,AA.danger_level) + if(A.atmosalert(new_area_danger_level,src)) //if area was in normal state or if area was in alert state + post_alert(new_area_danger_level) + + update_icon() + +/obj/machinery/airalarm/attackby(obj/item/W, mob/user, params) + switch(buildstage) + if(2) + if(istype(W, /obj/item/wirecutters) && panel_open && wires.is_all_cut()) + W.play_tool_sound(src) + to_chat(user, "You cut the final wires.") + new /obj/item/stack/cable_coil(loc, 5) + buildstage = 1 + update_icon() + return + else if(istype(W, /obj/item/screwdriver)) // Opening that Air Alarm up. + W.play_tool_sound(src) + panel_open = !panel_open + to_chat(user, "The wires have been [panel_open ? "exposed" : "unexposed"].") + update_icon() + return + else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda))// trying to unlock the interface with an ID card + togglelock(user) + else if(panel_open && is_wire_tool(W)) + wires.interact(user) + return + if(1) + if(istype(W, /obj/item/crowbar)) + user.visible_message("[user.name] removes the electronics from [src.name].",\ + "You start prying out the circuit...") + W.play_tool_sound(src) + if (W.use_tool(src, user, 20)) + if (buildstage == 1) + to_chat(user, "You remove the air alarm electronics.") + new /obj/item/electronics/airalarm( src.loc ) + playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) + buildstage = 0 + update_icon() + return + + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/cable = W + if(cable.get_amount() < 5) + to_chat(user, "You need five lengths of cable to wire the air alarm!") + return + user.visible_message("[user.name] wires the air alarm.", \ + "You start wiring the air alarm...") + if (do_after(user, 20, target = src)) + if (cable.get_amount() >= 5 && buildstage == 1) + cable.use(5) + to_chat(user, "You wire the air alarm.") + wires.repair() + aidisabled = 0 + locked = FALSE + mode = 1 + shorted = 0 + post_alert(0) + buildstage = 2 + update_icon() + return + if(0) + if(istype(W, /obj/item/electronics/airalarm)) + if(user.temporarilyRemoveItemFromInventory(W)) + to_chat(user, "You insert the circuit.") + buildstage = 1 + update_icon() + qdel(W) + return + + if(istype(W, /obj/item/electroadaptive_pseudocircuit)) + var/obj/item/electroadaptive_pseudocircuit/P = W + if(!P.adapt_circuit(user, 25)) + return + user.visible_message("[user] fabricates a circuit and places it into [src].", \ + "You adapt an air alarm circuit and slot it into the assembly.") + buildstage = 1 + update_icon() + return + + if(istype(W, /obj/item/wrench)) + to_chat(user, "You detach \the [src] from the wall.") + W.play_tool_sound(src) + new /obj/item/wallframe/airalarm( user.loc ) + qdel(src) + return + + return ..() + +/obj/machinery/airalarm/AltClick(mob/user) + ..() + if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) + return + else + togglelock(user) + +/obj/machinery/airalarm/proc/togglelock(mob/living/user) + if(stat & (NOPOWER|BROKEN)) + to_chat(user, "It does nothing!") + else + if(src.allowed(usr) && !wires.is_cut(WIRE_IDSCAN)) + locked = !locked + updateUsrDialog() + to_chat(user, "You [ locked ? "lock" : "unlock"] the air alarm interface.") + else + to_chat(user, "Access denied.") + return + +/obj/machinery/airalarm/power_change() + ..() + if(stat & NOPOWER) + set_light(0) + update_icon() + +/obj/machinery/airalarm/emag_act(mob/user) + if(obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + visible_message("Sparks fly out of [src]!", "You emag [src], disabling its safeties.") + playsound(src, "sparks", 50, 1) + +/obj/machinery/airalarm/obj_break(damage_flag) + ..() + update_icon() + set_light(0) + +/obj/machinery/airalarm/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + new /obj/item/stack/sheet/metal(loc, 2) + var/obj/item/I = new /obj/item/electronics/airalarm(loc) + if(!disassembled) + I.obj_integrity = I.max_integrity * 0.5 + new /obj/item/stack/cable_coil(loc, 3) + qdel(src) + +#undef AALARM_MODE_SCRUBBING +#undef AALARM_MODE_VENTING +#undef AALARM_MODE_PANIC +#undef AALARM_MODE_REPLACEMENT +#undef AALARM_MODE_OFF +#undef AALARM_MODE_FLOOD +#undef AALARM_MODE_SIPHON +#undef AALARM_MODE_CONTAMINATED +#undef AALARM_MODE_REFILL +#undef AALARM_REPORT_TIMEOUT diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index e7df188f70..abdc3ada57 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -27,7 +27,26 @@ Thus, the two variables affect pump operation are set in New(): construction_type = /obj/item/pipe/directional pipe_state = "pump" - + +/obj/machinery/atmospherics/components/binary/pump/CtrlClick(mob/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + on = !on + update_icon() + investigate_log("Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + return ..() + +/obj/machinery/atmospherics/components/binary/pump/AltClick(mob/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + target_pressure = MAX_OUTPUT_PRESSURE + to_chat(user,"You maximize the pressure on the [src].") + investigate_log("Pump, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Pump, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + /obj/machinery/atmospherics/components/binary/pump/layer1 piping_layer = PIPING_LAYER_MIN pixel_x = -PIPING_LAYER_P_X diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index 46b646cabf..2efff16301 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -28,6 +28,16 @@ Thus, the two variables affect pump operation are set in New(): construction_type = /obj/item/pipe/directional pipe_state = "volumepump" +/obj/machinery/atmospherics/components/binary/volume_pump/CtrlClick(mob/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + on = !on + update_icon() + investigate_log("Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + return ..() + /obj/machinery/atmospherics/components/binary/volume_pump/layer1 piping_layer = PIPING_LAYER_MIN pixel_x = -PIPING_LAYER_P_X @@ -192,4 +202,4 @@ Thus, the two variables affect pump operation are set in New(): else investigate_log("Pump, [src.name], was unwrenched by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) message_admins("Pump, [src.name], was unwrenched by [ADMIN_LOOKUPFLW(user)] at [A]") - return TRUE \ No newline at end of file + return TRUE diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 4101deb00c..52e8d9eb83 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -12,6 +12,25 @@ construction_type = /obj/item/pipe/trinary/flippable pipe_state = "filter" +/obj/machinery/atmospherics/components/trinary/filter/CtrlClick(mob/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + on = !on + update_icon() + investigate_log("Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + return ..() + +/obj/machinery/atmospherics/components/trinary/filter/AltClick(mob/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + target_pressure = MAX_OUTPUT_PRESSURE + to_chat(user,"You maximize the pressure on the [src].") + investigate_log("Pump, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Pump, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + /obj/machinery/atmospherics/components/trinary/filter/layer1 piping_layer = PIPING_LAYER_MIN pixel_x = -PIPING_LAYER_P_X @@ -159,11 +178,10 @@ var/datum/gas_mixture/filtered_out = new filtered_out.temperature = removed.temperature - filtered_out.add_gas(filter_type) - filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES] + filtered_out.gases[filter_type] = removed.gases[filter_type] - removed.gases[filter_type][MOLES] = 0 - removed.garbage_collect() + removed.gases[filter_type] = 0 + GAS_GARBAGE_COLLECT(removed.gases) var/datum/gas_mixture/target = (air2.return_pressure() < target_pressure ? air2 : air1) //if there's no room for the filtered gas; just leave it in air1 target.merge(filtered_out) @@ -191,9 +209,8 @@ data["filter_types"] = list() data["filter_types"] += list(list("name" = "Nothing", "path" = "", "selected" = !filter_type)) - for(var/path in GLOB.meta_gas_info) - var/list/gas = GLOB.meta_gas_info[path] - data["filter_types"] += list(list("name" = gas[META_GAS_NAME], "id" = gas[META_GAS_ID], "selected" = (path == gas_id2path(filter_type)))) + for(var/path in GLOB.meta_gas_ids) + data["filter_types"] += list(list("name" = GLOB.meta_gas_names[path], "id" = GLOB.meta_gas_ids[path], "selected" = (path == gas_id2path(filter_type)))) return data @@ -224,9 +241,9 @@ filter_type = null var/filter_name = "nothing" var/gas = gas_id2path(params["mode"]) - if(gas in GLOB.meta_gas_info) + if(gas in GLOB.meta_gas_names) filter_type = gas - filter_name = GLOB.meta_gas_info[gas][META_GAS_NAME] + filter_name = GLOB.meta_gas_names[gas] investigate_log("was set to filter [filter_name] by [key_name(usr)]", INVESTIGATE_ATMOS) . = TRUE update_icon() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 4dd2972526..ba9fdf31af 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -14,7 +14,25 @@ pipe_state = "mixer" //node 3 is the outlet, nodes 1 & 2 are intakes - +/obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + on = !on + update_icon() + investigate_log("Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + return ..() + +/obj/machinery/atmospherics/components/trinary/mixer/AltClick(mob/user) + var/area/A = get_area(src) + var/turf/T = get_turf(src) + if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + target_pressure = MAX_OUTPUT_PRESSURE + to_chat(user,"You maximize the pressure on the [src].") + investigate_log("Pump, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) + message_admins("Pump, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + /obj/machinery/atmospherics/components/trinary/mixer/layer1 piping_layer = PIPING_LAYER_MIN pixel_x = -PIPING_LAYER_P_X diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 9b69b2fa6f..bfe60cd573 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -183,8 +183,8 @@ if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic. beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents. beaker.reagents.reaction(occupant, VAPOR) - air1.gases[/datum/gas/oxygen][MOLES] -= max(0,air1.gases[/datum/gas/oxygen][MOLES] - 2 / efficiency) //Let's use gas for this - air1.garbage_collect() + air1.gases[/datum/gas/oxygen] -= max(0,air1.gases[/datum/gas/oxygen] - 2 / efficiency) //Let's use gas for this + GAS_GARBAGE_COLLECT(air1.gases) if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). reagent_transfer = 0 @@ -198,7 +198,7 @@ var/datum/gas_mixture/air1 = airs[1] - if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen][MOLES] < 5) // Turn off if the machine won't work. + if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen] < 5) // Turn off if the machine won't work. on = FALSE update_icon() return @@ -220,8 +220,8 @@ air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB) mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB) - air1.gases[/datum/gas/oxygen][MOLES] = max(0,air1.gases[/datum/gas/oxygen][MOLES] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic. - air1.garbage_collect() + air1.gases[/datum/gas/oxygen] = max(0,air1.gases[/datum/gas/oxygen] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic. + GAS_GARBAGE_COLLECT(air1.gases) /obj/machinery/atmospherics/components/unary/cryo_cell/power_change() ..() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm index 1a9d1cff30..4f16406456 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm @@ -17,9 +17,8 @@ air_contents.volume = volume air_contents.temperature = T20C if(gas_type) - air_contents.assert_gas(gas_type) - air_contents.gases[gas_type][MOLES] = AIR_CONTENTS - name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])" + air_contents.gases[gas_type] = AIR_CONTENTS + name = "[name] ([GLOB.meta_gas_names[gas_type]])" /obj/machinery/atmospherics/components/unary/tank/carbon_dioxide gas_type = /datum/gas/carbon_dioxide @@ -44,6 +43,5 @@ /obj/machinery/atmospherics/components/unary/tank/air/New() ..() var/datum/gas_mixture/air_contents = airs[1] - air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - air_contents.gases[/datum/gas/oxygen][MOLES] = AIR_CONTENTS * 0.2 - air_contents.gases[/datum/gas/nitrogen][MOLES] = AIR_CONTENTS * 0.8 + air_contents.gases[/datum/gas/oxygen] = AIR_CONTENTS * 0.2 + air_contents.gases[/datum/gas/nitrogen] = AIR_CONTENTS * 0.8 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index ee819d4f74..7f40630a86 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -1,330 +1,328 @@ -#define SIPHONING 0 -#define SCRUBBING 1 - -/obj/machinery/atmospherics/components/unary/vent_scrubber - name = "air scrubber" - desc = "Has a valve and pump attached to it." - icon_state = "scrub_map" - use_power = IDLE_POWER_USE - idle_power_usage = 10 - active_power_usage = 60 - can_unwrench = TRUE - welded = FALSE - level = 1 - layer = GAS_SCRUBBER_LAYER - - var/id_tag = null - var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing - - var/filter_types = list(/datum/gas/carbon_dioxide) - var/volume_rate = 200 - var/widenet = 0 //is this scrubber acting on the 3x3 area around it. - var/list/turf/adjacent_turfs = list() - - var/frequency = FREQ_ATMOS_CONTROL - var/datum/radio_frequency/radio_connection - var/radio_filter_out - var/radio_filter_in - - pipe_state = "scrubber" - -/obj/machinery/atmospherics/components/unary/vent_scrubber/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_scrubber/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_scrubber/New() - ..() - if(!id_tag) - id_tag = assign_uid_vents() - - for(var/f in filter_types) - if(istext(f)) - filter_types -= f - filter_types += gas_id2path(f) - -/obj/machinery/atmospherics/components/unary/vent_scrubber/on - on = TRUE - icon_state = "scrub_map_on" - -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy() - var/area/A = get_area(src) - if (A) - A.air_scrub_names -= id_tag - A.air_scrub_info -= id_tag - - SSradio.remove_object(src,frequency) - radio_connection = null - adjacent_turfs.Cut() - return ..() - -/obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power() - if(!on || welded || !is_operational() || !powered(power_channel)) - return FALSE - - var/amount = idle_power_usage - - if(scrubbing & SCRUBBING) - amount += idle_power_usage * length(filter_types) - else //scrubbing == SIPHONING - amount = active_power_usage - - if(widenet) - amount += amount * (adjacent_turfs.len * (adjacent_turfs.len / 2)) - use_power(amount, power_channel) - return TRUE - -/obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes() - cut_overlays() - if(showpipe) - add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions)) - - if(welded) - icon_state = "scrub_welded" - return - - if(!nodes[1] || !on || !is_operational()) - icon_state = "scrub_off" - return - - if(scrubbing & SCRUBBING) - if(widenet) - icon_state = "scrub_wide" - else - icon_state = "scrub_on" - else //scrubbing == SIPHONING - icon_state = "scrub_purge" - -/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, radio_filter_in) - -/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/broadcast_status() - if(!radio_connection) - return FALSE - - var/list/f_types = list() - for(var/path in GLOB.meta_gas_info) - var/list/gas = GLOB.meta_gas_info[path] - f_types += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in filter_types))) - - var/datum/signal/signal = new(list( - "tag" = id_tag, - "frequency" = frequency, - "device" = "VS", - "timestamp" = world.time, - "power" = on, - "scrubbing" = scrubbing, - "widenet" = widenet, - "filter_types" = f_types, - "sigtype" = "status" - )) - - var/area/A = get_area(src) - if(!A.air_scrub_names[id_tag]) - name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]" - A.air_scrub_names[id_tag] = name - - A.air_scrub_info[id_tag] = signal.data - radio_connection.post_signal(src, signal, radio_filter_out) - - return TRUE - -/obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit() - radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null - radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null - if(frequency) - set_frequency(frequency) - broadcast_status() - check_turfs() - ..() - -/obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos() - ..() - if(welded || !is_operational()) - return FALSE - if(!nodes[1] || !on) - on = FALSE - return FALSE - scrub(loc) - if(widenet) - for(var/turf/tile in adjacent_turfs) - scrub(tile) - return TRUE - -/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(var/turf/tile) - if(!istype(tile)) - return FALSE - var/datum/gas_mixture/environment = tile.return_air() - var/datum/gas_mixture/air_contents = airs[1] - var/list/env_gases = environment.gases - - if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE) - return FALSE - - if(scrubbing & SCRUBBING) - if(length(env_gases & filter_types)) - var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles() - - //Take a gas sample - var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) - - //Nothing left to remove from the tile - if(isnull(removed)) - return FALSE - - var/list/removed_gases = removed.gases - - //Filter it - var/datum/gas_mixture/filtered_out = new - var/list/filtered_gases = filtered_out.gases - filtered_out.temperature = removed.temperature - - for(var/gas in filter_types & removed_gases) - filtered_out.add_gas(gas) - filtered_gases[gas][MOLES] = removed_gases[gas][MOLES] - removed_gases[gas][MOLES] = 0 - - removed.garbage_collect() - - //Remix the resulting gases - air_contents.merge(filtered_out) - tile.assume_air(removed) - tile.air_update_turf() - - else //Just siphoning all air - - var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) - - var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) - - air_contents.merge(removed) - tile.air_update_turf() - - update_parents() - - return TRUE - -//There is no easy way for an object to be notified of changes to atmos can pass flags -// So we check every machinery process (2 seconds) -/obj/machinery/atmospherics/components/unary/vent_scrubber/process() - if(widenet) - check_turfs() - -//we populate a list of turfs with nonatmos-blocked cardinal turfs AND -// diagonal turfs that can share atmos with *both* of the cardinal turfs - -/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs() - adjacent_turfs.Cut() - var/turf/T = get_turf(src) - if(istype(T)) - adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = 1) - -/obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal) - if(!is_operational() || !signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command")) - return 0 - - var/mob/signal_sender = signal.data["user"] - - if("power" in signal.data) - on = text2num(signal.data["power"]) - if("power_toggle" in signal.data) - on = !on - - if("widenet" in signal.data) - widenet = text2num(signal.data["widenet"]) - if("toggle_widenet" in signal.data) - widenet = !widenet - - var/old_scrubbing = scrubbing - if("scrubbing" in signal.data) - scrubbing = text2num(signal.data["scrubbing"]) - if("toggle_scrubbing" in signal.data) - scrubbing = !scrubbing - if(scrubbing != old_scrubbing) - investigate_log(" was toggled to [scrubbing ? "scrubbing" : "siphon"] mode by [key_name(signal_sender)]",INVESTIGATE_ATMOS) - - if("toggle_filter" in signal.data) - filter_types ^= gas_id2path(signal.data["toggle_filter"]) - - if("set_filters" in signal.data) - filter_types = list() - for(var/gas in signal.data["set_filters"]) - filter_types += gas_id2path(gas) - - if("init" in signal.data) - name = signal.data["init"] - return - - if("status" in signal.data) - broadcast_status() - return //do not update_icon - - broadcast_status() - update_icon() - return - -/obj/machinery/atmospherics/components/unary/vent_scrubber/power_change() - ..() - update_icon_nopipes() - -/obj/machinery/atmospherics/components/unary/vent_scrubber/welder_act(mob/living/user, obj/item/I) - if(!I.tool_start_check(user, amount=0)) - return TRUE - to_chat(user, "Now welding the scrubber.") - if(I.use_tool(src, user, 20, volume=50)) - if(!welded) - user.visible_message("[user] welds the scrubber shut.","You weld the scrubber shut.", "You hear welding.") - welded = TRUE - else - user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.") - welded = FALSE - update_icon() - pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) - pipe_vision_img.plane = ABOVE_HUD_PLANE - return TRUE - -/obj/machinery/atmospherics/components/unary/vent_scrubber/can_unwrench(mob/user) - . = ..() - if(. && on && is_operational()) - to_chat(user, "You cannot unwrench [src], turn it off first!") - return FALSE - -/obj/machinery/atmospherics/components/unary/vent_scrubber/examine(mob/user) - ..() - if(welded) - to_chat(user, "It seems welded shut.") - -/obj/machinery/atmospherics/components/unary/vent_scrubber/can_crawl_through() - return !welded - -/obj/machinery/atmospherics/components/unary/vent_scrubber/attack_alien(mob/user) - if(!welded || !(do_after(user, 20, target = src))) - return - user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the scrubber.", "You hear loud scraping noises.") - welded = FALSE - update_icon() - pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) - pipe_vision_img.plane = ABOVE_HUD_PLANE - playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1) - - - -#undef SIPHONING -#undef SCRUBBING +#define SIPHONING 0 +#define SCRUBBING 1 + +/obj/machinery/atmospherics/components/unary/vent_scrubber + name = "air scrubber" + desc = "Has a valve and pump attached to it." + icon_state = "scrub_map" + use_power = IDLE_POWER_USE + idle_power_usage = 10 + active_power_usage = 60 + can_unwrench = TRUE + welded = FALSE + level = 1 + layer = GAS_SCRUBBER_LAYER + + var/id_tag = null + var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing + + var/filter_types = list(/datum/gas/carbon_dioxide) + var/volume_rate = 200 + var/widenet = 0 //is this scrubber acting on the 3x3 area around it. + var/list/turf/adjacent_turfs = list() + + var/frequency = FREQ_ATMOS_CONTROL + var/datum/radio_frequency/radio_connection + var/radio_filter_out + var/radio_filter_in + + pipe_state = "scrubber" + +/obj/machinery/atmospherics/components/unary/vent_scrubber/layer1 + piping_layer = PIPING_LAYER_MIN + pixel_x = -PIPING_LAYER_P_X + pixel_y = -PIPING_LAYER_P_Y + +/obj/machinery/atmospherics/components/unary/vent_scrubber/layer3 + piping_layer = PIPING_LAYER_MAX + pixel_x = PIPING_LAYER_P_X + pixel_y = PIPING_LAYER_P_Y + +/obj/machinery/atmospherics/components/unary/vent_scrubber/New() + ..() + if(!id_tag) + id_tag = assign_uid_vents() + + for(var/f in filter_types) + if(istext(f)) + filter_types -= f + filter_types += gas_id2path(f) + +/obj/machinery/atmospherics/components/unary/vent_scrubber/on + on = TRUE + icon_state = "scrub_map_on" + +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1 + piping_layer = PIPING_LAYER_MIN + pixel_x = -PIPING_LAYER_P_X + pixel_y = -PIPING_LAYER_P_Y + +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3 + piping_layer = PIPING_LAYER_MAX + pixel_x = PIPING_LAYER_P_X + pixel_y = PIPING_LAYER_P_Y + +/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy() + var/area/A = get_area(src) + if (A) + A.air_scrub_names -= id_tag + A.air_scrub_info -= id_tag + + SSradio.remove_object(src,frequency) + radio_connection = null + adjacent_turfs.Cut() + return ..() + +/obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power() + if(!on || welded || !is_operational() || !powered(power_channel)) + return FALSE + + var/amount = idle_power_usage + + if(scrubbing & SCRUBBING) + amount += idle_power_usage * length(filter_types) + else //scrubbing == SIPHONING + amount = active_power_usage + + if(widenet) + amount += amount * (adjacent_turfs.len * (adjacent_turfs.len / 2)) + use_power(amount, power_channel) + return TRUE + +/obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes() + cut_overlays() + if(showpipe) + add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions)) + + if(welded) + icon_state = "scrub_welded" + return + + if(!nodes[1] || !on || !is_operational()) + icon_state = "scrub_off" + return + + if(scrubbing & SCRUBBING) + if(widenet) + icon_state = "scrub_wide" + else + icon_state = "scrub_on" + else //scrubbing == SIPHONING + icon_state = "scrub_purge" + +/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + radio_connection = SSradio.add_object(src, frequency, radio_filter_in) + +/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/broadcast_status() + if(!radio_connection) + return FALSE + + var/list/f_types = list() + for(var/path in GLOB.meta_gas_ids) + f_types += list(list("gas_id" = GLOB.meta_gas_ids[path], "gas_name" = GLOB.meta_gas_names[path], "enabled" = (path in filter_types))) + + var/datum/signal/signal = new(list( + "tag" = id_tag, + "frequency" = frequency, + "device" = "VS", + "timestamp" = world.time, + "power" = on, + "scrubbing" = scrubbing, + "widenet" = widenet, + "filter_types" = f_types, + "sigtype" = "status" + )) + + var/area/A = get_area(src) + if(!A.air_scrub_names[id_tag]) + name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]" + A.air_scrub_names[id_tag] = name + + A.air_scrub_info[id_tag] = signal.data + radio_connection.post_signal(src, signal, radio_filter_out) + + return TRUE + +/obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit() + radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null + radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null + if(frequency) + set_frequency(frequency) + broadcast_status() + check_turfs() + ..() + +/obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos() + ..() + if(welded || !is_operational()) + return FALSE + if(!nodes[1] || !on) + on = FALSE + return FALSE + scrub(loc) + if(widenet) + for(var/turf/tile in adjacent_turfs) + scrub(tile) + return TRUE + +/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(var/turf/tile) + if(!istype(tile)) + return FALSE + var/datum/gas_mixture/environment = tile.return_air() + var/datum/gas_mixture/air_contents = airs[1] + var/list/env_gases = environment.gases + + if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE) + return FALSE + + if(scrubbing & SCRUBBING) + if(length(env_gases & filter_types)) + var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles() + + //Take a gas sample + var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) + + //Nothing left to remove from the tile + if(isnull(removed)) + return FALSE + + var/list/removed_gases = removed.gases + + //Filter it + var/datum/gas_mixture/filtered_out = new + var/list/filtered_gases = filtered_out.gases + filtered_out.temperature = removed.temperature + + for(var/gas in filter_types & removed_gases) + filtered_gases[gas] = removed_gases[gas] + removed_gases[gas] = 0 + + GAS_GARBAGE_COLLECT(removed.gases) + + //Remix the resulting gases + air_contents.merge(filtered_out) + tile.assume_air(removed) + tile.air_update_turf() + + else //Just siphoning all air + + var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) + + var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) + + air_contents.merge(removed) + tile.air_update_turf() + + update_parents() + + return TRUE + +//There is no easy way for an object to be notified of changes to atmos can pass flags +// So we check every machinery process (2 seconds) +/obj/machinery/atmospherics/components/unary/vent_scrubber/process() + if(widenet) + check_turfs() + +//we populate a list of turfs with nonatmos-blocked cardinal turfs AND +// diagonal turfs that can share atmos with *both* of the cardinal turfs + +/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs() + adjacent_turfs.Cut() + var/turf/T = get_turf(src) + if(istype(T)) + adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = 1) + +/obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal) + if(!is_operational() || !signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command")) + return 0 + + var/mob/signal_sender = signal.data["user"] + + if("power" in signal.data) + on = text2num(signal.data["power"]) + if("power_toggle" in signal.data) + on = !on + + if("widenet" in signal.data) + widenet = text2num(signal.data["widenet"]) + if("toggle_widenet" in signal.data) + widenet = !widenet + + var/old_scrubbing = scrubbing + if("scrubbing" in signal.data) + scrubbing = text2num(signal.data["scrubbing"]) + if("toggle_scrubbing" in signal.data) + scrubbing = !scrubbing + if(scrubbing != old_scrubbing) + investigate_log(" was toggled to [scrubbing ? "scrubbing" : "siphon"] mode by [key_name(signal_sender)]",INVESTIGATE_ATMOS) + + if("toggle_filter" in signal.data) + filter_types ^= gas_id2path(signal.data["toggle_filter"]) + + if("set_filters" in signal.data) + filter_types = list() + for(var/gas in signal.data["set_filters"]) + filter_types += gas_id2path(gas) + + if("init" in signal.data) + name = signal.data["init"] + return + + if("status" in signal.data) + broadcast_status() + return //do not update_icon + + broadcast_status() + update_icon() + return + +/obj/machinery/atmospherics/components/unary/vent_scrubber/power_change() + ..() + update_icon_nopipes() + +/obj/machinery/atmospherics/components/unary/vent_scrubber/welder_act(mob/living/user, obj/item/I) + if(!I.tool_start_check(user, amount=0)) + return TRUE + to_chat(user, "Now welding the scrubber.") + if(I.use_tool(src, user, 20, volume=50)) + if(!welded) + user.visible_message("[user] welds the scrubber shut.","You weld the scrubber shut.", "You hear welding.") + welded = TRUE + else + user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.") + welded = FALSE + update_icon() + pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) + pipe_vision_img.plane = ABOVE_HUD_PLANE + return TRUE + +/obj/machinery/atmospherics/components/unary/vent_scrubber/can_unwrench(mob/user) + . = ..() + if(. && on && is_operational()) + to_chat(user, "You cannot unwrench [src], turn it off first!") + return FALSE + +/obj/machinery/atmospherics/components/unary/vent_scrubber/examine(mob/user) + ..() + if(welded) + to_chat(user, "It seems welded shut.") + +/obj/machinery/atmospherics/components/unary/vent_scrubber/can_crawl_through() + return !welded + +/obj/machinery/atmospherics/components/unary/vent_scrubber/attack_alien(mob/user) + if(!welded || !(do_after(user, 20, target = src))) + return + user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the scrubber.", "You hear loud scraping noises.") + welded = FALSE + update_icon() + pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) + pipe_vision_img.plane = ABOVE_HUD_PLANE + playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1) + + + +#undef SIPHONING +#undef SCRUBBING diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm index c4fa387ab0..38178a4339 100644 --- a/code/modules/atmospherics/machinery/datum_pipeline.dm +++ b/code/modules/atmospherics/machinery/datum_pipeline.dm @@ -145,7 +145,7 @@ var/member_gases = member.air_temporary.gases for(var/id in member_gases) - member_gases[id][MOLES] *= member.volume/air.volume + member_gases[id] *= member.volume/air.volume member.air_temporary.temperature = air.temperature @@ -254,4 +254,4 @@ G.copy_from(total_gas_mixture) var/list/G_gases = G.gases for(var/id in G_gases) - G_gases[id][MOLES] *= G.volume/total_gas_mixture.volume + G_gases[id] *= G.volume/total_gas_mixture.volume diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index 20251418bc..adb17b4e94 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -131,8 +131,7 @@ if(!isopenturf(O)) return FALSE var/datum/gas_mixture/merger = new - merger.assert_gas(spawn_id) - merger.gases[spawn_id][MOLES] = (spawn_mol) + merger.gases[spawn_id] = (spawn_mol) merger.temperature = spawn_temp O.assume_air(merger) O.air_update_turf(TRUE) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index d23a5df958..bad2b85bfe 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -204,16 +204,14 @@ /obj/machinery/portable_atmospherics/canister/proc/create_gas() if(gas_type) - air_contents.add_gas(gas_type) if(starter_temp) air_contents.temperature = starter_temp - air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) + air_contents.gases[gas_type] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) if(starter_temp) air_contents.temperature = starter_temp /obj/machinery/portable_atmospherics/canister/air/create_gas() - air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - air_contents.gases[/datum/gas/oxygen][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - air_contents.gases[/datum/gas/nitrogen][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) + air_contents.gases[/datum/gas/oxygen] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) + air_contents.gases[/datum/gas/nitrogen] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) #define HOLDING (1<<0) #define CONNECTED (1<<1) @@ -439,10 +437,10 @@ var/list/danger = list() for(var/id in air_contents.gases) var/gas = air_contents.gases[id] - if(!gas[GAS_META][META_GAS_DANGER]) + if(!GLOB.meta_gas_dangers[id]) continue - if(gas[MOLES] > (gas[GAS_META][META_GAS_MOLES_VISIBLE] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility - danger[gas[GAS_META][META_GAS_NAME]] = gas[MOLES] //ex. "plasma" = 20 + if(gas > (GLOB.meta_gas_visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility + danger[GLOB.meta_gas_names[id]] = gas //ex. "plasma" = 20 if(danger.len) message_admins("[ADMIN_LOOKUPFLW(usr)] opened a canister that contains the following at [ADMIN_VERBOSEJMP(src)]:") diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 29a454f59a..28cdb56e3d 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -1,146 +1,144 @@ -/obj/machinery/portable_atmospherics/scrubber - name = "portable air scrubber" - icon_state = "pscrubber:0" - density = TRUE - - var/on = FALSE - var/volume_rate = 1000 - volume = 1000 - - var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitryl, /datum/gas/tritium, /datum/gas/hypernoblium, /datum/gas/water_vapor) - -/obj/machinery/portable_atmospherics/scrubber/Destroy() - var/turf/T = get_turf(src) - T.assume_air(air_contents) - air_update_turf() - return ..() - -/obj/machinery/portable_atmospherics/scrubber/update_icon() - icon_state = "pscrubber:[on]" - - cut_overlays() - if(holding) - add_overlay("scrubber-open") - if(connected_port) - add_overlay("scrubber-connector") - -/obj/machinery/portable_atmospherics/scrubber/process_atmos() - ..() - if(!on) - return - - if(holding) - scrub(holding.air_contents) - else - var/turf/T = get_turf(src) - scrub(T.return_air()) - -/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture) - var/transfer_moles = min(1, volume_rate / mixture.volume) * mixture.total_moles() - - var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter. - var/datum/gas_mixture/filtered = new - if(!filtering) - return - - filtered.temperature = filtering.temperature - for(var/gas in filtering.gases & scrubbing) - filtered.add_gas(gas) - filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture. - filtering.gases[gas][MOLES] = 0 - filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture. - - air_contents.merge(filtered) // Store filtered out gasses. - mixture.merge(filtering) // Returned the cleaned gas. - if(!holding) - air_update_turf() - -/obj/machinery/portable_atmospherics/scrubber/emp_act(severity) - . = ..() - if(. & EMP_PROTECT_SELF) - return - if(is_operational()) - if(prob(50 / severity)) - on = !on - update_icon() - -/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "portable_scrubber", name, 420, 435, master_ui, state) - ui.open() - -/obj/machinery/portable_atmospherics/scrubber/ui_data() - var/data = list() - data["on"] = on - data["connected"] = connected_port ? 1 : 0 - data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) - - data["id_tag"] = -1 //must be defined in order to reuse code between portable and vent scrubbers - data["filter_types"] = list() - for(var/path in GLOB.meta_gas_info) - var/list/gas = GLOB.meta_gas_info[path] - data["filter_types"] += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in scrubbing))) - - if(holding) - data["holding"] = list() - data["holding"]["name"] = holding.name - data["holding"]["pressure"] = round(holding.air_contents.return_pressure()) - return data - -/obj/machinery/portable_atmospherics/scrubber/ui_act(action, params) - if(..()) - return - switch(action) - if("power") - on = !on - . = TRUE - if("eject") - if(holding) - holding.forceMove(drop_location()) - holding = null - . = TRUE - if("toggle_filter") - scrubbing ^= gas_id2path(params["val"]) - . = TRUE - update_icon() - -/obj/machinery/portable_atmospherics/scrubber/huge - name = "huge air scrubber" - icon_state = "scrubber:0" - anchored = TRUE - active_power_usage = 500 - idle_power_usage = 10 - - volume_rate = 1500 - volume = 50000 - - var/movable = FALSE - -/obj/machinery/portable_atmospherics/scrubber/huge/movable - movable = TRUE - -/obj/machinery/portable_atmospherics/scrubber/huge/update_icon() - icon_state = "scrubber:[on]" - -/obj/machinery/portable_atmospherics/scrubber/huge/process_atmos() - if((!anchored && !movable) || !is_operational()) - on = FALSE - update_icon() - use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE - if(!on) - return - - ..() - if(!holding) - var/turf/T = get_turf(src) - for(var/turf/AT in T.GetAtmosAdjacentTurfs(alldir = TRUE)) - scrub(AT.return_air()) - -/obj/machinery/portable_atmospherics/scrubber/huge/attackby(obj/item/W, mob/user) - if(default_unfasten_wrench(user, W)) - if(!movable) - on = FALSE - else - return ..() +/obj/machinery/portable_atmospherics/scrubber + name = "portable air scrubber" + icon_state = "pscrubber:0" + density = TRUE + + var/on = FALSE + var/volume_rate = 1000 + volume = 1000 + + var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitryl, /datum/gas/tritium, /datum/gas/hypernoblium, /datum/gas/water_vapor) + +/obj/machinery/portable_atmospherics/scrubber/Destroy() + var/turf/T = get_turf(src) + T.assume_air(air_contents) + air_update_turf() + return ..() + +/obj/machinery/portable_atmospherics/scrubber/update_icon() + icon_state = "pscrubber:[on]" + + cut_overlays() + if(holding) + add_overlay("scrubber-open") + if(connected_port) + add_overlay("scrubber-connector") + +/obj/machinery/portable_atmospherics/scrubber/process_atmos() + ..() + if(!on) + return + + if(holding) + scrub(holding.air_contents) + else + var/turf/T = get_turf(src) + scrub(T.return_air()) + +/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture) + var/transfer_moles = min(1, volume_rate / mixture.volume) * mixture.total_moles() + + var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter. + var/datum/gas_mixture/filtered = new + if(!filtering) + return + + filtered.temperature = filtering.temperature + for(var/gas in filtering.gases & scrubbing) + filtered.gases[gas] = filtering.gases[gas] // Shuffle the "bad" gasses to the filtered mixture. + filtering.gases[gas] = 0 + GAS_GARBAGE_COLLECT(filtering.gases) + + air_contents.merge(filtered) // Store filtered out gasses. + mixture.merge(filtering) // Returned the cleaned gas. + if(!holding) + air_update_turf() + +/obj/machinery/portable_atmospherics/scrubber/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + if(is_operational()) + if(prob(50 / severity)) + on = !on + update_icon() + +/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "portable_scrubber", name, 420, 435, master_ui, state) + ui.open() + +/obj/machinery/portable_atmospherics/scrubber/ui_data() + var/data = list() + data["on"] = on + data["connected"] = connected_port ? 1 : 0 + data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) + + data["id_tag"] = -1 //must be defined in order to reuse code between portable and vent scrubbers + data["filter_types"] = list() + for(var/path in GLOB.meta_gas_ids) + data["filter_types"] += list(list("gas_id" = GLOB.meta_gas_ids[path], "gas_name" = GLOB.meta_gas_names[path], "enabled" = (path in scrubbing))) + + if(holding) + data["holding"] = list() + data["holding"]["name"] = holding.name + data["holding"]["pressure"] = round(holding.air_contents.return_pressure()) + return data + +/obj/machinery/portable_atmospherics/scrubber/ui_act(action, params) + if(..()) + return + switch(action) + if("power") + on = !on + . = TRUE + if("eject") + if(holding) + holding.forceMove(drop_location()) + holding = null + . = TRUE + if("toggle_filter") + scrubbing ^= gas_id2path(params["val"]) + . = TRUE + update_icon() + +/obj/machinery/portable_atmospherics/scrubber/huge + name = "huge air scrubber" + icon_state = "scrubber:0" + anchored = TRUE + active_power_usage = 500 + idle_power_usage = 10 + + volume_rate = 1500 + volume = 50000 + + var/movable = FALSE + +/obj/machinery/portable_atmospherics/scrubber/huge/movable + movable = TRUE + +/obj/machinery/portable_atmospherics/scrubber/huge/update_icon() + icon_state = "scrubber:[on]" + +/obj/machinery/portable_atmospherics/scrubber/huge/process_atmos() + if((!anchored && !movable) || !is_operational()) + on = FALSE + update_icon() + use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE + if(!on) + return + + ..() + if(!holding) + var/turf/T = get_turf(src) + for(var/turf/AT in T.GetAtmosAdjacentTurfs(alldir = TRUE)) + scrub(AT.return_air()) + +/obj/machinery/portable_atmospherics/scrubber/huge/attackby(obj/item/W, mob/user) + if(default_unfasten_wrench(user, W)) + if(!movable) + on = FALSE + else + return ..() diff --git a/code/modules/cargo/bounties/engineering.dm b/code/modules/cargo/bounties/engineering.dm index eb1764d482..e10d48f3bf 100644 --- a/code/modules/cargo/bounties/engineering.dm +++ b/code/modules/cargo/bounties/engineering.dm @@ -12,7 +12,7 @@ var/obj/item/tank/T = O if(!T.air_contents.gases[gas_type]) return FALSE - return T.air_contents.gases[gas_type][MOLES] >= moles_required + return T.air_contents.gases[gas_type] >= moles_required /datum/bounty/item/engineering/gas/nitryl_tank name = "Full Tank of Nitryl" diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index 9368a41731..b5f0e7a240 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -55,7 +55,6 @@ contents_cost = 700 export_types = list(/obj/structure/reagent_dispensers/beerkeg) - /datum/export/large/pipedispenser cost = 500 unit_name = "pipe dispenser" @@ -122,7 +121,6 @@ unit_name = "packaged antimatter reactor section" export_types = list(/obj/item/am_shielding_container) - /datum/export/large/iv cost = 50 unit_name = "iv drip" @@ -133,3 +131,86 @@ unit_name = "security barrier" export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security) +/datum/export/large/odysseus + cost = 5500 + unit_name = "working odysseus" + export_types = list(/obj/mecha/medical/odysseus) + include_subtypes = FALSE + +/datum/export/large/ripley + cost = 6500 + unit_name = "working ripley" + export_types = list(/obj/mecha/working/ripley) + include_subtypes = FALSE + +/datum/export/large/firefighter + cost = 9000 + unit_name = "working firefighter" + export_types = list(/obj/mecha/working/ripley/firefighter) + include_subtypes = FALSE + +/datum/export/large/gygax + cost = 19000 + unit_name = "working gygax" + export_types = list(/obj/mecha/combat/gygax) + include_subtypes = FALSE + +/datum/export/large/durand + cost = 10000 + unit_name = "working durand" + export_types = list(/obj/mecha/combat/durand) + include_subtypes = FALSE + +/datum/export/large/phazon + cost = 25000 //Little over half do to needing a core + unit_name = "working phazon" + export_types = list(/obj/mecha/combat/phazon) + include_subtypes = FALSE + +/datum/export/large/marauder + cost = 15000 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price. + unit_name = "working marauder" + export_types = list(/obj/mecha/combat/marauder) + include_subtypes = FALSE + +/datum/export/large/deathripley + cost = 8500 //Still a "Combat class" mech - Illegal tech as well! 165% "normal" boundy price. + unit_name = "working illegally modified" + export_types = list(/obj/mecha/working/ripley/deathripley) + include_subtypes = FALSE + +/datum/export/large/gygaxdark + cost = 28500 //Still a Combat class mech - Illegal tech as well! 150% "normal" boundy price. + unit_name = "working illegally modified gygax" + export_types = list(/obj/mecha/combat/gygax/dark) + include_subtypes = FALSE + +/datum/export/large/oldripley + cost = 6250 //old mech - Scrap metal ! 50% "normal" boundy price. + unit_name = "working miner ripley" + export_types = list(/obj/mecha/working/ripley/mining) + include_subtypes = FALSE + +/datum/export/large/honk + cost = 12000 //Still a "Combat class" mech - Comats bordem honk! + unit_name = "working honker" + export_types = list(/obj/mecha/combat/honker) + include_subtypes = FALSE + +/datum/export/large/reticence + cost = 12000 //Still a "Combat class" mech - Has cloking and lethal weaponds. + unit_name = "working reticence" + export_types = list(/obj/mecha/combat/reticence) + include_subtypes = FALSE + +/datum/export/large/seraph + cost = 25500 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price. + unit_name = "working seraph" + export_types = list(/obj/mecha/combat/marauder/seraph) + include_subtypes = FALSE + +/datum/export/large/mauler + cost = 12000 //Still a Combat class mech - CC lethal weaponds. + unit_name = "working legally modified marauder" + export_types = list(/obj/mecha/combat/marauder/mauler) + include_subtypes = FALSE diff --git a/code/modules/cargo/exports/manifest.dm b/code/modules/cargo/exports/manifest.dm index 763ca70dfe..02b060e0bf 100644 --- a/code/modules/cargo/exports/manifest.dm +++ b/code/modules/cargo/exports/manifest.dm @@ -80,13 +80,13 @@ // Paper work done correctly /datum/export/paperwork_correct - cost = 50 + cost = 150 unit_name = "correct paperwork" - export_types = list(/obj/item/paper/fluff/jobs/cargo/manifest/paperwork_correct) + export_types = list(/obj/item/folder/paperwork_correct) // Paper work not done retruned /datum/export/paperwork_incorrect cost = -500 // Failed to meet NT standers unit_name = "returned incorrect paperwork" - export_types = list(/obj/item/paper/fluff/jobs/cargo/manifest/paperwork) + export_types = list(/obj/item/folder/paperwork) diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index 1f0d7d29b3..b576928bfe 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -97,12 +97,14 @@ return C //Paperwork for NT -/obj/item/paper/fluff/jobs/cargo/manifest/paperwork +/obj/item/folder/paperwork name = "Incomplete Paperwork" desc = "These should've been filled out four months ago! Unfinished grant papers issued by Nanotrasen's finance department. Complete this page for additional funding." icon = 'icons/obj/bureaucracy.dmi' + icon_state = "docs_generic" -/obj/item/paper/fluff/jobs/cargo/manifest/paperwork_correct +/obj/item/folder/paperwork_correct name = "Finished Paperwork" desc = "A neat stack of filled-out forms, in triplicate and signed. Is there anything more satisfying? Make sure they get stamped." icon = 'icons/obj/bureaucracy.dmi' + icon_state = "docs_verified" diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 633f4fa850..2effbd7ada 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -433,7 +433,6 @@ /datum/supply_pack/security/russianclothing name = "Russian Surplus Clothing" desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!" - hidden = TRUE contraband = TRUE cost = 5000 // Its basicly sec suits, good boots/gloves contains = list(/obj/item/clothing/suit/security/officer/russian, @@ -873,8 +872,7 @@ /datum/supply_pack/engineering/shield_sat name = "Shield Generator Satellite" desc = "Protect the very existence of this station with these Anti-Meteor defenses. Contains three Shield Generator Satellites." - cost = 3000 - special = TRUE + cost = 4000 contains = list( /obj/machinery/satellite/meteor_shield, /obj/machinery/satellite/meteor_shield, @@ -882,16 +880,13 @@ ) crate_name= "shield sat crate" - /datum/supply_pack/engineering/shield_sat_control name = "Shield System Control Board" desc = "A control system for the Shield Generator Satellite system." - cost = 5000 - special = TRUE + cost = 4000 contains = list(/obj/item/circuitboard/computer/sat_control) crate_name= "shield control board crate" - ////////////////////////////////////////////////////////////////////////////// //////////////////////// Engine Construction ///////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -961,6 +956,15 @@ crate_name = "grounding rod crate" crate_type = /obj/structure/closet/crate/engineering/electrical +/datum/supply_pack/engine/mason + name = "M.A.S.O.N RIG Crate" + desc = "The rare M.A.S.O.N RIG. Requires CE access to open." + cost = 15000 + access = ACCESS_CE + contains = list(/obj/item/clothing/suit/space/hardsuit/ancient/mason) + crate_name = "M.A.S.O.N Rig" + crate_type = /obj/structure/closet/crate/secure/engineering + /datum/supply_pack/engine/PA name = "Particle Accelerator Crate" desc = "A supermassive black hole or hyper-powered teslaball are the perfect way to spice up any party! This \"My First Apocalypse\" kit contains everything you need to build your own Particle Accelerator! Ages 10 and up." @@ -1543,7 +1547,6 @@ /datum/supply_pack/service group = "Service" - /datum/supply_pack/service/advlighting name = "Advanced Lighting crate" desc = "Thanks to advanced lighting tech we here at the Lamp Factory have be able to produce more lamps and lamp items! This crate has three lamps, a box of lights and a state of the art rapid-light-device!" @@ -1568,6 +1571,14 @@ /obj/item/stack/packageWrap) crate_name = "cargo supplies crate" +/datum/supply_pack/service/food_cart + name = "Food Cart Crate" + desc = "Want to sell food on the go? Cook lost their cart? Well we just so happen to have a few carts to spare!" + cost = 1000 + contains = list(/obj/machinery/food_cart) + crate_name = "food cart crate" + crate_type = /obj/structure/closet/crate + /datum/supply_pack/service/noslipfloor name = "High-traction Floor Tiles" desc = "Make slipping a thing of the past with sixty industrial-grade anti-slip floortiles!" @@ -1576,6 +1587,14 @@ /obj/item/stack/tile/noslip/thirty) crate_name = "high-traction floor tiles crate" +/datum/supply_pack/service/icecream_cart + name = "Ice Cream Cart Crate" + desc = "Plasma fire a to hot for you, want a nice treat after a hard days work? Well now we have the cart for you! This Ice Cream Vat has everthing you need to make you and your friends so ice cream treats! This cart comes stocked with some ingredients for each type of scoopable icecream." + cost = 2750 //Comes prestocked with basic ingredients + contains = list(/obj/machinery/icecream_vat) + crate_name = "ice cream vat crate" + crate_type = /obj/structure/closet/crate + /datum/supply_pack/service/janitor name = "Janitorial Supplies Crate" desc = "Fight back against dirt and grime with Nanotrasen's Janitorial Essentials(tm)! Contains three buckets, caution signs, and cleaner grenades. Also has a single mop, spray cleaner, rag, NT soap and a trash bag." @@ -1699,11 +1718,15 @@ /obj/item/t_scanner/adv_mining_scanner/lesser, /obj/item/radio/headset/headset_cargo/mining, /obj/item/storage/bag/ore, - /obj/item/clothing/suit/hooded/explorer, + /obj/item/clothing/suit/hooded/explorer/standard, /obj/item/clothing/mask/gas/explorer) crate_name = "shaft miner starter kit" crate_type = /obj/structure/closet/crate/secure +////////////////////////////////////////////////////////////////////////////// +/////////////////////////// Vending Restocks ///////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + /datum/supply_pack/service/vending/bartending name = "Bartending Supply Crate" desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!" @@ -2673,16 +2696,16 @@ name = "Freelance Paper work" desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (10) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up. cost = 400 // Net of 0 credits - contains = list(/obj/item/paper/fluff/jobs/cargo/manifest/paperwork, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork, + contains = list(/obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, + /obj/item/folder/paperwork, /obj/item/pen/fountain, /obj/item/pen/fountain, /obj/item/pen/fountain, diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index bb3a4442b3..a0eea344a3 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -21,6 +21,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/last_ip var/last_id + //Cooldowns for saving/loading. These are four are all separate due to loading code calling these one after another + var/saveprefcooldown + var/loadprefcooldown + var/savecharcooldown + var/loadcharcooldown + //game-preferences var/lastchangelog = "" //Saved changlog filesize to detect if there was a change var/ooccolor = null @@ -75,13 +81,82 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/eye_color = "000" //Eye color var/datum/species/pref_species = new /datum/species/human() //Mutant race var/list/features = list("mcolor" = "FFF", - "tail_lizard" = "Smooth", "tail_human" = "Cat", - "snout" = "Round", "horns" = "None", "ears" = "Cat", - "wings" = "None", "frills" = "None", "spines" = "None", - "body_markings" = "None", "legs" = "Normal Legs", "moth_wings" = "Plain") + "tail_lizard" = "Smooth", + "tail_human" = "None", + "snout" = "Round", + "horns" = "None", + "ears" = "None", + "wings" = "None", + "frills" = "None", + "spines" = "None", + "body_markings" = "None", + "legs" = "Normal Legs", + "moth_wings" = "Plain", + "mcolor2" = "FFF", + "mcolor3" = "FFF", + "mam_body_markings" = "Plain", + "mam_ears" = "None", + "mam_snouts" = "None", + "mam_tail" = "None", + "mam_tail_animated" = "None", + "xenodorsal" = "Standard", + "xenohead" = "Standard", + "xenotail" = "Xenomorph Tail", + "taur" = "None", + "exhibitionist" = FALSE, + "genitals_use_skintone" = FALSE, + "has_cock" = FALSE, + "cock_shape" = "Human", + "cock_length" = 6, + "cock_girth_ratio" = COCK_GIRTH_RATIO_DEF, + "cock_color" = "fff", + "has_sheath" = FALSE, + "sheath_color" = "fff", + "has_balls" = FALSE, + "balls_internal" = FALSE, + "balls_color" = "fff", + "balls_amount" = 2, + "balls_sack_size" = BALLS_SACK_SIZE_DEF, + "balls_shape" = "Single", + "balls_size" = BALLS_SIZE_DEF, + "balls_cum_rate" = CUM_RATE, + "balls_cum_mult" = CUM_RATE_MULT, + "balls_efficiency" = CUM_EFFICIENCY, + "balls_fluid" = "semen", + "has_ovi" = FALSE, + "ovi_shape" = "knotted", + "ovi_length" = 6, + "ovi_color" = "fff", + "has_eggsack" = FALSE, + "eggsack_internal" = TRUE, + "eggsack_color" = "fff", + "eggsack_size" = BALLS_SACK_SIZE_DEF, + "eggsack_egg_color" = "fff", + "eggsack_egg_size" = EGG_GIRTH_DEF, + "has_breasts" = FALSE, + "breasts_color" = "fff", + "breasts_size" = "C", + "breasts_shape" = "Pair", + "breasts_fluid" = "milk", + "has_vag" = FALSE, + "vag_shape" = "Human", + "vag_color" = "fff", + "vag_clits" = 1, + "vag_clit_diam" = 0.25, + "has_womb" = FALSE, + "womb_cum_rate" = CUM_RATE, + "womb_cum_mult" = CUM_RATE_MULT, + "womb_efficiency" = CUM_EFFICIENCY, + "womb_fluid" = "femcum", + "ipc_screen" = "Sunburst", + "ipc_antenna" = "None", + "flavor_text" = "" + ) var/list/custom_names = list() + var/preferred_ai_core_display = "Blue" var/prefered_security_department = SEC_DEPT_RANDOM + var/custom_species = null //Quirk list var/list/positive_quirks = list() @@ -229,10 +304,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) old_group = namedata["group"] dat += "
" dat += "[namedata["pref_name"]]: [custom_names[custom_name_id]] " - dat += "
" - dat += "Custom job preferences:
" - dat += "Prefered security department: [prefered_security_department]
" + dat += "

" + dat += "Custom job preferences:
" + dat += "Preferred AI Core Display: [preferred_ai_core_display]
" + dat += "Preferred Security Department: [prefered_security_department]
" dat += "
Other Roles
" //Character Appearance @@ -269,6 +345,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "

Body

" dat += "Gender:[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
" dat += "Species:[pref_species.id]
" + dat += "Custom Species Name:[custom_species ? custom_species : "None"]
" dat += "Random Body
" dat += "Always Random Body:[be_random_body ? "Yes" : "No"]
" dat += "
Cycle background:[bgstate]
" @@ -627,6 +704,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) else dat += "Testicles Color:" dat += "    Change
" + dat += "Testicles showing:[features["balls_shape"]]" dat += APPEARANCE_CATEGORY_COLUMN dat += "Has Vagina:" dat += "[features["has_vag"] == TRUE ? "Yes" : "No"]" @@ -816,10 +894,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
" dat += "
[gear_tab]
" dat += "
" - dat += "Name" - dat += "Cost" - dat += "Restrictions" - dat += "Description" + dat += "Name" + dat += "Cost" + dat += "Restrictions" + dat += "Description" for(var/j in GLOB.loadout_items[gear_tab]) var/datum/gear/gear = GLOB.loadout_items[gear_tab][j] var/donoritem @@ -840,9 +918,14 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "[gear.cost]" if(islist(gear.restricted_roles)) if(gear.restricted_roles.len) - dat += "" - dat += gear.restricted_roles.Join(";") - dat += "" + if(gear.restricted_desc) + dat += "" + dat += gear.restricted_desc + dat += "" + else + dat += "" + dat += gear.restricted_roles.Join(";") + dat += "" dat += "[gear.description]" dat += "" @@ -1379,7 +1462,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) if("flavor_text") - var/msg = stripped_multiline_input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(features["flavor_text"]), MAX_MESSAGE_LEN*2, TRUE) as null|message + var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(features["flavor_text"]), MAX_MESSAGE_LEN*2, TRUE) if(!isnull(msg)) msg = copytext(msg, 1, MAX_MESSAGE_LEN*2) features["flavor_text"] = msg @@ -1456,12 +1539,14 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/newtype = GLOB.species_list[result] pref_species = new newtype() //let's ensure that no weird shit happens on species swapping. + custom_species = null if(!("body_markings" in pref_species.default_features)) features["body_markings"] = "None" if(!("mam_body_markings" in pref_species.default_features)) features["mam_body_markings"] = "None" - if("mam_body_markings" in pref_species.default_features && features["mam_body_markings"] == "None") - features["mam_body_markings"] = "Plain" + if("mam_body_markings" in pref_species.default_features) + if(features["mam_body_markings"] == "None") + features["mam_body_markings"] = "Plain" if("tail_lizard" in pref_species.default_features) features["tail_lizard"] = "Smooth" if(pref_species.id == "felinid") @@ -1477,6 +1562,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) features["mcolor3"] = pref_species.default_color + if("custom_species") + var/new_species = reject_bad_name(input(user, "Choose your species subtype, if unique. This will show up on examinations and health scans. Do not abuse this:", "Character Preference", custom_species) as null|text) + if(new_species) + custom_species = new_species + else + custom_species = null + if("mutant_color") var/new_mutantcolor = input(user, "Choose your character's alien/mutant color:", "Character Preference","#"+features["mcolor"]) as color|null if(new_mutantcolor) @@ -1748,7 +1840,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["cock_color"] = sanitize_hexcolor(new_cockcolor) else - user << "Invalid color. Your color is not bright enough." + to_chat(user,"Invalid color. Your color is not bright enough.") if("cock_length") var/new_length = input(user, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Character Preference") as num|null @@ -1770,7 +1862,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["balls_color"] = sanitize_hexcolor(new_ballscolor) else - user << "Invalid color. Your color is not bright enough." + to_chat(user,"Invalid color. Your color is not bright enough.") + + if("balls_shape") + var/new_shape + new_shape = input(user, "Testicle Type:", "Character Preference") as null|anything in GLOB.balls_shapes_list + if(new_shape) + features["balls_shape"] = new_shape if("egg_size") var/new_size @@ -1786,7 +1884,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["eggsack_egg_color"] = sanitize_hexcolor(new_egg_color) else - user << "Invalid color. Your color is not bright enough." + to_chat(user,"Invalid color. Your color is not bright enough.") if("breasts_size") var/new_size @@ -1809,7 +1907,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["breasts_color"] = sanitize_hexcolor(new_breasts_color) else - user << "Invalid color. Your color is not bright enough." + to_chat(user,"Invalid color. Your color is not bright enough.") if("vag_shape") var/new_shape @@ -1826,7 +1924,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["vag_color"] = sanitize_hexcolor(new_vagcolor) else - user << "Invalid color. Your color is not bright enough." + to_chat(user,"Invalid color. Your color is not bright enough.") if("ooccolor") var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference",ooccolor) as color|null @@ -1843,8 +1941,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(new_loc) uplink_spawn_loc = new_loc + if("ai_core_icon") + var/ai_core_icon = input(user, "Choose your preferred AI core display screen:", "AI Core Display Screen Selection") as null|anything in GLOB.ai_core_display_screens + if(ai_core_icon) + preferred_ai_core_display = ai_core_icon + if("sec_dept") - var/department = input(user, "Choose your prefered security department:", "Security Departments") as null|anything in GLOB.security_depts_prefs + var/department = input(user, "Choose your preferred security department:", "Security Departments") as null|anything in GLOB.security_depts_prefs if(department) prefered_security_department = department @@ -2115,6 +2218,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.real_name = nameless ? "[real_name] #[rand(10000, 99999)]" : real_name character.name = character.real_name character.nameless = nameless + character.custom_species = custom_species character.gender = gender character.age = age @@ -2149,6 +2253,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.dna.features = features.Copy() character.dna.real_name = character.real_name character.dna.nameless = character.nameless + character.dna.custom_species = character.custom_species if("tail_lizard" in pref_species.default_features) character.dna.species.mutant_bodyparts |= "tail_lizard" diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index b6210d94b8..7401a54efc 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -58,6 +58,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /datum/preferences/proc/load_preferences() if(!path) return 0 + if(world.time < loadprefcooldown) + if(istype(parent)) + to_chat(parent, "You're attempting to load your preferences a little too fast. Wait half a second, then try again.") + return 0 + loadprefcooldown = world.time + PREF_SAVELOAD_COOLDOWN if(!fexists(path)) return 0 @@ -152,6 +157,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /datum/preferences/proc/save_preferences() if(!path) return 0 + if(world.time < saveprefcooldown) + if(istype(parent)) + to_chat(parent, "You're attempting to save your preferences a little too fast. Wait half a second, then try again.") + return 0 + saveprefcooldown = world.time + PREF_SAVELOAD_COOLDOWN var/savefile/S = new /savefile(path) if(!S) return 0 @@ -204,6 +214,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /datum/preferences/proc/load_character(slot) if(!path) return 0 + if(world.time < loadcharcooldown) //This is before the check to see if the filepath exists to ensure that BYOND can't get hung up on read attempts when the hard drive is a little slow + if(istype(parent)) + to_chat(parent, "You're attempting to load your character a little too fast. Wait half a second, then try again.") + return "SLOW THE FUCK DOWN" //the reason this isn't null is to make sure that people don't have their character slots overridden by random chars if they accidentally double-click a slot + loadcharcooldown = world.time + PREF_SAVELOAD_COOLDOWN if(!fexists(path)) return 0 var/savefile/S = new /savefile(path) @@ -236,6 +251,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //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 @@ -268,6 +284,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car 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 //Jobs @@ -314,6 +331,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["feature_has_balls"] >> features["has_balls"] S["feature_balls_color"] >> features["balls_color"] S["feature_balls_size"] >> features["balls_size"] + S["feature_balls_shape"] >> features["balls_shape"] S["feature_balls_sack_size"] >> features["balls_sack_size"] S["feature_balls_fluid"] >> features["balls_fluid"] //breasts features @@ -350,7 +368,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car gender = sanitize_gender(gender, TRUE, TRUE) if(!real_name) 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"]) @@ -417,6 +435,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /datum/preferences/proc/save_character() if(!path) return 0 + if(world.time < savecharcooldown) + if(istype(parent)) + to_chat(parent, "You're attempting to save your character a little too fast. Wait half a second, then try again.") + return 0 + savecharcooldown = world.time + PREF_SAVELOAD_COOLDOWN var/savefile/S = new /savefile(path) if(!S) return 0 @@ -427,6 +450,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //Character WRITE_FILE(S["real_name"] , real_name) WRITE_FILE(S["nameless"] , nameless) + WRITE_FILE(S["custom_species"] , custom_species) WRITE_FILE(S["name_is_always_random"] , be_random_name) WRITE_FILE(S["body_is_always_random"] , be_random_body) WRITE_FILE(S["gender"] , gender) @@ -460,6 +484,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/savefile_slot_name = custom_name_id + "_name" //TODO remove this WRITE_FILE(S[savefile_slot_name],custom_names[custom_name_id]) + WRITE_FILE(S["preferred_ai_core_display"] , preferred_ai_core_display) WRITE_FILE(S["prefered_security_department"] , prefered_security_department) //Jobs diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 7f7b3ae0ed..67d0252bb2 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -45,7 +45,7 @@ /obj/item/clothing/glasses/proc/thermal_overload() if(ishuman(src.loc)) var/mob/living/carbon/human/H = src.loc - if(!(H.has_trait(TRAIT_BLIND))) + if(!(HAS_TRAIT(H, TRAIT_BLIND))) if(H.glasses == src) to_chat(H, "[src] overloads and blinds you!") H.flash_act(visual = 1) diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index b691074c27..bc36353ac5 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -27,7 +27,7 @@ /obj/item/clothing/gloves/combat name = "combat gloves" desc = "These tactical gloves are fireproof and shock resistant." - icon_state = "black" + icon_state = "combat" item_state = "blackgloves" siemens_coefficient = 0 permeability_coefficient = 0.05 diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm index f47361e794..8bd7065c1f 100644 --- a/code/modules/clothing/head/_head.dm +++ b/code/modules/clothing/head/_head.dm @@ -27,14 +27,19 @@ if("mam_snouts" in pref_species.default_features) if(H.dna.features["mam_snouts"] != "None") muzzle_var = ALT_STYLE + else + muzzle_var = NORMAL_STYLE else if("snout" in pref_species.default_features) if(H.dna.features["snout"] != "None") muzzle_var = ALT_STYLE + else + muzzle_var = NORMAL_STYLE else muzzle_var = NORMAL_STYLE - H.update_inv_head() + + H.update_inv_head() /obj/item/clothing/head/worn_overlays(isinhands = FALSE) . = list() diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index b1503f26fb..b6c5a5417a 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -26,7 +26,7 @@ icon_state = "captain" item_state = "that" flags_inv = 0 - armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) strip_delay = 60 dog_fashion = /datum/dog_fashion/head/captain @@ -50,7 +50,7 @@ name = "head of personnel's cap" icon_state = "hopcap" desc = "The symbol of true bureaucratic micromanagement." - armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) dog_fashion = /datum/dog_fashion/head/hop /obj/item/clothing/head/hopcap/beret @@ -200,4 +200,4 @@ /obj/item/clothing/head/beret/qm name = "quartermaster's beret" desc = "This headwear shows off your Cargonian leadership" - icon_state = "qmberet" \ No newline at end of file + icon_state = "qmberet" diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm index ea4c9e16b7..8f10184f86 100644 --- a/code/modules/clothing/masks/_masks.dm +++ b/code/modules/clothing/masks/_masks.dm @@ -30,10 +30,15 @@ if("mam_snouts" in pref_species.default_features) if(H.dna.features["mam_snouts"] != "None") muzzle_var = ALT_STYLE + else + muzzle_var = NORMAL_STYLE else if("snout" in pref_species.default_features) if(H.dna.features["snout"] != "None") muzzle_var = ALT_STYLE + else + muzzle_var = NORMAL_STYLE + else muzzle_var = NORMAL_STYLE diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 8245148096..330f69ddaf 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -66,7 +66,7 @@ var/obj/item/organ/heart/heart = M.getorganslot(ORGAN_SLOT_HEART) var/obj/item/organ/lungs/lungs = M.getorganslot(ORGAN_SLOT_LUNGS) - if(!(M.stat == DEAD || (M.has_trait(TRAIT_FAKEDEATH)))) + if(!(M.stat == DEAD || (HAS_TRAIT(M, TRAIT_FAKEDEATH)))) if(heart && istype(heart)) heart_strength = "an unstable" if(heart.beating) @@ -171,17 +171,114 @@ icon_state = "stripedbluescarf" item_color = "stripedbluescarf" -/obj/item/clothing/neck/petcollar //don't really wear this though please c'mon seriously guys +/////////// +//COLLARS// +/////////// + +/obj/item/clothing/neck/petcollar name = "pet collar" - desc = "It's for pets. Though you probably could wear it yourself, you'd doubtless be the subject of ridicule." + desc = "It's for pets. Though you probably could wear it yourself, you'd doubtless be the subject of ridicule. It seems to be made out of a polychromic material." icon_state = "petcollar" item_color = "petcollar" + alternate_worn_icon = 'icons/mob/neck.dmi' //Because, as it appears, the item itself is normally not directly aware of its worn overlays, so this is about the easiest way, without adding a new var. + hasprimary = TRUE + primary_color = "#00BBBB" + pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/collar var/tagname = null /obj/item/clothing/neck/petcollar/attack_self(mob/user) tagname = copytext(sanitize(input(user, "Would you like to change the name on the tag?", "Name your new pet", "Spot") as null|text),1,MAX_NAME_LEN) name = "[initial(name)] - [tagname]" +/obj/item/clothing/neck/petcollar/worn_overlays(isinhands, icon_file) + . = ..() + if(hasprimary | hassecondary | hastertiary) + if(!isinhands) //prevents the worn sprites from showing up if you're just holding them + if(hasprimary) //checks if overlays are enabled + var/mutable_appearance/primary_worn = mutable_appearance(alternate_worn_icon, "[item_color]-primary") //automagical sprite selection + primary_worn.color = primary_color //colors the overlay + . += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite + if(hassecondary) + var/mutable_appearance/secondary_worn = mutable_appearance(alternate_worn_icon, "[item_color]-secondary") + secondary_worn.color = secondary_color + . += secondary_worn + if(hastertiary) + var/mutable_appearance/tertiary_worn = mutable_appearance(alternate_worn_icon, "[item_color]-tertiary") + tertiary_worn.color = tertiary_color + . += tertiary_worn + +/obj/item/clothing/neck/petcollar/leather + name = "leather pet collar" + icon_state = "leathercollar" + item_color = "leathercollar" + + hasprimary = TRUE + hassecondary = TRUE + primary_color = "#222222" + secondary_color = "#888888" + +/obj/item/clothing/neck/petcollar/choker + desc = "Quite fashionable... if you're somebody who's just read their first BDSM-themed erotica novel." + name = "choker" + icon_state = "choker" + item_color = "choker" + + hasprimary = TRUE + primary_color = "#222222" + +/obj/item/clothing/neck/petcollar/locked + name = "locked collar" + desc = "A collar that has a small lock on it to keep it from being removed." + pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/collar/locked + var/lock = FALSE + +/obj/item/clothing/neck/petcollar/locked/attackby(obj/item/K, mob/user, params) + if(istype(K, /obj/item/key/collar)) + if(lock != FALSE) + to_chat(user, "With a click the collar unlocks!") + lock = FALSE + else + to_chat(user, "With a click the collar locks!") + lock = TRUE + return + +/obj/item/clothing/neck/petcollar/locked/attack_hand(mob/user) + if(loc == user && user.get_item_by_slot(SLOT_NECK) && lock != FALSE) + to_chat(user, "The collar is locked! You'll need unlock the collar before you can take it off!") + return + ..() + +/obj/item/clothing/neck/petcollar/locked/leather + name = "leather pet collar" + icon_state = "leathercollar" + item_color = "leathercollar" + + hasprimary = TRUE + hassecondary = TRUE + primary_color = "#222222" + secondary_color = "#888888" + +/obj/item/clothing/neck/petcollar/locked/choker + name = "choker" + desc = "Quite fashionable... if you're somebody who's just read their first BDSM-themed erotica novel." + icon_state = "choker" + item_color = "choker" + + hasprimary = TRUE + primary_color = "#222222" + +/obj/item/key/collar + name = "Collar Key" + desc = "A key for a tiny lock on a collar or bag." + +/obj/item/clothing/neck/petcollar/Initialize() + . = ..() + new /obj/item/reagent_containers/food/snacks/cookie(src) + +/obj/item/clothing/neck/petcollar/locked/Initialize() + . = ..() + new /obj/item/key/collar(src) + ////////////// //DOPE BLING// ////////////// @@ -191,4 +288,4 @@ desc = "Damn, it feels good to be a gangster." icon = 'icons/obj/clothing/neck.dmi' icon_state = "bling" - item_color = "bling" \ No newline at end of file + item_color = "bling" diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index c6d657b271..b4310a7f42 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -46,7 +46,8 @@ /datum/outfit/ert/commander/alert name = "ERT Commander - High Alert" - + + suit = /obj/item/clothing/suit/space/hardsuit/ert/alert glasses = /obj/item/clothing/glasses/thermal/eyepatch backpack_contents = list(/obj/item/storage/box/engineer=1,\ /obj/item/melee/baton/loaded=1,\ @@ -80,7 +81,8 @@ /datum/outfit/ert/security/alert name = "ERT Security - High Alert" - + + suit = /obj/item/clothing/suit/space/hardsuit/ert/alert/sec backpack_contents = list(/obj/item/storage/box/engineer=1,\ /obj/item/storage/box/handcuffs=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ @@ -117,6 +119,7 @@ /datum/outfit/ert/medic/alert name = "ERT Medic - High Alert" + suit = /obj/item/clothing/suit/space/hardsuit/ert/alert/med backpack_contents = list(/obj/item/storage/box/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ @@ -153,6 +156,7 @@ /datum/outfit/ert/engineer/alert name = "ERT Engineer - High Alert" + suit = /obj/item/clothing/suit/space/hardsuit/ert/alert/engi backpack_contents = list(/obj/item/storage/box/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ diff --git a/code/modules/clothing/shoes/taeclowndo.dm b/code/modules/clothing/shoes/taeclowndo.dm new file mode 100644 index 0000000000..f2bbdf0ceb --- /dev/null +++ b/code/modules/clothing/shoes/taeclowndo.dm @@ -0,0 +1,36 @@ +/obj/item/clothing/shoes/clown_shoes/taeclowndo + var/list/spelltypes = list ( + /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pie, + /obj/effect/proc_holder/spell/aimed/banana_peel, + /obj/effect/proc_holder/spell/targeted/touch/megahonk, + /obj/effect/proc_holder/spell/targeted/touch/bspie, + ) + var/list/spells = list() + + +/obj/item/clothing/shoes/clown_shoes/taeclowndo/equipped(mob/user, slot) + . = ..() + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(!(HAS_TRAIT(H, TRAIT_CLUMSY)) && !(H.mind && H.mind.assigned_role == "Clown")) + return + if(slot == SLOT_SHOES) + spells = new + for(var/spell in spelltypes) + var/obj/effect/proc_holder/spell/S = new spell + spells += S + S.charge_counter = 0 + S.start_recharge() + H.mind.AddSpell(S) + +/obj/item/clothing/shoes/clown_shoes/taeclowndo/dropped(mob/user) + . = ..() + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(H.get_item_by_slot(SLOT_SHOES) == src) + for(var/spell in spells) + var/obj/effect/proc_holder/spell/S = spell + H.mind.spell_list.Remove(S) + qdel(S) \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 02982998e1..d40b5f4e9b 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -435,7 +435,6 @@ . = ..() AddComponent(/datum/component/anti_magic, TRUE, FALSE) - //Medical hardsuit /obj/item/clothing/head/helmet/space/hardsuit/medical name = "medical hardsuit helmet" @@ -443,9 +442,9 @@ icon_state = "hardsuit0-medical" item_state = "medical_helm" item_color = "medical" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR flash_protect = 0 armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75) + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR scan_reagents = 1 /obj/item/clothing/suit/space/hardsuit/medical @@ -500,8 +499,6 @@ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/rd tauric = TRUE //Citadel Add for tauric hardsuits - - //Security hardsuit /obj/item/clothing/head/helmet/space/hardsuit/security name = "security hardsuit helmet" @@ -511,7 +508,6 @@ item_color = "sec" armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75) - /obj/item/clothing/suit/space/hardsuit/security icon_state = "hardsuit-sec" name = "security hardsuit" @@ -533,7 +529,6 @@ item_color = "hos" armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95) - /obj/item/clothing/suit/space/hardsuit/security/hos icon_state = "hardsuit-hos" name = "head of security's hardsuit" @@ -624,6 +619,49 @@ var/footstep = 1 var/datum/component/mobhook +/obj/item/clothing/suit/space/hardsuit/ancient/mason + name = "M.A.S.O.N RIG" + desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storge bags on to the suit." + icon_state = "hardsuit-ancient" + item_state = "anc_hardsuit" + armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500) + slowdown = 6 //Slow + allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason + name = "M.A.S.O.N RIG helmet" + desc = "The M.A.S.O.N RIG helmet is complimentary to the rest of the armor. It features a very large, high powered flood lamp and robust flash protection." + icon_state = "hardsuit0-ancient" + item_state = "anc_helm" + armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500) + item_color = "ancient" + brightness_on = 16 + scan_reagents = 1 + flash_protect = 5 //We will not be flash by bombs + tint = 1 + var/obj/machinery/doppler_array/integrated/bomb_radar + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize() + . = ..() + bomb_radar = new /obj/machinery/doppler_array/integrated(src) + +/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/equipped(mob/living/carbon/human/user, slot) + ..() + if (slot == SLOT_HEAD) + var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC] + DHUD.add_hud_to(user) + +/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/dropped(mob/living/carbon/human/user) + ..() + if (user.head == src) + var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC] + DHUD.remove_hud_from(user) + /obj/item/clothing/suit/space/hardsuit/ancient/proc/on_mob_move() var/mob/living/carbon/human/H = loc if(!istype(H) || H.wear_suit != src) @@ -693,7 +731,6 @@ return 1 return 0 - /obj/item/clothing/suit/space/hardsuit/shielded/Destroy() STOP_PROCESSING(SSobj, src) return ..() @@ -751,8 +788,6 @@ item_state = "ert_command" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/blue - - /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf name = "shielded hardsuit helmet" desc = "Standard issue hardsuit helmet for playing capture the flag." @@ -761,7 +796,6 @@ item_color = "ert_medical" armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95) - /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red icon_state = "hardsuit0-ert_security" item_state = "hardsuit0-ert_security" @@ -774,10 +808,6 @@ item_state = "hardsuit0-ert_commander" item_color = "ert_commander" - - - - //////Syndicate Version /obj/item/clothing/suit/space/hardsuit/shielded/syndi @@ -792,7 +822,6 @@ slowdown = 0 tauric = TRUE //Citadel Add for tauric hardsuits - /obj/item/clothing/suit/space/hardsuit/shielded/syndi/Initialize() jetpack = new /obj/item/tank/jetpack/suit(src) . = ..() diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 652c0048c2..6d7c1036be 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -8,7 +8,8 @@ Contains: - NASA Voidsuit - Father Christmas' magical clothes - Pirate's spacesuit - - ERT hardsuit: command, sec, engi, med + - ERT hardsuit: Command, Sec, Engi, Med + - ERT High Alarm - Command, Sec, Engi, Med - EVA spacesuit - Freedom's spacesuit (freedom from vacuum's oppression) - Carp hardsuit @@ -185,6 +186,7 @@ Contains: slowdown = 0 strip_delay = 130 resistance_flags = ACID_PROOF + tauric = TRUE //Citadel Add for tauric hardsuits //ERT Security /obj/item/clothing/head/helmet/space/hardsuit/ert/sec @@ -198,7 +200,6 @@ Contains: icon_state = "ert_security" item_state = "ert_security" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/sec - tauric = TRUE //Citadel Add for tauric hardsuits //ERT Engineering /obj/item/clothing/head/helmet/space/hardsuit/ert/engi @@ -212,7 +213,6 @@ Contains: icon_state = "ert_engineer" item_state = "ert_engineer" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/engi - tauric = TRUE //Citadel Add for tauric hardsuits //ERT Medical /obj/item/clothing/head/helmet/space/hardsuit/ert/med @@ -227,8 +227,73 @@ Contains: item_state = "ert_medical" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/med species_exception = list(/datum/species/angel) + + //Red alert ERT + +/obj/item/clothing/head/helmet/space/hardsuit/ert/alert + name = "emergency response unit helmet" + desc = "Red alert command helmet for the ERT. This one is more armored than its standard version." + icon_state = "hardsuit0-ert_commander-alert" + item_state = "hardsuit0-ert_commander-alert" + item_color = "ert_commander-alert" + armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + strip_delay = 130 + item_flags = NODROP + brightness_on = 8 + resistance_flags = FIRE_PROOF | ACID_PROOF + +/obj/item/clothing/suit/space/hardsuit/ert/alert + name = "emergency response team suit" + desc = "Red alert command suit for the ERT. This one is more armored than its standard version." + icon_state = "ert_command-alert" + item_state = "ert_command-alert" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert + allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals) + armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + strip_delay = 130 + resistance_flags = FIRE_PROOF | ACID_PROOF tauric = TRUE //Citadel Add for tauric hardsuits + //ERT Security +/obj/item/clothing/head/helmet/space/hardsuit/ert/alert/sec + desc = "Red alert security helmet for the ERT. This one is more armored than its standard version." + icon_state = "hardsuit0-ert_security-alert" + item_state = "hardsuit0-ert_security-alert" + item_color = "ert_security-alert" + +/obj/item/clothing/suit/space/hardsuit/ert/alert/sec + desc = "Red alert security suit for the ERT. This one is more armored than its standard version." + icon_state = "ert_security-alert" + item_state = "ert_security-alert" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert/sec + + //ERT Engineering +/obj/item/clothing/head/helmet/space/hardsuit/ert/alert/engi + desc = "Red alert engineer helmet for the ERT. This one is more armored than its standard version." + icon_state = "hardsuit0-ert_engineer-alert" + item_state = "hardsuit0-ert_engineer-alert" + item_color = "ert_engineer-alert" + +/obj/item/clothing/suit/space/hardsuit/ert/alert/engi + desc = "Red alert engineer suit for the ERT. This one is more armored than its standard version." + icon_state = "ert_engineer-alert" + item_state = "ert_engineer-alert" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert/engi + + //ERT Medical +/obj/item/clothing/head/helmet/space/hardsuit/ert/alert/med + desc = "Red alert medical helmet for the ERT. This one is more armored than its standard version." + icon_state = "hardsuit0-ert_medical-alert" + item_state = "hardsuit0-ert_medical-alert" + item_color = "ert_medical-alert" + +/obj/item/clothing/suit/space/hardsuit/ert/alert/med + desc = "Red alert medical suit for the ERT. This one is more armored than its standard version." + icon_state = "ert_medical-alert" + item_state = "ert_medical-alert" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert/med + species_exception = list(/datum/species/angel) + /obj/item/clothing/suit/space/eva name = "EVA suit" icon_state = "space" @@ -280,7 +345,6 @@ Contains: item_flags = NODROP mutantrace_variation = NO_MUTANTRACE_VARIATION - /obj/item/clothing/suit/space/hardsuit/carp name = "carp space suit" desc = "A slimming piece of dubious space carp technology, you suspect it won't stand up to hand-to-hand blows." @@ -291,7 +355,6 @@ Contains: allowed = list(/obj/item/tank/internals, /obj/item/gun/ballistic/automatic/speargun) //I'm giving you a hint here helmettype = /obj/item/clothing/head/helmet/space/hardsuit/carp - /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal name = "paranormal response unit helmet" desc = "A helmet worn by those who deal with paranormal threats for a living." diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 054154639c..7346dc9ea9 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -36,17 +36,11 @@ if(tauric == TRUE) center = TRUE dimension_x = 64 - else if(H.dna.features["taur"] in list("Fox","Wolf","Otie","Drake","Lab","Shepherd","Husky","Eevee","Panther","Horse","Cow","Tiger")) + else if(H.dna.features["taur"] in list("Fox","Wolf","Otie","Drake","Lab","Shepherd","Husky","Eevee","Panther","Horse","Cow","Tiger","Deer")) taurmode = PAW_TAURIC if(tauric == TRUE) center = TRUE dimension_x = 64 - /* - else if(H.dna.features["taur"] == "Horse" || "Cow") - taurmode = HOOF_TAURIC //tweak this for when the exotics get their own suits, if ever. - center = TRUE - dimension_x = 64 - */ else taurmode = NOT_TAURIC if(tauric == TRUE) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index b10bf39729..5d2d4c115a 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -23,7 +23,6 @@ item_state = "armoralt" blood_overlay_type = "armor" dog_fashion = /datum/dog_fashion/back - tauric = TRUE //Citadel Add for tauric hardsuits /obj/item/clothing/suit/armor/vest/alt desc = "A Type I armored vest that provides decent protection against most types of damage." diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index 481fbade71..5d534e00a7 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -24,11 +24,11 @@ ToggleHood() /obj/item/clothing/suit/hooded/item_action_slot_check(slot, mob/user) - if(slot == SLOT_WEAR_SUIT) + if(slot == SLOT_WEAR_SUIT || slot == SLOT_NECK) return 1 /obj/item/clothing/suit/hooded/equipped(mob/user, slot) - if(slot != SLOT_WEAR_SUIT) + if(slot != SLOT_WEAR_SUIT && slot != SLOT_NECK) RemoveHood() ..() diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index ea1db981e5..ba2a27af77 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -21,6 +21,8 @@ CAT_BURGER, CAT_CAKE, CAT_EGG, + CAT_SUSHI, //Called Fish + CAT_ICE, //Called Frozen CAT_MEAT, CAT_MISCFOOD, CAT_PASTRY, diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 750b172286..dbff7988c1 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -10,7 +10,6 @@ var/category = CAT_NONE //where it shows up in the crafting UI var/subcategory = CAT_NONE - /datum/crafting_recipe/pin_removal name = "Pin Removal" result = /obj/item/gun @@ -54,6 +53,18 @@ category = CAT_WEAPONRY subcategory = CAT_WEAPON +/datum/crafting_recipe/makeshiftshield + name = "Makeshift Metal Shield" + result = /obj/item/shield/makeshift + reqs = list(/obj/item/stack/cable_coil = 30, + /obj/item/stack/sheet/metal = 10, + /obj/item/stack/sheet/cloth = 2, + /obj/item/stack/sheet/leather = 3) + tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER) + time = 100 + category = CAT_WEAPONRY + subcategory = CAT_WEAPON + /datum/crafting_recipe/molotov name = "Molotov" result = /obj/item/reagent_containers/food/drinks/bottle/molotov @@ -189,6 +200,16 @@ time = 40 category = CAT_ROBOT +/datum/crafting_recipe/Firebot + name = "Firebot" + result = /mob/living/simple_animal/bot/firebot + reqs = list(/obj/item/extinguisher = 1, + /obj/item/bodypart/r_arm/robot = 1, + /obj/item/assembly/prox_sensor = 1, + /obj/item/clothing/head/hardhat/red = 1) + time = 40 + category = CAT_ROBOT + /datum/crafting_recipe/improvised_pneumatic_cannon //Pretty easy to obtain but name = "Pneumatic Cannon" result = /obj/item/pneumatic_cannon/ghetto @@ -302,6 +323,18 @@ category = CAT_WEAPONRY subcategory = CAT_WEAPON +/datum/crafting_recipe/irifle + name = "Improvised Rifle(7.62mm)" + result = /obj/item/gun/ballistic/shotgun/boltaction/improvised + reqs = list(/obj/item/weaponcrafting/receiver = 1, + /obj/item/pipe = 2, + /obj/item/weaponcrafting/stock = 1, + /obj/item/stack/packageWrap = 5) + tools = list(TOOL_SCREWDRIVER) + time = 100 + category = CAT_WEAPONRY + subcategory = CAT_WEAPON + /datum/crafting_recipe/chainsaw name = "Chainsaw" result = /obj/item/twohanded/required/chainsaw @@ -385,7 +418,6 @@ reqs = list(/obj/item/paper = 5) category = CAT_MISC - /datum/crafting_recipe/flashlight_eyes name = "Flashlight Eyes" result = /obj/item/organ/eyes/robotic/flashlight @@ -435,6 +467,15 @@ result = /obj/item/extendohand category = CAT_MISC +/datum/crafting_recipe/bluespacehonker + name = "Bluespace Bike horn" + result = /obj/item/bikehorn/bluespacehonker + time = 10 + reqs = list(/obj/item/stack/ore/bluespace_crystal = 1, + /obj/item/toy/crayon/blue = 1, + /obj/item/bikehorn = 1) + category = CAT_MISC + /datum/crafting_recipe/chemical_payload name = "Chemical Payload (C4)" result = /obj/item/bombcore/chemical @@ -517,6 +558,14 @@ /obj/item/stack/sheet/animalhide/ashdrake = 5) category = CAT_PRIMAL +/datum/crafting_recipe/bonebag + name = "Bone Satchel" + result = /obj/item/storage/backpack/satchel/bone + time = 30 + reqs = list(/obj/item/stack/sheet/bone = 3, + /obj/item/stack/sheet/sinew = 2) + category = CAT_PRIMAL + /datum/crafting_recipe/gold_horn name = "Golden Bike Horn" result = /obj/item/bikehorn/golden @@ -592,7 +641,6 @@ /obj/item/assembly/igniter = 1) category = CAT_MISC - /datum/crafting_recipe/rcl name = "Makeshift Rapid Cable Layer" result = /obj/item/twohanded/rcl/ghetto @@ -686,6 +734,16 @@ reqs = list(/obj/item/bedsheet = 1) category = CAT_CLOTHING +/datum/crafting_recipe/briefcase + name = "Hand made Briefcase" + result = /obj/item/storage/briefcase/crafted + time = 35 + tools = list(TOOL_WIRECUTTER) + reqs = list(/obj/item/stack/sheet/cardboard = 1, + /obj/item/stack/sheet/cloth = 2, + /obj/item/stack/sheet/leather = 5) + category = CAT_CLOTHING + /datum/crafting_recipe/aitater name = "intelliTater" result = /obj/item/aicard/aitater @@ -696,16 +754,30 @@ /datum/crafting_recipe/paperwork name = "Filed Paper Work" - result = /obj/item/paper/fluff/jobs/cargo/manifest/paperwork_correct - time = 90 //Takes time for people to file and complete paper work! + result = /obj/item/folder/paperwork_correct + time = 60 //Takes time for people to file and complete paper work! reqs = list(/obj/item/pen = 1, - /obj/item/paper/fluff/jobs/cargo/manifest/paperwork = 2) + /obj/item/folder/paperwork = 2) category = CAT_MISC /datum/crafting_recipe/ghettojetpack name = "Improvised Jetpack" result = /obj/item/tank/jetpack/improvised time = 30 - reqs = list(/obj/item/tank/internals/oxygen/red = 2, /obj/item/extinguisher = 1, /obj/item/pipe = 3, /obj/item/stack/cable_coil = 30)//red oxygen tank so it looks right + reqs = list(/obj/item/tank/internals/oxygen = 2, + /obj/item/extinguisher = 1, + /obj/item/pipe = 3, + /obj/item/stack/cable_coil = 30) category = CAT_MISC tools = list(TOOL_WRENCH, TOOL_WELDER, TOOL_WIRECUTTER) + +/datum/crafting_recipe/goldenbox + name = "Gold Plated Toolbox" + result = /obj/item/storage/toolbox/gold_fake + reqs = list(/obj/item/stack/sheet/cardboard = 1, //so we dont null items in crafting + /obj/item/stack/cable_coil = 10, + /obj/item/stack/sheet/mineral/gold = 1, + /obj/item/stock_parts/cell = 1, + /datum/reagent/water = 15) + time = 40 + category = CAT_MISC diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm index 9f1f2bf380..a25bc01b13 100644 --- a/code/modules/detectivework/footprints_and_rag.dm +++ b/code/modules/detectivework/footprints_and_rag.dm @@ -13,7 +13,7 @@ icon = 'icons/obj/toy.dmi' icon_state = "rag" item_flags = NOBLUDGEON - container_type = OPENCONTAINER + reagent_flags = OPENCONTAINER amount_per_transfer_from_this = 5 possible_transfer_amounts = list() volume = 5 diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index f09c0481f6..f63ca39874 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -39,7 +39,7 @@ continue if(H.stat == DEAD) continue - if(H.has_trait(TRAIT_VIRUSIMMUNE)) //Don't pick someone who's virus immune, only for it to not do anything. + if(HAS_TRAIT(H, TRAIT_VIRUSIMMUNE)) //Don't pick someone who's virus immune, only for it to not do anything. continue var/foundAlready = FALSE // don't infect someone that already has a disease for(var/thing in H.diseases) @@ -51,7 +51,7 @@ var/datum/disease/D if(!advanced_virus) if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. - if(!H.dna || (H.has_trait(TRAIT_BLIND))) //A blindness disease would be the worst. + if(!H.dna || (HAS_TRAIT(H, TRAIT_BLIND))) //A blindness disease would be the worst. continue D = new virus_type() var/datum/disease/dnaspread/DS = D diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index 910e94f680..7256ddb6ea 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -48,8 +48,6 @@ if(!shuttle_spawned) spawn_shuttle() - - /datum/round_event/pirates/start() if(!paid_off && !shuttle_spawned) spawn_shuttle() @@ -150,7 +148,6 @@ to_chat(user,"You retrieve the siphoned credits!") credits_stored = 0 - /obj/machinery/shuttle_scrambler/proc/send_notification() priority_announce("Data theft signal detected, source registered on local gps units.") @@ -222,8 +219,7 @@ suit_type = /obj/item/clothing/suit/space helmet_type = /obj/item/clothing/head/helmet/space mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/tank/internals/oxygen - + storage_type = /obj/item/tank/jetpack/void /obj/machinery/loot_locator name = "Booty Locator" @@ -454,4 +450,4 @@ /datum/export/pirate/cash/get_amount(obj/O) var/obj/item/stack/spacecash/C = O - return ..() * C.amount * C.value \ No newline at end of file + return ..() * C.amount * C.value diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 966d5cc0d8..d8906de036 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -1,548 +1,548 @@ -/datum/round_event_control/spacevine - name = "Spacevine" - typepath = /datum/round_event/spacevine - weight = 15 - max_occurrences = 3 - min_players = 10 - -/datum/round_event/spacevine - fakeable = FALSE - -/datum/round_event/spacevine/start() - var/list/turfs = list() //list of all the empty floor turfs in the hallway areas - - var/obj/structure/spacevine/SV = new() - - for(var/area/hallway/A in world) - for(var/turf/F in A) - if(F.Enter(SV)) - turfs += F - - qdel(SV) - - if(turfs.len) //Pick a turf to spawn at if we can - var/turf/T = pick(turfs) - new /datum/spacevine_controller(T) //spawn a controller at turf - - -/datum/spacevine_mutation - var/name = "" - var/severity = 1 - var/hue - var/quality - -/datum/spacevine_mutation/proc/add_mutation_to_vinepiece(obj/structure/spacevine/holder) - holder.mutations |= src - holder.add_atom_colour(hue, FIXED_COLOUR_PRIORITY) - -/datum/spacevine_mutation/proc/process_mutation(obj/structure/spacevine/holder) - return - -/datum/spacevine_mutation/proc/process_temperature(obj/structure/spacevine/holder, temp, volume) - return - -/datum/spacevine_mutation/proc/on_birth(obj/structure/spacevine/holder) - return - -/datum/spacevine_mutation/proc/on_grow(obj/structure/spacevine/holder) - return - -/datum/spacevine_mutation/proc/on_death(obj/structure/spacevine/holder) - return - -/datum/spacevine_mutation/proc/on_hit(obj/structure/spacevine/holder, mob/hitter, obj/item/I, expected_damage) - . = expected_damage - -/datum/spacevine_mutation/proc/on_cross(obj/structure/spacevine/holder, mob/crosser) - return - -/datum/spacevine_mutation/proc/on_chem(obj/structure/spacevine/holder, datum/reagent/R) - return - -/datum/spacevine_mutation/proc/on_eat(obj/structure/spacevine/holder, mob/living/eater) - return - -/datum/spacevine_mutation/proc/on_spread(obj/structure/spacevine/holder, turf/target) - return - -/datum/spacevine_mutation/proc/on_buckle(obj/structure/spacevine/holder, mob/living/buckled) - return - -/datum/spacevine_mutation/proc/on_explosion(severity, target, obj/structure/spacevine/holder) - return - - -/datum/spacevine_mutation/light - name = "light" - hue = "#ffff00" - quality = POSITIVE - severity = 4 - -/datum/spacevine_mutation/light/on_grow(obj/structure/spacevine/holder) - if(holder.energy) - holder.set_light(severity, 0.3) - -/datum/spacevine_mutation/toxicity - name = "toxic" - hue = "#ff00ff" - severity = 10 - quality = NEGATIVE - -/datum/spacevine_mutation/toxicity/on_cross(obj/structure/spacevine/holder, mob/living/crosser) - if(issilicon(crosser)) - return - if(prob(severity) && istype(crosser) && !isvineimmune(crosser)) - to_chat(crosser, "You accidentally touch the vine and feel a strange sensation.") - crosser.adjustToxLoss(5) - -/datum/spacevine_mutation/toxicity/on_eat(obj/structure/spacevine/holder, mob/living/eater) - if(!isvineimmune(eater)) - eater.adjustToxLoss(5) - -/datum/spacevine_mutation/explosive //OH SHIT IT CAN CHAINREACT RUN!!! - name = "explosive" - hue = "#ff0000" - quality = NEGATIVE - severity = 2 - -/datum/spacevine_mutation/explosive/on_explosion(explosion_severity, target, obj/structure/spacevine/holder) - if(explosion_severity < 3) - qdel(holder) - else - . = 1 - QDEL_IN(holder, 5) - -/datum/spacevine_mutation/explosive/on_death(obj/structure/spacevine/holder, mob/hitter, obj/item/I) - explosion(holder.loc, 0, 0, severity, 0, 0) - -/datum/spacevine_mutation/fire_proof - name = "fire proof" - hue = "#ff8888" - quality = MINOR_NEGATIVE - -/datum/spacevine_mutation/fire_proof/process_temperature(obj/structure/spacevine/holder, temp, volume) - return 1 - -/datum/spacevine_mutation/fire_proof/on_hit(obj/structure/spacevine/holder, mob/hitter, obj/item/I, expected_damage) - if(I && I.damtype == "fire") - . = 0 - else - . = expected_damage - -/datum/spacevine_mutation/vine_eating - name = "vine eating" - hue = "#ff7700" - quality = MINOR_NEGATIVE - -/datum/spacevine_mutation/vine_eating/on_spread(obj/structure/spacevine/holder, turf/target) - var/obj/structure/spacevine/prey = locate() in target - if(prey && !prey.mutations.Find(src)) //Eat all vines that are not of the same origin - qdel(prey) - -/datum/spacevine_mutation/aggressive_spread //very OP, but im out of other ideas currently - name = "aggressive spreading" - hue = "#333333" - severity = 3 - quality = NEGATIVE - -/datum/spacevine_mutation/aggressive_spread/on_spread(obj/structure/spacevine/holder, turf/target) - target.ex_act(severity, null, src) // vine immunity handled at /mob/ex_act - -/datum/spacevine_mutation/aggressive_spread/on_buckle(obj/structure/spacevine/holder, mob/living/buckled) - buckled.ex_act(severity, null, src) - -/datum/spacevine_mutation/transparency - name = "transparent" - hue = "" - quality = POSITIVE - -/datum/spacevine_mutation/transparency/on_grow(obj/structure/spacevine/holder) - holder.set_opacity(0) - holder.alpha = 125 - -/datum/spacevine_mutation/oxy_eater - name = "oxygen consuming" - hue = "#ffff88" - severity = 3 - quality = NEGATIVE - -/datum/spacevine_mutation/oxy_eater/process_mutation(obj/structure/spacevine/holder) - var/turf/open/floor/T = holder.loc - if(istype(T)) - var/datum/gas_mixture/GM = T.air - if(!GM.gases[/datum/gas/oxygen]) - return - GM.gases[/datum/gas/oxygen][MOLES] = max(GM.gases[/datum/gas/oxygen][MOLES] - severity * holder.energy, 0) - GM.garbage_collect() - -/datum/spacevine_mutation/nitro_eater - name = "nitrogen consuming" - hue = "#8888ff" - severity = 3 - quality = NEGATIVE - -/datum/spacevine_mutation/nitro_eater/process_mutation(obj/structure/spacevine/holder) - var/turf/open/floor/T = holder.loc - if(istype(T)) - var/datum/gas_mixture/GM = T.air - if(!GM.gases[/datum/gas/nitrogen]) - return - GM.gases[/datum/gas/nitrogen][MOLES] = max(GM.gases[/datum/gas/nitrogen][MOLES] - severity * holder.energy, 0) - GM.garbage_collect() - -/datum/spacevine_mutation/carbondioxide_eater - name = "CO2 consuming" - hue = "#00ffff" - severity = 3 - quality = POSITIVE - -/datum/spacevine_mutation/carbondioxide_eater/process_mutation(obj/structure/spacevine/holder) - var/turf/open/floor/T = holder.loc - if(istype(T)) - var/datum/gas_mixture/GM = T.air - if(!GM.gases[/datum/gas/carbon_dioxide]) - return - GM.gases[/datum/gas/carbon_dioxide][MOLES] = max(GM.gases[/datum/gas/carbon_dioxide][MOLES] - severity * holder.energy, 0) - GM.garbage_collect() - -/datum/spacevine_mutation/plasma_eater - name = "toxins consuming" - hue = "#ffbbff" - severity = 3 - quality = POSITIVE - -/datum/spacevine_mutation/plasma_eater/process_mutation(obj/structure/spacevine/holder) - var/turf/open/floor/T = holder.loc - if(istype(T)) - var/datum/gas_mixture/GM = T.air - if(!GM.gases[/datum/gas/plasma]) - return - GM.gases[/datum/gas/plasma][MOLES] = max(GM.gases[/datum/gas/plasma][MOLES] - severity * holder.energy, 0) - GM.garbage_collect() - -/datum/spacevine_mutation/thorns - name = "thorny" - hue = "#666666" - severity = 10 - quality = NEGATIVE - -/datum/spacevine_mutation/thorns/on_cross(obj/structure/spacevine/holder, mob/living/crosser) - if(prob(severity) && istype(crosser) && !isvineimmune(holder)) - var/mob/living/M = crosser - M.adjustBruteLoss(5) - to_chat(M, "You cut yourself on the thorny vines.") - -/datum/spacevine_mutation/thorns/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage) - if(prob(severity) && istype(hitter) && !isvineimmune(holder)) - var/mob/living/M = hitter - M.adjustBruteLoss(5) - to_chat(M, "You cut yourself on the thorny vines.") - . = expected_damage - -/datum/spacevine_mutation/woodening - name = "hardened" - hue = "#997700" - quality = NEGATIVE - -/datum/spacevine_mutation/woodening/on_grow(obj/structure/spacevine/holder) - if(holder.energy) - holder.density = TRUE - holder.max_integrity = 100 - holder.obj_integrity = holder.max_integrity - -/datum/spacevine_mutation/woodening/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage) - if(I.is_sharp()) - . = expected_damage * 0.5 - else - . = expected_damage - -/datum/spacevine_mutation/flowering - name = "flowering" - hue = "#0A480D" - quality = NEGATIVE - severity = 10 - -/datum/spacevine_mutation/flowering/on_grow(obj/structure/spacevine/holder) - if(holder.energy == 2 && prob(severity) && !locate(/obj/structure/alien/resin/flower_bud_enemy) in range(5,holder)) - new/obj/structure/alien/resin/flower_bud_enemy(get_turf(holder)) - -/datum/spacevine_mutation/flowering/on_cross(obj/structure/spacevine/holder, mob/living/crosser) - if(prob(25)) - holder.entangle(crosser) - - -// SPACE VINES (Note that this code is very similar to Biomass code) -/obj/structure/spacevine - name = "space vines" - desc = "An extremely expansionistic species of vine." - icon = 'icons/effects/spacevines.dmi' - icon_state = "Light1" - anchored = TRUE - density = FALSE - layer = SPACEVINE_LAYER - mouse_opacity = MOUSE_OPACITY_OPAQUE //Clicking anywhere on the turf is good enough - pass_flags = PASSTABLE | PASSGRILLE - max_integrity = 50 - var/energy = 0 - var/datum/spacevine_controller/master = null - var/list/mutations = list() - -/obj/structure/spacevine/Initialize() - . = ..() - add_atom_colour("#ffffff", FIXED_COLOUR_PRIORITY) - -/obj/structure/spacevine/examine(mob/user) - ..() - var/text = "This one is a" - if(mutations.len) - for(var/A in mutations) - var/datum/spacevine_mutation/SM = A - text += " [SM.name]" - else - text += " normal" - text += " vine." - to_chat(user, text) - -/obj/structure/spacevine/Destroy() - for(var/datum/spacevine_mutation/SM in mutations) - SM.on_death(src) - if(master) - master.VineDestroyed(src) - mutations = list() - set_opacity(0) - if(has_buckled_mobs()) - unbuckle_all_mobs(force=1) - return ..() - -/obj/structure/spacevine/proc/on_chem_effect(datum/reagent/R) - var/override = 0 - for(var/datum/spacevine_mutation/SM in mutations) - override += SM.on_chem(src, R) - if(!override && istype(R, /datum/reagent/toxin/plantbgone)) - if(prob(50)) - qdel(src) - -/obj/structure/spacevine/proc/eat(mob/eater) - var/override = 0 - for(var/datum/spacevine_mutation/SM in mutations) - override += SM.on_eat(src, eater) - if(!override) - qdel(src) - -/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user) - var/damage_dealt = I.force - if(I.is_sharp()) - damage_dealt *= 4 - if(I.damtype == BURN) - damage_dealt *= 4 - - for(var/datum/spacevine_mutation/SM in mutations) - damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further - take_damage(damage_dealt, I.damtype, "melee", 1) - -/obj/structure/spacevine/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - if(damage_amount) - playsound(src, 'sound/weapons/slash.ogg', 50, 1) - else - playsound(src, 'sound/weapons/tap.ogg', 50, 1) - if(BURN) - playsound(src.loc, 'sound/items/welder.ogg', 100, 1) - -/obj/structure/spacevine/Crossed(mob/crosser) - if(isliving(crosser)) - for(var/datum/spacevine_mutation/SM in mutations) - SM.on_cross(src, crosser) - -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/spacevine/attack_hand(mob/user) - for(var/datum/spacevine_mutation/SM in mutations) - SM.on_hit(src, user) - user_unbuckle_mob(user, user) - . = ..() - -/obj/structure/spacevine/attack_paw(mob/living/user) - for(var/datum/spacevine_mutation/SM in mutations) - SM.on_hit(src, user) - user_unbuckle_mob(user,user) - -/obj/structure/spacevine/attack_alien(mob/living/user) - eat(user) - -/datum/spacevine_controller - var/list/obj/structure/spacevine/vines - var/list/growth_queue - var/spread_multiplier = 5 - var/spread_cap = 30 - var/list/vine_mutations_list - var/mutativeness = 1 - -/datum/spacevine_controller/New(turf/location, list/muts, potency, production) - vines = list() - growth_queue = list() - spawn_spacevine_piece(location, null, muts) - START_PROCESSING(SSobj, src) - vine_mutations_list = list() - init_subtypes(/datum/spacevine_mutation/, vine_mutations_list) - if(potency != null) - mutativeness = potency / 10 - if(production != null) - spread_cap *= production / 5 - spread_multiplier /= production / 5 - -/datum/spacevine_controller/vv_get_dropdown() - . = ..() - . += "---" - .["Delete Vines"] = "?_src_=[REF(src)];[HrefToken()];purge_vines=1" - -/datum/spacevine_controller/Topic(href, href_list) - if(..() || !check_rights(R_ADMIN, FALSE) || !usr.client.holder.CheckAdminHref(href, href_list)) - return - - if(href_list["purge_vines"]) - if(alert(usr, "Are you sure you want to delete this spacevine cluster?", "Delete Vines", "Yes", "No") != "Yes") - return - DeleteVines() - -/datum/spacevine_controller/proc/DeleteVines() //this is kill - QDEL_LIST(vines) //this will also qdel us - -/datum/spacevine_controller/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/datum/spacevine_controller/proc/spawn_spacevine_piece(turf/location, obj/structure/spacevine/parent, list/muts) - var/obj/structure/spacevine/SV = new(location) - growth_queue += SV - vines += SV - SV.master = src - if(muts && muts.len) - for(var/datum/spacevine_mutation/M in muts) - M.add_mutation_to_vinepiece(SV) - return - if(parent) - SV.mutations |= parent.mutations - var/parentcolor = parent.atom_colours[FIXED_COLOUR_PRIORITY] - SV.add_atom_colour(parentcolor, FIXED_COLOUR_PRIORITY) - if(prob(mutativeness)) - var/datum/spacevine_mutation/randmut = pick(vine_mutations_list - SV.mutations) - randmut.add_mutation_to_vinepiece(SV) - - for(var/datum/spacevine_mutation/SM in SV.mutations) - SM.on_birth(SV) - location.Entered(SV) - -/datum/spacevine_controller/proc/VineDestroyed(obj/structure/spacevine/S) - S.master = null - vines -= S - growth_queue -= S - if(!vines.len) - var/obj/item/seeds/kudzu/KZ = new(S.loc) - KZ.mutations |= S.mutations - KZ.set_potency(mutativeness * 10) - KZ.set_production((spread_cap / initial(spread_cap)) * 5) - qdel(src) - -/datum/spacevine_controller/process() - if(!LAZYLEN(vines)) - qdel(src) //space vines exterminated. Remove the controller - return - if(!growth_queue) - qdel(src) //Sanity check - return - - var/length = 0 - - length = min( spread_cap , max( 1 , vines.len / spread_multiplier ) ) - var/i = 0 - var/list/obj/structure/spacevine/queue_end = list() - - for(var/obj/structure/spacevine/SV in growth_queue) - if(QDELETED(SV)) - continue - i++ - queue_end += SV - growth_queue -= SV - for(var/datum/spacevine_mutation/SM in SV.mutations) - SM.process_mutation(SV) - if(SV.energy < 2) //If tile isn't fully grown - if(prob(20)) - SV.grow() - else //If tile is fully grown - SV.entangle_mob() - - SV.spread() - if(i >= length) - break - - growth_queue = growth_queue + queue_end - -/obj/structure/spacevine/proc/grow() - if(!energy) - src.icon_state = pick("Med1", "Med2", "Med3") - energy = 1 - set_opacity(1) - else - src.icon_state = pick("Hvy1", "Hvy2", "Hvy3") - energy = 2 - - for(var/datum/spacevine_mutation/SM in mutations) - SM.on_grow(src) - -/obj/structure/spacevine/proc/entangle_mob() - if(!has_buckled_mobs() && prob(25)) - for(var/mob/living/V in src.loc) - entangle(V) - if(has_buckled_mobs()) - break //only capture one mob at a time - - -/obj/structure/spacevine/proc/entangle(mob/living/V) - if(!V || isvineimmune(V)) - return - for(var/datum/spacevine_mutation/SM in mutations) - SM.on_buckle(src, V) - if((V.stat != DEAD) && (V.buckled != src)) //not dead or captured - to_chat(V, "The vines [pick("wind", "tangle", "tighten")] around you!") - buckle_mob(V, 1) - -/obj/structure/spacevine/proc/spread() - var/direction = pick(GLOB.cardinals) - var/turf/stepturf = get_step(src,direction) - if (!isspaceturf(stepturf) && stepturf.Enter(src)) - for(var/datum/spacevine_mutation/SM in mutations) - SM.on_spread(src, stepturf) - stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen - if(!locate(/obj/structure/spacevine, stepturf)) - if(master) - master.spawn_spacevine_piece(stepturf, src) - -/obj/structure/spacevine/ex_act(severity, target) - if(istype(target, type)) //if its agressive spread vine dont do anything - return - var/i - for(var/datum/spacevine_mutation/SM in mutations) - i += SM.on_explosion(severity, target, src) - if(!i && prob(100/severity)) - qdel(src) - -/obj/structure/spacevine/temperature_expose(null, temp, volume) - var/override = 0 - for(var/datum/spacevine_mutation/SM in mutations) - override += SM.process_temperature(src, temp, volume) - if(!override) - qdel(src) - -/obj/structure/spacevine/CanPass(atom/movable/mover, turf/target) - if(isvineimmune(mover)) - . = TRUE - else - . = ..() - -/proc/isvineimmune(atom/A) - . = FALSE - if(isliving(A)) - var/mob/living/M = A - if(("vines" in M.faction) || ("plants" in M.faction)) - . = TRUE +/datum/round_event_control/spacevine + name = "Spacevine" + typepath = /datum/round_event/spacevine + weight = 15 + max_occurrences = 3 + min_players = 10 + +/datum/round_event/spacevine + fakeable = FALSE + +/datum/round_event/spacevine/start() + var/list/turfs = list() //list of all the empty floor turfs in the hallway areas + + var/obj/structure/spacevine/SV = new() + + for(var/area/hallway/A in world) + for(var/turf/F in A) + if(F.Enter(SV)) + turfs += F + + qdel(SV) + + if(turfs.len) //Pick a turf to spawn at if we can + var/turf/T = pick(turfs) + new /datum/spacevine_controller(T) //spawn a controller at turf + + +/datum/spacevine_mutation + var/name = "" + var/severity = 1 + var/hue + var/quality + +/datum/spacevine_mutation/proc/add_mutation_to_vinepiece(obj/structure/spacevine/holder) + holder.mutations |= src + holder.add_atom_colour(hue, FIXED_COLOUR_PRIORITY) + +/datum/spacevine_mutation/proc/process_mutation(obj/structure/spacevine/holder) + return + +/datum/spacevine_mutation/proc/process_temperature(obj/structure/spacevine/holder, temp, volume) + return + +/datum/spacevine_mutation/proc/on_birth(obj/structure/spacevine/holder) + return + +/datum/spacevine_mutation/proc/on_grow(obj/structure/spacevine/holder) + return + +/datum/spacevine_mutation/proc/on_death(obj/structure/spacevine/holder) + return + +/datum/spacevine_mutation/proc/on_hit(obj/structure/spacevine/holder, mob/hitter, obj/item/I, expected_damage) + . = expected_damage + +/datum/spacevine_mutation/proc/on_cross(obj/structure/spacevine/holder, mob/crosser) + return + +/datum/spacevine_mutation/proc/on_chem(obj/structure/spacevine/holder, datum/reagent/R) + return + +/datum/spacevine_mutation/proc/on_eat(obj/structure/spacevine/holder, mob/living/eater) + return + +/datum/spacevine_mutation/proc/on_spread(obj/structure/spacevine/holder, turf/target) + return + +/datum/spacevine_mutation/proc/on_buckle(obj/structure/spacevine/holder, mob/living/buckled) + return + +/datum/spacevine_mutation/proc/on_explosion(severity, target, obj/structure/spacevine/holder) + return + + +/datum/spacevine_mutation/light + name = "light" + hue = "#ffff00" + quality = POSITIVE + severity = 4 + +/datum/spacevine_mutation/light/on_grow(obj/structure/spacevine/holder) + if(holder.energy) + holder.set_light(severity, 0.3) + +/datum/spacevine_mutation/toxicity + name = "toxic" + hue = "#ff00ff" + severity = 10 + quality = NEGATIVE + +/datum/spacevine_mutation/toxicity/on_cross(obj/structure/spacevine/holder, mob/living/crosser) + if(issilicon(crosser)) + return + if(prob(severity) && istype(crosser) && !isvineimmune(crosser)) + to_chat(crosser, "You accidentally touch the vine and feel a strange sensation.") + crosser.adjustToxLoss(5) + +/datum/spacevine_mutation/toxicity/on_eat(obj/structure/spacevine/holder, mob/living/eater) + if(!isvineimmune(eater)) + eater.adjustToxLoss(5) + +/datum/spacevine_mutation/explosive //OH SHIT IT CAN CHAINREACT RUN!!! + name = "explosive" + hue = "#ff0000" + quality = NEGATIVE + severity = 2 + +/datum/spacevine_mutation/explosive/on_explosion(explosion_severity, target, obj/structure/spacevine/holder) + if(explosion_severity < 3) + qdel(holder) + else + . = 1 + QDEL_IN(holder, 5) + +/datum/spacevine_mutation/explosive/on_death(obj/structure/spacevine/holder, mob/hitter, obj/item/I) + explosion(holder.loc, 0, 0, severity, 0, 0) + +/datum/spacevine_mutation/fire_proof + name = "fire proof" + hue = "#ff8888" + quality = MINOR_NEGATIVE + +/datum/spacevine_mutation/fire_proof/process_temperature(obj/structure/spacevine/holder, temp, volume) + return 1 + +/datum/spacevine_mutation/fire_proof/on_hit(obj/structure/spacevine/holder, mob/hitter, obj/item/I, expected_damage) + if(I && I.damtype == "fire") + . = 0 + else + . = expected_damage + +/datum/spacevine_mutation/vine_eating + name = "vine eating" + hue = "#ff7700" + quality = MINOR_NEGATIVE + +/datum/spacevine_mutation/vine_eating/on_spread(obj/structure/spacevine/holder, turf/target) + var/obj/structure/spacevine/prey = locate() in target + if(prey && !prey.mutations.Find(src)) //Eat all vines that are not of the same origin + qdel(prey) + +/datum/spacevine_mutation/aggressive_spread //very OP, but im out of other ideas currently + name = "aggressive spreading" + hue = "#333333" + severity = 3 + quality = NEGATIVE + +/datum/spacevine_mutation/aggressive_spread/on_spread(obj/structure/spacevine/holder, turf/target) + target.ex_act(severity, null, src) // vine immunity handled at /mob/ex_act + +/datum/spacevine_mutation/aggressive_spread/on_buckle(obj/structure/spacevine/holder, mob/living/buckled) + buckled.ex_act(severity, null, src) + +/datum/spacevine_mutation/transparency + name = "transparent" + hue = "" + quality = POSITIVE + +/datum/spacevine_mutation/transparency/on_grow(obj/structure/spacevine/holder) + holder.set_opacity(0) + holder.alpha = 125 + +/datum/spacevine_mutation/oxy_eater + name = "oxygen consuming" + hue = "#ffff88" + severity = 3 + quality = NEGATIVE + +/datum/spacevine_mutation/oxy_eater/process_mutation(obj/structure/spacevine/holder) + var/turf/open/floor/T = holder.loc + if(istype(T)) + var/datum/gas_mixture/GM = T.air + if(!GM.gases[/datum/gas/oxygen]) + return + GM.gases[/datum/gas/oxygen] = max(GM.gases[/datum/gas/oxygen] - severity * holder.energy, 0) + GAS_GARBAGE_COLLECT(GM.gases) + +/datum/spacevine_mutation/nitro_eater + name = "nitrogen consuming" + hue = "#8888ff" + severity = 3 + quality = NEGATIVE + +/datum/spacevine_mutation/nitro_eater/process_mutation(obj/structure/spacevine/holder) + var/turf/open/floor/T = holder.loc + if(istype(T)) + var/datum/gas_mixture/GM = T.air + if(!GM.gases[/datum/gas/nitrogen]) + return + GM.gases[/datum/gas/nitrogen] = max(GM.gases[/datum/gas/nitrogen] - severity * holder.energy, 0) + GAS_GARBAGE_COLLECT(GM.gases) + +/datum/spacevine_mutation/carbondioxide_eater + name = "CO2 consuming" + hue = "#00ffff" + severity = 3 + quality = POSITIVE + +/datum/spacevine_mutation/carbondioxide_eater/process_mutation(obj/structure/spacevine/holder) + var/turf/open/floor/T = holder.loc + if(istype(T)) + var/datum/gas_mixture/GM = T.air + if(!GM.gases[/datum/gas/carbon_dioxide]) + return + GM.gases[/datum/gas/carbon_dioxide] = max(GM.gases[/datum/gas/carbon_dioxide] - severity * holder.energy, 0) + GAS_GARBAGE_COLLECT(GM.gases) + +/datum/spacevine_mutation/plasma_eater + name = "toxins consuming" + hue = "#ffbbff" + severity = 3 + quality = POSITIVE + +/datum/spacevine_mutation/plasma_eater/process_mutation(obj/structure/spacevine/holder) + var/turf/open/floor/T = holder.loc + if(istype(T)) + var/datum/gas_mixture/GM = T.air + if(!GM.gases[/datum/gas/plasma]) + return + GM.gases[/datum/gas/plasma] = max(GM.gases[/datum/gas/plasma] - severity * holder.energy, 0) + GAS_GARBAGE_COLLECT(GM.gases) + +/datum/spacevine_mutation/thorns + name = "thorny" + hue = "#666666" + severity = 10 + quality = NEGATIVE + +/datum/spacevine_mutation/thorns/on_cross(obj/structure/spacevine/holder, mob/living/crosser) + if(prob(severity) && istype(crosser) && !isvineimmune(holder)) + var/mob/living/M = crosser + M.adjustBruteLoss(5) + to_chat(M, "You cut yourself on the thorny vines.") + +/datum/spacevine_mutation/thorns/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage) + if(prob(severity) && istype(hitter) && !isvineimmune(holder)) + var/mob/living/M = hitter + M.adjustBruteLoss(5) + to_chat(M, "You cut yourself on the thorny vines.") + . = expected_damage + +/datum/spacevine_mutation/woodening + name = "hardened" + hue = "#997700" + quality = NEGATIVE + +/datum/spacevine_mutation/woodening/on_grow(obj/structure/spacevine/holder) + if(holder.energy) + holder.density = TRUE + holder.max_integrity = 100 + holder.obj_integrity = holder.max_integrity + +/datum/spacevine_mutation/woodening/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage) + if(I.is_sharp()) + . = expected_damage * 0.5 + else + . = expected_damage + +/datum/spacevine_mutation/flowering + name = "flowering" + hue = "#0A480D" + quality = NEGATIVE + severity = 10 + +/datum/spacevine_mutation/flowering/on_grow(obj/structure/spacevine/holder) + if(holder.energy == 2 && prob(severity) && !locate(/obj/structure/alien/resin/flower_bud_enemy) in range(5,holder)) + new/obj/structure/alien/resin/flower_bud_enemy(get_turf(holder)) + +/datum/spacevine_mutation/flowering/on_cross(obj/structure/spacevine/holder, mob/living/crosser) + if(prob(25)) + holder.entangle(crosser) + + +// SPACE VINES (Note that this code is very similar to Biomass code) +/obj/structure/spacevine + name = "space vines" + desc = "An extremely expansionistic species of vine." + icon = 'icons/effects/spacevines.dmi' + icon_state = "Light1" + anchored = TRUE + density = FALSE + layer = SPACEVINE_LAYER + mouse_opacity = MOUSE_OPACITY_OPAQUE //Clicking anywhere on the turf is good enough + pass_flags = PASSTABLE | PASSGRILLE + max_integrity = 50 + var/energy = 0 + var/datum/spacevine_controller/master = null + var/list/mutations = list() + +/obj/structure/spacevine/Initialize() + . = ..() + add_atom_colour("#ffffff", FIXED_COLOUR_PRIORITY) + +/obj/structure/spacevine/examine(mob/user) + ..() + var/text = "This one is a" + if(mutations.len) + for(var/A in mutations) + var/datum/spacevine_mutation/SM = A + text += " [SM.name]" + else + text += " normal" + text += " vine." + to_chat(user, text) + +/obj/structure/spacevine/Destroy() + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_death(src) + if(master) + master.VineDestroyed(src) + mutations = list() + set_opacity(0) + if(has_buckled_mobs()) + unbuckle_all_mobs(force=1) + return ..() + +/obj/structure/spacevine/proc/on_chem_effect(datum/reagent/R) + var/override = 0 + for(var/datum/spacevine_mutation/SM in mutations) + override += SM.on_chem(src, R) + if(!override && istype(R, /datum/reagent/toxin/plantbgone)) + if(prob(50)) + qdel(src) + +/obj/structure/spacevine/proc/eat(mob/eater) + var/override = 0 + for(var/datum/spacevine_mutation/SM in mutations) + override += SM.on_eat(src, eater) + if(!override) + qdel(src) + +/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user) + var/damage_dealt = I.force + if(I.is_sharp()) + damage_dealt *= 4 + if(I.damtype == BURN) + damage_dealt *= 4 + + for(var/datum/spacevine_mutation/SM in mutations) + damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further + take_damage(damage_dealt, I.damtype, "melee", 1) + +/obj/structure/spacevine/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(src, 'sound/weapons/slash.ogg', 50, 1) + else + playsound(src, 'sound/weapons/tap.ogg', 50, 1) + if(BURN) + playsound(src.loc, 'sound/items/welder.ogg', 100, 1) + +/obj/structure/spacevine/Crossed(mob/crosser) + if(isliving(crosser)) + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_cross(src, crosser) + +//ATTACK HAND IGNORING PARENT RETURN VALUE +/obj/structure/spacevine/attack_hand(mob/user) + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_hit(src, user) + user_unbuckle_mob(user, user) + . = ..() + +/obj/structure/spacevine/attack_paw(mob/living/user) + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_hit(src, user) + user_unbuckle_mob(user,user) + +/obj/structure/spacevine/attack_alien(mob/living/user) + eat(user) + +/datum/spacevine_controller + var/list/obj/structure/spacevine/vines + var/list/growth_queue + var/spread_multiplier = 5 + var/spread_cap = 30 + var/list/vine_mutations_list + var/mutativeness = 1 + +/datum/spacevine_controller/New(turf/location, list/muts, potency, production) + vines = list() + growth_queue = list() + spawn_spacevine_piece(location, null, muts) + START_PROCESSING(SSobj, src) + vine_mutations_list = list() + init_subtypes(/datum/spacevine_mutation/, vine_mutations_list) + if(potency != null) + mutativeness = potency / 10 + if(production != null) + spread_cap *= production / 5 + spread_multiplier /= production / 5 + +/datum/spacevine_controller/vv_get_dropdown() + . = ..() + . += "---" + .["Delete Vines"] = "?_src_=[REF(src)];[HrefToken()];purge_vines=1" + +/datum/spacevine_controller/Topic(href, href_list) + if(..() || !check_rights(R_ADMIN, FALSE) || !usr.client.holder.CheckAdminHref(href, href_list)) + return + + if(href_list["purge_vines"]) + if(alert(usr, "Are you sure you want to delete this spacevine cluster?", "Delete Vines", "Yes", "No") != "Yes") + return + DeleteVines() + +/datum/spacevine_controller/proc/DeleteVines() //this is kill + QDEL_LIST(vines) //this will also qdel us + +/datum/spacevine_controller/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/datum/spacevine_controller/proc/spawn_spacevine_piece(turf/location, obj/structure/spacevine/parent, list/muts) + var/obj/structure/spacevine/SV = new(location) + growth_queue += SV + vines += SV + SV.master = src + if(muts && muts.len) + for(var/datum/spacevine_mutation/M in muts) + M.add_mutation_to_vinepiece(SV) + return + if(parent) + SV.mutations |= parent.mutations + var/parentcolor = parent.atom_colours[FIXED_COLOUR_PRIORITY] + SV.add_atom_colour(parentcolor, FIXED_COLOUR_PRIORITY) + if(prob(mutativeness)) + var/datum/spacevine_mutation/randmut = pick(vine_mutations_list - SV.mutations) + randmut.add_mutation_to_vinepiece(SV) + + for(var/datum/spacevine_mutation/SM in SV.mutations) + SM.on_birth(SV) + location.Entered(SV) + +/datum/spacevine_controller/proc/VineDestroyed(obj/structure/spacevine/S) + S.master = null + vines -= S + growth_queue -= S + if(!vines.len) + var/obj/item/seeds/kudzu/KZ = new(S.loc) + KZ.mutations |= S.mutations + KZ.set_potency(mutativeness * 10) + KZ.set_production((spread_cap / initial(spread_cap)) * 5) + qdel(src) + +/datum/spacevine_controller/process() + if(!LAZYLEN(vines)) + qdel(src) //space vines exterminated. Remove the controller + return + if(!growth_queue) + qdel(src) //Sanity check + return + + var/length = 0 + + length = min( spread_cap , max( 1 , vines.len / spread_multiplier ) ) + var/i = 0 + var/list/obj/structure/spacevine/queue_end = list() + + for(var/obj/structure/spacevine/SV in growth_queue) + if(QDELETED(SV)) + continue + i++ + queue_end += SV + growth_queue -= SV + for(var/datum/spacevine_mutation/SM in SV.mutations) + SM.process_mutation(SV) + if(SV.energy < 2) //If tile isn't fully grown + if(prob(20)) + SV.grow() + else //If tile is fully grown + SV.entangle_mob() + + SV.spread() + if(i >= length) + break + + growth_queue = growth_queue + queue_end + +/obj/structure/spacevine/proc/grow() + if(!energy) + src.icon_state = pick("Med1", "Med2", "Med3") + energy = 1 + set_opacity(1) + else + src.icon_state = pick("Hvy1", "Hvy2", "Hvy3") + energy = 2 + + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_grow(src) + +/obj/structure/spacevine/proc/entangle_mob() + if(!has_buckled_mobs() && prob(25)) + for(var/mob/living/V in src.loc) + entangle(V) + if(has_buckled_mobs()) + break //only capture one mob at a time + + +/obj/structure/spacevine/proc/entangle(mob/living/V) + if(!V || isvineimmune(V)) + return + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_buckle(src, V) + if((V.stat != DEAD) && (V.buckled != src)) //not dead or captured + to_chat(V, "The vines [pick("wind", "tangle", "tighten")] around you!") + buckle_mob(V, 1) + +/obj/structure/spacevine/proc/spread() + var/direction = pick(GLOB.cardinals) + var/turf/stepturf = get_step(src,direction) + if (!isspaceturf(stepturf) && stepturf.Enter(src)) + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_spread(src, stepturf) + stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen + if(!locate(/obj/structure/spacevine, stepturf)) + if(master) + master.spawn_spacevine_piece(stepturf, src) + +/obj/structure/spacevine/ex_act(severity, target) + if(istype(target, type)) //if its agressive spread vine dont do anything + return + var/i + for(var/datum/spacevine_mutation/SM in mutations) + i += SM.on_explosion(severity, target, src) + if(!i && prob(100/severity)) + qdel(src) + +/obj/structure/spacevine/temperature_expose(null, temp, volume) + var/override = 0 + for(var/datum/spacevine_mutation/SM in mutations) + override += SM.process_temperature(src, temp, volume) + if(!override) + qdel(src) + +/obj/structure/spacevine/CanPass(atom/movable/mover, turf/target) + if(isvineimmune(mover)) + . = TRUE + else + . = ..() + +/proc/isvineimmune(atom/A) + . = FALSE + if(isliving(A)) + var/mob/living/M = A + if(("vines" in M.faction) || ("plants" in M.faction)) + . = TRUE diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index 86ede7f255..0deb880674 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -13,42 +13,95 @@ var/list/vents = list() var/randomProbability = 1 var/reagentsAmount = 100 - var/list/saferChems = list("water","carbon","flour","cleaner","nutriment","condensedcapsaicin","mushroomhallucinogen","lube","pink_glitter","cryptobiolin", - "plantbgone","blood","charcoal","space_drugs","morphine","holywater","ethanol","hot_coco","sacid","mindbreaker","rotatium","bluespace", - "pax","laughter","concentrated_barbers_aid","colorful_reagent","dizzysolution","tiresolution","sodiumchloride","beer","hair_dye","sugar","white_glitter","growthserum") + var/list/saferChems = list( + "water", + "carbon", + "flour", + "cleaner", + "nutriment", + "condensedcapsaicin", + "mushroomhallucinogen", + "lube", + "pink_glitter", + "cryptobiolin", + "plantbgone", + "blood", + "charcoal", + "space_drugs", + "morphine", + "holywater", + "ethanol", + "hot_coco", + "sacid", + "mindbreaker", + "rotatium", + "bluespace", + "pax", + "laughter", + "concentrated_barbers_aid", + "colorful_reagent", + "dizzysolution", + "tiresolution", + "sodiumchloride", + "beer", + "hair_dye", + "sugar", + "white_glitter", + "growthserum", + "cornoil", + "uranium", + "carpet", + "firefighting_foam", + "semen", + "femcum", + "tearjuice", + "strange_reagent" + + ) //needs to be chemid unit checked at some point /datum/round_event/vent_clog/announce() priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert") /datum/round_event/vent_clog/setup() - endWhen = rand(25, 100) + endWhen = rand(120, 180) for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/temp_vent in GLOB.machines) var/turf/T = get_turf(temp_vent) - if(T && is_station_level(T.z) && !temp_vent.welded) + var/area/A = T.loc + if(T && is_station_level(T.z) && !temp_vent.welded && !A.safe) vents += temp_vent + if(!vents.len) return kill() -/datum/round_event/vent_clog/start() - for(var/obj/machinery/atmospherics/components/unary/vent in vents) - if(vent && vent.loc) - var/datum/reagents/R = new/datum/reagents(1000) - R.my_atom = vent - if (prob(randomProbability)) - R.add_reagent(get_random_reagent_id(), reagentsAmount) - else - R.add_reagent(pick(saferChems), reagentsAmount) +/datum/round_event/vent_clog/tick() - var/datum/effect_system/foam_spread/foam = new - foam.set_up(200, get_turf(vent), R) - foam.start() + if(!vents.len) + return kill() - var/cockroaches = prob(33) ? 3 : 0 - while(cockroaches) - new /mob/living/simple_animal/cockroach(get_turf(vent)) - cockroaches-- - CHECK_TICK + CHECK_TICK + + var/obj/machinery/atmospherics/components/unary/vent = pick(vents) + vents -= vent + + if(!vent || vent.welded) + return + + var/turf/T = get_turf(vent) + if(!T) + return + + var/datum/reagents/R = new/datum/reagents(1000) + R.my_atom = vent + if (prob(randomProbability)) + R.add_reagent(get_random_reagent_id(), reagentsAmount) + else + R.add_reagent(pick(saferChems), reagentsAmount) + + var/datum/effect_system/smoke_spread/chem/smoke_machine/C = new + C.set_up(R,16,1,T) + C.start() + playsound(T, 'sound/effects/smoke.ogg', 50, 1, -3) /datum/round_event_control/vent_clog/threatening name = "Clogged Vents: Threatening" @@ -108,7 +161,7 @@ /datum/round_event/vent_clog/beer/start() for(var/obj/machinery/atmospherics/components/unary/vent in vents) - if(vent && vent.loc) + if(vent && vent.loc && !vent.welded) var/datum/reagents/R = new/datum/reagents(1000) R.my_atom = vent R.add_reagent("beer", reagentsAmount) @@ -123,7 +176,7 @@ /datum/round_event/vent_clog/male/start() for(var/obj/machinery/atmospherics/components/unary/vent in vents) - if(vent && vent.loc) + if(vent && vent.loc && !vent.welded) var/datum/reagents/R = new/datum/reagents(1000) R.my_atom = vent R.add_reagent("semen", reagentsAmount) @@ -138,7 +191,7 @@ /datum/round_event/vent_clog/female/start() for(var/obj/machinery/atmospherics/components/unary/vent in vents) - if(vent && vent.loc) + if(vent && vent.loc && !vent.welded) var/datum/reagents/R = new/datum/reagents(1000) R.my_atom = vent R.add_reagent("femcum", reagentsAmount) @@ -153,7 +206,7 @@ /datum/round_event/vent_clog/plasma_decon/start() for(var/obj/machinery/atmospherics/components/unary/vent in vents) - if(vent && vent.loc) + if(vent && vent.loc && !vent.welded) var/datum/effect_system/smoke_spread/freezing/decon/smoke = new smoke.set_up(7, get_turf(vent), 7) smoke.start() diff --git a/code/modules/events/wizard/race.dm b/code/modules/events/wizard/race.dm index 32b45e46f8..7ea875f152 100644 --- a/code/modules/events/wizard/race.dm +++ b/code/modules/events/wizard/race.dm @@ -5,6 +5,18 @@ max_occurrences = 5 earliest_start = 0 MINUTES +/datum/round_event/wizard/race + var/list/stored_name + var/list/stored_species + var/list/stored_dna + +/datum/round_event/wizard/race/setup() + stored_name = list() + stored_species = list() + stored_dna = list() + endWhen = rand(600,1200) //10 to 20 minutes + ..() + /datum/round_event/wizard/race/start() var/all_the_same = 0 @@ -12,18 +24,35 @@ for(var/speciestype in subtypesof(/datum/species)) var/datum/species/S = new speciestype() - if(!S.dangerous_existence && !S.blacklisted) + if(!S.dangerous_existence && !S.blacklisted && !S.nojumpsuit) //Dangerous Species, Blacklisted Species, and Species who can't wear jumpsuits are blacklisted. all_species += speciestype var/datum/species/new_species = pick(all_species) - if(prob(50)) + if(prob(75)) all_the_same = 1 - for(var/mob/living/carbon/human/H in GLOB.carbon_list) //yes, even the dead + for(var/mob/living/carbon/human/H in GLOB.carbon_list) + var/turf/T = get_turf(H) + if(!T) + continue + if(!is_station_level(T.z)) + continue + stored_name[H] = H.real_name + stored_species[H] = H.dna.species + stored_dna[H] = H.dna.unique_enzymes H.set_species(new_species) H.real_name = H.dna.species.random_name(H.gender,1) H.dna.unique_enzymes = H.dna.generate_unique_enzymes() to_chat(H, "You feel somehow... different?") if(!all_the_same) new_species = pick(all_species) + +/datum/round_event/wizard/race/end() + for(var/mob/living/carbon/human/H in GLOB.carbon_list) + if(!(stored_name[H] && stored_species[H] && stored_dna[H])) + continue + H.set_species(stored_species[H]) + H.real_name = stored_name[H] + H.dna.unique_enzymes = stored_dna[H] + to_chat(H, "You feel back to your normal self again.") \ No newline at end of file diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 6594146e81..a6b7de0330 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -8,7 +8,7 @@ icon_state = null lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' - container_type = OPENCONTAINER + reagent_flags = OPENCONTAINER var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it. possible_transfer_amounts = list(5,10,15,20,25,30,50) volume = 50 @@ -36,7 +36,7 @@ if(M == user) user.visible_message("[user] swallows a gulp of [src].", "You swallow a gulp of [src].") - if(M.has_trait(TRAIT_VORACIOUS)) + if(HAS_TRAIT(M, TRAIT_VORACIOUS)) M.changeNext_move(CLICK_CD_MELEE * 0.5) //chug! chug! chug! else @@ -152,7 +152,6 @@ possible_transfer_amounts = list() volume = 5 flags_1 = CONDUCT_1 - container_type = OPENCONTAINER spillable = TRUE resistance_flags = FIRE_PROOF isGlass = FALSE @@ -399,7 +398,7 @@ name = "soda can" lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' - container_type = NONE + reagent_flags = NONE spillable = FALSE isGlass = FALSE @@ -423,7 +422,7 @@ /obj/item/reagent_containers/food/drinks/soda_cans/attack_self(mob/user) if(!is_drainable()) to_chat(user, "You pull back the tab of \the [src] with a satisfying pop.") //Ahhhhhhhh - container_type = OPENCONTAINER + ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) playsound(src, "can_open", 50, 1) spillable = TRUE return diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 46e637e640..dab933ca4e 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -57,7 +57,7 @@ if(user.a_intent != INTENT_HARM || !isGlass) return ..() - if(user.has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to harm [target]!") return @@ -73,7 +73,7 @@ var/mob/living/carbon/human/H = target var/headarmor = 0 // Target's head armor - armor_block = H.run_armor_check(affecting, "melee","","",armour_penetration) // For normal attack damage + armor_block = H.run_armor_check(affecting, "melee", null, null,armour_penetration) // For normal attack damage //If they have a hat/helmet and the user is targeting their head. if(istype(H.head, /obj/item/clothing/head) && affecting == BODY_ZONE_HEAD) diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index f9d9a3d85a..51433da841 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -4,7 +4,7 @@ /obj/item/reagent_containers/food possible_transfer_amounts = list() volume = 50 //Sets the default container amount for all food items. - container_type = INJECTABLE + reagent_flags = INJECTABLE resistance_flags = FLAMMABLE var/foodtype = NONE var/last_check_time @@ -19,7 +19,7 @@ if(last_check_time + 50 < world.time) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(!H.has_trait(TRAIT_AGEUSIA)) + if(!HAS_TRAIT(H, TRAIT_AGEUSIA)) if(foodtype & H.dna.species.toxic_food) to_chat(H,"What the hell was that thing?!") H.adjust_disgust(25 + 30 * fraction) diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index d6d744f4db..0aef697883 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -10,7 +10,7 @@ desc = "Just your average condiment container." icon = 'icons/obj/food/containers.dmi' icon_state = "emptycondiment" - container_type = OPENCONTAINER + reagent_flags = OPENCONTAINER possible_transfer_amounts = list(1, 5, 10, 15, 20, 25, 30, 50) volume = 50 //Possible_states has the reagent id as key and a list of, in order, the icon_state, the name and the desc as values. Used in the on_reagent_change(changetype) to change names, descs and sprites. diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 7c7545869b..3eeb5b9417 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -290,7 +290,7 @@ desc = "A simple bowl, used for soups and salads." icon = 'icons/obj/food/soupsalad.dmi' icon_state = "bowl" - container_type = OPENCONTAINER + reagent_flags = OPENCONTAINER materials = list(MAT_GLASS = 500) w_class = WEIGHT_CLASS_NORMAL diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index f2b195c32d..d3408ca5e5 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -108,11 +108,11 @@ All foods are distributed among various categories. Use common sense. else if(fullness > 150 && fullness < 500) user.visible_message("[user] takes a [eatverb] from \the [src].", "You take a [eatverb] from \the [src].") else if(fullness > 500 && fullness < 600) - user.visible_message("[user] unwillingly takes a [eatverb] of a bit of \the [src].", "You unwillingly take a [eatverb] of a bit of \the [src].") + user.visible_message("[user] unwillingly takes a [eatverb] of a bit of \the [src].", "You unwillingly take a [eatverb] of a bit of \the [src].") else if(fullness > (600 * (1 + M.overeatduration / 2000))) // The more you eat - the more you can eat - user.visible_message("[user] cannot force any more of \the [src] to go down [user.p_their()] throat!", "You cannot force any more of \the [src] to go down your throat!") + user.visible_message("[user] cannot force any more of \the [src] to go down [user.p_their()] throat!", "You cannot force any more of \the [src] to go down your throat!") return 0 - if(M.has_trait(TRAIT_VORACIOUS)) + if(HAS_TRAIT(M, TRAIT_VORACIOUS)) M.changeNext_move(CLICK_CD_MELEE * 0.5) //nom nom nom else if(!isbrain(M)) //If you're feeding it to someone else. diff --git a/code/modules/food_and_drinks/food/snacks_cake.dm b/code/modules/food_and_drinks/food/snacks_cake.dm index 781b021d05..1eeea79410 100644 --- a/code/modules/food_and_drinks/food/snacks_cake.dm +++ b/code/modules/food_and_drinks/food/snacks_cake.dm @@ -54,7 +54,6 @@ tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1) foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR - /obj/item/reagent_containers/food/snacks/store/cake/brain name = "brain cake" desc = "A squishy cake-thing." @@ -86,7 +85,6 @@ tastes = list("cake" = 4, "cream cheese" = 3) foodtype = GRAIN | DAIRY - /obj/item/reagent_containers/food/snacks/cakeslice/cheese name = "cheese cake slice" desc = "Slice of pure cheestisfaction." @@ -95,7 +93,6 @@ tastes = list("cake" = 4, "cream cheese" = 3) foodtype = GRAIN | DAIRY - /obj/item/reagent_containers/food/snacks/store/cake/orange name = "orange cake" desc = "A cake with added orange." @@ -132,7 +129,6 @@ tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2) foodtype = GRAIN | DAIRY | FRUIT | SUGAR - /obj/item/reagent_containers/food/snacks/store/cake/lemon name = "lemon cake" desc = "A cake with added lemon." @@ -143,7 +139,6 @@ tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) foodtype = GRAIN | DAIRY | FRUIT | SUGAR - /obj/item/reagent_containers/food/snacks/cakeslice/lemon name = "lemon cake slice" desc = "Just a slice of cake, it is enough for everyone." @@ -163,7 +158,6 @@ tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR - /obj/item/reagent_containers/food/snacks/cakeslice/chocolate name = "chocolate cake slice" desc = "Just a slice of cake, it is enough for everyone." @@ -172,7 +166,6 @@ tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR - /obj/item/reagent_containers/food/snacks/store/cake/birthday name = "birthday cake" desc = "Happy Birthday little clown..." @@ -250,5 +243,100 @@ icon_state = "pumpkinspicecakeslice" filling_color = "#FFD700" tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1) - foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR + +/obj/item/reagent_containers/food/snacks/store/cake/bsvc // blackberry strawberries vanilla cake + name = "blackberry and strawberry vanilla cake" + desc = "A plain cake, filled with assortment of blackberries and strawberries!" + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "blackbarry_strawberries_cake_vanilla_cake" + slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/bsvc + bonus_reagents = list("nutriment" = 14, "vitamin" = 4) + tastes = list("blackbarry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2, "cake" = 3) + foodtype = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/reagent_containers/food/snacks/cakeslice/bsvc + name = "blackberry and strawberry vanilla cake slice" + desc = "Just a slice of cake filled with assortment of blackberries and strawberries!" + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "blackbarry_strawberries_cake_vanilla_slice" + filling_color = "#FFD700" + tastes = list("blackbarry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2,"cake" = 3) + foodtype = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/reagent_containers/food/snacks/store/cake/bscc // blackbarry strawberries chocolate cake + name = "blackberry and strawberry chocolate cake" + desc = "A plain cake, filled with assortment of blackberries and strawberries!" + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "blackbarry_strawberries_cake_coco_cake" + slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/bscc + bonus_reagents = list("nutriment" = 14, "vitamin" = 4, "cocoa" = 5) + tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3) + foodtype = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/reagent_containers/food/snacks/cakeslice/bscc + name = "blackberry and strawberry chocolate cake slice" + desc = "Just a slice of cake filled with assortment of blackberries and strawberries!" + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "blackbarry_strawberries_cake_coco_cake_slice" + filling_color = "#FFD700" + tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3) + foodtype = GRAIN | DAIRY | FRUIT | SUGAR + +obj/item/reagent_containers/food/snacks/store/cake/holy_cake + name = "angel food cake" + desc = "A cake made for angels and chaplains alike! Contains holy water." + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "holy_cake" + slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/holy_cake_slice + bonus_reagents = list("nutriment" = 1, "vitamin" = 3, "holy_water" = 10) + tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1) + foodtype = GRAIN | DAIRY | SUGAR + +/obj/item/reagent_containers/food/snacks/cakeslice/holy_cake_slice + name = "angel food cake slice" + desc = "A slice of heavenly cake." + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "holy_cake_slice" + filling_color = "#00FFFF" + tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1) + foodtype = GRAIN | DAIRY | SUGAR + +obj/item/reagent_containers/food/snacks/store/cake/pound_cake + name = "pound cake" + desc = "A condensed cake made for filling people up quickly." + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "pound_cake" + slices_num = 7 //Its ment to feed the party + slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/pound_cake_slice + bonus_reagents = list("nutriment" = 60) + tastes = list("cake" = 5, "sweetness" = 1, "batter" = 1) + foodtype = GRAIN | DAIRY | SUGAR | JUNKFOOD + +/obj/item/reagent_containers/food/snacks/cakeslice/pound_cake_slice + name = "pound cake slice" + desc = "A slice of condensed cake made for filling people up quickly." + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "pound_cake_slice" + filling_color = "#00FFFF" + tastes = list("cake" = 5, "sweetness" = 5, "batter" = 1) + foodtype = GRAIN | DAIRY | SUGAR | JUNKFOOD + +obj/item/reagent_containers/food/snacks/store/cake/hardware_cake + name = "hardware cake" + desc = "A cake that is made with electronic boards and leaks acid..." + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "hardware_cake" + slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/hardware_cake_slice + bonus_reagents = list("sacid" = 15, "oil" = 15) + tastes = list("acid" = 1, "metal" = 1, "regret" = 10) + foodtype = GRAIN | GROSS + +/obj/item/reagent_containers/food/snacks/cakeslice/hardware_cake_slice + name = "hardware cake slice" + desc = "A slice of electronic boards and some acid." + icon = 'modular_citadel/icons/obj/food/cake.dmi' + icon_state = "hardware_cake_slice" + filling_color = "#00FFFF" + tastes = list("acid" = 1, "metal" = 1, "regret" = 10) + foodtype = GRAIN | GROSS diff --git a/code/modules/food_and_drinks/food/snacks_frozen.dm b/code/modules/food_and_drinks/food/snacks_frozen.dm new file mode 100644 index 0000000000..febfa527ca --- /dev/null +++ b/code/modules/food_and_drinks/food/snacks_frozen.dm @@ -0,0 +1,187 @@ +/obj/item/reagent_containers/food/snacks/icecreamsandwich + name = "icecream sandwich" + desc = "Portable Ice-cream in its own packaging." + icon = 'icons/obj/food/food.dmi' + icon_state = "icecreamsandwich" + bonus_reagents = list("nutriment" = 1, "ice" = 2) + list_reagents = list("nutriment" = 2, "ice" = 2) + tastes = list("ice cream" = 1) + foodtype = GRAIN | DAIRY + +/obj/item/reagent_containers/food/snacks/sundae + name = "sundae" + desc = "A classic dessert." + icon_state = "sundae" + bonus_reagents = list("nutriment" = 2, "vitamin" = 1) + list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) + filling_color = "#FFFACD" + tastes = list("ice cream" = 1, "banana" = 1) + foodtype = FRUIT | DAIRY | SUGAR + +/obj/item/reagent_containers/food/snacks/honkdae + name = "honkdae" + desc = "The clown's favorite dessert." + icon_state = "honkdae" + bonus_reagents = list("nutriment" = 2, "vitamin" = 2) + list_reagents = list("nutriment" = 6, "banana" = 10, "vitamin" = 4) + filling_color = "#FFFACD" + tastes = list("ice cream" = 1, "banana" = 1, "a bad joke" = 1) + foodtype = FRUIT | DAIRY | SUGAR + +/obj/item/reagent_containers/food/snacks/spacefreezy + name = "space freezy" + desc = "The best icecream in space." + icon_state = "spacefreezy" + bonus_reagents = list("nutriment" = 2, "vitamin" = 2) + list_reagents = list("nutriment" = 6, "bluecherryjelly" = 5, "vitamin" = 4) + filling_color = "#87CEFA" + tastes = list("blue cherries" = 2, "ice cream" = 2) + foodtype = FRUIT | DAIRY + +///////////// +//SNOWCONES// +///////////// + +/obj/item/reagent_containers/food/snacks/snowcones //We use this as a base for all other snowcones + name = "flaverless snowcone" + desc = "Its just harden water slivers. Still fun to chew on." + icon = 'icons/obj/food/snowcones.dmi' + icon_state = "flaverless_sc" + trash = /obj/item/reagent_containers/food/drinks/sillycup //We dont eat paper cups + bonus_reagents = list("water" = 10) //Base line will allways give water + list_reagents = list("water" = 1) // We dont get food for water/juices + filling_color = "#FFFFFF" //Ice is white + tastes = list("ice" = 1, "water" = 1) + foodtype = SUGAR //We use SUGAR as a base line to act in as junkfood, other wise we use fruit + +/obj/item/reagent_containers/food/snacks/snowcones/lime + name = "lime flavored snowcone" + desc = "A lime flavord snowball in a paper cup." + icon_state = "lime_sc" + list_reagents = list("nutriment" = 1, "limejuice" = 5) + tastes = list("ice" = 1, "water" = 1, "limes" = 5) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/lemon + name = "lemon flavored snowcone" + desc = "A lemon flavord snowball in a paper cup." + icon_state = "lemon_sc" + list_reagents = list("nutriment" = 1, "lemonjuice" = 5) + tastes = list("ice" = 1, "water" = 1, "lemons" = 5) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/apple + name = "apple flavored snowcone" + desc = "A apple flavord snowball in a paper cup." + icon_state = "blue_sc" + list_reagents = list("nutriment" = 1, "applejuice" = 5) + tastes = list("ice" = 1, "water" = 1, "apples" = 5) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/grape + name = "grape flavored snowcone" + desc = "A grape flavord snowball in a paper cup." + icon_state = "grape_sc" + list_reagents = list("nutriment" = 1, "berryjuice" = 5) + tastes = list("ice" = 1, "water" = 1, "grape" = 5) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/orange + name = "orange flavored snowcone" + desc = "A mix of different flavors dizzled on a snowball in a paper cup." + icon_state = "orange_sc" + list_reagents = list("nutriment" = 1, "orangejuice" = 10) + tastes = list("ice" = 1, "water" = 1, "berries" = 5) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/blue + name = "bluecherry flavored snowcone" + desc = "A bluecharry flavord snowball in a paper cup, how rare!" + icon_state = "red_sc" + list_reagents = list("nutriment" = 1, "bluecherryjelly" = 5) + tastes = list("ice" = 1, "water" = 1, "blue" = 5) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/red + name = "cherry flavored snowcone" + desc = "A cherry flavord snowball in a paper cup." + icon_state = "blue_sc" + list_reagents = list("nutriment" = 1, "cherryjelly" = 5) + tastes = list("ice" = 1, "water" = 1, "red" = 5) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/kiwi + name = "kiwi flavored snowcone" + desc = "A kiwi flavord snowball in a paper cup." + icon_state = "kiwi_sc" + list_reagents = list("nutriment" = 3, "vitamin" = 6) + tastes = list("ice" = 1, "space" = 3, "kiwi" = 5) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/mix + name = "mixed berry flavored snowcone" + desc = "A mix of different flavors dizzled on a snowball in a paper cup." + icon_state = "berry_sc" + list_reagents = list("nutriment" = 1, "berryjuice" = 10) + tastes = list("ice" = 1, "water" = 1, "berries" = 5) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/fruitsalad + name = "mixed fruit flavored snowcone" + desc = "A mix of different flavors dizzled on a snowball in a paper cup." + icon_state = "fruitsalad_sc" + list_reagents = list("nutriment" = 1, "lemonjuice" = 5, "limejuice" = 5, "lemonjuice" = 5, "orangejuice" = 5) + tastes = list("ice" = 1, "water" = 1, "fruits" = 25) + foodtype = FRUIT + +/obj/item/reagent_containers/food/snacks/snowcones/pineapple + name = "pineapple flavored snowcone" + desc = "A pineapple flavord snowball in a paper cup." + icon_state = "pineapple_sc" + list_reagents = list("nutriment" = 1, "water" = 1) + tastes = list("ice" = 1, "water" = 1, "pineapples" = 5) + foodtype = PINEAPPLE //Pineapple to allow all that like pineapple to enjoy + +/obj/item/reagent_containers/food/snacks/snowcones/mime + name = "mime snowcone" + desc = "..." + icon_state = "mime_sc" + list_reagents = list("nutriment" = 1, "nothing" = 5) + tastes = list("nothing" = 5) + +/obj/item/reagent_containers/food/snacks/snowcones/clown + name = "joke flavored snowcone" + desc = "A waterd down jokeful flavord snowball in a paper cup." + icon_state = "clown_sc" + list_reagents = list("nutriment" = 1, "laughter" = 5) + tastes = list("jokes" = 5, "brainfreeze" = 5, "joy" = 5) + +/obj/item/reagent_containers/food/snacks/snowcones/soda + name = "sodawater flavored snowcone" + desc = "A waterd down sodawater flavored snowcone snowball in a paper cup." + icon_state = "soda_sc" + list_reagents = list("nutriment" = 1, "sodawater" = 5) + tastes = list("surgar" = 1, "water" = 5, "soda" = 5) + foodtype = JUNKFOOD | SUGAR + +/obj/item/reagent_containers/food/snacks/snowcones/pwgrmer + name = "pwergamer flavored snowcone" + desc = "A waterd down pwergamer soda flavord snowball in a paper cup." + icon_state = "pwergamer_sc" + list_reagents = list("nutriment" = 1, "laughter" = 1) + tastes = list("vaild" = 5, "salt" = 5, "wats" = 5) + foodtype = JUNKFOOD | SUGAR + +/obj/item/reagent_containers/food/snacks/snowcones/honey + name = "honey flavored snowcone" + desc = "A honey flavord snowball in a paper cup." + icon_state = "honey_sc" + list_reagents = list("nutriment" = 1, "honey" = 5) + tastes = list("pollen" = 5, "sweetness" = 5, "wax" = 1) + +/obj/item/reagent_containers/food/snacks/snowcones/rainbow + name = "rainbow color snowcone" + desc = "A rainbow color snowball in a paper cup." + icon_state = "rainbow_sc" + list_reagents = list("nutriment" = 5, "laughter" = 25) + tastes = list("sunlight" = 5, "light" = 5, "slime" = 5, "paint" = 3, "clouds" = 3) diff --git a/code/modules/food_and_drinks/food/snacks_meat.dm b/code/modules/food_and_drinks/food/snacks_meat.dm index d3466caa5e..cf99bd78d9 100644 --- a/code/modules/food_and_drinks/food/snacks_meat.dm +++ b/code/modules/food_and_drinks/food/snacks_meat.dm @@ -54,6 +54,43 @@ tastes = list("fish" = 1, "chips" = 1) foodtype = MEAT | VEGETABLES | FRIED +/obj/item/reagent_containers/food/snacks/sushi_basic + name = "funa hosomaki" + desc = "A small cylindrical kudzu skin, filled with rice and fish." + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sushie_basic" + bonus_reagents = list("vitamin" = 2) + list_reagents = list("nutriment" = 4) + bitesize = 10 + filling_color = "#F2EEEA" //rgb(242, 238, 234) + tastes = list("fish" = 1, "rice" = 2, "salt" = 1) + foodtype = MEAT | VEGETABLES + +/obj/item/reagent_containers/food/snacks/sushi_adv + name = "funa nigiri" + desc = "A peace of carp lightly placed on some rice." + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sushie_adv" + bonus_reagents = list("vitamin" = 2) + list_reagents = list("nutriment" = 6) + bitesize = 10 + filling_color = "#F2EEEA" //rgb(242, 238, 234) + tastes = list("fish" = 2, "rice" = 2, "salt" = 1) + foodtype = MEAT | VEGETABLES + +/obj/item/reagent_containers/food/snacks/sushi_pro + name = "funa nigiri" + desc = "A well prepared peace of the best of the carp fillet placed on rice. Looks fancy and fresh!" + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sushie_pro" + bonus_reagents = list("nutriment" = 2, "vitamin" = 2) + list_reagents = list("nutriment" = 6, "vitamin" = 2) + bitesize = 10 + filling_color = "#F2EEEA" //rgb(242, 238, 234) + tastes = list("fish" = 3, "rice" = 2, "salt" = 1) + foodtype = MEAT | VEGETABLES + + ////////////////////////////////////////////MEATS AND ALIKE//////////////////////////////////////////// /obj/item/reagent_containers/food/snacks/tofu diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index af7a8c06f4..c1abec86c1 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -207,6 +207,16 @@ tastes = list("cobwebs" = 1, "sugar" = 2) foodtype = JUNKFOOD | SUGAR +/obj/item/reagent_containers/food/snacks/tobiko + name = "tobiko" + desc = "Spider eggs wrapped in a thin salted Kudzu pod" + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sushie_egg" + list_reagents = list("nutriment" = 6, "vitamin" = 2) + filling_color = "#FF3333" // R225 G051 B051 + tastes = list("seaweed" = 1, "cobwebs" = 1, "salty" = 2) + foodtype = MEAT | VEGETABLES + /obj/item/reagent_containers/food/snacks/chococoin name = "chocolate coin" desc = "A completely edible but nonflippable festive coin." @@ -330,36 +340,6 @@ tastes = list("melon" = 1) foodtype = FRUIT -/obj/item/reagent_containers/food/snacks/spacefreezy - name = "space freezy" - desc = "The best icecream in space." - icon_state = "spacefreezy" - bonus_reagents = list("nutriment" = 2, "vitamin" = 2) - list_reagents = list("nutriment" = 6, "bluecherryjelly" = 5, "vitamin" = 4) - filling_color = "#87CEFA" - tastes = list("blue cherries" = 2, "ice cream" = 2) - foodtype = FRUIT | DAIRY - -/obj/item/reagent_containers/food/snacks/sundae - name = "sundae" - desc = "A classic dessert." - icon_state = "sundae" - bonus_reagents = list("nutriment" = 2, "vitamin" = 1) - list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) - filling_color = "#FFFACD" - tastes = list("ice cream" = 1, "banana" = 1) - foodtype = FRUIT | DAIRY | SUGAR - -/obj/item/reagent_containers/food/snacks/honkdae - name = "honkdae" - desc = "The clown's favorite dessert." - icon_state = "honkdae" - bonus_reagents = list("nutriment" = 2, "vitamin" = 2) - list_reagents = list("nutriment" = 6, "banana" = 10, "vitamin" = 4) - filling_color = "#FFFACD" - tastes = list("ice cream" = 1, "banana" = 1, "a bad joke" = 1) - foodtype = FRUIT | DAIRY | SUGAR - /obj/item/reagent_containers/food/snacks/nachos name = "nachos" desc = "Chips from Space Mexico." @@ -569,3 +549,12 @@ filling_color = "#A0522D" tastes = list("chocolate" = 1) foodtype = JUNKFOOD | SUGAR + +/obj/item/reagent_containers/food/snacks/riceball + name = "onigiri" + desc = "A ball of rice with some light salt and a wrap of Kudzu skin." + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "riceball" + list_reagents = list("nutriment" = 6, "sodiumchloride" = 2) + tastes = list("rice" = 3, "salt" = 1) + foodtype = GRAIN diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 435b4a371a..927a7d2697 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -28,7 +28,7 @@ if(last_check_time + 50 < world.time) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.mind && H.mind.assigned_role == "Security Officer" || H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Warden" || H.mind.assigned_role == "Head of Security" && !H.has_trait(TRAIT_AGEUSIA)) + if(H.mind && H.mind.assigned_role == "Security Officer" || H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Warden" || H.mind.assigned_role == "Head of Security" && !HAS_TRAIT(H, TRAIT_AGEUSIA)) to_chat(H,"I love this taste!") H.adjust_disgust(-5 + -2.5 * fraction) GET_COMPONENT_FROM(mood, /datum/component/mood, H) @@ -203,7 +203,7 @@ list_reagents = list("nutriment" = 1) filling_color = "#F0E68C" tastes = list("cookie" = 1) - foodtype = GRAIN | SUGAR + foodtype = SUGAR /obj/item/reagent_containers/food/snacks/donkpocket name = "\improper Donk-pocket" diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm index 04177783e6..8264b4153e 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -62,6 +62,28 @@ /obj/item/reagent_containers/food/snacks/pie/cream/nostun stunning = FALSE +/obj/item/reagent_containers/food/snacks/pie/cream/body + +/obj/item/reagent_containers/food/snacks/pie/cream/body/Destroy() + var/turf/T = get_turf(src) + for(var/atom/movable/A in contents) + A.forceMove(T) + A.throw_at(T, 1, 1) + . = ..() + +/obj/item/reagent_containers/food/snacks/pie/cream/body/On_Consume(mob/living/carbon/M) + if(!reagents.total_volume) //so that it happens on the last bite + if(iscarbon(M) && contents.len) + var/turf/T = get_turf(src) + for(var/atom/movable/A in contents) + A.forceMove(T) + A.throw_at(T, 1, 1) + M.visible_message("[src] bursts out of [M]!
") + M.emote("scream") + M.Knockdown(40) + M.adjustBruteLoss(60) + return ..() + /obj/item/reagent_containers/food/snacks/pie/berryclafoutis name = "berry clafoutis" desc = "No black birds, this is a good sign." diff --git a/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm b/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm index 747f5f7d35..1b602b6759 100644 --- a/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm +++ b/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm @@ -52,16 +52,6 @@ list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2) foodtype = GRAIN | FRUIT -/obj/item/reagent_containers/food/snacks/icecreamsandwich - name = "icecream sandwich" - desc = "Portable Ice-cream in its own packaging." - icon = 'icons/obj/food/food.dmi' - icon_state = "icecreamsandwich" - bonus_reagents = list("nutriment" = 1, "ice" = 2) - list_reagents = list("nutriment" = 2, "ice" = 2) - tastes = list("ice cream" = 1) - foodtype = GRAIN | DAIRY - /obj/item/reagent_containers/food/snacks/notasandwich name = "not-a-sandwich" desc = "Something seems to be wrong with this, you can't quite figure what. Maybe it's his moustache." @@ -102,3 +92,13 @@ list_reagents = list("nutriment" = 2, "vitamin" = 2) tastes = list("bread" = 2) foodtype = GRAIN + +/obj/item/reagent_containers/food/snacks/tuna_sandwich + name = "tuna sandwich" + desc = "Both a salad and a sandwich in one." + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "tunasandwich" + trash = /obj/item/trash/plate + bonus_reagents = list("nutriment" = 1, "vitamin" = 3) + tastes = list("tuna" = 4, "mayonnaise" = 2, "bread" = 2) + foodtype = GRAIN | MEAT diff --git a/code/modules/food_and_drinks/food/snacks_sushi.dm b/code/modules/food_and_drinks/food/snacks_sushi.dm new file mode 100644 index 0000000000..a4cbc5e344 --- /dev/null +++ b/code/modules/food_and_drinks/food/snacks_sushi.dm @@ -0,0 +1,95 @@ +//////////////////////////Sushi Components/////////////////////// + +/obj/item/reagent_containers/food/snacks/sushi_rice + name = "Sushi Rice" + desc = "A bowl of sticky rice for making sushi." + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sushi_rice" + list_reagents = list("sodiumchloride" = 5) + tastes = list("rice" = 5, "salt" = 1) + foodtype = GRAIN + +/obj/item/reagent_containers/food/snacks/sea_weed + name = "Sea Weed Sheet" + desc = "A thin, light salt sheet of plant mater. This is commenly used in sushi recipes," + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sea_weed" + list_reagents = list("sodiumchloride" = 2) + tastes = list("plants" = 2, "salt" = 1) + foodtype = VEGETABLES + +/obj/item/reagent_containers/food/snacks/tuna + name = "Canned Tuna" + desc = "A small can of tuna fish beloved by felines." + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "tuna_can" +//trash = /obj/item/trash/tuna_used //I dont know if I like this idea - A Masked Cat + list_reagents = list("sodiumchloride" = 5, "mercury" = 2) + tastes = list("tuna" = 15, "mercury" = 1, "salt" = 3) + foodtype = MEAT + +//////////////////////////Sushi///////////////////////////////// +/obj/item/reagent_containers/food/snacks/sushie_basic + name = "Funa Hosomaki" + desc = "A small cylindrical filled with rice and fish." + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sushie_basic" + bonus_reagents = list("vitamin" = 2) + list_reagents = list("nutriment" = 1) + bitesize = 1 + filling_color = "#F2EEEA" //rgb(242, 238, 234) + tastes = list("fish" = 1, "rice" = 1, "salt" = 1) + foodtype = MEAT | VEGETABLES + +/obj/item/reagent_containers/food/snacks/sushie_adv + name = "Funa Nigiri" + desc = "A pice of carp lightly placed on some rice." + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sushie_adv" + bonus_reagents = list("vitamin" = 2) + list_reagents = list("nutriment" = 2) + bitesize = 1 + filling_color = "#F2EEEA" //rgb(242, 238, 234) + tastes = list("fish" = 1, "rice" = 1, "salt" = 1) + foodtype = MEAT | VEGETABLES + +/obj/item/reagent_containers/food/snacks/sushie_pro + name = "Funa Nigiri" + desc = "A well prepared pice of the best of the carp fillet placed on rice. Looks fancy and fresh!" + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sushie_pro" + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 8, "vitamin" = 1) + bitesize = 1 + filling_color = "#F2EEEA" //rgb(242, 238, 234) + tastes = list("fish" = 1, "rice" = 1, "salt" = 1) + foodtype = MEAT | VEGETABLES + +/obj/item/reagent_containers/food/snacks/tobiko + name = "Tobiko" + desc = "Spider eggs wrapped in a thin salted Kudzu pod" + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "sushie_egg" + list_reagents = list("nutriment" = 3, "vitamin" = 2) + filling_color = "#FF3333" // R225 G051 B051 + tastes = list("seaweed" = 1, "salty" = 2) + foodtype = MEAT | VEGETABLES + +/obj/item/reagent_containers/food/snacks/riceball + name = "Onigiri" + desc = "A ball of rice with some light salt and a wrap of Kudzu skin." + icon = 'modular_citadel/icons/obj/food/food.dmi' + icon_state = "riceball" + list_reagents = list("nutriment" = 5, "sodiumchloride" = 2) + tastes = list("rice" = 4, "salt" = 1) + foodtype = GRAIN + +/obj/item/reagent_containers/food/snacks/sashimi + name = "carp sashimi" + desc = "Celebrate surviving attack from hostile alien lifeforms by hospitalising yourself." + icon_state = "sashimi" + bonus_reagents = list("nutriment" = 1, "capsaicin" = 4, "vitamin" = 4) + list_reagents = list("nutriment" = 6, "capsaicin" = 5) + filling_color = "#FA8072" + tastes = list("fish" = 1, "hot peppers" = 1) + foodtype = MEAT | TOXIC \ No newline at end of file diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 5e7a3db504..23172841e4 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -28,7 +28,6 @@ God bless America. density = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 - container_type = OPENCONTAINER layer = BELOW_OBJ_LAYER var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW? var/cook_time = 0 @@ -52,7 +51,7 @@ God bless America. /obj/machinery/deepfryer/Initialize() . = ..() - create_reagents(50) + create_reagents(50, OPENCONTAINER) reagents.add_reagent("cooking_oil", 25) component_parts = list() component_parts += new /obj/item/circuitboard/machine/deep_fryer(null) diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm index b1da39daf3..4dda9dd773 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm @@ -15,13 +15,11 @@ var/portion = 10 var/selected_drink var/list/stored_food = list() - container_type = OPENCONTAINER var/obj/item/reagent_containers/mixer /obj/machinery/food_cart/Initialize() . = ..() - create_reagents(LIQUID_CAPACIY) - reagents.set_reacting(FALSE) + create_reagents(LIQUID_CAPACIY, OPENCONTAINER | NO_REACT) mixer = new /obj/item/reagent_containers(src, MIXER_CAPACITY) mixer.name = "Mixer" diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm index 46c9907cef..58d3ef69bb 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm @@ -14,7 +14,6 @@ anchored = FALSE use_power = NO_POWER_USE layer = BELOW_OBJ_LAYER - container_type = OPENCONTAINER max_integrity = 300 var/list/product_types = list() var/dispense_flavour = ICECREAM_VANILLA @@ -65,8 +64,7 @@ . = ..() while(product_types.len < 6) product_types.Add(5) - create_reagents() - reagents.set_reacting(FALSE) + create_reagents(100, OPENCONTAINER | NO_REACT) for(var/reagent in icecream_vat_reagents) reagents.add_reagent(reagent, icecream_vat_reagents[reagent]) diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 913fb44dae..10ecfd6e20 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -86,7 +86,6 @@ src.icon_state = "mw" src.broken = 0 // Fix it! src.dirty = 0 // just to be sure - src.container_type = OPENCONTAINER return 0 //to use some fuel else to_chat(user, "It's broken!") @@ -103,7 +102,6 @@ src.dirty = 0 // It's clean! src.broken = 0 // just to be sure src.icon_state = "mw" - src.container_type = OPENCONTAINER src.updateUsrDialog() return 1 // Disables the after-attack so we don't spray the floor/user. else @@ -124,7 +122,6 @@ src.dirty = 0 // It's clean! src.broken = 0 // just to be sure src.icon_state = "mw" - src.container_type = OPENCONTAINER else if(src.dirty==100) // The microwave is all dirty so can't be used! to_chat(user, "It's dirty!") diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index b6e3b19640..deba080ca2 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -18,8 +18,7 @@ /obj/machinery/smartfridge/Initialize() . = ..() - create_reagents() - reagents.set_reacting(FALSE) + create_reagents(100, NO_REACT) if(islist(initial_contents)) for(var/typekey in initial_contents) diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm index 01c13abf47..464b8ce26f 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm @@ -102,6 +102,52 @@ result = /obj/item/reagent_containers/food/snacks/store/cake/pumpkinspice subcategory = CAT_CAKE +/datum/crafting_recipe/food/holycake + name = "Angel food cake" + reqs = list( + /datum/reagent/water/holywater = 15, + /obj/item/reagent_containers/food/snacks/store/cake/plain = 1 + ) + result = /obj/item/reagent_containers/food/snacks/store/cake/holy_cake + subcategory = CAT_CAKE + +/datum/crafting_recipe/food/poundcake + name = "Pound cake" + reqs = list( + /obj/item/reagent_containers/food/snacks/store/cake/plain = 4 + ) + result = /obj/item/reagent_containers/food/snacks/store/cake/pound_cake + subcategory = CAT_CAKE + +/datum/crafting_recipe/food/hardwarecake + name = "Hardware cake" + reqs = list( + /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/circuitboard = 2, + /datum/reagent/toxin/acid = 5 + ) + result = /obj/item/reagent_containers/food/snacks/store/cake/hardware_cake + subcategory = CAT_CAKE + +/datum/crafting_recipe/food/bscccake + name = "blackberry and strawberry chocolate cake" + reqs = list( + /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/reagent_containers/food/snacks/chocolatebar = 2, + /obj/item/reagent_containers/food/snacks/grown/berries = 5 + ) + result = /obj/item/reagent_containers/food/snacks/store/cake/bscc + subcategory = CAT_CAKE + +/datum/crafting_recipe/food/bscvcake + name = "blackberry and strawberry vanilla cake" + reqs = list( + /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/reagent_containers/food/snacks/grown/berries = 5 + ) + result = /obj/item/reagent_containers/food/snacks/store/cake/bsvc + subcategory = CAT_CAKE + /datum/crafting_recipe/food/cak name = "Living cat/cake hybrid" reqs = list( @@ -114,4 +160,4 @@ /datum/reagent/teslium = 1 //To shock the whole thing into life ) result = /mob/living/simple_animal/pet/cat/cak - subcategory = CAT_CAKE //Cat! Haha, get it? CAT? GET IT??? + subcategory = CAT_CAKE //Cat! Haha, get it? CAT? GET IT? We get it - Love Catpeople diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm new file mode 100644 index 0000000000..08d5716779 --- /dev/null +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm @@ -0,0 +1,244 @@ + +/datum/crafting_recipe/food/icecreamsandwich + name = "Icecream sandwich" + reqs = list( + /datum/reagent/consumable/cream = 5, + /datum/reagent/consumable/ice = 5, + /obj/item/reagent_containers/food/snacks/icecream = 1 + ) + result = /obj/item/reagent_containers/food/snacks/icecreamsandwich + subcategory = CAT_ICE + +/datum/crafting_recipe/food/spacefreezy + name ="Space freezy" + reqs = list( + /datum/reagent/consumable/bluecherryjelly = 5, + /datum/reagent/consumable/spacemountainwind = 15, + /obj/item/reagent_containers/food/snacks/icecream = 1 + ) + result = /obj/item/reagent_containers/food/snacks/spacefreezy + subcategory = CAT_ICE + +/datum/crafting_recipe/food/sundae + name ="Sundae" + reqs = list( + /datum/reagent/consumable/cream = 5, + /obj/item/reagent_containers/food/snacks/grown/cherries = 1, + /obj/item/reagent_containers/food/snacks/grown/banana = 1, + /obj/item/reagent_containers/food/snacks/icecream = 1 + ) + result = /obj/item/reagent_containers/food/snacks/sundae + subcategory = CAT_ICE + +/datum/crafting_recipe/food/honkdae + name ="Honkdae" + reqs = list( + /datum/reagent/consumable/cream = 5, + /obj/item/clothing/mask/gas/clown_hat = 1, + /obj/item/reagent_containers/food/snacks/grown/cherries = 1, + /obj/item/reagent_containers/food/snacks/grown/banana = 2, + /obj/item/reagent_containers/food/snacks/icecream = 1 + ) + result = /obj/item/reagent_containers/food/snacks/honkdae + subcategory = CAT_ICE + +//////////////////////////SNOW CONES/////////////////////// + +/datum/crafting_recipe/food/flaverless_sc + name = "Flaverless snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones + subcategory = CAT_ICE + +/datum/crafting_recipe/food/pineapple_sc + name = "Pineapple snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /obj/item/reagent_containers/food/snacks/pineappleslice = 2 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/pineapple + subcategory = CAT_ICE + +/datum/crafting_recipe/food/lime_sc + name = "Lime snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/limejuice = 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/lime + subcategory = CAT_ICE + +/datum/crafting_recipe/food/lemon_sc + name = "Lemon snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/lemonjuice = 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/lemon + subcategory = CAT_ICE + +/datum/crafting_recipe/food/apple_sc + name = "Apple snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/applejuice = 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/apple + subcategory = CAT_ICE + +/datum/crafting_recipe/food/grape_sc + name = "Grape snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/berryjuice = 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/grape + subcategory = CAT_ICE + +/datum/crafting_recipe/food/orange_sc + name = "Orange snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/orangejuice = 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/orange + subcategory = CAT_ICE + +/datum/crafting_recipe/food/blue_sc + name = "Bluecherry snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/bluecherryjelly= 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/blue + subcategory = CAT_ICE + +/datum/crafting_recipe/food/red_sc + name = "Cherry snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/cherryjelly= 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/red + subcategory = CAT_ICE + +/datum/crafting_recipe/food/mix_sc + name = "Mixed berrie snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/berryjuice = 15 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/mix + subcategory = CAT_ICE + +/datum/crafting_recipe/food/fruitsalad_sc + name = "Fruit Salad snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/orangejuice = 5, + /datum/reagent/consumable/limejuice = 5, + /datum/reagent/consumable/lemonjuice = 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/fruitsalad + subcategory = CAT_ICE + +/datum/crafting_recipe/food/mime_sc + name = "Mime snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/nothing = 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/mime + subcategory = CAT_ICE + +/datum/crafting_recipe/food/clown_sc + name = "Clown snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/clownstears = 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/clown + subcategory = CAT_ICE + +/datum/crafting_recipe/food/soda_sc + name = "Soda water snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/sodawater = 15 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/soda + subcategory = CAT_ICE + +/datum/crafting_recipe/food/pwgrmer_sc + name = "Pwergamer snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/pwr_game = 15 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/pwgrmer + subcategory = CAT_ICE + +/datum/crafting_recipe/food/kiwi_sc + name = "Soda water snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /obj/item/reagent_containers/food/snacks/egg/kiwiEgg = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/kiwi + subcategory = CAT_ICE + +/datum/crafting_recipe/food/honey_sc + name = "Honey snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/consumable/honey = 5 + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/honey + subcategory = CAT_ICE + +/datum/crafting_recipe/food/honey_sc + name = "Rainbow snowcone" + reqs = list( + /obj/item/reagent_containers/food/drinks/sillycup = 1, + /datum/reagent/water = 5, + /datum/reagent/consumable/ice = 15, + /datum/reagent/colorful_reagent = 1 //Hard to make + ) + result = /obj/item/reagent_containers/food/snacks/snowcones/rainbow + subcategory = CAT_ICE diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm index b33d6a520b..c16c7268b9 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm @@ -1,5 +1,3 @@ - - ////////////////////////////////////////////////KEBABS//////////////////////////////////////////////// /datum/crafting_recipe/food/humankebab @@ -71,16 +69,6 @@ result = /obj/item/reagent_containers/food/snacks/fishfingers subcategory = CAT_MEAT -/datum/crafting_recipe/food/sashimi - name = "Sashimi" - reqs = list( - /datum/reagent/consumable/soysauce = 5, - /obj/item/reagent_containers/food/snacks/spidereggs = 1, - /obj/item/reagent_containers/food/snacks/carpmeat = 1 - ) - result = /obj/item/reagent_containers/food/snacks/sashimi - subcategory = CAT_MEAT - ////////////////////////////////////////////////MR SPIDER//////////////////////////////////////////////// /datum/crafting_recipe/food/spidereggsham diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm index 3925416560..0c4e2c2e30 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm @@ -186,39 +186,6 @@ result = /obj/item/reagent_containers/food/snacks/melonfruitbowl subcategory = CAT_MISCFOOD -/datum/crafting_recipe/food/spacefreezy - name ="Space freezy" - reqs = list( - /datum/reagent/consumable/bluecherryjelly = 5, - /datum/reagent/consumable/spacemountainwind = 15, - /obj/item/reagent_containers/food/snacks/icecream = 1 - ) - result = /obj/item/reagent_containers/food/snacks/spacefreezy - subcategory = CAT_MISCFOOD - -/datum/crafting_recipe/food/sundae - name ="Sundae" - reqs = list( - /datum/reagent/consumable/cream = 5, - /obj/item/reagent_containers/food/snacks/grown/cherries = 1, - /obj/item/reagent_containers/food/snacks/grown/banana = 1, - /obj/item/reagent_containers/food/snacks/icecream = 1 - ) - result = /obj/item/reagent_containers/food/snacks/sundae - subcategory = CAT_MISCFOOD - -/datum/crafting_recipe/food/honkdae - name ="Honkdae" - reqs = list( - /datum/reagent/consumable/cream = 5, - /obj/item/clothing/mask/gas/clown_hat = 1, - /obj/item/reagent_containers/food/snacks/grown/cherries = 1, - /obj/item/reagent_containers/food/snacks/grown/banana = 2, - /obj/item/reagent_containers/food/snacks/icecream = 1 - ) - result = /obj/item/reagent_containers/food/snacks/honkdae - subcategory = CAT_MISCFOOD - /datum/crafting_recipe/food/nachos name ="Nachos" reqs = list( @@ -345,3 +312,13 @@ ) result = /obj/item/reagent_containers/food/snacks/salad/ricepudding subcategory = CAT_MISCFOOD + +/datum/crafting_recipe/food/riceball + name = "Onigiri" + reqs = list( + /datum/reagent/consumable/soysauce = 1, + /obj/item/reagent_containers/food/snacks/grown/kudzupod = 1, + /obj/item/reagent_containers/food/snacks/salad/boiledrice = 1 + ) + result = /obj/item/reagent_containers/food/snacks/riceball + subcategory = CAT_MISCFOOD diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm index 9750e91930..0f1c40da3f 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm @@ -43,16 +43,6 @@ result = /obj/item/reagent_containers/food/snacks/jellysandwich/cherry subcategory = CAT_SANDWICH -/datum/crafting_recipe/food/icecreamsandwich - name = "Icecream sandwich" - reqs = list( - /datum/reagent/consumable/cream = 5, - /datum/reagent/consumable/ice = 5, - /obj/item/reagent_containers/food/snacks/icecream = 1 - ) - result = /obj/item/reagent_containers/food/snacks/icecreamsandwich - subcategory = CAT_SANDWICH - /datum/crafting_recipe/food/notasandwich name = "Not a sandwich" reqs = list( @@ -62,5 +52,13 @@ result = /obj/item/reagent_containers/food/snacks/notasandwich subcategory = CAT_SANDWICH - - +/datum/crafting_recipe/food/notasandwich + name = "Tuna sandwich" + reqs = list( + /obj/item/reagent_containers/food/snacks/breadslice/plain = 2, + /obj/item/reagent_containers/food/snacks/tuna = 1, + /obj/item/reagent_containers/food/snacks/grown/onion = 1, + /obj/item/reagent_containers/food/condiment/mayonnaise = 5 + ) + result = /obj/item/reagent_containers/food/snacks/tuna_sandwich + subcategory = CAT_SANDWICH diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sushi.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sushi.dm new file mode 100644 index 0000000000..99d48cf69d --- /dev/null +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sushi.dm @@ -0,0 +1,94 @@ +//////////////////////////Sushi Components/////////////////////// + +/datum/crafting_recipe/food/sushi_rice + name = "Sushi Rice" + reqs = list( + /datum/reagent/water = 40, + /datum/reagent/consumable/rice = 10 + ) + result = /obj/item/reagent_containers/food/snacks/sushi_rice + subcategory = CAT_SUSHI + +/datum/crafting_recipe/food/sea_weed + name = "Sea Weed Sheet" + reqs = list( + /datum/reagent/water = 30, + /datum/reagent/consumable/soysauce = 5, + /obj/item/reagent_containers/food/snacks/grown/kudzupod = 1, + ) + result = /obj/item/reagent_containers/food/snacks/sea_weed + subcategory = CAT_SUSHI + +/datum/crafting_recipe/food/tuna_can + name = "Can of Tuna" + reqs = list( + /datum/reagent/consumable/sodiumchloride = 15, + /datum/reagent/consumable/cooking_oil = 5, + /obj/item/reagent_containers/food/snacks/carpmeat = 1, + ) + result = /obj/item/reagent_containers/food/snacks/tuna + subcategory = CAT_SUSHI + +//////////////////////////Sushi///////////////////////////////// + +/datum/crafting_recipe/food/sashimi + name = "Sashimi" + reqs = list( + /datum/reagent/consumable/soysauce = 5, + /obj/item/reagent_containers/food/snacks/spidereggs = 1, + /obj/item/reagent_containers/food/snacks/carpmeat = 1 + ) + result = /obj/item/reagent_containers/food/snacks/sashimi + subcategory = CAT_SUSHI + +/datum/crafting_recipe/food/riceball + name = "Onigiri" + reqs = list( + /datum/reagent/consumable/soysauce = 1, + /obj/item/reagent_containers/food/snacks/sea_weed = 1, + /obj/item/reagent_containers/food/snacks/sushi_rice = 1 + ) + result = /obj/item/reagent_containers/food/snacks/riceball + subcategory = CAT_SUSHI + +/datum/crafting_recipe/food/sushie_egg + name = "Tobiko" + reqs = list( + /datum/reagent/consumable/soysauce = 6, + /obj/item/reagent_containers/food/snacks/spidereggs = 1, + /obj/item/reagent_containers/food/snacks/sea_weed = 2, + ) + result = /obj/item/reagent_containers/food/snacks/tobiko + subcategory = CAT_SUSHI + +/datum/crafting_recipe/food/sushie_basic + name = "Funa Hosomaki" + reqs = list( + /datum/reagent/consumable/soysauce = 3, + /obj/item/reagent_containers/food/snacks/sushi_rice = 1, + /obj/item/reagent_containers/food/snacks/carpmeat = 2, + /obj/item/reagent_containers/food/snacks/sea_weed = 3, + ) + result = /obj/item/reagent_containers/food/snacks/sushie_basic + subcategory = CAT_SUSHI + +/datum/crafting_recipe/food/sushie_adv + name = "Funa Nigiri" + reqs = list( + /datum/reagent/consumable/soysauce = 5, + /obj/item/reagent_containers/food/snacks/sushi_rice = 1, + /obj/item/reagent_containers/food/snacks/carpmeat = 1 + ) + result = /obj/item/reagent_containers/food/snacks/sushie_adv + subcategory = CAT_SUSHI + +/datum/crafting_recipe/food/sushie_pro + name = "Well made Funa Nigiri" + reqs = list( + /datum/reagent/consumable/soysauce = 10, + /obj/item/reagent_containers/food/snacks/sushi_rice = 2, + /obj/item/reagent_containers/food/snacks/carpmeat = 5, + /obj/item/reagent_containers/food/snacks/sea_weed = 1 + ) + result = /obj/item/reagent_containers/food/snacks/sushie_pro + subcategory = CAT_SUSHI diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 6466a47e42..33884f8ef0 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -316,7 +316,9 @@ h1.alert, h2.alert {color: #000000;} .unconscious {color: #0000ff; font-weight: bold;} .suicide {color: #ff5050; font-style: italic;} .green {color: #03ff39;} -.nicegreen {color: #14a833;} +.nicegreen {color: #14a833;} +.userlove {color: #FF1493; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #ff6dbc;} +.love {color: #ff006a; font-style: italic; text-shadow: 0 0 6px #ff6d6d;} .shadowling {color: #3b2769;} .cult {color: #960000;} diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 23a63d9708..64b41a5921 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -158,7 +158,16 @@ function byondDecode(message) { // The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b. // Marvelous. message = message.replace(/\+/g, "%20"); - message = decoder(message); + try { + // This is a workaround for the above not always working when BYOND's shitty url encoding breaks. (byond bug id:2399401) + if (decodeURIComponent) { + message = decodeURIComponent(message); + } else { + throw new Error("Easiest way to trigger the fallback") + } + } catch (err) { + message = unescape(message); + } return message; } @@ -361,7 +370,7 @@ function setCookie(cname, cvalue, exdays) { var d = new Date(); d.setTime(d.getTime() + (exdays*24*60*60*1000)); var expires = 'expires='+d.toUTCString(); - document.cookie = cname + '=' + cvalue + '; ' + expires; + document.cookie = cname + '=' + cvalue + '; ' + expires + "; path=/"; } function getCookie(cname) { diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index e1eb976966..eaffeaf016 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -304,6 +304,8 @@ else if(href_list["create"]) var/amount = (text2num(href_list["amount"])) + //Can't be outside these (if you change this keep a sane limit) + amount = CLAMP(amount, 1, 50) var/datum/design/D = locate(href_list["create"]) create_product(D, amount) updateUsrDialog() diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm index b88e6e1ebb..83fc18dcb9 100644 --- a/code/modules/hydroponics/fermenting_barrel.dm +++ b/code/modules/hydroponics/fermenting_barrel.dm @@ -5,14 +5,13 @@ icon_state = "barrel" density = TRUE anchored = FALSE - container_type = DRAINABLE | AMOUNT_VISIBLE pressure_resistance = 2 * ONE_ATMOSPHERE max_integrity = 300 var/open = FALSE var/speed_multiplier = 1 //How fast it distills. Defaults to 100% (1.0). Lower is better. /obj/structure/fermenting_barrel/Initialize() - create_reagents(300) //Bluespace beakers, but without the portability or efficiency in circuits. + create_reagents(300, DRAINABLE | AMOUNT_VISIBLE) //Bluespace beakers, but without the portability or efficiency in circuits. . = ..() /obj/structure/fermenting_barrel/examine(mob/user) @@ -56,10 +55,12 @@ /obj/structure/fermenting_barrel/attack_hand(mob/user) open = !open if(open) - container_type = REFILLABLE | AMOUNT_VISIBLE + DISABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE) + ENABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE) to_chat(user, "You open [src], letting you fill it.") else - container_type = DRAINABLE | AMOUNT_VISIBLE + DISABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE) + ENABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE) to_chat(user, "You close [src], letting you draw from its tap.") update_icon() diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index e3f8c254ac..dbcce2830b 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -56,7 +56,7 @@ var/mob/living/carbon/C = user if(C.gloves) return FALSE - if(C.has_trait(TRAIT_PIERCEIMMUNE)) + if(HAS_TRAIT(C, TRAIT_PIERCEIMMUNE)) return FALSE var/hit_zone = (C.held_index_to_dir(C.active_hand_index) == "l" ? "l_":"r_") + "arm" var/obj/item/bodypart/affecting = C.get_bodypart(hit_zone) diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index 55c0da91f2..ce0ca0220b 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -7,7 +7,6 @@ species = "replicapod" plantname = "Replica Pod" product = /mob/living/carbon/human //verrry special -- Urist - container_type = INJECTABLE|DRAWABLE lifespan = 50 endurance = 8 maturation = 10 @@ -28,7 +27,7 @@ /obj/item/seeds/replicapod/Initialize() . = ..() - create_reagents(volume) + create_reagents(volume, INJECTABLE | DRAWABLE) /obj/item/seeds/replicapod/on_reagent_change(changetype) if(changetype == ADD_REAGENT) diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 3fe5a2dfca..23f178edc9 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -187,7 +187,7 @@ var/turf/open/O = loc if(O.air) var/loc_gases = O.air.gases - if(loc_gases[/datum/gas/oxygen][MOLES] > 13) + if(loc_gases[/datum/gas/oxygen] > 13) return TRUE return FALSE diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index 97bf2a31b9..17462c0626 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -310,10 +310,10 @@ /datum/plant_gene/trait/noreact/on_new(obj/item/reagent_containers/food/snacks/grown/G, newloc) ..() - G.reagents.set_reacting(FALSE) + ENABLE_BITFIELD(G.reagents.reagents_holder_flags, NO_REACT) /datum/plant_gene/trait/noreact/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target) - G.reagents.set_reacting(TRUE) + DISABLE_BITFIELD(G.reagents.reagents_holder_flags, NO_REACT) G.reagents.handle_reactions() diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 1a4bb1fb1b..3862967363 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -643,6 +643,11 @@ icon_state = "setup_small_pda" desc = "It's a case, for building small electronics with. This one resembles a PDA." +/obj/item/electronic_assembly/dildo + name = "type-g electronic assembly" + icon_state = "setup_dildo_medium" + desc = "It's a case, for building small electronics with. This one has a phallic design." + /obj/item/electronic_assembly/small name = "electronic device" icon_state = "setup_device" @@ -674,6 +679,11 @@ icon_state = "setup_device_box" desc = "It's a case, for building tiny-sized electronics with. This one has a boxy design." +/obj/item/electronic_assembly/small/dildo + name = "type-f electronic device" + icon_state = "setup_dildo_small" + desc = "It's a case, for building tiny-sized electronics with. This one has a phallic design." + /obj/item/electronic_assembly/medium name = "electronic mechanism" icon_state = "setup_medium" @@ -714,6 +724,12 @@ icon_state = "setup_medium_radio" desc = "It's a case, for building medium-sized electronics with. This one resembles an old radio." +/obj/item/electronic_assembly/medium/dildo + name = "type-g electronic mechanism" + icon_state = "setup_dildo_large" + desc = "It's a case, for building medium-sized electronics with. This one has a phallic design." + + /obj/item/electronic_assembly/large name = "electronic machine" icon_state = "setup_large" diff --git a/code/modules/integrated_electronics/core/detailer.dm b/code/modules/integrated_electronics/core/detailer.dm index 33f7ef96ad..52739c7940 100644 --- a/code/modules/integrated_electronics/core/detailer.dm +++ b/code/modules/integrated_electronics/core/detailer.dm @@ -25,7 +25,9 @@ "green" = COLOR_ASSEMBLY_GREEN, "light blue" = COLOR_ASSEMBLY_LBLUE, "blue" = COLOR_ASSEMBLY_BLUE, - "purple" = COLOR_ASSEMBLY_PURPLE + "purple" = COLOR_ASSEMBLY_PURPLE, + "pink" = COLOR_ASSEMBLY_PINK, + "custom" = COLOR_ASSEMBLY_WHITE ) /obj/item/integrated_electronics/detailer/Initialize() @@ -43,6 +45,9 @@ if(!color_list[color_choice]) return if(!in_range(src, user)) - return - detail_color = color_list[color_choice] + return + if(color_choice == "custom") + detail_color = input(user,"","Choose Color",detail_color) as color|null + else + detail_color = color_list[color_choice] update_icon() diff --git a/code/modules/integrated_electronics/core/saved_circuits.dm b/code/modules/integrated_electronics/core/saved_circuits.dm index eef4fe38dd..2fe6984808 100644 --- a/code/modules/integrated_electronics/core/saved_circuits.dm +++ b/code/modules/integrated_electronics/core/saved_circuits.dm @@ -124,7 +124,7 @@ // Save modified name if(initial(name) != name) assembly_params["name"] = name - + // Save modified description if(initial(desc) != desc) assembly_params["desc"] = desc @@ -144,7 +144,7 @@ return "Bad assembly name." if(assembly_params["desc"] && !reject_bad_text(assembly_params["desc"])) return "Bad assembly description." - if(assembly_params["detail_color"] && !(assembly_params["detail_color"] in color_whitelist)) + if(assembly_params["detail_color"] && !reject_bad_text(assembly_params["detail_color"], 7)) return "Bad assembly color." // Loads assembly parameters from a list @@ -153,7 +153,7 @@ // Load modified name, if any. if(assembly_params["name"]) name = assembly_params["name"] - + // Load modified description, if any. if(assembly_params["desc"]) desc = assembly_params["desc"] diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index c849dc0e27..d4899a4621 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -90,7 +90,6 @@ icon_state = "chemical_cell" extended_desc = "This is effectively an internal beaker. It will consume and produce power from plasma, slime jelly, welding fuel, carbon,\ ethanol, nutriment, and blood in order of decreasing efficiency. It will consume fuel only if the battery can take more energy." - container_type = OPENCONTAINER complexity = 4 inputs = list() outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_SELFREF) @@ -101,9 +100,9 @@ var/multi = 1 var/lfwb =TRUE -/obj/item/integrated_circuit/passive/power/chemical_cell/New() +/obj/item/integrated_circuit/passive/power/chemical_cell/Initialize() ..() - create_reagents(volume) + create_reagents(volume, OPENCONTAINER) extended_desc +="But no fuel can be compared with blood of living human." diff --git a/code/modules/integrated_electronics/subtypes/atmospherics.dm b/code/modules/integrated_electronics/subtypes/atmospherics.dm index 1715223fa2..230d1ce154 100644 --- a/code/modules/integrated_electronics/subtypes/atmospherics.dm +++ b/code/modules/integrated_electronics/subtypes/atmospherics.dm @@ -1,762 +1,761 @@ -#define SOURCE_TO_TARGET 0 -#define TARGET_TO_SOURCE 1 -#define PUMP_EFFICIENCY 0.6 -#define TANK_FAILURE_PRESSURE (ONE_ATMOSPHERE*25) -#define PUMP_MAX_PRESSURE (ONE_ATMOSPHERE*24) -#define PUMP_MAX_VOLUME 100 - - -/obj/item/integrated_circuit/atmospherics - category_text = "Atmospherics" - cooldown_per_use = 2 SECONDS - complexity = 10 - size = 7 - outputs = list( - "self reference" = IC_PINTYPE_SELFREF, - "pressure" = IC_PINTYPE_NUMBER - ) - var/datum/gas_mixture/air_contents - var/volume = 2 //Pretty small, I know - -/obj/item/integrated_circuit/atmospherics/Initialize() - air_contents = new(volume) - ..() - -/obj/item/integrated_circuit/atmospherics/return_air() - return air_contents - -//Check if the gas container is adjacent and of the right type -/obj/item/integrated_circuit/atmospherics/proc/check_gassource(atom/gasholder) - if(!gasholder) - return FALSE - if(!gasholder.Adjacent(get_object())) - return FALSE - if(!istype(gasholder, /obj/item/tank) && !istype(gasholder, /obj/machinery/portable_atmospherics) && !istype(gasholder, /obj/item/integrated_circuit/atmospherics)) - return FALSE - return TRUE - -//Needed in circuits where source and target types differ -/obj/item/integrated_circuit/atmospherics/proc/check_gastarget(atom/gasholder) - return check_gassource(gasholder) - - -// - gas pump - // **works** -/obj/item/integrated_circuit/atmospherics/pump - name = "gas pump" - desc = "Somehow moves gases between two tanks, canisters, and other gas containers." - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - inputs = list( - "source" = IC_PINTYPE_REF, - "target" = IC_PINTYPE_REF, - "target pressure" = IC_PINTYPE_NUMBER - ) - activators = list( - "transfer" = IC_PINTYPE_PULSE_IN, - "on transfer" = IC_PINTYPE_PULSE_OUT - ) - var/direction = SOURCE_TO_TARGET - var/target_pressure = PUMP_MAX_PRESSURE - power_draw_per_use = 20 - -/obj/item/integrated_circuit/atmospherics/pump/Initialize() - air_contents = new(volume) - extended_desc += " Use negative pressure to move air from target to source. \ - Note that only part of the gas is moved on each transfer, \ - so multiple activations will be necessary to achieve target pressure. \ - The pressure limit for circuit pumps is [round(PUMP_MAX_PRESSURE)] kPa." - . = ..() - -// This proc gets the direction of the gas flow depending on its value, by calling update target -/obj/item/integrated_circuit/atmospherics/pump/on_data_written() - var/amt = get_pin_data(IC_INPUT, 3) - update_target(amt) - -/obj/item/integrated_circuit/atmospherics/pump/proc/update_target(new_amount) - if(!isnum(new_amount)) - new_amount = 0 - // See in which direction the gas moves - if(new_amount < 0) - direction = TARGET_TO_SOURCE - else - direction = SOURCE_TO_TARGET - target_pressure = min(round(PUMP_MAX_PRESSURE),abs(new_amount)) - -/obj/item/integrated_circuit/atmospherics/pump/do_work() - var/obj/source = get_pin_data_as_type(IC_INPUT, 1, /obj) - var/obj/target = get_pin_data_as_type(IC_INPUT, 2, /obj) - perform_magic(source, target) - activate_pin(2) - -/obj/item/integrated_circuit/atmospherics/pump/proc/perform_magic(atom/source, atom/target) - //Check if both atoms are of the right type: atmos circuits/gas tanks/canisters. If one is the same, use the circuit var - if(!check_gassource(source)) - source = src - - if(!check_gastarget(target)) - target = src - - // If both are the same, this whole proc would do nothing and just waste performance - if(source == target) - return - - var/datum/gas_mixture/source_air = source.return_air() - var/datum/gas_mixture/target_air = target.return_air() - - if(!source_air || !target_air) - return - - // Swapping both source and target - if(direction == TARGET_TO_SOURCE) - var/temp = source_air - source_air = target_air - target_air = temp - - // If what you are pumping is empty, use the circuit's storage - if(source_air.total_moles() <= 0) - source_air = air_contents - - // Move gas from one place to another - move_gas(source_air, target_air) - air_update_turf() - -/obj/item/integrated_circuit/atmospherics/pump/proc/move_gas(datum/gas_mixture/source_air, datum/gas_mixture/target_air) - - // No moles = nothing to pump - if(source_air.total_moles() <= 0 || target_air.return_pressure() >= PUMP_MAX_PRESSURE) - return - - // Negative Kelvin temperatures should never happen and if they do, normalize them - if(source_air.temperature < TCMB) - source_air.temperature = TCMB - - var/pressure_delta = target_pressure - target_air.return_pressure() - if(pressure_delta > 0.1) - var/transfer_moles = (pressure_delta*target_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY - var/datum/gas_mixture/removed = source_air.remove(transfer_moles) - target_air.merge(removed) - - -// - volume pump - // **Works** -/obj/item/integrated_circuit/atmospherics/pump/volume - name = "volume pump" - desc = "Moves gases between two tanks, canisters, and other gas containers by using their volume, up to 200 L/s." - extended_desc = " Use negative volume to move air from target to source. Note that only part of the gas is moved on each transfer. Its maximum pumping volume is capped at 1000kPa." - - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - inputs = list( - "source" = IC_PINTYPE_REF, - "target" = IC_PINTYPE_REF, - "transfer volume" = IC_PINTYPE_NUMBER - ) - activators = list( - "transfer" = IC_PINTYPE_PULSE_IN, - "on transfer" = IC_PINTYPE_PULSE_OUT - ) - direction = SOURCE_TO_TARGET - var/transfer_rate = PUMP_MAX_VOLUME - power_draw_per_use = 20 - -/obj/item/integrated_circuit/atmospherics/pump/volume/update_target(new_amount) - if(!isnum(new_amount)) - new_amount = 0 - // See in which direction the gas moves - if(new_amount < 0) - direction = TARGET_TO_SOURCE - else - direction = SOURCE_TO_TARGET - target_pressure = min(PUMP_MAX_VOLUME,abs(new_amount)) - -/obj/item/integrated_circuit/atmospherics/pump/volume/move_gas(datum/gas_mixture/source_air, datum/gas_mixture/target_air) - // No moles = nothing to pump - if(source_air.total_moles() <= 0) - return - - // Negative Kelvin temperatures should never happen and if they do, normalize them - if(source_air.temperature < TCMB) - source_air.temperature = TCMB - - if((source_air.return_pressure() < 0.01) || (target_air.return_pressure() >= PUMP_MAX_PRESSURE)) - return - - //The second part of the min caps the pressure built by the volume pumps to the max pump pressure - var/transfer_ratio = min(transfer_rate,target_air.volume*PUMP_MAX_PRESSURE/source_air.return_pressure())/source_air.volume - - var/datum/gas_mixture/removed = source_air.remove_ratio(transfer_ratio * PUMP_EFFICIENCY) - - target_air.merge(removed) - - -// - gas vent - // **works** -/obj/item/integrated_circuit/atmospherics/pump/vent - name = "gas vent" - extended_desc = "Use negative volume to move air from target to environment. Note that only part of the gas is moved on each transfer. Unlike the gas pump, this one keeps pumping even further to pressures of 9000 pKa and it is not advised to use it on tank circuits." - desc = "Moves gases between the environment and adjacent gas containers." - inputs = list( - "container" = IC_PINTYPE_REF, - "target pressure" = IC_PINTYPE_NUMBER - ) - -/obj/item/integrated_circuit/atmospherics/pump/vent/on_data_written() - var/amt = get_pin_data(IC_INPUT, 2) - update_target(amt) - -/obj/item/integrated_circuit/atmospherics/pump/vent/do_work() - var/turf/source = get_turf(src) - var/obj/target = get_pin_data_as_type(IC_INPUT, 1, /obj) - perform_magic(source, target) - activate_pin(2) - -/obj/item/integrated_circuit/atmospherics/pump/vent/check_gastarget(atom/gasholder) - if(!gasholder) - return FALSE - if(!gasholder.Adjacent(get_object())) - return FALSE - if(!istype(gasholder, /obj/item/tank) && !istype(gasholder, /obj/machinery/portable_atmospherics) && !istype(gasholder, /obj/item/integrated_circuit/atmospherics)) - return FALSE - return TRUE - - -/obj/item/integrated_circuit/atmospherics/pump/vent/check_gassource(atom/target) - if(!target) - return FALSE - if(!istype(target, /turf)) - return FALSE - return TRUE - - -// - integrated connector - // Can connect and disconnect properly -/obj/item/integrated_circuit/atmospherics/connector - name = "integrated connector" - desc = "Creates an airtight seal with standard connectors found on the floor, \ - allowing the assembly to exchange gases with a pipe network." - extended_desc = "This circuit will automatically attempt to locate and connect to ports on the floor beneath it when activated. \ - You must set a target before connecting." - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - inputs = list( - "target" = IC_PINTYPE_REF - ) - activators = list( - "toggle connection" = IC_PINTYPE_PULSE_IN, - "on connected" = IC_PINTYPE_PULSE_OUT, - "on connection failed" = IC_PINTYPE_PULSE_OUT, - "on disconnected" = IC_PINTYPE_PULSE_OUT - ) - - var/obj/machinery/atmospherics/components/unary/portables_connector/connector - -/obj/item/integrated_circuit/atmospherics/connector/Initialize() - air_contents = new(volume) - START_PROCESSING(SSobj, src) - . = ..() - -//Sucks up the gas from the connector -/obj/item/integrated_circuit/atmospherics/connector/process() - set_pin_data(IC_OUTPUT, 2, air_contents.return_pressure()) - -/obj/item/integrated_circuit/atmospherics/connector/check_gassource(atom/gasholder) - if(!gasholder) - return FALSE - if(!istype(gasholder,/obj/machinery/atmospherics/components/unary/portables_connector)) - return FALSE - return TRUE - -//If the assembly containing this is moved from the tile the connector pipe is in, the connection breaks -/obj/item/integrated_circuit/atmospherics/connector/ext_moved() - if(connector) - if(get_dist(get_object(), connector) > 0) - // The assembly is set as connected device and the connector handles the rest - connector.connected_device = null - connector = null - activate_pin(4) - -/obj/item/integrated_circuit/atmospherics/connector/do_work() - // If there is a connection, disconnect - if(connector) - connector.connected_device = null - connector = null - activate_pin(4) - return - - var/obj/machinery/atmospherics/components/unary/portables_connector/PC = locate() in get_turf(src) - // If no connector can't connect - if(!PC) - activate_pin(3) - return - connector = PC - connector.connected_device = src - activate_pin(2) - -// Required for making the connector port script work -obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir() - return air_contents - - -// - gas filter - // **works** -/obj/item/integrated_circuit/atmospherics/pump/filter - name = "gas filter" - desc = "Filters one gas out of a mixture." - complexity = 20 - size = 8 - spawn_flags = IC_SPAWN_RESEARCH - inputs = list( - "source" = IC_PINTYPE_REF, - "filtered output" = IC_PINTYPE_REF, - "contaminants output" = IC_PINTYPE_REF, - "wanted gases" = IC_PINTYPE_LIST, - "target pressure" = IC_PINTYPE_NUMBER - ) - power_draw_per_use = 30 - -/obj/item/integrated_circuit/atmospherics/pump/filter/on_data_written() - var/amt = get_pin_data(IC_INPUT, 5) - target_pressure = CLAMP(amt, 0, PUMP_MAX_PRESSURE) - -/obj/item/integrated_circuit/atmospherics/pump/filter/do_work() - activate_pin(2) - var/obj/source = get_pin_data_as_type(IC_INPUT, 1, /obj) - var/obj/filtered = get_pin_data_as_type(IC_INPUT, 2, /obj) - var/obj/contaminants = get_pin_data_as_type(IC_INPUT, 3, /obj) - - var/wanted = get_pin_data(IC_INPUT, 4) - - // If there is no filtered output, this whole thing makes no sense - if(!check_gassource(filtered)) - return - - var/datum/gas_mixture/filtered_air = filtered.return_air() - if(!filtered_air) - return - - // If no source is set, the source is possibly this circuit's content - if(!check_gassource(source)) - source = src - var/datum/gas_mixture/source_air = source.return_air() - - //No source air: source is this circuit - if(!source_air) - source_air = air_contents - - // If no filtering tank is set, filter through itself - if(!check_gassource(contaminants)) - contaminants = src - var/datum/gas_mixture/contaminated_air = contaminants.return_air() - - //If there is no gas mixture datum for unfiltered, pump the contaminants back into the circuit - if(!contaminated_air) - contaminated_air = air_contents - - if(contaminated_air.return_pressure() >= PUMP_MAX_PRESSURE || filtered_air.return_pressure() >= PUMP_MAX_PRESSURE) - return - - var/pressure_delta = target_pressure - contaminated_air.return_pressure() - var/transfer_moles - - //Negative Kelvins are an anomaly and should be normalized if encountered - if(source_air.temperature < TCMB) - source_air.temperature = TCMB - - transfer_moles = (pressure_delta*contaminated_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY - - //If there is nothing to transfer, just return - if(transfer_moles <= 0) - return - - //This is the var that holds the currently filtered part of the gas - var/datum/gas_mixture/removed = source_air.remove(transfer_moles) - if(!removed) - return - - //This is the gas that will be moved from source to filtered - var/datum/gas_mixture/filtered_out = new - - for(var/filtered_gas in removed.gases) - //Get the name of the gas and see if it is in the list - if(removed.gases[filtered_gas][GAS_META][META_GAS_NAME] in wanted) - //The gas that is put in all the filtered out gases - filtered_out.temperature = removed.temperature - filtered_out.add_gas(filtered_gas) - filtered_out.gases[filtered_gas][MOLES] = removed.gases[filtered_gas][MOLES] - - //The filtered out gas is entirely removed from the currently filtered gases - removed.gases[filtered_gas][MOLES] = 0 - removed.garbage_collect() - - //Check if the pressure is high enough to put stuff in filtered, or else just put it back in the source - var/datum/gas_mixture/target = (filtered_air.return_pressure() < target_pressure ? filtered_air : source_air) - target.merge(filtered_out) - contaminated_air.merge(removed) - - -/obj/item/integrated_circuit/atmospherics/pump/filter/Initialize() - air_contents = new(volume) - . = ..() - extended_desc = "Remember to properly spell and capitalize the filtered gas name. \ - Note that only part of the gas is moved on each transfer, \ - so multiple activations will be necessary to achieve target pressure. \ - The pressure limit for circuit pumps is [round(PUMP_MAX_PRESSURE)] kPa." - - -// - gas mixer - // **works** -/obj/item/integrated_circuit/atmospherics/pump/mixer - name = "gas mixer" - desc = "Mixes 2 different types of gases." - complexity = 20 - size = 8 - spawn_flags = IC_SPAWN_RESEARCH - inputs = list( - "first source" = IC_PINTYPE_REF, - "second source" = IC_PINTYPE_REF, - "output" = IC_PINTYPE_REF, - "first source percentage" = IC_PINTYPE_NUMBER, - "target pressure" = IC_PINTYPE_NUMBER - ) - power_draw_per_use = 30 - -/obj/item/integrated_circuit/atmospherics/pump/mixer/do_work() - activate_pin(2) - var/obj/source_1 = get_pin_data(IC_INPUT, 1) - var/obj/source_2 = get_pin_data(IC_INPUT, 2) - var/obj/gas_output = get_pin_data(IC_INPUT, 3) - if(!check_gassource(source_1)) - source_1 = src - - if(!check_gassource(source_2)) - source_2 = src - - if(!check_gassource(gas_output)) - gas_output = src - - if(source_1 == gas_output || source_2 == gas_output) - return - - var/datum/gas_mixture/source_1_gases = source_1.return_air() - var/datum/gas_mixture/source_2_gases = source_2.return_air() - var/datum/gas_mixture/output_gases = gas_output.return_air() - - if(!source_1_gases || !source_2_gases || !output_gases) - return - - if(output_gases.return_pressure() >= PUMP_MAX_PRESSURE) - return - - if(source_1_gases.return_pressure() <= 0 || source_2_gases.return_pressure() <= 0) - return - - //This calculates how much should be sent - var/gas_percentage = round(max(min(get_pin_data(IC_INPUT, 4),100),0) / 100) - - //Basically: number of moles = percentage of pressure filled up * efficiency coefficient * (pressure from both gases * volume of output) / (R * Temperature) - var/transfer_moles = (get_pin_data(IC_INPUT, 5) / max(1,output_gases.return_pressure())) * PUMP_EFFICIENCY * (source_1_gases.return_pressure() * gas_percentage + source_2_gases.return_pressure() * (1 - gas_percentage)) * output_gases.volume/ (R_IDEAL_GAS_EQUATION * max(output_gases.temperature,TCMB)) - - - if(transfer_moles <= 0) - return - - var/datum/gas_mixture/mix = source_1_gases.remove(transfer_moles * gas_percentage) - output_gases.merge(mix) - mix = source_2_gases.remove(transfer_moles * (1-gas_percentage)) - output_gases.merge(mix) - - -// - integrated tank - // **works** -/obj/item/integrated_circuit/atmospherics/tank - name = "integrated tank" - desc = "A small tank for the storage of gases." - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - size = 4 - activators = list( - "push ref" = IC_PINTYPE_PULSE_IN - ) - volume = 3 //emergency tank sized - var/broken = FALSE - -/obj/item/integrated_circuit/atmospherics/tank/Initialize() - air_contents = new(volume) - START_PROCESSING(SSobj, src) - extended_desc = "Take care not to pressurize it above [round(TANK_FAILURE_PRESSURE)] kPa, or else it will break." - . = ..() - -/obj/item/integrated_circuit/atmospherics/tank/Destroy() - STOP_PROCESSING(SSobj, src) - . = ..() - -/obj/item/integrated_circuit/atmospherics/tank/do_work() - set_pin_data(IC_OUTPUT, 1, WEAKREF(src)) - push_data() - -/obj/item/integrated_circuit/atmospherics/tank/process() - var/tank_pressure = air_contents.return_pressure() - set_pin_data(IC_OUTPUT, 2, tank_pressure) - push_data() - - //Check if tank broken - if(!broken && tank_pressure > TANK_FAILURE_PRESSURE) - broken = TRUE - to_chat(view(2),"The [name] ruptures, releasing its gases!") - if(broken) - release() - -/obj/item/integrated_circuit/atmospherics/tank/proc/release() - if(air_contents.total_moles() > 0) - playsound(loc, 'sound/effects/spray.ogg', 10, 1, -3) - var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles()) - var/turf/current_turf = get_turf(src) - var/datum/gas_mixture/exterior_gas - if(!current_turf) - return - - exterior_gas = current_turf.return_air() - exterior_gas.merge(expelled_gas) - - -// - large integrated tank - // **works** -/obj/item/integrated_circuit/atmospherics/tank/large - name = "large integrated tank" - desc = "A less small tank for the storage of gases." - volume = 9 - size = 12 - spawn_flags = IC_SPAWN_RESEARCH - - -// - freezer tank - // **works** -/obj/item/integrated_circuit/atmospherics/tank/freezer - name = "freezer tank" - desc = "Cools the gas it contains to a preset temperature." - volume = 6 - size = 8 - inputs = list( - "target temperature" = IC_PINTYPE_NUMBER, - "on" = IC_PINTYPE_BOOLEAN - ) - inputs_default = list("1" = 300) - spawn_flags = IC_SPAWN_RESEARCH - var/temperature = 293.15 - var/heater_coefficient = 0.1 - -/obj/item/integrated_circuit/atmospherics/tank/freezer/on_data_written() - temperature = max(73.15,min(293.15,get_pin_data(IC_INPUT, 1))) - if(get_pin_data(IC_INPUT, 2)) - power_draw_idle = 30 - else - power_draw_idle = 0 - -/obj/item/integrated_circuit/atmospherics/tank/freezer/process() - var/tank_pressure = air_contents.return_pressure() - set_pin_data(IC_OUTPUT, 2, tank_pressure) - push_data() - - //Cool the tank if the power is on and the temp is above - if(!power_draw_idle || air_contents.temperature < temperature) - return - - air_contents.temperature = max(73.15,air_contents.temperature - (air_contents.temperature - temperature) * heater_coefficient) - - -// - heater tank - // **works** -/obj/item/integrated_circuit/atmospherics/tank/freezer/heater - name = "heater tank" - desc = "Heats the gas it contains to a preset temperature." - volume = 6 - inputs = list( - "target temperature" = IC_PINTYPE_NUMBER, - "on" = IC_PINTYPE_BOOLEAN - ) - spawn_flags = IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/atmospherics/tank/freezer/heater/on_data_written() - temperature = max(293.15,min(573.15,get_pin_data(IC_INPUT, 1))) - if(get_pin_data(IC_INPUT, 2)) - power_draw_idle = 30 - else - power_draw_idle = 0 - -/obj/item/integrated_circuit/atmospherics/tank/freezer/heater/process() - var/tank_pressure = air_contents.return_pressure() - set_pin_data(IC_OUTPUT, 2, tank_pressure) - push_data() - - //Heat the tank if the power is on or its temperature is below what is set - if(!power_draw_idle || air_contents.temperature > temperature) - return - - air_contents.temperature = min(573.15,air_contents.temperature + (temperature - air_contents.temperature) * heater_coefficient) - - -// - atmospheric cooler - // **works** -/obj/item/integrated_circuit/atmospherics/cooler - name = "atmospheric cooler circuit" - desc = "Cools the air around it." - volume = 6 - size = 13 - spawn_flags = IC_SPAWN_RESEARCH - inputs = list( - "target temperature" = IC_PINTYPE_NUMBER, - "on" = IC_PINTYPE_BOOLEAN - ) - var/temperature = 293.15 - var/heater_coefficient = 0.1 - -/obj/item/integrated_circuit/atmospherics/cooler/Initialize() - air_contents = new(volume) - START_PROCESSING(SSobj, src) - . = ..() - -/obj/item/integrated_circuit/atmospherics/cooler/Destroy() - STOP_PROCESSING(SSobj, src) - . = ..() - -/obj/item/integrated_circuit/atmospherics/cooler/on_data_written() - temperature = max(243.15,min(293.15,get_pin_data(IC_INPUT, 1))) - if(get_pin_data(IC_INPUT, 2)) - power_draw_idle = 30 - else - power_draw_idle = 0 - -/obj/item/integrated_circuit/atmospherics/cooler/process() - set_pin_data(IC_OUTPUT, 2, air_contents.return_pressure()) - push_data() - - - //Get the turf you're on and its gas mixture - var/turf/current_turf = get_turf(src) - if(!current_turf) - return - - var/datum/gas_mixture/turf_air = current_turf.return_air() - if(!power_draw_idle || turf_air.temperature < temperature) - return - - //Cool the gas - turf_air.temperature = max(243.15,turf_air.temperature - (turf_air.temperature - temperature) * heater_coefficient) - - -// - atmospheric heater - // **works** -/obj/item/integrated_circuit/atmospherics/cooler/heater - name = "atmospheric heater circuit" - desc = "Heats the air around it." - -/obj/item/integrated_circuit/atmospherics/cooler/heater/on_data_written() - temperature = max(293.15,min(323.15,get_pin_data(IC_INPUT, 1))) - if(get_pin_data(IC_INPUT, 2)) - power_draw_idle = 30 - else - power_draw_idle = 0 - -/obj/item/integrated_circuit/atmospherics/cooler/heater/process() - set_pin_data(IC_OUTPUT, 2, air_contents.return_pressure()) - push_data() - - //Get the turf and its air mixture - var/turf/current_turf = get_turf(src) - if(!current_turf) - return - - var/datum/gas_mixture/turf_air = current_turf.return_air() - if(!power_draw_idle || turf_air.temperature > temperature) - return - - //Heat the gas - turf_air.temperature = min(323.15,turf_air.temperature + (temperature - turf_air.temperature) * heater_coefficient) - - -// - tank slot - // **works** -/obj/item/integrated_circuit/input/tank_slot - category_text = "Atmospherics" - cooldown_per_use = 1 - name = "tank slot" - desc = "Lets you add a tank to your assembly and remove it even when the assembly is closed." - extended_desc = "It can help you extract gases easier." - complexity = 25 - size = 30 - inputs = list() - outputs = list( - "pressure used" = IC_PINTYPE_NUMBER, - "current tank" = IC_PINTYPE_REF - ) - activators = list( - "push ref" = IC_PINTYPE_PULSE_IN, - "on insert" = IC_PINTYPE_PULSE_OUT, - "on remove" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - - can_be_asked_input = TRUE - demands_object_input = TRUE - can_input_object_when_closed = TRUE - - var/obj/item/tank/internals/current_tank - -/obj/item/integrated_circuit/input/tank_slot/Initialize() - START_PROCESSING(SSobj, src) - . = ..() - -/obj/item/integrated_circuit/input/tank_slot/process() - push_pressure() - -/obj/item/integrated_circuit/input/tank_slot/attackby(var/obj/item/tank/internals/I, var/mob/living/user) - //Check if it truly is a tank - if(!istype(I,/obj/item/tank/internals)) - to_chat(user,"The [I.name] doesn't seem to fit in here.") - return - - //Check if there is no other tank already inside - if(current_tank) - to_chat(user,"There is already a gas tank inside.") - return - - //The current tank is the one we just attached, its location is inside the circuit - current_tank = I - user.transferItemToLoc(I,src) - to_chat(user,"You put the [I.name] inside the tank slot.") - - //Set the pin to a weak reference of the current tank - push_pressure() - set_pin_data(IC_OUTPUT, 2, WEAKREF(current_tank)) - push_data() - do_work(1) - - -/obj/item/integrated_circuit/input/tank_slot/ask_for_input(mob/user) - attack_self(user) - -/obj/item/integrated_circuit/input/tank_slot/attack_self(mob/user) - //Check if no tank attached - if(!current_tank) - to_chat(user, "There is currently no tank attached.") - return - - //Remove tank and put in user's hands/location - to_chat(user, "You take [current_tank] out of the tank slot.") - user.put_in_hands(current_tank) - current_tank = null - - //Remove tank reference - push_pressure() - set_pin_data(IC_OUTPUT, 2, null) - push_data() - do_work(2) - -/obj/item/integrated_circuit/input/tank_slot/do_work() - set_pin_data(IC_OUTPUT, 2, WEAKREF(current_tank)) - push_data() - -/obj/item/integrated_circuit/input/tank_slot/proc/push_pressure() - if(!current_tank) - set_pin_data(IC_OUTPUT, 1, 0) - return - - var/datum/gas_mixture/tank_air = current_tank.return_air() - if(!tank_air) - set_pin_data(IC_OUTPUT, 1, 0) - return - - set_pin_data(IC_OUTPUT, 1, tank_air.return_pressure()) - push_data() - - -#undef SOURCE_TO_TARGET -#undef TARGET_TO_SOURCE -#undef PUMP_EFFICIENCY -#undef TANK_FAILURE_PRESSURE -#undef PUMP_MAX_PRESSURE -#undef PUMP_MAX_VOLUME +#define SOURCE_TO_TARGET 0 +#define TARGET_TO_SOURCE 1 +#define PUMP_EFFICIENCY 0.6 +#define TANK_FAILURE_PRESSURE (ONE_ATMOSPHERE*25) +#define PUMP_MAX_PRESSURE (ONE_ATMOSPHERE*24) +#define PUMP_MAX_VOLUME 100 + + +/obj/item/integrated_circuit/atmospherics + category_text = "Atmospherics" + cooldown_per_use = 2 SECONDS + complexity = 10 + size = 7 + outputs = list( + "self reference" = IC_PINTYPE_SELFREF, + "pressure" = IC_PINTYPE_NUMBER + ) + var/datum/gas_mixture/air_contents + var/volume = 2 //Pretty small, I know + +/obj/item/integrated_circuit/atmospherics/Initialize() + air_contents = new(volume) + ..() + +/obj/item/integrated_circuit/atmospherics/return_air() + return air_contents + +//Check if the gas container is adjacent and of the right type +/obj/item/integrated_circuit/atmospherics/proc/check_gassource(atom/gasholder) + if(!gasholder) + return FALSE + if(!gasholder.Adjacent(get_object())) + return FALSE + if(!istype(gasholder, /obj/item/tank) && !istype(gasholder, /obj/machinery/portable_atmospherics) && !istype(gasholder, /obj/item/integrated_circuit/atmospherics)) + return FALSE + return TRUE + +//Needed in circuits where source and target types differ +/obj/item/integrated_circuit/atmospherics/proc/check_gastarget(atom/gasholder) + return check_gassource(gasholder) + + +// - gas pump - // **works** +/obj/item/integrated_circuit/atmospherics/pump + name = "gas pump" + desc = "Somehow moves gases between two tanks, canisters, and other gas containers." + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + inputs = list( + "source" = IC_PINTYPE_REF, + "target" = IC_PINTYPE_REF, + "target pressure" = IC_PINTYPE_NUMBER + ) + activators = list( + "transfer" = IC_PINTYPE_PULSE_IN, + "on transfer" = IC_PINTYPE_PULSE_OUT + ) + var/direction = SOURCE_TO_TARGET + var/target_pressure = PUMP_MAX_PRESSURE + power_draw_per_use = 20 + +/obj/item/integrated_circuit/atmospherics/pump/Initialize() + air_contents = new(volume) + extended_desc += " Use negative pressure to move air from target to source. \ + Note that only part of the gas is moved on each transfer, \ + so multiple activations will be necessary to achieve target pressure. \ + The pressure limit for circuit pumps is [round(PUMP_MAX_PRESSURE)] kPa." + . = ..() + +// This proc gets the direction of the gas flow depending on its value, by calling update target +/obj/item/integrated_circuit/atmospherics/pump/on_data_written() + var/amt = get_pin_data(IC_INPUT, 3) + update_target(amt) + +/obj/item/integrated_circuit/atmospherics/pump/proc/update_target(new_amount) + if(!isnum(new_amount)) + new_amount = 0 + // See in which direction the gas moves + if(new_amount < 0) + direction = TARGET_TO_SOURCE + else + direction = SOURCE_TO_TARGET + target_pressure = min(round(PUMP_MAX_PRESSURE),abs(new_amount)) + +/obj/item/integrated_circuit/atmospherics/pump/do_work() + var/obj/source = get_pin_data_as_type(IC_INPUT, 1, /obj) + var/obj/target = get_pin_data_as_type(IC_INPUT, 2, /obj) + perform_magic(source, target) + activate_pin(2) + +/obj/item/integrated_circuit/atmospherics/pump/proc/perform_magic(atom/source, atom/target) + //Check if both atoms are of the right type: atmos circuits/gas tanks/canisters. If one is the same, use the circuit var + if(!check_gassource(source)) + source = src + + if(!check_gastarget(target)) + target = src + + // If both are the same, this whole proc would do nothing and just waste performance + if(source == target) + return + + var/datum/gas_mixture/source_air = source.return_air() + var/datum/gas_mixture/target_air = target.return_air() + + if(!source_air || !target_air) + return + + // Swapping both source and target + if(direction == TARGET_TO_SOURCE) + var/temp = source_air + source_air = target_air + target_air = temp + + // If what you are pumping is empty, use the circuit's storage + if(source_air.total_moles() <= 0) + source_air = air_contents + + // Move gas from one place to another + move_gas(source_air, target_air) + air_update_turf() + +/obj/item/integrated_circuit/atmospherics/pump/proc/move_gas(datum/gas_mixture/source_air, datum/gas_mixture/target_air) + + // No moles = nothing to pump + if(source_air.total_moles() <= 0 || target_air.return_pressure() >= PUMP_MAX_PRESSURE) + return + + // Negative Kelvin temperatures should never happen and if they do, normalize them + if(source_air.temperature < TCMB) + source_air.temperature = TCMB + + var/pressure_delta = target_pressure - target_air.return_pressure() + if(pressure_delta > 0.1) + var/transfer_moles = (pressure_delta*target_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY + var/datum/gas_mixture/removed = source_air.remove(transfer_moles) + target_air.merge(removed) + + +// - volume pump - // **Works** +/obj/item/integrated_circuit/atmospherics/pump/volume + name = "volume pump" + desc = "Moves gases between two tanks, canisters, and other gas containers by using their volume, up to 200 L/s." + extended_desc = " Use negative volume to move air from target to source. Note that only part of the gas is moved on each transfer. Its maximum pumping volume is capped at 1000kPa." + + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + inputs = list( + "source" = IC_PINTYPE_REF, + "target" = IC_PINTYPE_REF, + "transfer volume" = IC_PINTYPE_NUMBER + ) + activators = list( + "transfer" = IC_PINTYPE_PULSE_IN, + "on transfer" = IC_PINTYPE_PULSE_OUT + ) + direction = SOURCE_TO_TARGET + var/transfer_rate = PUMP_MAX_VOLUME + power_draw_per_use = 20 + +/obj/item/integrated_circuit/atmospherics/pump/volume/update_target(new_amount) + if(!isnum(new_amount)) + new_amount = 0 + // See in which direction the gas moves + if(new_amount < 0) + direction = TARGET_TO_SOURCE + else + direction = SOURCE_TO_TARGET + target_pressure = min(PUMP_MAX_VOLUME,abs(new_amount)) + +/obj/item/integrated_circuit/atmospherics/pump/volume/move_gas(datum/gas_mixture/source_air, datum/gas_mixture/target_air) + // No moles = nothing to pump + if(source_air.total_moles() <= 0) + return + + // Negative Kelvin temperatures should never happen and if they do, normalize them + if(source_air.temperature < TCMB) + source_air.temperature = TCMB + + if((source_air.return_pressure() < 0.01) || (target_air.return_pressure() >= PUMP_MAX_PRESSURE)) + return + + //The second part of the min caps the pressure built by the volume pumps to the max pump pressure + var/transfer_ratio = min(transfer_rate,target_air.volume*PUMP_MAX_PRESSURE/source_air.return_pressure())/source_air.volume + + var/datum/gas_mixture/removed = source_air.remove_ratio(transfer_ratio * PUMP_EFFICIENCY) + + target_air.merge(removed) + + +// - gas vent - // **works** +/obj/item/integrated_circuit/atmospherics/pump/vent + name = "gas vent" + extended_desc = "Use negative volume to move air from target to environment. Note that only part of the gas is moved on each transfer. Unlike the gas pump, this one keeps pumping even further to pressures of 9000 pKa and it is not advised to use it on tank circuits." + desc = "Moves gases between the environment and adjacent gas containers." + inputs = list( + "container" = IC_PINTYPE_REF, + "target pressure" = IC_PINTYPE_NUMBER + ) + +/obj/item/integrated_circuit/atmospherics/pump/vent/on_data_written() + var/amt = get_pin_data(IC_INPUT, 2) + update_target(amt) + +/obj/item/integrated_circuit/atmospherics/pump/vent/do_work() + var/turf/source = get_turf(src) + var/obj/target = get_pin_data_as_type(IC_INPUT, 1, /obj) + perform_magic(source, target) + activate_pin(2) + +/obj/item/integrated_circuit/atmospherics/pump/vent/check_gastarget(atom/gasholder) + if(!gasholder) + return FALSE + if(!gasholder.Adjacent(get_object())) + return FALSE + if(!istype(gasholder, /obj/item/tank) && !istype(gasholder, /obj/machinery/portable_atmospherics) && !istype(gasholder, /obj/item/integrated_circuit/atmospherics)) + return FALSE + return TRUE + + +/obj/item/integrated_circuit/atmospherics/pump/vent/check_gassource(atom/target) + if(!target) + return FALSE + if(!istype(target, /turf)) + return FALSE + return TRUE + + +// - integrated connector - // Can connect and disconnect properly +/obj/item/integrated_circuit/atmospherics/connector + name = "integrated connector" + desc = "Creates an airtight seal with standard connectors found on the floor, \ + allowing the assembly to exchange gases with a pipe network." + extended_desc = "This circuit will automatically attempt to locate and connect to ports on the floor beneath it when activated. \ + You must set a target before connecting." + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + inputs = list( + "target" = IC_PINTYPE_REF + ) + activators = list( + "toggle connection" = IC_PINTYPE_PULSE_IN, + "on connected" = IC_PINTYPE_PULSE_OUT, + "on connection failed" = IC_PINTYPE_PULSE_OUT, + "on disconnected" = IC_PINTYPE_PULSE_OUT + ) + + var/obj/machinery/atmospherics/components/unary/portables_connector/connector + +/obj/item/integrated_circuit/atmospherics/connector/Initialize() + air_contents = new(volume) + START_PROCESSING(SSobj, src) + . = ..() + +//Sucks up the gas from the connector +/obj/item/integrated_circuit/atmospherics/connector/process() + set_pin_data(IC_OUTPUT, 2, air_contents.return_pressure()) + +/obj/item/integrated_circuit/atmospherics/connector/check_gassource(atom/gasholder) + if(!gasholder) + return FALSE + if(!istype(gasholder,/obj/machinery/atmospherics/components/unary/portables_connector)) + return FALSE + return TRUE + +//If the assembly containing this is moved from the tile the connector pipe is in, the connection breaks +/obj/item/integrated_circuit/atmospherics/connector/ext_moved() + if(connector) + if(get_dist(get_object(), connector) > 0) + // The assembly is set as connected device and the connector handles the rest + connector.connected_device = null + connector = null + activate_pin(4) + +/obj/item/integrated_circuit/atmospherics/connector/do_work() + // If there is a connection, disconnect + if(connector) + connector.connected_device = null + connector = null + activate_pin(4) + return + + var/obj/machinery/atmospherics/components/unary/portables_connector/PC = locate() in get_turf(src) + // If no connector can't connect + if(!PC) + activate_pin(3) + return + connector = PC + connector.connected_device = src + activate_pin(2) + +// Required for making the connector port script work +obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir() + return air_contents + + +// - gas filter - // **works** +/obj/item/integrated_circuit/atmospherics/pump/filter + name = "gas filter" + desc = "Filters one gas out of a mixture." + complexity = 20 + size = 8 + spawn_flags = IC_SPAWN_RESEARCH + inputs = list( + "source" = IC_PINTYPE_REF, + "filtered output" = IC_PINTYPE_REF, + "contaminants output" = IC_PINTYPE_REF, + "wanted gases" = IC_PINTYPE_LIST, + "target pressure" = IC_PINTYPE_NUMBER + ) + power_draw_per_use = 30 + +/obj/item/integrated_circuit/atmospherics/pump/filter/on_data_written() + var/amt = get_pin_data(IC_INPUT, 5) + target_pressure = CLAMP(amt, 0, PUMP_MAX_PRESSURE) + +/obj/item/integrated_circuit/atmospherics/pump/filter/do_work() + activate_pin(2) + var/obj/source = get_pin_data_as_type(IC_INPUT, 1, /obj) + var/obj/filtered = get_pin_data_as_type(IC_INPUT, 2, /obj) + var/obj/contaminants = get_pin_data_as_type(IC_INPUT, 3, /obj) + + var/wanted = get_pin_data(IC_INPUT, 4) + + // If there is no filtered output, this whole thing makes no sense + if(!check_gassource(filtered)) + return + + var/datum/gas_mixture/filtered_air = filtered.return_air() + if(!filtered_air) + return + + // If no source is set, the source is possibly this circuit's content + if(!check_gassource(source)) + source = src + var/datum/gas_mixture/source_air = source.return_air() + + //No source air: source is this circuit + if(!source_air) + source_air = air_contents + + // If no filtering tank is set, filter through itself + if(!check_gassource(contaminants)) + contaminants = src + var/datum/gas_mixture/contaminated_air = contaminants.return_air() + + //If there is no gas mixture datum for unfiltered, pump the contaminants back into the circuit + if(!contaminated_air) + contaminated_air = air_contents + + if(contaminated_air.return_pressure() >= PUMP_MAX_PRESSURE || filtered_air.return_pressure() >= PUMP_MAX_PRESSURE) + return + + var/pressure_delta = target_pressure - contaminated_air.return_pressure() + var/transfer_moles + + //Negative Kelvins are an anomaly and should be normalized if encountered + if(source_air.temperature < TCMB) + source_air.temperature = TCMB + + transfer_moles = (pressure_delta*contaminated_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY + + //If there is nothing to transfer, just return + if(transfer_moles <= 0) + return + + //This is the var that holds the currently filtered part of the gas + var/datum/gas_mixture/removed = source_air.remove(transfer_moles) + if(!removed) + return + + //This is the gas that will be moved from source to filtered + var/datum/gas_mixture/filtered_out = new + + for(var/filtered_gas in removed.gases) + //Get the name of the gas and see if it is in the list + if(GLOB.meta_gas_names[filtered_gas] in wanted) + //The gas that is put in all the filtered out gases + filtered_out.temperature = removed.temperature + filtered_out.gases[filtered_gas] = removed.gases[filtered_gas] + + //The filtered out gas is entirely removed from the currently filtered gases + removed.gases[filtered_gas] = 0 + GAS_GARBAGE_COLLECT(removed.gases) + + //Check if the pressure is high enough to put stuff in filtered, or else just put it back in the source + var/datum/gas_mixture/target = (filtered_air.return_pressure() < target_pressure ? filtered_air : source_air) + target.merge(filtered_out) + contaminated_air.merge(removed) + + +/obj/item/integrated_circuit/atmospherics/pump/filter/Initialize() + air_contents = new(volume) + . = ..() + extended_desc = "Remember to properly spell and capitalize the filtered gas name. \ + Note that only part of the gas is moved on each transfer, \ + so multiple activations will be necessary to achieve target pressure. \ + The pressure limit for circuit pumps is [round(PUMP_MAX_PRESSURE)] kPa." + + +// - gas mixer - // **works** +/obj/item/integrated_circuit/atmospherics/pump/mixer + name = "gas mixer" + desc = "Mixes 2 different types of gases." + complexity = 20 + size = 8 + spawn_flags = IC_SPAWN_RESEARCH + inputs = list( + "first source" = IC_PINTYPE_REF, + "second source" = IC_PINTYPE_REF, + "output" = IC_PINTYPE_REF, + "first source percentage" = IC_PINTYPE_NUMBER, + "target pressure" = IC_PINTYPE_NUMBER + ) + power_draw_per_use = 30 + +/obj/item/integrated_circuit/atmospherics/pump/mixer/do_work() + activate_pin(2) + var/obj/source_1 = get_pin_data(IC_INPUT, 1) + var/obj/source_2 = get_pin_data(IC_INPUT, 2) + var/obj/gas_output = get_pin_data(IC_INPUT, 3) + if(!check_gassource(source_1)) + source_1 = src + + if(!check_gassource(source_2)) + source_2 = src + + if(!check_gassource(gas_output)) + gas_output = src + + if(source_1 == gas_output || source_2 == gas_output) + return + + var/datum/gas_mixture/source_1_gases = source_1.return_air() + var/datum/gas_mixture/source_2_gases = source_2.return_air() + var/datum/gas_mixture/output_gases = gas_output.return_air() + + if(!source_1_gases || !source_2_gases || !output_gases) + return + + if(output_gases.return_pressure() >= PUMP_MAX_PRESSURE) + return + + if(source_1_gases.return_pressure() <= 0 || source_2_gases.return_pressure() <= 0) + return + + //This calculates how much should be sent + var/gas_percentage = round(max(min(get_pin_data(IC_INPUT, 4),100),0) / 100) + + //Basically: number of moles = percentage of pressure filled up * efficiency coefficient * (pressure from both gases * volume of output) / (R * Temperature) + var/transfer_moles = (get_pin_data(IC_INPUT, 5) / max(1,output_gases.return_pressure())) * PUMP_EFFICIENCY * (source_1_gases.return_pressure() * gas_percentage + source_2_gases.return_pressure() * (1 - gas_percentage)) * output_gases.volume/ (R_IDEAL_GAS_EQUATION * max(output_gases.temperature,TCMB)) + + + if(transfer_moles <= 0) + return + + var/datum/gas_mixture/mix = source_1_gases.remove(transfer_moles * gas_percentage) + output_gases.merge(mix) + mix = source_2_gases.remove(transfer_moles * (1-gas_percentage)) + output_gases.merge(mix) + + +// - integrated tank - // **works** +/obj/item/integrated_circuit/atmospherics/tank + name = "integrated tank" + desc = "A small tank for the storage of gases." + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + size = 4 + activators = list( + "push ref" = IC_PINTYPE_PULSE_IN + ) + volume = 3 //emergency tank sized + var/broken = FALSE + +/obj/item/integrated_circuit/atmospherics/tank/Initialize() + air_contents = new(volume) + START_PROCESSING(SSobj, src) + extended_desc = "Take care not to pressurize it above [round(TANK_FAILURE_PRESSURE)] kPa, or else it will break." + . = ..() + +/obj/item/integrated_circuit/atmospherics/tank/Destroy() + STOP_PROCESSING(SSobj, src) + . = ..() + +/obj/item/integrated_circuit/atmospherics/tank/do_work() + set_pin_data(IC_OUTPUT, 1, WEAKREF(src)) + push_data() + +/obj/item/integrated_circuit/atmospherics/tank/process() + var/tank_pressure = air_contents.return_pressure() + set_pin_data(IC_OUTPUT, 2, tank_pressure) + push_data() + + //Check if tank broken + if(!broken && tank_pressure > TANK_FAILURE_PRESSURE) + broken = TRUE + to_chat(view(2),"The [name] ruptures, releasing its gases!") + if(broken) + release() + +/obj/item/integrated_circuit/atmospherics/tank/proc/release() + if(air_contents.total_moles() > 0) + playsound(loc, 'sound/effects/spray.ogg', 10, 1, -3) + var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles()) + var/turf/current_turf = get_turf(src) + var/datum/gas_mixture/exterior_gas + if(!current_turf) + return + + exterior_gas = current_turf.return_air() + exterior_gas.merge(expelled_gas) + + +// - large integrated tank - // **works** +/obj/item/integrated_circuit/atmospherics/tank/large + name = "large integrated tank" + desc = "A less small tank for the storage of gases." + volume = 9 + size = 12 + spawn_flags = IC_SPAWN_RESEARCH + + +// - freezer tank - // **works** +/obj/item/integrated_circuit/atmospherics/tank/freezer + name = "freezer tank" + desc = "Cools the gas it contains to a preset temperature." + volume = 6 + size = 8 + inputs = list( + "target temperature" = IC_PINTYPE_NUMBER, + "on" = IC_PINTYPE_BOOLEAN + ) + inputs_default = list("1" = 300) + spawn_flags = IC_SPAWN_RESEARCH + var/temperature = 293.15 + var/heater_coefficient = 0.1 + +/obj/item/integrated_circuit/atmospherics/tank/freezer/on_data_written() + temperature = max(73.15,min(293.15,get_pin_data(IC_INPUT, 1))) + if(get_pin_data(IC_INPUT, 2)) + power_draw_idle = 30 + else + power_draw_idle = 0 + +/obj/item/integrated_circuit/atmospherics/tank/freezer/process() + var/tank_pressure = air_contents.return_pressure() + set_pin_data(IC_OUTPUT, 2, tank_pressure) + push_data() + + //Cool the tank if the power is on and the temp is above + if(!power_draw_idle || air_contents.temperature < temperature) + return + + air_contents.temperature = max(73.15,air_contents.temperature - (air_contents.temperature - temperature) * heater_coefficient) + + +// - heater tank - // **works** +/obj/item/integrated_circuit/atmospherics/tank/freezer/heater + name = "heater tank" + desc = "Heats the gas it contains to a preset temperature." + volume = 6 + inputs = list( + "target temperature" = IC_PINTYPE_NUMBER, + "on" = IC_PINTYPE_BOOLEAN + ) + spawn_flags = IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/atmospherics/tank/freezer/heater/on_data_written() + temperature = max(293.15,min(573.15,get_pin_data(IC_INPUT, 1))) + if(get_pin_data(IC_INPUT, 2)) + power_draw_idle = 30 + else + power_draw_idle = 0 + +/obj/item/integrated_circuit/atmospherics/tank/freezer/heater/process() + var/tank_pressure = air_contents.return_pressure() + set_pin_data(IC_OUTPUT, 2, tank_pressure) + push_data() + + //Heat the tank if the power is on or its temperature is below what is set + if(!power_draw_idle || air_contents.temperature > temperature) + return + + air_contents.temperature = min(573.15,air_contents.temperature + (temperature - air_contents.temperature) * heater_coefficient) + + +// - atmospheric cooler - // **works** +/obj/item/integrated_circuit/atmospherics/cooler + name = "atmospheric cooler circuit" + desc = "Cools the air around it." + volume = 6 + size = 13 + spawn_flags = IC_SPAWN_RESEARCH + inputs = list( + "target temperature" = IC_PINTYPE_NUMBER, + "on" = IC_PINTYPE_BOOLEAN + ) + var/temperature = 293.15 + var/heater_coefficient = 0.1 + +/obj/item/integrated_circuit/atmospherics/cooler/Initialize() + air_contents = new(volume) + START_PROCESSING(SSobj, src) + . = ..() + +/obj/item/integrated_circuit/atmospherics/cooler/Destroy() + STOP_PROCESSING(SSobj, src) + . = ..() + +/obj/item/integrated_circuit/atmospherics/cooler/on_data_written() + temperature = max(243.15,min(293.15,get_pin_data(IC_INPUT, 1))) + if(get_pin_data(IC_INPUT, 2)) + power_draw_idle = 30 + else + power_draw_idle = 0 + +/obj/item/integrated_circuit/atmospherics/cooler/process() + set_pin_data(IC_OUTPUT, 2, air_contents.return_pressure()) + push_data() + + + //Get the turf you're on and its gas mixture + var/turf/current_turf = get_turf(src) + if(!current_turf) + return + + var/datum/gas_mixture/turf_air = current_turf.return_air() + if(!power_draw_idle || turf_air.temperature < temperature) + return + + //Cool the gas + turf_air.temperature = max(243.15,turf_air.temperature - (turf_air.temperature - temperature) * heater_coefficient) + + +// - atmospheric heater - // **works** +/obj/item/integrated_circuit/atmospherics/cooler/heater + name = "atmospheric heater circuit" + desc = "Heats the air around it." + +/obj/item/integrated_circuit/atmospherics/cooler/heater/on_data_written() + temperature = max(293.15,min(323.15,get_pin_data(IC_INPUT, 1))) + if(get_pin_data(IC_INPUT, 2)) + power_draw_idle = 30 + else + power_draw_idle = 0 + +/obj/item/integrated_circuit/atmospherics/cooler/heater/process() + set_pin_data(IC_OUTPUT, 2, air_contents.return_pressure()) + push_data() + + //Get the turf and its air mixture + var/turf/current_turf = get_turf(src) + if(!current_turf) + return + + var/datum/gas_mixture/turf_air = current_turf.return_air() + if(!power_draw_idle || turf_air.temperature > temperature) + return + + //Heat the gas + turf_air.temperature = min(323.15,turf_air.temperature + (temperature - turf_air.temperature) * heater_coefficient) + + +// - tank slot - // **works** +/obj/item/integrated_circuit/input/tank_slot + category_text = "Atmospherics" + cooldown_per_use = 1 + name = "tank slot" + desc = "Lets you add a tank to your assembly and remove it even when the assembly is closed." + extended_desc = "It can help you extract gases easier." + complexity = 25 + size = 30 + inputs = list() + outputs = list( + "pressure used" = IC_PINTYPE_NUMBER, + "current tank" = IC_PINTYPE_REF + ) + activators = list( + "push ref" = IC_PINTYPE_PULSE_IN, + "on insert" = IC_PINTYPE_PULSE_OUT, + "on remove" = IC_PINTYPE_PULSE_OUT + ) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + + can_be_asked_input = TRUE + demands_object_input = TRUE + can_input_object_when_closed = TRUE + + var/obj/item/tank/internals/current_tank + +/obj/item/integrated_circuit/input/tank_slot/Initialize() + START_PROCESSING(SSobj, src) + . = ..() + +/obj/item/integrated_circuit/input/tank_slot/process() + push_pressure() + +/obj/item/integrated_circuit/input/tank_slot/attackby(var/obj/item/tank/internals/I, var/mob/living/user) + //Check if it truly is a tank + if(!istype(I,/obj/item/tank/internals)) + to_chat(user,"The [I.name] doesn't seem to fit in here.") + return + + //Check if there is no other tank already inside + if(current_tank) + to_chat(user,"There is already a gas tank inside.") + return + + //The current tank is the one we just attached, its location is inside the circuit + current_tank = I + user.transferItemToLoc(I,src) + to_chat(user,"You put the [I.name] inside the tank slot.") + + //Set the pin to a weak reference of the current tank + push_pressure() + set_pin_data(IC_OUTPUT, 2, WEAKREF(current_tank)) + push_data() + do_work(1) + + +/obj/item/integrated_circuit/input/tank_slot/ask_for_input(mob/user) + attack_self(user) + +/obj/item/integrated_circuit/input/tank_slot/attack_self(mob/user) + //Check if no tank attached + if(!current_tank) + to_chat(user, "There is currently no tank attached.") + return + + //Remove tank and put in user's hands/location + to_chat(user, "You take [current_tank] out of the tank slot.") + user.put_in_hands(current_tank) + current_tank = null + + //Remove tank reference + push_pressure() + set_pin_data(IC_OUTPUT, 2, null) + push_data() + do_work(2) + +/obj/item/integrated_circuit/input/tank_slot/do_work() + set_pin_data(IC_OUTPUT, 2, WEAKREF(current_tank)) + push_data() + +/obj/item/integrated_circuit/input/tank_slot/proc/push_pressure() + if(!current_tank) + set_pin_data(IC_OUTPUT, 1, 0) + return + + var/datum/gas_mixture/tank_air = current_tank.return_air() + if(!tank_air) + set_pin_data(IC_OUTPUT, 1, 0) + return + + set_pin_data(IC_OUTPUT, 1, tank_air.return_pressure()) + push_data() + + +#undef SOURCE_TO_TARGET +#undef TARGET_TO_SOURCE +#undef PUMP_EFFICIENCY +#undef TANK_FAILURE_PRESSURE +#undef PUMP_MAX_PRESSURE +#undef PUMP_MAX_VOLUME diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 668f49c98f..c323718c07 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -142,13 +142,14 @@ /obj/item/integrated_circuit/converter/concatenator name = "concatenator" - desc = "This can join up to 8 strings together to get one big string." + desc = "This can join up to 8 strings together to get a string with a maximum of 512 characters." complexity = 4 inputs = list() outputs = list("result" = IC_PINTYPE_STRING) activators = list("concatenate" = IC_PINTYPE_PULSE_IN, "on concatenated" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/number_of_pins = 8 + var/max_string_length = 512 /obj/item/integrated_circuit/converter/concatenator/Initialize() for(var/i = 1 to number_of_pins) @@ -157,26 +158,46 @@ /obj/item/integrated_circuit/converter/concatenator/do_work() var/result = null + var/spamprotection for(var/k in 1 to inputs.len) var/I = get_pin_data(IC_INPUT, k) if(!isnull(I)) + if((result ? length(result) : 0) + length(I) > max_string_length) + spamprotection = (result ? length(result) : 0) + length(I) + break result = result + I + if(spamprotection >= max_string_length*1.75 && assembly) + if(assembly.fingerprintslast) + var/mob/M = get_mob_by_key(assembly.fingerprintslast) + var/more = "" + if(M) + more = "[ADMIN_LOOKUPFLW(M)] " + message_admins("A concatenator circuit has greatly exceeded its [max_string_length] character limit with a total of [spamprotection] characters, and has been deleted. Assembly last touched by [more ? more : assembly.fingerprintslast].") + investigate_log("A concatenator circuit has greatly exceeded its [max_string_length] character limit with a total of [spamprotection] characters, and has been deleted. Assembly last touched by [assembly.fingerprintslast].", INVESTIGATE_CIRCUIT) + else + message_admins("A concatenator circuit has greatly exceeded its [max_string_length] character limit with a total of [spamprotection] characters, and has been deleted. No associated key.") + investigate_log("A concatenator circuit has greatly exceeded its [max_string_length] character limit with a total of [spamprotection] characters, and has been deleted. No associated key.", INVESTIGATE_CIRCUIT) + qdel(assembly) + return + set_pin_data(IC_OUTPUT, 1, result) push_data() activate_pin(2) /obj/item/integrated_circuit/converter/concatenator/small name = "small concatenator" - desc = "This can join up to 4 strings together to get one big string." + desc = "This can join up to 4 strings together to get a string with a maximum of 256 characters." complexity = 2 number_of_pins = 4 + max_string_length = 256 /obj/item/integrated_circuit/converter/concatenator/large name = "large concatenator" - desc = "This can join up to 16 strings together to get one very big string." + desc = "This can join up to 16 strings together to get a string with a maximum of 1024 characters." complexity = 6 number_of_pins = 16 + max_string_length = 1024 /obj/item/integrated_circuit/converter/separator name = "separator" diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 6e8b0cb777..b258a15972 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -1165,8 +1165,8 @@ var/list/gas_names = list() var/list/gas_amounts = list() for(var/id in gases) - var/name = gases[id][GAS_META][META_GAS_NAME] - var/amt = round(gases[id][MOLES], 0.001) + var/name = GLOB.meta_gas_names[id] + var/amt = round(gases[id], 0.001) gas_names.Add(name) gas_amounts.Add(amt) @@ -1309,4 +1309,35 @@ set_pin_data(IC_OUTPUT, 2, regurgitated_contents) push_data() + activate_pin(2) + +//Degens +/obj/item/integrated_circuit/input/bonermeter + name = "bonermeter" + desc = "Detects the target's arousal and various statistics about the target's arousal levels. Invasive!" + icon_state = "medscan" + complexity = 4 + inputs = list("target" = IC_PINTYPE_REF) + outputs = list( + "current arousal" = IC_PINTYPE_NUMBER, + "minimum arousal" = IC_PINTYPE_NUMBER, + "maximum arousal" = IC_PINTYPE_NUMBER, + "can be aroused" = IC_PINTYPE_BOOLEAN + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + +/obj/item/integrated_circuit/input/bonermeter/do_work() + + var/mob/living/L = get_pin_data_as_type(IC_INPUT, 1, /mob/living) + + if(!istype(L) || !L.Adjacent(get_turf(src)) ) //Invalid input + return + + set_pin_data(IC_OUTPUT, 1, L.getArousalLoss()) + set_pin_data(IC_OUTPUT, 2, L.min_arousal) + set_pin_data(IC_OUTPUT, 3, L.max_arousal) + set_pin_data(IC_OUTPUT, 4, L.canbearoused) + push_data() activate_pin(2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index f63d58b707..682e76a46e 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -1,139 +1,6 @@ /obj/item/integrated_circuit/manipulation category_text = "Manipulation" -/obj/item/integrated_circuit/manipulation/weapon_firing - name = "weapon firing mechanism" - desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it." - extended_desc = "The firing mechanism can slot in any energy weapon. \ - The first and second inputs need to be numbers which correspond to coordinates for the gun to fire at relative to the machine itself. \ - The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Mode will switch between \ - lethal (TRUE) or stun (FALSE) modes. It uses the internal battery of the weapon itself, not the assembly. If you wish to fire the gun while the circuit is in \ - hand, you will need to use an assembly that is a gun." - complexity = 20 - w_class = WEIGHT_CLASS_SMALL - size = 3 - inputs = list( - "target X rel" = IC_PINTYPE_NUMBER, - "target Y rel" = IC_PINTYPE_NUMBER, - "mode" = IC_PINTYPE_BOOLEAN - ) - outputs = list("reference to gun" = IC_PINTYPE_REF) - activators = list( - "fire" = IC_PINTYPE_PULSE_IN - - ) - var/obj/item/gun/energy/installed_gun = null - spawn_flags = IC_SPAWN_RESEARCH - action_flags = IC_ACTION_COMBAT - power_draw_per_use = 0 - ext_cooldown = 1 - var/mode = FALSE - - var/stun_projectile = null //stun mode projectile type - var/stun_projectile_sound - var/lethal_projectile = null //lethal mode projectile type - var/lethal_projectile_sound - - demands_object_input = TRUE // You can put stuff in once the circuit is in assembly,passed down from additem and handled by attackby() - - - -/obj/item/integrated_circuit/manipulation/weapon_firing/Destroy() - qdel(installed_gun) - return ..() - -/obj/item/integrated_circuit/manipulation/weapon_firing/attackby(var/obj/O, var/mob/user) - if(istype(O, /obj/item/gun/energy)) - var/obj/item/gun/gun = O - if(installed_gun) - to_chat(user, "There's already a weapon installed.") - return - user.transferItemToLoc(gun,src) - installed_gun = gun - var/list/gun_properties = gun.get_turret_properties() - to_chat(user, "You slide \the [gun] into the firing mechanism.") - playsound(src, 'sound/items/Crowbar.ogg', 50, 1) - stun_projectile = gun_properties["stun_projectile"] - stun_projectile_sound = gun_properties["stun_projectile_sound"] - lethal_projectile = gun_properties["lethal_projectile"] - lethal_projectile_sound = gun_properties["lethal_projectile_sound"] - if(gun_properties["shot_delay"]) - cooldown_per_use = gun_properties["shot_delay"]*10 - if(cooldown_per_use<30) - cooldown_per_use = 30 - if(gun_properties["reqpower"]) - power_draw_per_use = gun_properties["reqpower"] - set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun)) - push_data() - else - ..() - -/obj/item/integrated_circuit/manipulation/weapon_firing/attack_self(var/mob/user) - if(installed_gun) - installed_gun.forceMove(drop_location()) - to_chat(user, "You slide \the [installed_gun] out of the firing mechanism.") - size = initial(size) - playsound(src, 'sound/items/Crowbar.ogg', 50, 1) - installed_gun = null - set_pin_data(IC_OUTPUT, 1, WEAKREF(null)) - push_data() - else - to_chat(user, "There's no weapon to remove from the mechanism.") - -/obj/item/integrated_circuit/manipulation/weapon_firing/do_work() - if(!installed_gun || !installed_gun.handle_pins()) - return - if(!isturf(assembly.loc) && !(assembly.can_fire_equipped && ishuman(assembly.loc))) - return - set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun)) - push_data() - var/datum/integrated_io/xo = inputs[1] - var/datum/integrated_io/yo = inputs[2] - var/datum/integrated_io/mode1 = inputs[3] - - mode = mode1.data - if(assembly) - if(isnum(xo.data)) - xo.data = round(xo.data, 1) - if(isnum(yo.data)) - yo.data = round(yo.data, 1) - - var/turf/T = get_turf(assembly) - var/target_x = CLAMP(T.x + xo.data, 0, world.maxx) - var/target_y = CLAMP(T.y + yo.data, 0, world.maxy) - - assembly.visible_message("[assembly] fires [installed_gun]!") - shootAt(locate(target_x, target_y, T.z)) - -/obj/item/integrated_circuit/manipulation/weapon_firing/proc/shootAt(turf/target) - var/turf/T = get_turf(src) - var/turf/U = target - if(!istype(T) || !istype(U)) - return - if(!installed_gun.cell) - return - if(!installed_gun.cell.charge) - return - var/obj/item/ammo_casing/energy/shot = installed_gun.ammo_type[mode?2:1] - if(installed_gun.cell.charge < shot.e_cost) - return - if(!shot) - return - update_icon() - var/obj/item/projectile/A - if(!mode) - A = new stun_projectile(T) - playsound(loc, stun_projectile_sound, 75, 1) - else - A = new lethal_projectile(T) - playsound(loc, lethal_projectile_sound, 75, 1) - installed_gun.cell.use(shot.e_cost) - //Shooting Code: - A.preparePixelProjectile(target, src) - A.fire() - log_attack("[assembly] [REF(assembly)] has fired [installed_gun].") - return A - /obj/item/integrated_circuit/manipulation/locomotion name = "locomotion circuit" desc = "This allows a machine to move in a given direction." @@ -144,7 +11,7 @@ w_class = WEIGHT_CLASS_SMALL complexity = 10 cooldown_per_use = 1 - ext_cooldown = 1 + ext_cooldown = 2 inputs = list("direction" = IC_PINTYPE_DIR) outputs = list("obstacle" = IC_PINTYPE_REF) activators = list("step towards dir" = IC_PINTYPE_PULSE_IN,"on step"=IC_PINTYPE_PULSE_OUT,"blocked"=IC_PINTYPE_PULSE_OUT) @@ -171,80 +38,6 @@ return FALSE return FALSE -/obj/item/integrated_circuit/manipulation/grenade - name = "grenade primer" - desc = "This circuit comes with the ability to attach most types of grenades and prime them at will." - extended_desc = "The time between priming and detonation is limited to between 1 to 12 seconds, but is optional. \ - If the input is not set, not a number, or a number less than 1, the grenade's built-in timing will be used. \ - Beware: Once primed, there is no aborting the process!" - icon_state = "grenade" - complexity = 30 - cooldown_per_use = 10 - inputs = list("detonation time" = IC_PINTYPE_NUMBER) - outputs = list() - activators = list("prime grenade" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_RESEARCH - action_flags = IC_ACTION_COMBAT - var/obj/item/grenade/attached_grenade - var/pre_attached_grenade_type - demands_object_input = TRUE // You can put stuff in once the circuit is in assembly,passed down from additem and handled by attackby() - -/obj/item/integrated_circuit/manipulation/grenade/Initialize() - . = ..() - if(pre_attached_grenade_type) - var/grenade = new pre_attached_grenade_type(src) - attach_grenade(grenade) - -/obj/item/integrated_circuit/manipulation/grenade/Destroy() - if(attached_grenade && !attached_grenade.active) - attached_grenade.forceMove(loc) - detach_grenade() - return ..() - -/obj/item/integrated_circuit/manipulation/grenade/attackby(var/obj/item/grenade/G, var/mob/user) - if(istype(G)) - if(attached_grenade) - to_chat(user, "There is already a grenade attached!") - else if(user.transferItemToLoc(G,src)) - user.visible_message("\The [user] attaches \a [G] to \the [src]!", "You attach \the [G] to \the [src].") - attach_grenade(G) - G.forceMove(src) - else - return ..() - -/obj/item/integrated_circuit/manipulation/grenade/attack_self(var/mob/user) - if(attached_grenade) - user.visible_message("\The [user] removes \an [attached_grenade] from \the [src]!", "You remove \the [attached_grenade] from \the [src].") - user.put_in_hands(attached_grenade) - detach_grenade() - else - return ..() - -/obj/item/integrated_circuit/manipulation/grenade/do_work() - if(attached_grenade && !attached_grenade.active) - var/datum/integrated_io/detonation_time = inputs[1] - var/dt - if(isnum(detonation_time.data) && detonation_time.data > 0) - dt = CLAMP(detonation_time.data, 1, 12)*10 - else - dt = 15 - addtimer(CALLBACK(attached_grenade, /obj/item/grenade.proc/prime), dt) - var/atom/holder = loc - message_admins("activated a grenade assembly. Last touches: Assembly: [holder.fingerprintslast] Circuit: [fingerprintslast] Grenade: [attached_grenade.fingerprintslast]") - -// These procs do not relocate the grenade, that's the callers responsibility -/obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/grenade/G) - attached_grenade = G - G.forceMove(src) - desc += " \An [attached_grenade] is attached to it!" - -/obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade() - if(!attached_grenade) - return - attached_grenade.forceMove(drop_location()) - attached_grenade = null - desc = initial(desc) - /obj/item/integrated_circuit/manipulation/plant_module name = "plant manipulation module" desc = "Used to uproot weeds and harvest/plant trays." @@ -478,7 +271,7 @@ /obj/item/integrated_circuit/manipulation/thrower name = "thrower" - desc = "A compact launcher to throw things from inside or nearby tiles." + desc = "A compact launcher to throw things from inside or nearby tiles at a low enough velocity not to harm someone." extended_desc = "The first and second inputs need to be numbers which correspond to the coordinates to throw objects at relative to the machine itself. \ The 'fire' activator will cause the mechanism to attempt to throw objects at the coordinates, if possible. Note that the \ projectile needs to be inside the machine, or on an adjacent tile, and must be medium sized or smaller. The assembly \ @@ -544,7 +337,7 @@ A.embedding = list("embed_chance" = 0) //throw it assembly.visible_message("[assembly] has thrown [A]!") - log_attack("[assembly] [REF(assembly)] has thrown [A].") + log_attack("[assembly] [REF(assembly)] has thrown [A] with non-lethal force.") A.forceMove(drop_location()) A.throw_at(locate(x_abs, y_abs, T.z), range, 3, , , , CALLBACK(src, .proc/post_throw, A)) @@ -813,4 +606,7 @@ set_pin_data(IC_OUTPUT, 1, assembly.detail_color) push_data() - activate_pin(3) \ No newline at end of file + activate_pin(3) + + + diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 0d8bf96afc..027a03650a 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -51,7 +51,6 @@ extended_desc = "This autoinjector can push up to 30 units of reagents into another container or someone else outside of the machine. The target \ must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing. Negative given amounts makes the injector suck out reagents instead." - container_type = OPENCONTAINER volume = 30 complexity = 20 @@ -80,6 +79,10 @@ var/transfer_amount = 10 var/busy = FALSE +/obj/item/integrated_circuit/reagent/injector/Initialize() + . = ..() + ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + /obj/item/integrated_circuit/reagent/injector/on_reagent_change(changetype) push_vol() @@ -260,7 +263,6 @@ icon_state = "reagent_storage" extended_desc = "This is effectively an internal beaker." - container_type = OPENCONTAINER volume = 60 complexity = 4 @@ -272,7 +274,9 @@ activators = list("push ref" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - +/obj/item/integrated_circuit/reagent/storage/Initialize() + . = ..() + ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) /obj/item/integrated_circuit/reagent/storage/do_work() set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) @@ -302,7 +306,7 @@ /obj/item/integrated_circuit/reagent/storage/cryo/Initialize() . = ..() - reagents.set_reacting(FALSE) + ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) /obj/item/integrated_circuit/reagent/storage/grinder name = "reagent grinder" @@ -501,7 +505,6 @@ desc = "Stores liquid inside the device away from electrical components. It can store up to 60u. It will heat or cool the reagents \ to the target temperature when turned on." icon_state = "heater" - container_type = OPENCONTAINER complexity = 8 inputs = list( "target temperature" = IC_PINTYPE_NUMBER, @@ -548,9 +551,11 @@ desc = "Unlike most electronics, creating smoke is completely intentional." icon_state = "smoke" extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ - into the smoke clouds when activated. The reagents are consumed when the smoke is made." + into the smoke clouds when activated. The reagents are consumed when the smoke is made. Requires at least 10 units of reagents to generate smoke." ext_cooldown = 1 + volume = 100 + complexity = 20 cooldown_per_use = 1 SECONDS inputs = list() @@ -568,11 +573,16 @@ var/smoke_radius = 5 var/notified = FALSE +/obj/item/integrated_circuit/reagent/smoke/Initialize() + . = ..() + ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + /obj/item/integrated_circuit/reagent/smoke/on_reagent_change(changetype) //reset warning only if we have reagents now if(changetype == ADD_REAGENT) notified = FALSE push_vol() + /obj/item/integrated_circuit/reagent/smoke/do_work(ord) switch(ord) if(1) @@ -598,7 +608,7 @@ name = "integrated extinguisher" desc = "This circuit sprays any of its contents out like an extinguisher." icon_state = "injector" - extended_desc = "This circuit can hold up to 30 units of any given chemicals. On each use, it sprays these reagents like a fire extinguisher." + extended_desc = "This circuit can hold up to 30 units of any given chemicals. On each use, it sprays these reagents like a fire extinguisher. Requires at least 10 units of reagents to work." volume = 30 @@ -623,6 +633,7 @@ /obj/item/integrated_circuit/reagent/extinguisher/Initialize() .=..() + ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) set_pin_data(IC_OUTPUT,2, src) /obj/item/integrated_circuit/reagent/extinguisher/on_reagent_change(changetype) @@ -631,7 +642,7 @@ /obj/item/integrated_circuit/reagent/extinguisher/do_work() //Check if enough volume set_pin_data(IC_OUTPUT, 1, reagents.total_volume) - if(!reagents || reagents.total_volume < 5 || busy) + if(!reagents || reagents.total_volume < IC_SMOKE_REAGENTS_MINIMUM_UNITS || busy) push_data() activate_pin(3) return diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index b9bd4627c4..1959fb55c7 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -125,7 +125,7 @@ name = "man-machine interface tank" desc = "This circuit is just a jar filled with an artificial liquid mimicking the cerebrospinal fluid." extended_desc = "This jar can hold 1 man-machine interface and let it take control of some basic functions of the assembly." - complexity = 29 + complexity = 60 inputs = list("laws" = IC_PINTYPE_LIST) outputs = list( "man-machine interface" = IC_PINTYPE_REF, @@ -254,7 +254,7 @@ name = "pAI connector circuit" desc = "This circuit lets you fit in a personal artificial intelligence to give it some form of control over the bot." extended_desc = "You can wire various functions to it." - complexity = 29 + complexity = 60 inputs = list("laws" = IC_PINTYPE_LIST) outputs = list( "personal artificial intelligence" = IC_PINTYPE_REF, diff --git a/code/modules/integrated_electronics/subtypes/weaponized.dm b/code/modules/integrated_electronics/subtypes/weaponized.dm new file mode 100644 index 0000000000..7bccbfafcd --- /dev/null +++ b/code/modules/integrated_electronics/subtypes/weaponized.dm @@ -0,0 +1,343 @@ +/obj/item/integrated_circuit/weaponized + category_text = "Weaponized" + +/obj/item/integrated_circuit/weaponized/weapon_firing + name = "weapon firing mechanism" + desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it." + extended_desc = "The firing mechanism can slot in any energy weapon. \ + The first and second inputs need to be numbers which correspond to coordinates for the gun to fire at relative to the machine itself. \ + The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Mode will switch between \ + lethal (TRUE) or stun (FALSE) modes. It uses the internal battery of the weapon itself, not the assembly. If you wish to fire the gun while the circuit is in \ + hand, you will need to use an assembly that is a gun." + complexity = 20 + w_class = WEIGHT_CLASS_SMALL + size = 3 + inputs = list( + "target X rel" = IC_PINTYPE_NUMBER, + "target Y rel" = IC_PINTYPE_NUMBER, + "mode" = IC_PINTYPE_BOOLEAN + ) + outputs = list("reference to gun" = IC_PINTYPE_REF) + activators = list( + "fire" = IC_PINTYPE_PULSE_IN + + ) + var/obj/item/gun/energy/installed_gun = null + spawn_flags = IC_SPAWN_RESEARCH + action_flags = IC_ACTION_COMBAT + power_draw_per_use = 0 + ext_cooldown = 1 + var/mode = FALSE + + var/stun_projectile = null //stun mode projectile type + var/stun_projectile_sound + var/lethal_projectile = null //lethal mode projectile type + var/lethal_projectile_sound + + demands_object_input = TRUE // You can put stuff in once the circuit is in assembly,passed down from additem and handled by attackby() + + + +/obj/item/integrated_circuit/weaponized/weapon_firing/Destroy() + qdel(installed_gun) + return ..() + +/obj/item/integrated_circuit/weaponized/weapon_firing/attackby(var/obj/O, var/mob/user) + if(istype(O, /obj/item/gun/energy)) + var/obj/item/gun/gun = O + if(installed_gun) + to_chat(user, "There's already a weapon installed.") + return + user.transferItemToLoc(gun,src) + installed_gun = gun + var/list/gun_properties = gun.get_turret_properties() + to_chat(user, "You slide \the [gun] into the firing mechanism.") + playsound(src, 'sound/items/Crowbar.ogg', 50, 1) + stun_projectile = gun_properties["stun_projectile"] + stun_projectile_sound = gun_properties["stun_projectile_sound"] + lethal_projectile = gun_properties["lethal_projectile"] + lethal_projectile_sound = gun_properties["lethal_projectile_sound"] + if(gun_properties["shot_delay"]) + cooldown_per_use = gun_properties["shot_delay"]*10 + if(cooldown_per_use<30) + cooldown_per_use = 30 + if(gun_properties["reqpower"]) + power_draw_per_use = gun_properties["reqpower"] + set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun)) + push_data() + else + ..() + +/obj/item/integrated_circuit/weaponized/weapon_firing/attack_self(var/mob/user) + if(installed_gun) + installed_gun.forceMove(drop_location()) + to_chat(user, "You slide \the [installed_gun] out of the firing mechanism.") + size = initial(size) + playsound(src, 'sound/items/Crowbar.ogg', 50, 1) + installed_gun = null + set_pin_data(IC_OUTPUT, 1, WEAKREF(null)) + push_data() + else + to_chat(user, "There's no weapon to remove from the mechanism.") + +/obj/item/integrated_circuit/weaponized/weapon_firing/do_work() + if(!installed_gun || !installed_gun.handle_pins()) + return + if(!isturf(assembly.loc) && !(assembly.can_fire_equipped && ishuman(assembly.loc))) + return + set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun)) + push_data() + var/datum/integrated_io/xo = inputs[1] + var/datum/integrated_io/yo = inputs[2] + var/datum/integrated_io/mode1 = inputs[3] + + mode = mode1.data + if(assembly) + if(isnum(xo.data)) + xo.data = round(xo.data, 1) + if(isnum(yo.data)) + yo.data = round(yo.data, 1) + + var/turf/T = get_turf(assembly) + var/target_x = CLAMP(T.x + xo.data, 0, world.maxx) + var/target_y = CLAMP(T.y + yo.data, 0, world.maxy) + + assembly.visible_message("[assembly] fires [installed_gun]!") + shootAt(locate(target_x, target_y, T.z)) + +/obj/item/integrated_circuit/weaponized/weapon_firing/proc/shootAt(turf/target) + var/turf/T = get_turf(src) + var/turf/U = target + if(!istype(T) || !istype(U)) + return + if(!installed_gun.cell) + return + if(!installed_gun.cell.charge) + return + var/obj/item/ammo_casing/energy/shot = installed_gun.ammo_type[mode?2:1] + if(installed_gun.cell.charge < shot.e_cost) + return + if(!shot) + return + update_icon() + var/obj/item/projectile/A + if(!mode) + A = new stun_projectile(T) + playsound(loc, stun_projectile_sound, 75, 1) + else + A = new lethal_projectile(T) + playsound(loc, lethal_projectile_sound, 75, 1) + installed_gun.cell.use(shot.e_cost) + //Shooting Code: + A.preparePixelProjectile(target, src) + A.fire() + log_attack("[assembly] [REF(assembly)] has fired [installed_gun].") + return A + +/obj/item/integrated_circuit/weaponized/grenade + name = "grenade primer" + desc = "This circuit comes with the ability to attach most types of grenades and prime them at will." + extended_desc = "The time between priming and detonation is limited to between 1 to 12 seconds, but is optional. \ + If the input is not set, not a number, or a number less than 1, the grenade's built-in timing will be used. \ + Beware: Once primed, there is no aborting the process!" + icon_state = "grenade" + complexity = 30 + cooldown_per_use = 10 + inputs = list("detonation time" = IC_PINTYPE_NUMBER) + outputs = list() + activators = list("prime grenade" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_RESEARCH + action_flags = IC_ACTION_COMBAT + var/obj/item/grenade/attached_grenade + var/pre_attached_grenade_type + demands_object_input = TRUE // You can put stuff in once the circuit is in assembly,passed down from additem and handled by attackby() + +/obj/item/integrated_circuit/weaponized/grenade/Initialize() + . = ..() + if(pre_attached_grenade_type) + var/grenade = new pre_attached_grenade_type(src) + attach_grenade(grenade) + +/obj/item/integrated_circuit/weaponized/grenade/Destroy() + if(attached_grenade && !attached_grenade.active) + attached_grenade.forceMove(loc) + detach_grenade() + return ..() + +/obj/item/integrated_circuit/weaponized/grenade/attackby(var/obj/item/grenade/G, var/mob/user) + if(istype(G)) + if(attached_grenade) + to_chat(user, "There is already a grenade attached!") + else if(user.transferItemToLoc(G,src)) + user.visible_message("\The [user] attaches \a [G] to \the [src]!", "You attach \the [G] to \the [src].") + attach_grenade(G) + G.forceMove(src) + else + return ..() + +/obj/item/integrated_circuit/weaponized/grenade/attack_self(var/mob/user) + if(attached_grenade) + user.visible_message("\The [user] removes \an [attached_grenade] from \the [src]!", "You remove \the [attached_grenade] from \the [src].") + user.put_in_hands(attached_grenade) + detach_grenade() + else + return ..() + +/obj/item/integrated_circuit/weaponized/grenade/do_work() + if(attached_grenade && !attached_grenade.active) + var/datum/integrated_io/detonation_time = inputs[1] + var/dt + if(isnum(detonation_time.data) && detonation_time.data > 0) + dt = CLAMP(detonation_time.data, 1, 12)*10 + else + dt = 15 + addtimer(CALLBACK(attached_grenade, /obj/item/grenade.proc/prime), dt) + var/atom/holder = loc + message_admins("activated a grenade assembly. Last touches: Assembly: [holder.fingerprintslast] Circuit: [fingerprintslast] Grenade: [attached_grenade.fingerprintslast]") + +// These procs do not relocate the grenade, that's the callers responsibility +/obj/item/integrated_circuit/weaponized/grenade/proc/attach_grenade(var/obj/item/grenade/G) + attached_grenade = G + G.forceMove(src) + desc += " \An [attached_grenade] is attached to it!" + +/obj/item/integrated_circuit/weaponized/grenade/proc/detach_grenade() + if(!attached_grenade) + return + attached_grenade.forceMove(drop_location()) + attached_grenade = null + desc = initial(desc) + +/obj/item/integrated_circuit/weaponized/air_cannon + name = "pneumatic cannon" + desc = "A compact pneumatic cannon to throw things from inside or nearby tiles at a high enough velocity to cause damage. Requires air from a canister to fire." + extended_desc = "The first and second inputs need to be numbers which correspond to the coordinates to throw objects at relative to the machine itself. \ + The 'fire' activator will cause the mechanism to attempt to launch objects at the coordinates, if possible. Note that the \ + projectile needs to be inside the machine, or on an adjacent tile, and must be medium sized or smaller. The assembly \ + must also be a gun if you wish to launch something while the assembly is in hand." + complexity = 50 + w_class = WEIGHT_CLASS_SMALL + size = 4 + cooldown_per_use = 30 + ext_cooldown = 15 + inputs = list( + "target X rel" = IC_PINTYPE_NUMBER, + "target Y rel" = IC_PINTYPE_NUMBER, + "projectile" = IC_PINTYPE_REF, + "canister" = IC_PINTYPE_REF + ) + outputs = list() + activators = list( + "fire" = IC_PINTYPE_PULSE_IN + ) + spawn_flags = IC_SPAWN_RESEARCH + action_flags = IC_ACTION_COMBAT + power_draw_per_use = 50 + var/gas_per_throw = 6 + +/obj/item/integrated_circuit/weaponized/air_cannon/do_work() + + var/max_w_class = assembly.w_class + var/target_x_rel = round(get_pin_data(IC_INPUT, 1)) + var/target_y_rel = round(get_pin_data(IC_INPUT, 2)) + var/obj/item/A = get_pin_data_as_type(IC_INPUT, 3, /obj/item) + var/obj/item/integrated_circuit/atmospherics/AT = get_pin_data_as_type(IC_INPUT, 4, /obj/item/integrated_circuit/atmospherics) + + if(!A || A.anchored || A.throwing || A == assembly || istype(A, /obj/item/twohanded) || istype(A, /obj/item/transfer_valve)) + return + + if(!AT || !AT.air_contents) + return + + if (istype(assembly.loc, /obj/item/implant/storage)) //Prevents the more abusive form of chestgun. + return + + if(max_w_class && (A.w_class > max_w_class)) + return + + if(!assembly.can_fire_equipped && ishuman(assembly.loc)) + return + + // Is the target inside the assembly or close to it? + if(!check_target(A, exclude_components = TRUE)) + return + + var/turf/T = get_turf(get_object()) + if(!T) + return + + // If the item is in mob's inventory, try to remove it from there. + if(ismob(A.loc)) + var/mob/living/M = A.loc + if(!M.temporarilyRemoveItemFromInventory(A)) + return + + var/datum/gas_mixture/source_air = AT.return_air() + var/datum/gas_mixture/target_air = T.return_air() + + if(!source_air || !target_air) + return + + var/datum/gas_mixture/removed = source_air.remove(gas_per_throw) + if(!removed) + return + target_air.merge(removed) + + // If the item is in a grabber circuit we'll update the grabber's outputs after we've thrown it. + var/obj/item/integrated_circuit/manipulation/grabber/G = A.loc + + var/x_abs = CLAMP(T.x + target_x_rel, 0, world.maxx) + var/y_abs = CLAMP(T.y + target_y_rel, 0, world.maxy) + var/range = round(CLAMP(sqrt(target_x_rel*target_x_rel+target_y_rel*target_y_rel),0,8),1) + assembly.visible_message("\The [assembly] has thrown [A]!") + log_attack("[assembly] [REF(assembly)] has thrown [A] with lethal force.") + A.forceMove(drop_location()) + A.throw_at(locate(x_abs, y_abs, T.z), range, 3) + + air_update_turf() + + // If the item came from a grabber now we can update the outputs since we've thrown it. + if(istype(G)) + G.update_outputs() + + +/obj/item/integrated_circuit/weaponized/stun + name = "electronic stun module" + desc = "Used to stun a target holding the device via electricity." + icon_state = "power_relay" + extended_desc = "Attempts to stun the holder of this device, with the strength input being the strength of the stun, from 1 to 70." + complexity = 30 + size = 4 + inputs = list("strength" = IC_PINTYPE_NUMBER) + activators = list("stun" = IC_PINTYPE_PULSE_IN, "on success" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 2000 + cooldown_per_use = 50 + ext_cooldown = 25 + + +/obj/item/integrated_circuit/weaponized/stun/do_work() + var/stunforce = CLAMP(get_pin_data(IC_INPUT, 1),1,70) + var/mob/living/L = assembly.loc + if(attempt_stun(L,stunforce)) + activate_pin(2) + else + activate_pin(3) + +/obj/item/integrated_circuit/weaponized/proc/attempt_stun(var/mob/living/L,var/stunforce = 70) //Copied from stunbaton code. + + if(!L || !isliving(L)) + return 0 + + L.Knockdown(stunforce) + SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK) + + message_admins("stunned someone with an assembly. Last touches: Assembly: [assembly.fingerprintslast] Circuit: [fingerprintslast]") + + L.visible_message("\The [assembly] has stunned \the [L] with \the [src]!", "\The [assembly] has stunned you with \the [src]!") + playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + H.forcesay(GLOB.hit_appends) + + return 1 diff --git a/code/modules/jobs/job_types/cargo_service.dm b/code/modules/jobs/job_types/cargo_service.dm index 053373c05a..22ef2a9211 100644 --- a/code/modules/jobs/job_types/cargo_service.dm +++ b/code/modules/jobs/job_types/cargo_service.dm @@ -110,7 +110,7 @@ Shaft Miner /datum/outfit/job/miner/equipped name = "Shaft Miner (Lavaland + Equipment)" - suit = /obj/item/clothing/suit/hooded/explorer + suit = /obj/item/clothing/suit/hooded/explorer/standard mask = /obj/item/clothing/mask/gas/explorer glasses = /obj/item/clothing/glasses/meson suit_store = /obj/item/tank/internals/oxygen diff --git a/code/modules/jobs/job_types/silicon.dm b/code/modules/jobs/job_types/silicon.dm index 662f666cf1..ab963eb8f3 100644 --- a/code/modules/jobs/job_types/silicon.dm +++ b/code/modules/jobs/job_types/silicon.dm @@ -35,6 +35,7 @@ AI qdel(lateJoinCore) var/mob/living/silicon/ai/AI = H AI.apply_pref_name("ai", M.client) //If this runtimes oh well jobcode is fucked. + AI.set_core_display_icon(null, M.client) //we may have been created after our borg if(SSticker.current_state == GAME_STATE_SETTING_UP) diff --git a/code/modules/language/slime.dm b/code/modules/language/slime.dm index 7171c07b39..cca56ca933 100644 --- a/code/modules/language/slime.dm +++ b/code/modules/language/slime.dm @@ -5,6 +5,7 @@ ask_verb = "warbles" exclaim_verb = "warbles" key = "k" + flags = TONGUELESS_SPEECH syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") default_priority = 70 diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index dec574566f..2c35c3148f 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -15,6 +15,7 @@ resistance_flags = FIRE_PROOF tauric = TRUE //Citadel Add for tauric hardsuits + /obj/item/clothing/head/hooded/explorer name = "explorer hood" desc = "An armoured hood for exploring harsh environments." @@ -26,11 +27,15 @@ armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) resistance_flags = FIRE_PROOF -/obj/item/clothing/suit/hooded/explorer/Initialize() +/obj/item/clothing/suit/hooded/explorer/standard + +/obj/item/clothing/head/hooded/explorer/standard + +/obj/item/clothing/suit/hooded/explorer/standard/Initialize() . = ..() AddComponent(/datum/component/armor_plate) -/obj/item/clothing/head/hooded/explorer/Initialize() +/obj/item/clothing/head/hooded/explorer/standard/Initialize() . = ..() AddComponent(/datum/component/armor_plate) @@ -176,4 +181,4 @@ desc = "A face-covering mask that can be connected to an air supply. Intended for use with the Exosuit." icon_state = "exo" item_state = "exo" - resistance_flags = FIRE_PROOF \ No newline at end of file + resistance_flags = FIRE_PROOF diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index b8195e23d9..b4afaac17f 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -230,7 +230,7 @@ desc = "A wing ripped from a watcher. Suitable as a trophy for a kinetic crusher." icon_state = "watcher_wing" denied_type = /obj/item/crusher_trophy/watcher_wing - bonus_value = 5 + bonus_value = 10 /obj/item/crusher_trophy/watcher_wing/effect_desc() return "mark detonation to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s" diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm index ca313182b6..0d6c337444 100644 --- a/code/modules/mining/equipment/mining_tools.dm +++ b/code/modules/mining/equipment/mining_tools.dm @@ -31,7 +31,7 @@ force = 10 throwforce = 7 slot_flags = ITEM_SLOT_BELT - w_class = WEIGHT_CLASS_NORMAL + w_class = WEIGHT_CLASS_SMALL materials = list(MAT_METAL=1000) /obj/item/pickaxe/silver @@ -41,6 +41,7 @@ toolspeed = 0.5 //mines faster than a normal pickaxe, bought from mining vendor desc = "A silver-plated pickaxe that mines slightly faster than standard-issue." force = 17 + materials = list(MAT_SILVER=4000) /obj/item/pickaxe/diamond name = "diamond-tipped pickaxe" @@ -49,6 +50,7 @@ toolspeed = 0.3 desc = "A pickaxe with a diamond pick head. Extremely robust at cracking rock walls and digging up dirt." force = 19 + materials = list(MAT_DIAMOND=4000) /obj/item/pickaxe/drill name = "mining drill" @@ -75,12 +77,13 @@ /obj/item/pickaxe/drill/cyborg/diamond //This is the BORG version! name = "diamond-tipped cyborg mining drill" //To inherit the NODROP_1 flag, and easier to change borg specific drill mechanics. icon_state = "diamonddrill" - toolspeed = 0.2 + toolspeed = 0.1 /obj/item/pickaxe/drill/jackhammer name = "sonic jackhammer" icon_state = "jackhammer" item_state = "jackhammer" + w_class = WEIGHT_CLASS_HUGE toolspeed = 0.1 //the epitome of powertools. extremely fast mining, laughs at puny walls usesound = 'sound/weapons/sonic_jackhammer.ogg' hitsound = 'sound/weapons/sonic_jackhammer.ogg' @@ -97,12 +100,12 @@ slot_flags = ITEM_SLOT_BELT force = 8 tool_behaviour = TOOL_SHOVEL - toolspeed = 1 + toolspeed = 0.1 //Can only dig ash and thats about it, out classed by the picks and drills no more! usesound = 'sound/effects/shovel_dig.ogg' throwforce = 4 item_state = "shovel" w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL=50) + materials = list(MAT_METAL=350) attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") sharpness = IS_SHARP @@ -124,6 +127,8 @@ item_state = "spade" lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi' + toolspeed = 0.5 force = 5 throwforce = 7 + materials = list(MAT_METAL=50) w_class = WEIGHT_CLASS_SMALL diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm index e23c3deb58..f63b459f10 100644 --- a/code/modules/mining/equipment/resonator.dm +++ b/code/modules/mining/equipment/resonator.dm @@ -8,10 +8,10 @@ righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi' desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It does increased damage in low pressure." w_class = WEIGHT_CLASS_NORMAL - force = 15 + force = 18 throwforce = 10 var/burst_time = 30 - var/fieldlimit = 4 + var/fieldlimit = 6 var/list/fields = list() var/quick_burst_mod = 0.8 @@ -20,7 +20,8 @@ desc = "An upgraded version of the resonator that can produce more fields at once, as well as having no damage penalty for bursting a resonance field early." icon_state = "resonator_u" item_state = "resonator_u" - fieldlimit = 6 + force = 20 + fieldlimit = 8 quick_burst_mod = 1 /obj/item/resonator/attack_self(mob/user) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 23823e1e18..0990ca961a 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -222,9 +222,9 @@ to_chat(user, "You feel your life being drained by the pendant...") if(do_after(user, 40, target = user)) to_chat(user, "Your lifeforce is now linked to the pendant! You feel like removing it would kill you, and yet you instinctively know that until then, you won't die.") - user.add_trait(TRAIT_NODEATH, "memento_mori") - user.add_trait(TRAIT_NOHARDCRIT, "memento_mori") - user.add_trait(TRAIT_NOCRITDAMAGE, "memento_mori") + ADD_TRAIT(user, TRAIT_NODEATH, "memento_mori") + ADD_TRAIT(user, TRAIT_NOHARDCRIT, "memento_mori") + ADD_TRAIT(user, TRAIT_NOCRITDAMAGE, "memento_mori") icon_state = "memento_mori_active" active_owner = user @@ -662,7 +662,7 @@ playsound(user, 'sound/magic/clockwork/fellowship_armory.ogg', 35, TRUE, frequency = 90000 - (active * 30000)) /obj/item/melee/transforming/cleaving_saw/clumsy_transform_effect(mob/living/user) - if(user.has_trait(TRAIT_CLUMSY) && prob(50)) + if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) to_chat(user, "You accidentally cut yourself with [src], like a doofus!") user.take_bodypart_damage(10) diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 79270ebf63..aed90cebdf 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -22,11 +22,11 @@ new /datum/data/mining_equipment("Alien Toy", /obj/item/clothing/mask/facehugger/toy, 300), new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 400), new /datum/data/mining_equipment("Shelter Capsule", /obj/item/survivalcapsule, 400), + new /datum/data/mining_equipment("Survival Knife", /obj/item/kitchen/knife/combat/survival, 450), new /datum/data/mining_equipment("GAR Meson Scanners", /obj/item/clothing/glasses/meson/gar, 500), new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500), new /datum/data/mining_equipment("Larger Ore Bag", /obj/item/storage/bag/ore/large, 500), new /datum/data/mining_equipment("500 Point Transfer Card", /obj/item/card/mining_point_card/mp500, 500), - new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/storage/firstaid/brute, 600), new /datum/data/mining_equipment("Tracking Implant Kit", /obj/item/storage/box/minertracker, 600), new /datum/data/mining_equipment("Survival Medipen", /obj/item/reagent_containers/hypospray/medipen/survival, 750), new /datum/data/mining_equipment("Stabilizing Serum", /obj/item/hivelordstabilizer, 750), @@ -50,9 +50,11 @@ new /datum/data/mining_equipment("Space Cash", /obj/item/stack/spacecash/c1000, 2000), new /datum/data/mining_equipment("Mining Hardsuit", /obj/item/clothing/suit/space/hardsuit/mining, 2000), new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/pickaxe/diamond, 2000), + new /datum/data/mining_equipment("Spare Suit Voucher", /obj/item/suit_voucher, 2000), new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3000), + new /datum/data/mining_equipment("Miner Full Replacement", /obj/item/storage/backpack/duffelbag/mining_cloned, 3000), new /datum/data/mining_equipment("Nanotrasen Minebot", /mob/living/simple_animal/hostile/mining_drone, 800), new /datum/data/mining_equipment("Minebot Melee Upgrade", /obj/item/mine_bot_upgrade, 400), new /datum/data/mining_equipment("Minebot Armor Upgrade", /obj/item/mine_bot_upgrade/health, 400), @@ -67,9 +69,7 @@ new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), new /datum/data/mining_equipment("KA Cooldown Decrease", /obj/item/borg/upgrade/modkit/cooldown, 1000), new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), - new /datum/data/mining_equipment("Premium Accelerator", /obj/item/gun/energy/kinetic_accelerator/premiumka, 8000), - new /datum/data/mining_equipment("Miner Full Replacement", /obj/item/storage/backpack/duffelbag/mining_cloned, 12000), - new /datum/data/mining_equipment("Spare Suit Voucher", /obj/item/suit_voucher, 15000) + new /datum/data/mining_equipment("Premium Accelerator", /obj/item/gun/energy/kinetic_accelerator/premiumka, 8000) ) @@ -319,7 +319,7 @@ new /obj/item/clothing/glasses/meson(src) new /obj/item/t_scanner/adv_mining_scanner/lesser(src) new /obj/item/storage/bag/ore(src) - new /obj/item/clothing/suit/hooded/explorer(src) + new /obj/item/clothing/suit/hooded/explorer/standard(src) new /obj/item/encryptionkey/headset_cargo(src) new /obj/item/clothing/mask/gas/explorer(src) new /obj/item/card/mining_access_card(src) @@ -340,7 +340,7 @@ new /obj/item/storage/firstaid/regular(src) new /obj/item/reagent_containers/hypospray/medipen/survival(src) new /obj/item/t_scanner/adv_mining_scanner(src) - new /obj/item/clothing/suit/hooded/explorer(src) + new /obj/item/clothing/suit/hooded/explorer/standard(src) new /obj/item/encryptionkey/headset_cargo(src) new /obj/item/clothing/mask/gas/explorer(src) new /obj/item/card/id/mining(src) diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index fc879ed7a8..353df3aa66 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -28,7 +28,7 @@ if(job_engsec_high) switch(job_engsec_high) if(AI_JF) - parent.show_character_previews(image('icons/mob/ai.dmi', icon_state = "AI", dir = SOUTH)) + parent.show_character_previews(image('icons/mob/ai.dmi', resolve_ai_icon(preferred_ai_core_display), dir = SOUTH)) return if(CYBORG) parent.show_character_previews(image('icons/mob/robots.dmi', icon_state = "robot", dir = SOUTH)) diff --git a/code/modules/mob/dead/new_player/sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories.dm deleted file mode 100644 index 44c1f7601d..0000000000 --- a/code/modules/mob/dead/new_player/sprite_accessories.dm +++ /dev/null @@ -1,1524 +0,0 @@ -/* - - Hello and welcome to sprite_accessories: For sprite accessories, such as hair, - facial hair, and possibly tattoos and stuff somewhere along the line. This file is - intended to be friendly for people with little to no actual coding experience. - The process of adding in new hairstyles has been made pain-free and easy to do. - Enjoy! - Doohl - - - Notice: This all gets automatically compiled in a list in dna.dm, so you do not - have to define any UI values for sprite accessories manually for hair and facial - hair. Just add in new hair types and the game will naturally adapt. - - !!WARNING!!: changing existing hair information can be VERY hazardous to savefiles, - to the point where you may completely corrupt a server's savefiles. Please refrain - from doing this unless you absolutely know what you are doing, and have defined a - conversion in savefile.dm -*/ -/proc/init_sprite_accessory_subtypes(prototype, list/L, list/male, list/female,var/roundstart = FALSE)//Roundstart argument builds a specific list for roundstart parts where some parts may be locked - if(!istype(L)) - L = list() - if(!istype(male)) - male = list() - if(!istype(female)) - female = list() - - for(var/path in typesof(prototype)) - if(path == prototype) - continue - if(roundstart) - var/datum/sprite_accessory/P = path - if(initial(P.locked)) - continue - var/datum/sprite_accessory/D = new path() - - if(D.icon_state) - L[D.name] = D - else - L += D.name - - switch(D.gender) - if(MALE) - male += D.name - if(FEMALE) - female += D.name - else - male += D.name - female += D.name - return L - -/datum/sprite_accessory - var/icon //the icon file the accessory is located in - var/icon_state //the icon_state of the accessory - var/name //the preview name of the accessory - var/gender = NEUTER //Determines if the accessory will be skipped or included in random hair generations - var/gender_specific //Something that can be worn by either gender, but looks different on each - var/color_src = MUTCOLORS //Currently only used by mutantparts so don't worry about hair and stuff. This is the source that this accessory will get its color from. Default is MUTCOLOR, but can also be HAIR, FACEHAIR, EYECOLOR and 0 if none. - var/hasinner //Decides if this sprite has an "inner" part, such as the fleshy parts on ears. - var/locked = FALSE //Is this part locked from roundstart selection? Used for parts that apply effects - var/dimension_x = 32 - var/dimension_y = 32 - var/center = FALSE //Should we center the sprite? - -////////////////////// -// Hair Definitions // -////////////////////// -/datum/sprite_accessory/hair - icon = 'icons/mob/human_face.dmi' // default icon for all hairs - - // please make sure they're sorted alphabetically and, where needed, categorized - // try to capitalize the names please~ - // try to spell - // you do not need to define _s or _l sub-states, game automatically does this for you - -/datum/sprite_accessory/hair/afro - name = "Afro" - icon_state = "hair_afro" - -/datum/sprite_accessory/hair/afro2 - name = "Afro 2" - icon_state = "hair_afro2" - -/datum/sprite_accessory/hair/afro_large - name = "Afro (Large)" - icon_state = "hair_bigafro" - -/datum/sprite_accessory/hair/antenna - name = "Ahoge" - icon_state = "hair_antenna" - -/datum/sprite_accessory/hair/bald - name = "Bald" - icon_state = null - -/datum/sprite_accessory/hair/balding - name = "Balding Hair" - icon_state = "hair_e" - -/datum/sprite_accessory/hair/bedhead - name = "Bedhead" - icon_state = "hair_bedhead" - -/datum/sprite_accessory/hair/bedhead2 - name = "Bedhead 2" - icon_state = "hair_bedheadv2" - -/datum/sprite_accessory/hair/bedhead3 - name = "Bedhead 3" - icon_state = "hair_bedheadv3" - -/datum/sprite_accessory/hair/beehive - name = "Beehive" - icon_state = "hair_beehive" - -/datum/sprite_accessory/hair/beehive2 - name = "Beehive 2" - icon_state = "hair_beehivev2" - -/datum/sprite_accessory/hair/bob - name = "Bob Hair" - icon_state = "hair_bob" - -/datum/sprite_accessory/hair/bob2 - name = "Bob Hair 2" - icon_state = "hair_bob2" - -/datum/sprite_accessory/hair/bob3 - name = "Bob Hair 3" - icon_state = "hair_bobcut" - -/datum/sprite_accessory/hair/bobcurl - name = "Bobcurl" - icon_state = "hair_bobcurl" - -/datum/sprite_accessory/hair/boddicker - name = "Boddicker" - icon_state = "hair_boddicker" - -/datum/sprite_accessory/hair/bowl - name = "Bowl" - icon_state = "hair_bowlcut" - -/datum/sprite_accessory/hair/braid - name = "Braid (Floorlength)" - icon_state = "hair_braid" - -/datum/sprite_accessory/hair/braided - name = "Braided" - icon_state = "hair_braided" - -/datum/sprite_accessory/hair/front_braid - name = "Braided Front" - icon_state = "hair_braidfront" - -/datum/sprite_accessory/hair/not_floorlength_braid - name = "Braid (High)" - icon_state = "hair_braid2" - -/datum/sprite_accessory/hair/lowbraid - name = "Braid (Low)" - icon_state = "hair_hbraid" - -/datum/sprite_accessory/hair/shortbraid - name = "Braid (Short)" - icon_state = "hair_shortbraid" - -/datum/sprite_accessory/hair/braidtail - name = "Braided Tail" - icon_state = "hair_braidtail" - -/datum/sprite_accessory/hair/bun - name = "Bun Head" - icon_state = "hair_bun" - -/datum/sprite_accessory/hair/bun2 - name = "Bun Head 2" - icon_state = "hair_bunhead2" - -/datum/sprite_accessory/hair/largebun - name = "Bun (Large)" - icon_state = "hair_largebun" - -/datum/sprite_accessory/hair/business - name = "Business Hair" - icon_state = "hair_business" - -/datum/sprite_accessory/hair/business2 - name = "Business Hair 2" - icon_state = "hair_business2" - -/datum/sprite_accessory/hair/business3 - name = "Business Hair 3" - icon_state = "hair_business3" - -/datum/sprite_accessory/hair/business4 - name = "Business Hair 4" - icon_state = "hair_business4" - -/datum/sprite_accessory/hair/buzz - name = "Buzzcut" - icon_state = "hair_buzzcut" - -/datum/sprite_accessory/hair/combover - name = "Combover" - icon_state = "hair_combover" - -/datum/sprite_accessory/hair/crew - name = "Crewcut" - icon_state = "hair_crewcut" - -/datum/sprite_accessory/hair/curls - name = "Curls" - icon_state = "hair_curls" - -/datum/sprite_accessory/hair/cut - name = "Cut Hair" - icon_state = "hair_c" - -/datum/sprite_accessory/hair/devillock - name = "Devil Lock" - icon_state = "hair_devilock" - -/datum/sprite_accessory/hair/dreadlocks - name = "Dreadlocks" - icon_state = "hair_dreads" - -/datum/sprite_accessory/hair/drillhair - name = "Drill Hair" - icon_state = "hair_drillhair" - -/datum/sprite_accessory/hair/drillhairextended - name = "Drill Hair (Extended)" - icon_state = "hair_drillhairextended" - -/datum/sprite_accessory/hair/emo - name = "Emo" - icon_state = "hair_emo" - -/datum/sprite_accessory/hair/feather - name = "Feather" - icon_state = "hair_feather" - -/datum/sprite_accessory/hair/sargeant - name = "Flat Top" - icon_state = "hair_sargeant" - -/datum/sprite_accessory/hair/bigflattop - name = "Flat Top (Big)" - icon_state = "hair_bigflattop" - -/datum/sprite_accessory/hair/fag - name = "Flow Hair" - icon_state = "hair_f" - -/datum/sprite_accessory/hair/gelled - name = "Gelled Back" - icon_state = "hair_gelled" - -/datum/sprite_accessory/hair/gentle - name = "Gentle" - icon_state = "hair_gentle" - -/datum/sprite_accessory/hair/halfbang - name = "Half-banged Hair" - icon_state = "hair_halfbang" - -/datum/sprite_accessory/hair/halfbang2 - name = "Half-banged Hair 2" - icon_state = "hair_halfbang2" - -/datum/sprite_accessory/hair/hedgehog - name = "Hedgehog Hair" - icon_state = "hair_hedgehog" - -/datum/sprite_accessory/hair/himecut - name = "Hime Cut" - icon_state = "hair_himecut" - -/datum/sprite_accessory/hair/himecut2 - name = "Hime Cut 2" - icon_state = "hair_himecut2" - -/datum/sprite_accessory/hair/himeup - name = "Hime Updo" - icon_state = "hair_himeup" - -/datum/sprite_accessory/hair/hitop - name = "Hitop" - icon_state = "hair_hitop" - -/datum/sprite_accessory/hair/jensen - name = "Jensen Hair" - icon_state = "hair_jensen" - -/datum/sprite_accessory/hair/keanu - name = "Keanu Hair" - icon_state = "hair_keanu" - -/datum/sprite_accessory/hair/kusangi - name = "Kusanagi Hair" - icon_state = "hair_kusanagi" - -/datum/sprite_accessory/hair/long - name = "Long Hair 1" - icon_state = "hair_long" - -/datum/sprite_accessory/hair/long2 - name = "Long Hair 2" - icon_state = "hair_long2" - -/datum/sprite_accessory/hair/long3 - name = "Long Hair 3" - icon_state = "hair_long3" - -/datum/sprite_accessory/hair/long_over_eye - name = "Long Over Eye" - icon_state = "hair_longovereye" - -/datum/sprite_accessory/hair/longbangs - name = "Long Bangs" - icon_state = "hair_lbangs" - -/datum/sprite_accessory/hair/longemo - name = "Long Emo" - icon_state = "hair_longemo" - -/datum/sprite_accessory/hair/longfringe - name = "Long Fringe" - icon_state = "hair_longfringe" - -/datum/sprite_accessory/hair/sidepartlongalt - name = "Long Side Part" - icon_state = "hair_longsidepart" - -/datum/sprite_accessory/hair/megaeyebrows - name = "Mega Eyebrows" - icon_state = "hair_megaeyebrows" - -/datum/sprite_accessory/hair/messy - name = "Messy" - icon_state = "hair_messy" - -/datum/sprite_accessory/hair/mohawk - name = "Mohawk" - icon_state = "hair_d" - -/datum/sprite_accessory/hair/reversemohawk - name = "Mohawk (Reverse)" - icon_state = "hair_reversemohawk" - -/datum/sprite_accessory/hair/odango - name = "Odango" - icon_state = "hair_odango" - -/datum/sprite_accessory/hair/ombre - name = "Ombre" - icon_state = "hair_ombre" - -/datum/sprite_accessory/hair/oneshoulder - name = "One Shoulder" - icon_state = "hair_oneshoulder" - -/datum/sprite_accessory/hair/over_eye - name = "Over Eye" - icon_state = "hair_shortovereye" - -//Donator item - fractious -/datum/sprite_accessory/hair/over_eye_fr - name = "Over Eye (fract)" - icon_state = "hair_shortovereye_1f" - ckeys_allowed = list("fractious") - -/datum/sprite_accessory/hair/parted - name = "Parted" - icon_state = "hair_parted" - -/datum/sprite_accessory/hair/partedside - name = "Parted (Side)" - icon_state = "hair_part" - -/datum/sprite_accessory/hair/kagami - name = "Pigtails" - icon_state = "hair_kagami" - -/datum/sprite_accessory/hair/pigtail - name = "Pigtails 2" - icon_state = "hair_pigtails" - -/datum/sprite_accessory/hair/pigtail2 - name = "Pigtails 3" - icon_state = "hair_pigtails2" - -/datum/sprite_accessory/hair/pixie - name = "Pixie Cut" - icon_state = "hair_pixie" - -/datum/sprite_accessory/hair/pompadour - name = "Pompadour" - icon_state = "hair_pompadour" - -/datum/sprite_accessory/hair/bigpompadour - name = "Pompadour (Big)" - icon_state = "hair_bigpompadour" - -/datum/sprite_accessory/hair/ponytail1 - name = "Ponytail" - icon_state = "hair_ponytail" - -/datum/sprite_accessory/hair/ponytail2 - name = "Ponytail 2" - icon_state = "hair_ponytail2" - -/datum/sprite_accessory/hair/ponytail3 - name = "Ponytail 3" - icon_state = "hair_ponytail3" - -/datum/sprite_accessory/hair/ponytail4 - name = "Ponytail 4" - icon_state = "hair_ponytail4" - -/datum/sprite_accessory/hair/ponytail5 - name = "Ponytail 5" - icon_state = "hair_ponytail5" - -/datum/sprite_accessory/hair/highponytail - name = "Ponytail (High)" - icon_state = "hair_highponytail" - -/datum/sprite_accessory/hair/longponytail - name = "Ponytail (Long)" - icon_state = "hair_longstraightponytail" - -/datum/sprite_accessory/hair/sidetail - name = "Ponytail (Side)" - icon_state = "hair_sidetail" - -/datum/sprite_accessory/hair/sidetail2 - name = "Ponytail (Side) 2" - icon_state = "hair_sidetail2" - -/datum/sprite_accessory/hair/sidetail3 - name = "Ponytail (Side) 3" - icon_state = "hair_sidetail3" - -/datum/sprite_accessory/hair/sidetail4 - name = "Ponytail (Side) 4" - icon_state = "hair_sidetail4" - -/datum/sprite_accessory/hair/quiff - name = "Quiff" - icon_state = "hair_quiff" - -/datum/sprite_accessory/hair/short - name = "Short Hair" - icon_state = "hair_a" - -/datum/sprite_accessory/hair/shorthair2 - name = "Short Hair 2" - icon_state = "hair_shorthair2" - -/datum/sprite_accessory/hair/shorthair3 - name = "Short Hair 3" - icon_state = "hair_shorthair3" - -/datum/sprite_accessory/hair/shoulderlength - name = "Shoulder-length Hair" - icon_state = "hair_b" - -/datum/sprite_accessory/hair/sidecut - name = "Sidecut" - icon_state = "hair_sidecut" - -/datum/sprite_accessory/hair/skinhead - name = "Skinhead" - icon_state = "hair_skinhead" - -/datum/sprite_accessory/hair/protagonist - name = "Slightly Long Hair" - icon_state = "hair_protagonist" - -/datum/sprite_accessory/hair/spiky - name = "Spiky" - icon_state = "hair_spikey" - -/datum/sprite_accessory/hair/spiky2 - name = "Spiky 2" - icon_state = "hair_spiky" - -/datum/sprite_accessory/hair/spiky3 - name = "Spiky 3" - icon_state = "hair_spiky2" - -/datum/sprite_accessory/hair/swept - name = "Swept Back Hair" - icon_state = "hair_swept" - -/datum/sprite_accessory/hair/swept2 - name = "Swept Back Hair 2" - icon_state = "hair_swept2" - -/datum/sprite_accessory/hair/tressshoulder - name = "Tress Shoulder" - icon_state = "hair_tressshoulder" - -/datum/sprite_accessory/hair/updo - name = "Updo" - icon_state = "hair_updo" - -/datum/sprite_accessory/hair/longer - name = "Very Long Hair" - icon_state = "hair_vlong" - -/datum/sprite_accessory/hair/longest - name = "Very Long Hair 2" - icon_state = "hair_longest" - -/datum/sprite_accessory/hair/longest2 - name = "Very Long Over Eye" - icon_state = "hair_longest2" - -/datum/sprite_accessory/hair/longestalt - name = "Very Long with Fringe" - icon_state = "hair_vlongfringe" - -///////////////////////////// -// Facial Hair Definitions // -///////////////////////////// - -/datum/sprite_accessory/facial_hair - icon = 'icons/mob/human_face.dmi' - gender = MALE // barf (unless you're a dorf, dorfs dig chix w/ beards :P) - -// please make sure they're sorted alphabetically and categorized - -/datum/sprite_accessory/facial_hair/abe - name = "Beard (Abraham Lincoln)" - icon_state = "facial_abe" - -/datum/sprite_accessory/facial_hair/brokenman - name = "Beard (Broken Man)" - icon_state = "facial_brokenman" - -/datum/sprite_accessory/facial_hair/chinstrap - name = "Beard (Chinstrap)" - icon_state = "facial_chin" - -/datum/sprite_accessory/facial_hair/dwarf - name = "Beard (Dwarf)" - icon_state = "facial_dwarf" - -/datum/sprite_accessory/facial_hair/fiveoclock - name = "Beard (Five o Clock Shadow)" - icon_state = "facial_fiveoclock" - -/datum/sprite_accessory/facial_hair/fullbeard - name = "Beard (Full)" - icon_state = "facial_fullbeard" - -/datum/sprite_accessory/facial_hair/gt - name = "Beard (Goatee)" - icon_state = "facial_gt" - -/datum/sprite_accessory/facial_hair/hip - name = "Beard (Hipster)" - icon_state = "facial_hip" - -/datum/sprite_accessory/facial_hair/jensen - name = "Beard (Jensen)" - icon_state = "facial_jensen" - -/datum/sprite_accessory/facial_hair/neckbeard - name = "Beard (Neckbeard)" - icon_state = "facial_neckbeard" - -/datum/sprite_accessory/facial_hair/vlongbeard - name = "Beard (Very Long)" - icon_state = "facial_wise" - -/datum/sprite_accessory/facial_hair/longbeard - name = "Beard (Long)" - icon_state = "facial_longbeard" - -/datum/sprite_accessory/facial_hair/fu - name = "Moustache (Fu Manchu)" - icon_state = "facial_fumanchu" - -/datum/sprite_accessory/facial_hair/hogan - name = "Moustache (Hulk Hogan)" - icon_state = "facial_hogan" //-Neek - -/datum/sprite_accessory/facial_hair/selleck - name = "Moustache (Selleck)" - icon_state = "facial_selleck" - -/datum/sprite_accessory/facial_hair/chaplin - name = "Moustache (Square)" - icon_state = "facial_chaplin" - -/datum/sprite_accessory/facial_hair/vandyke - name = "Moustache (Van Dyke)" - icon_state = "facial_vandyke" - -/datum/sprite_accessory/facial_hair/watson - name = "Moustache (Watson)" - icon_state = "facial_watson" - -/datum/sprite_accessory/facial_hair/shaved - name = "Shaved" - icon_state = null - gender = NEUTER - -/datum/sprite_accessory/facial_hair/elvis - name = "Sideburns (Elvis)" - icon_state = "facial_elvis" - - -/////////////////////////// -// Underwear Definitions // -/////////////////////////// -/datum/sprite_accessory/underwear - icon = 'icons/mob/underwear.dmi' - -/datum/sprite_accessory/underwear/nude - name = "Nude" - icon_state = null - gender = NEUTER - -/datum/sprite_accessory/underwear/male_mankini - name = "Mankini" - icon_state = "male_mankini" - gender = MALE - -/datum/sprite_accessory/underwear/male_black - name = "Men's Black" - icon_state = "male_black" - gender = MALE - -/datum/sprite_accessory/underwear/male_blackalt - name = "Men's Black Boxer" - icon_state = "male_blackalt" - gender = MALE - -/datum/sprite_accessory/underwear/male_blue - name = "Men's Blue" - icon_state = "male_blue" - gender = MALE - -/datum/sprite_accessory/underwear/male_green - name = "Men's Green" - icon_state = "male_green" - gender = MALE - -/datum/sprite_accessory/underwear/male_grey - name = "Men's Grey" - icon_state = "male_grey" - gender = MALE - -/datum/sprite_accessory/underwear/male_greyalt - name = "Men's Grey Boxer" - icon_state = "male_greyalt" - gender = MALE - -/datum/sprite_accessory/underwear/male_hearts - name = "Men's Hearts Boxer" - icon_state = "male_hearts" - gender = MALE - -/datum/sprite_accessory/underwear/male_kinky - name = "Men's Kinky" - icon_state = "male_kinky" - gender = MALE - -/datum/sprite_accessory/underwear/male_red - name = "Men's Red" - icon_state = "male_red" - gender = MALE - -/datum/sprite_accessory/underwear/male_stripe - name = "Men's Striped Boxer" - icon_state = "male_stripe" - gender = MALE - -/datum/sprite_accessory/underwear/male_commie - name = "Men's Striped Commie Boxer" - icon_state = "male_commie" - gender = MALE - -/datum/sprite_accessory/underwear/male_usastripe - name = "Men's Striped Freedom Boxer" - icon_state = "male_assblastusa" - gender = MALE - -/datum/sprite_accessory/underwear/male_uk - name = "Men's Striped UK Boxer" - icon_state = "male_uk" - gender = MALE - -/datum/sprite_accessory/underwear/male_white - name = "Men's White" - icon_state = "male_white" - gender = MALE - -/datum/sprite_accessory/underwear/female_babydoll - name = "Babydoll" - icon_state = "female_babydoll" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_babyblue - name = "Ladies' Baby-Blue" - icon_state = "female_babyblue" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_black - name = "Ladies' Black" - icon_state = "female_black" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_black_neko - name = "Ladies' Black Neko" - icon_state = "female_neko_black" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_blackalt - name = "Ladies' Black Sport" - icon_state = "female_blackalt" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_blue - name = "Ladies' Blue" - icon_state = "female_blue" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_commie - name = "Ladies' Commie" - icon_state = "female_commie" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_usastripe - name = "Ladies' Freedom" - icon_state = "female_assblastusa" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_green - name = "Ladies' Green" - icon_state = "female_green" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_kinky - name = "Ladies' Kinky" - icon_state = "female_kinky" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_pink - name = "Ladies' Pink" - icon_state = "female_pink" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_red - name = "Ladies' Red" - icon_state = "female_red" - gender = FEMALE - -/datum/sprite_accessory/underwear/swimsuit - name = "Ladies' Swimsuit (Black)" - icon_state = "swim_black" - gender = FEMALE - -/datum/sprite_accessory/underwear/swimsuit_blue - name = "Ladies' Swimsuit (Blue)" - icon_state = "swim_blue" - gender = FEMALE - -/datum/sprite_accessory/underwear/swimsuit_green - name = "Ladies' Swimsuit (Green)" - icon_state = "swim_green" - gender = FEMALE - -/datum/sprite_accessory/underwear/swimsuit_purple - name = "Ladies' Swimsuit (Purple)" - icon_state = "swim_purple" - gender = FEMALE - -/datum/sprite_accessory/underwear/swimsuit_red - name = "Ladies' Swimsuit (Red)" - icon_state = "swim_red" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_thong - name = "Ladies' Thong" - icon_state = "female_thong" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_uk - name = "Ladies' UK" - icon_state = "female_uk" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_white - name = "Ladies' White" - icon_state = "female_white" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_white_neko - name = "Ladies' White Neko" - icon_state = "female_neko_white" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_whitealt - name = "Ladies' White Sport" - icon_state = "female_whitealt" - gender = FEMALE - -/datum/sprite_accessory/underwear/female_yellow - name = "Ladies' Yellow" - icon_state = "female_yellow" - gender = FEMALE - -//////////////////////////// -// Undershirt Definitions // -//////////////////////////// - -/datum/sprite_accessory/undershirt - icon = 'icons/mob/underwear.dmi' - -/datum/sprite_accessory/undershirt/nude - name = "Nude" - icon_state = null - gender = NEUTER - -// please make sure they're sorted alphabetically and categorized - -/datum/sprite_accessory/undershirt/bluejersey - name = "Jersey (Blue)" - icon_state = "shirt_bluejersey" - gender = NEUTER - -/datum/sprite_accessory/undershirt/redjersey - name = "Jersey (Red)" - icon_state = "shirt_redjersey" - gender = NEUTER - -/datum/sprite_accessory/undershirt/bluepolo - name = "Polo Shirt (Blue)" - icon_state = "bluepolo" - gender = NEUTER - -/datum/sprite_accessory/undershirt/grayyellowpolo - name = "Polo Shirt (Gray-Yellow)" - icon_state = "grayyellowpolo" - gender = NEUTER - -/datum/sprite_accessory/undershirt/redpolo - name = "Polo Shirt (Red)" - icon_state = "redpolo" - gender = NEUTER - -/datum/sprite_accessory/undershirt/whitepolo - name = "Polo Shirt (White)" - icon_state = "whitepolo" - gender = NEUTER - -/datum/sprite_accessory/undershirt/alienshirt - name = "Shirt (Alien)" - icon_state = "shirt_alien" - gender = NEUTER - -/datum/sprite_accessory/undershirt/mondmondjaja - name = "Shirt (Band)" - icon_state = "band" - gender = NEUTER - -/datum/sprite_accessory/undershirt/shirt_black - name = "Shirt (Black)" - icon_state = "shirt_black" - gender = NEUTER - -/datum/sprite_accessory/undershirt/blueshirt - name = "Shirt (Blue)" - icon_state = "shirt_blue" - gender = NEUTER - -/datum/sprite_accessory/undershirt/clownshirt - name = "Shirt (Clown)" - icon_state = "shirt_clown" - gender = NEUTER - -/datum/sprite_accessory/undershirt/commie - name = "Shirt (Commie)" - icon_state = "shirt_commie" - gender = NEUTER - -/datum/sprite_accessory/undershirt/greenshirt - name = "Shirt (Green)" - icon_state = "shirt_green" - gender = NEUTER - -/datum/sprite_accessory/undershirt/shirt_grey - name = "Shirt (Grey)" - icon_state = "shirt_grey" - gender = NEUTER - -/datum/sprite_accessory/undershirt/ian - name = "Shirt (Ian)" - icon_state = "ian" - gender = NEUTER - -/datum/sprite_accessory/undershirt/ilovent - name = "Shirt (I Love NT)" - icon_state = "ilovent" - gender = NEUTER - -/datum/sprite_accessory/undershirt/lover - name = "Shirt (Lover)" - icon_state = "lover" - gender = NEUTER - -/datum/sprite_accessory/undershirt/matroska - name = "Shirt (Matroska)" - icon_state = "matroska" - gender = NEUTER - -/datum/sprite_accessory/undershirt/meat - name = "Shirt (Meat)" - icon_state = "shirt_meat" - gender = NEUTER - -/datum/sprite_accessory/undershirt/nano - name = "Shirt (Nanotrasen)" - icon_state = "shirt_nano" - gender = NEUTER - -/datum/sprite_accessory/undershirt/peace - name = "Shirt (Peace)" - icon_state = "peace" - gender = NEUTER - -/datum/sprite_accessory/undershirt/pacman - name = "Shirt (Pogoman)" - icon_state = "pogoman" - gender = NEUTER - -/datum/sprite_accessory/undershirt/question - name = "Shirt (Question)" - icon_state = "shirt_question" - gender = NEUTER - -/datum/sprite_accessory/undershirt/redshirt - name = "Shirt (Red)" - icon_state = "shirt_red" - gender = NEUTER - -/datum/sprite_accessory/undershirt/skull - name = "Shirt (Skull)" - icon_state = "shirt_skull" - gender = NEUTER - -/datum/sprite_accessory/undershirt/ss13 - name = "Shirt (SS13)" - icon_state = "shirt_ss13" - gender = NEUTER - -/datum/sprite_accessory/undershirt/stripe - name = "Shirt (Striped)" - icon_state = "shirt_stripes" - gender = NEUTER - -/datum/sprite_accessory/undershirt/tiedye - name = "Shirt (Tie-dye)" - icon_state = "shirt_tiedye" - gender = NEUTER - -/datum/sprite_accessory/undershirt/uk - name = "Shirt (UK)" - icon_state = "uk" - gender = NEUTER - -/datum/sprite_accessory/undershirt/usa - name = "Shirt (USA)" - icon_state = "shirt_assblastusa" - gender = NEUTER - -/datum/sprite_accessory/undershirt/shirt_white - name = "Shirt (White)" - icon_state = "shirt_white" - gender = NEUTER - -/datum/sprite_accessory/undershirt/blackshortsleeve - name = "Short-sleeved Shirt (Black)" - icon_state = "blackshortsleeve" - gender = NEUTER - -/datum/sprite_accessory/undershirt/blueshortsleeve - name = "Short-sleeved Shirt (Blue)" - icon_state = "blueshortsleeve" - gender = NEUTER - -/datum/sprite_accessory/undershirt/greenshortsleeve - name = "Short-sleeved Shirt (Green)" - icon_state = "greenshortsleeve" - gender = NEUTER - -/datum/sprite_accessory/undershirt/purpleshortsleeve - name = "Short-sleeved Shirt (Purple)" - icon_state = "purpleshortsleeve" - gender = NEUTER - -/datum/sprite_accessory/undershirt/whiteshortsleeve - name = "Short-sleeved Shirt (White)" - icon_state = "whiteshortsleeve" - gender = NEUTER - -/datum/sprite_accessory/undershirt/sports_bra - name = "Sports Bra" - icon_state = "sports_bra" - gender = NEUTER - -/datum/sprite_accessory/undershirt/sports_bra2 - name = "Sports Bra (Alt)" - icon_state = "sports_bra_alt" - gender = NEUTER - -/datum/sprite_accessory/undershirt/blueshirtsport - name = "Sports Shirt (Blue)" - icon_state = "blueshirtsport" - gender = NEUTER - -/datum/sprite_accessory/undershirt/greenshirtsport - name = "Sports Shirt (Green)" - icon_state = "greenshirtsport" - gender = NEUTER - -/datum/sprite_accessory/undershirt/redshirtsport - name = "Sports Shirt (Red)" - icon_state = "redshirtsport" - gender = NEUTER - -/datum/sprite_accessory/undershirt/tank_black - name = "Tank Top (Black)" - icon_state = "tank_black" - gender = NEUTER - -/datum/sprite_accessory/undershirt/tankfire - name = "Tank Top (Fire)" - icon_state = "tank_fire" - gender = NEUTER - -/datum/sprite_accessory/undershirt/tank_grey - name = "Tank Top (Grey)" - icon_state = "tank_grey" - gender = NEUTER - -/datum/sprite_accessory/undershirt/female_midriff - name = "Tank Top (Midriff)" - icon_state = "tank_midriff" - gender = FEMALE - -/datum/sprite_accessory/undershirt/tank_red - name = "Tank Top (Red)" - icon_state = "tank_red" - gender = NEUTER - -/datum/sprite_accessory/undershirt/tankstripe - name = "Tank Top (Striped)" - icon_state = "tank_stripes" - gender = NEUTER - -/datum/sprite_accessory/undershirt/tank_white - name = "Tank Top (White)" - icon_state = "tank_white" - gender = NEUTER - -/datum/sprite_accessory/undershirt/redtop - name = "Top (Red)" - icon_state = "redtop" - gender = FEMALE - -/datum/sprite_accessory/undershirt/whitetop - name = "Top (White)" - icon_state = "whitetop" - gender = FEMALE - -/datum/sprite_accessory/undershirt/tshirt_blue - name = "T-Shirt (Blue)" - icon_state = "blueshirt" - gender = NEUTER - -/datum/sprite_accessory/undershirt/tshirt_green - name = "T-Shirt (Green)" - icon_state = "greenshirt" - gender = NEUTER - -/datum/sprite_accessory/undershirt/tshirt_red - name = "T-Shirt (Red)" - icon_state = "redshirt" - gender = NEUTER - -/datum/sprite_accessory/undershirt/yellowshirt - name = "T-Shirt (Yellow)" - icon_state = "yellowshirt" - gender = NEUTER - -/////////////////////// -// Socks Definitions // -/////////////////////// - -/datum/sprite_accessory/socks - icon = 'icons/mob/underwear.dmi' - -/datum/sprite_accessory/socks/nude - name = "Nude" - icon_state = null - -// please make sure they're sorted alphabetically and categorized - -/datum/sprite_accessory/socks/black_knee - name = "Knee-high (Black)" - icon_state = "black_knee" - -/datum/sprite_accessory/socks/commie_knee - name = "Knee-High (Commie)" - icon_state = "commie_knee" - -/datum/sprite_accessory/socks/usa_knee - name = "Knee-High (Freedom)" - icon_state = "assblastusa_knee" - -/datum/sprite_accessory/socks/rainbow_knee - name = "Knee-high (Rainbow)" - icon_state = "rainbow_knee" - -/datum/sprite_accessory/socks/striped_knee - name = "Knee-high (Striped)" - icon_state = "striped_knee" - -/datum/sprite_accessory/socks/thin_knee - name = "Knee-high (Thin)" - icon_state = "thin_knee" - -/datum/sprite_accessory/socks/uk_knee - name = "Knee-High (UK)" - icon_state = "uk_knee" - -/datum/sprite_accessory/socks/white_knee - name = "Knee-high (White)" - icon_state = "white_knee" - -/datum/sprite_accessory/socks/black_norm - name = "Normal (Black)" - icon_state = "black_norm" - -/datum/sprite_accessory/socks/white_norm - name = "Normal (White)" - icon_state = "white_norm" - -/datum/sprite_accessory/socks/pantyhose - name = "Pantyhose" - icon_state = "pantyhose" - -/datum/sprite_accessory/socks/black_short - name = "Short (Black)" - icon_state = "black_short" - -/datum/sprite_accessory/socks/white_short - name = "Short (White)" - icon_state = "white_short" - -/datum/sprite_accessory/socks/black_thigh - name = "Thigh-high (Black)" - icon_state = "black_thigh" - -/datum/sprite_accessory/socks/commie_thigh - name = "Thigh-high (Commie)" - icon_state = "commie_thigh" - -/datum/sprite_accessory/socks/usa_thigh - name = "Thigh-high (Freedom)" - icon_state = "assblastusa_thigh" - -/datum/sprite_accessory/socks/rainbow_thigh - name = "Thigh-high (Rainbow)" - icon_state = "rainbow_thigh" - -/datum/sprite_accessory/socks/striped_thigh - name = "Thigh-high (Striped)" - icon_state = "striped_thigh" - -/datum/sprite_accessory/socks/thin_thigh - name = "Thigh-high (Thin)" - icon_state = "thin_thigh" - -/datum/sprite_accessory/socks/uk_thigh - name = "Thigh-high (UK)" - icon_state = "uk_thigh" - -/datum/sprite_accessory/socks/white_thigh - name = "Thigh-high (White)" - icon_state = "white_thigh" - -//////////.////////////////// -// MutantParts Definitions // -///////////////////////////// - -/datum/sprite_accessory/body_markings - icon = 'icons/mob/mutant_bodyparts.dmi' - -/datum/sprite_accessory/body_markings/none - name = "None" - icon_state = "none" - -/datum/sprite_accessory/body_markings/dtiger - name = "Dark Tiger Body" - icon_state = "dtiger" - gender_specific = 1 - -/datum/sprite_accessory/body_markings/ltiger - name = "Light Tiger Body" - icon_state = "ltiger" - gender_specific = 1 - -/datum/sprite_accessory/body_markings/lbelly - name = "Light Belly" - icon_state = "lbelly" - gender_specific = 1 - -/datum/sprite_accessory/tails - icon = 'icons/mob/mutant_bodyparts.dmi' - -/datum/sprite_accessory/tails_animated - icon = 'icons/mob/mutant_bodyparts.dmi' - -/datum/sprite_accessory/tails/lizard/smooth - name = "Smooth" - icon_state = "smooth" - -/datum/sprite_accessory/tails_animated/lizard/smooth - name = "Smooth" - icon_state = "smooth" - -/datum/sprite_accessory/tails/lizard/dtiger - name = "Dark Tiger" - icon_state = "dtiger" - -/datum/sprite_accessory/tails_animated/lizard/dtiger - name = "Dark Tiger" - icon_state = "dtiger" - -/datum/sprite_accessory/tails/lizard/ltiger - name = "Light Tiger" - icon_state = "ltiger" - -/datum/sprite_accessory/tails_animated/lizard/ltiger - name = "Light Tiger" - icon_state = "ltiger" - -/datum/sprite_accessory/tails/lizard/spikes - name = "Spikes" - icon_state = "spikes" - -/datum/sprite_accessory/tails_animated/lizard/spikes - name = "Spikes" - icon_state = "spikes" - -/datum/sprite_accessory/tails/human/none - name = "None" - icon_state = "none" - -/datum/sprite_accessory/tails_animated/human/none - name = "None" - icon_state = "none" -/* -/datum/sprite_accessory/tails/human/cat - name = "Cat" - icon_state = "cat" - color_src = HAIR - -/datum/sprite_accessory/tails_animated/human/cat - name = "Cat" - icon_state = "cat" - color_src = HAIR*/ - -/datum/sprite_accessory/snouts - icon = 'icons/mob/mutant_bodyparts.dmi' - -/datum/sprite_accessory/snouts/sharp - name = "Sharp" - icon_state = "sharp" - -/datum/sprite_accessory/snouts/round - name = "Round" - icon_state = "round" - -/datum/sprite_accessory/snouts/sharplight - name = "Sharp + Light" - icon_state = "sharplight" - -/datum/sprite_accessory/snouts/roundlight - name = "Round + Light" - icon_state = "roundlight" - -/datum/sprite_accessory/horns - icon = 'icons/mob/mutant_bodyparts.dmi' - -/datum/sprite_accessory/horns/none - name = "None" - icon_state = "none" - -/datum/sprite_accessory/horns/simple - name = "Simple" - icon_state = "simple" - -/datum/sprite_accessory/horns/short - name = "Short" - icon_state = "short" - -/datum/sprite_accessory/horns/curled - name = "Curled" - icon_state = "curled" - -/datum/sprite_accessory/horns/ram - name = "Ram" - icon_state = "ram" - -/datum/sprite_accessory/horns/angler - name = "Angeler" - icon_state = "angler" - -/datum/sprite_accessory/ears - icon = 'icons/mob/mutant_bodyparts.dmi' - -/datum/sprite_accessory/ears/none - name = "None" - icon_state = "none" - -/datum/sprite_accessory/ears/cat - name = "Cat" - icon_state = "cat" - hasinner = 1 - color_src = HAIR - -/datum/sprite_accessory/wings/none - name = "None" - icon_state = "none" - -/datum/sprite_accessory/wings_open - icon = 'icons/mob/wings.dmi' - -/datum/sprite_accessory/wings_open/angel - name = "Angel" - icon_state = "angel" - color_src = 0 - dimension_x = 46 - center = TRUE - dimension_y = 34 - -/datum/sprite_accessory/wings - icon = 'icons/mob/wings.dmi' - -/datum/sprite_accessory/wings/angel - name = "Angel" - icon_state = "angel" - color_src = 0 - dimension_x = 46 - center = TRUE - dimension_y = 34 - locked = TRUE - -/datum/sprite_accessory/frills - icon = 'icons/mob/mutant_bodyparts.dmi' - -/datum/sprite_accessory/frills/none - name = "None" - icon_state = "none" - -/datum/sprite_accessory/frills/simple - name = "Simple" - icon_state = "simple" - -/datum/sprite_accessory/frills/short - name = "Short" - icon_state = "short" - -/datum/sprite_accessory/frills/aquatic - name = "Aquatic" - icon_state = "aqua" - -/datum/sprite_accessory/spines - icon = 'icons/mob/mutant_bodyparts.dmi' - -/datum/sprite_accessory/spines_animated - icon = 'icons/mob/mutant_bodyparts.dmi' - -/datum/sprite_accessory/spines/none - name = "None" - icon_state = "none" - -/datum/sprite_accessory/spines_animated/none - name = "None" - icon_state = "none" - -/datum/sprite_accessory/spines/short - name = "Short" - icon_state = "short" - -/datum/sprite_accessory/spines_animated/short - name = "Short" - icon_state = "short" - -/datum/sprite_accessory/spines/shortmeme - name = "Short + Membrane" - icon_state = "shortmeme" - -/datum/sprite_accessory/spines_animated/shortmeme - name = "Short + Membrane" - icon_state = "shortmeme" - -/datum/sprite_accessory/spines/long - name = "Long" - icon_state = "long" - -/datum/sprite_accessory/spines_animated/long - name = "Long" - icon_state = "long" - -/datum/sprite_accessory/spines/longmeme - name = "Long + Membrane" - icon_state = "longmeme" - -/datum/sprite_accessory/spines_animated/longmeme - name = "Long + Membrane" - icon_state = "longmeme" - -/datum/sprite_accessory/spines/aqautic - name = "Aquatic" - icon_state = "aqua" - -/datum/sprite_accessory/spines_animated/aqautic - name = "Aquatic" - icon_state = "aqua" - -/datum/sprite_accessory/legs //legs are a special case, they aren't actually sprite_accessories but are updated with them. - icon = null //These datums exist for selecting legs on preference, and little else - -/datum/sprite_accessory/legs/none - name = "Normal Legs" - -/datum/sprite_accessory/legs/digitigrade_lizard - name = "Digitigrade Legs" - -/datum/sprite_accessory/caps - icon = 'icons/mob/mutant_bodyparts.dmi' - color_src = HAIR - -/datum/sprite_accessory/caps/round - name = "Round" - icon_state = "round" - -/datum/sprite_accessory/moth_wings - icon = 'icons/mob/wings.dmi' - color_src = null - -/datum/sprite_accessory/moth_wings/plain - name = "Plain" - icon_state = "plain" - -/datum/sprite_accessory/moth_wings/monarch - name = "Monarch" - icon_state = "monarch" - -/datum/sprite_accessory/moth_wings/luna - name = "Luna" - icon_state = "luna" - -/datum/sprite_accessory/moth_wings/atlas - name = "Atlas" - icon_state = "atlas" - -/datum/sprite_accessory/moth_wings/reddish - name = "Reddish" - icon_state = "redish" - -/datum/sprite_accessory/moth_wings/royal - name = "Royal" - icon_state = "royal" - -/datum/sprite_accessory/moth_wings/gothic - name = "Gothic" - icon_state = "gothic" - -/datum/sprite_accessory/moth_wings/lovers - name = "Lovers" - icon_state = "lovers" - -/datum/sprite_accessory/moth_wings/whitefly - name = "White Fly" - icon_state = "whitefly" - -/datum/sprite_accessory/moth_wings/punished - name = "Burnt Off" - icon_state = "punished" - locked = TRUE - -/datum/sprite_accessory/moth_wings/firewatch - name = "Firewatch" - icon_state = "firewatch" - -/datum/sprite_accessory/moth_wings/deathhead - name = "Deathshead" - icon_state = "deathhead" - -/datum/sprite_accessory/moth_wings/poison - name = "Poison" - icon_state = "poison" - -/datum/sprite_accessory/moth_wings/ragged - name = "Ragged" - icon_state = "ragged" - -/datum/sprite_accessory/moth_wings/moonfly - name = "Moon Fly" - icon_state = "moonfly" - -/datum/sprite_accessory/moth_wings/snow - name = "Snow" - icon_state = "snow" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm new file mode 100644 index 0000000000..699c3c97e4 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm @@ -0,0 +1,62 @@ +/* + + Hello and welcome to sprite_accessories: For sprite accessories, such as hair, + facial hair, and possibly tattoos and stuff somewhere along the line. This file is + intended to be friendly for people with little to no actual coding experience. + The process of adding in new hairstyles has been made pain-free and easy to do. + Enjoy! - Doohl + + + Notice: This all gets automatically compiled in a list in dna.dm, so you do not + have to define any UI values for sprite accessories manually for hair and facial + hair. Just add in new hair types and the game will naturally adapt. + + !!WARNING!!: changing existing hair information can be VERY hazardous to savefiles, + to the point where you may completely corrupt a server's savefiles. Please refrain + from doing this unless you absolutely know what you are doing, and have defined a + conversion in savefile.dm +*/ +/proc/init_sprite_accessory_subtypes(prototype, list/L, list/male, list/female,var/roundstart = FALSE)//Roundstart argument builds a specific list for roundstart parts where some parts may be locked + if(!istype(L)) + L = list() + if(!istype(male)) + male = list() + if(!istype(female)) + female = list() + + for(var/path in typesof(prototype)) + if(path == prototype) + continue + if(roundstart) + var/datum/sprite_accessory/P = path + if(initial(P.locked)) + continue + var/datum/sprite_accessory/D = new path() + + if(D.icon_state) + L[D.name] = D + else + L += D.name + + switch(D.gender) + if(MALE) + male += D.name + if(FEMALE) + female += D.name + else + male += D.name + female += D.name + return L + +/datum/sprite_accessory + var/icon //the icon file the accessory is located in + var/icon_state //the icon_state of the accessory + var/name //the preview name of the accessory + var/gender = NEUTER //Determines if the accessory will be skipped or included in random hair generations + var/gender_specific //Something that can be worn by either gender, but looks different on each + var/color_src = MUTCOLORS //Currently only used by mutantparts so don't worry about hair and stuff. This is the source that this accessory will get its color from. Default is MUTCOLOR, but can also be HAIR, FACEHAIR, EYECOLOR and 0 if none. + var/hasinner //Decides if this sprite has an "inner" part, such as the fleshy parts on ears. + var/locked = FALSE //Is this part locked from roundstart selection? Used for parts that apply effects + var/dimension_x = 32 + var/dimension_y = 32 + var/center = FALSE //Should we center the sprite? \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm b/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm new file mode 100644 index 0000000000..6bce18d7ce --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm @@ -0,0 +1,25 @@ +//////////.////////////////// +// MutantParts Definitions // +///////////////////////////// + +/datum/sprite_accessory/body_markings + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/body_markings/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/body_markings/dtiger + name = "Dark Tiger Body" + icon_state = "dtiger" + gender_specific = 1 + +/datum/sprite_accessory/body_markings/ltiger + name = "Light Tiger Body" + icon_state = "ltiger" + gender_specific = 1 + +/datum/sprite_accessory/body_markings/lbelly + name = "Light Belly" + icon_state = "lbelly" + gender_specific = 1 \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/caps.dm b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm new file mode 100644 index 0000000000..debb4865ba --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm @@ -0,0 +1,7 @@ +datum/sprite_accessory/caps + icon = 'icons/mob/mutant_bodyparts.dmi' + color_src = HAIR + +/datum/sprite_accessory/caps/round + name = "Round" + icon_state = "round" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm new file mode 100644 index 0000000000..163f8370a2 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm @@ -0,0 +1,12 @@ +/datum/sprite_accessory/ears + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/ears/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/ears/cat + name = "Cat" + icon_state = "cat" + hasinner = 1 + color_src = HAIR \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/frills.dm b/code/modules/mob/dead/new_player/sprite_accessories/frills.dm new file mode 100644 index 0000000000..93c4af6df0 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/frills.dm @@ -0,0 +1,18 @@ +/datum/sprite_accessory/frills + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/frills/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/frills/simple + name = "Simple" + icon_state = "simple" + +/datum/sprite_accessory/frills/short + name = "Short" + icon_state = "short" + +/datum/sprite_accessory/frills/aquatic + name = "Aquatic" + icon_state = "aqua" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm new file mode 100644 index 0000000000..3566f3dea5 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm @@ -0,0 +1,89 @@ +///////////////////////////// +// Facial Hair Definitions // +///////////////////////////// +/datum/sprite_accessory/facial_hair + icon = 'icons/mob/human_face.dmi' + gender = MALE // barf (unless you're a dorf, dorfs dig chix w/ beards :P) + +// please make sure they're sorted alphabetically and categorized + +/datum/sprite_accessory/facial_hair/abe + name = "Beard (Abraham Lincoln)" + icon_state = "facial_abe" + +/datum/sprite_accessory/facial_hair/brokenman + name = "Beard (Broken Man)" + icon_state = "facial_brokenman" + +/datum/sprite_accessory/facial_hair/chinstrap + name = "Beard (Chinstrap)" + icon_state = "facial_chin" + +/datum/sprite_accessory/facial_hair/dwarf + name = "Beard (Dwarf)" + icon_state = "facial_dwarf" + +/datum/sprite_accessory/facial_hair/fiveoclock + name = "Beard (Five o Clock Shadow)" + icon_state = "facial_fiveoclock" + +/datum/sprite_accessory/facial_hair/fullbeard + name = "Beard (Full)" + icon_state = "facial_fullbeard" + +/datum/sprite_accessory/facial_hair/gt + name = "Beard (Goatee)" + icon_state = "facial_gt" + +/datum/sprite_accessory/facial_hair/hip + name = "Beard (Hipster)" + icon_state = "facial_hip" + +/datum/sprite_accessory/facial_hair/jensen + name = "Beard (Jensen)" + icon_state = "facial_jensen" + +/datum/sprite_accessory/facial_hair/neckbeard + name = "Beard (Neckbeard)" + icon_state = "facial_neckbeard" + +/datum/sprite_accessory/facial_hair/vlongbeard + name = "Beard (Very Long)" + icon_state = "facial_wise" + +/datum/sprite_accessory/facial_hair/longbeard + name = "Beard (Long)" + icon_state = "facial_longbeard" + +/datum/sprite_accessory/facial_hair/fu + name = "Moustache (Fu Manchu)" + icon_state = "facial_fumanchu" + +/datum/sprite_accessory/facial_hair/hogan + name = "Moustache (Hulk Hogan)" + icon_state = "facial_hogan" //-Neek + +/datum/sprite_accessory/facial_hair/selleck + name = "Moustache (Selleck)" + icon_state = "facial_selleck" + +/datum/sprite_accessory/facial_hair/chaplin + name = "Moustache (Square)" + icon_state = "facial_chaplin" + +/datum/sprite_accessory/facial_hair/vandyke + name = "Moustache (Van Dyke)" + icon_state = "facial_vandyke" + +/datum/sprite_accessory/facial_hair/watson + name = "Moustache (Watson)" + icon_state = "facial_watson" + +/datum/sprite_accessory/facial_hair/shaved + name = "Shaved" + icon_state = null + gender = NEUTER + +/datum/sprite_accessory/facial_hair/elvis + name = "Sideburns (Elvis)" + icon_state = "facial_elvis" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm new file mode 100644 index 0000000000..f8d8d26328 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm @@ -0,0 +1,464 @@ +////////////////////// +// Hair Definitions // +////////////////////// +/datum/sprite_accessory/hair + icon = 'icons/mob/human_face.dmi' // default icon for all hairs + + // please make sure they're sorted alphabetically and, where needed, categorized + // try to capitalize the names please~ + // try to spell + // you do not need to define _s or _l sub-states, game automatically does this for you + +/datum/sprite_accessory/hair/afro + name = "Afro" + icon_state = "hair_afro" + +/datum/sprite_accessory/hair/afro2 + name = "Afro 2" + icon_state = "hair_afro2" + +/datum/sprite_accessory/hair/afro_large + name = "Afro (Large)" + icon_state = "hair_bigafro" + +/datum/sprite_accessory/hair/antenna + name = "Ahoge" + icon_state = "hair_antenna" + +/datum/sprite_accessory/hair/bald + name = "Bald" + icon_state = null + +/datum/sprite_accessory/hair/balding + name = "Balding Hair" + icon_state = "hair_e" + +/datum/sprite_accessory/hair/bedhead + name = "Bedhead" + icon_state = "hair_bedhead" + +/datum/sprite_accessory/hair/bedhead2 + name = "Bedhead 2" + icon_state = "hair_bedheadv2" + +/datum/sprite_accessory/hair/bedhead3 + name = "Bedhead 3" + icon_state = "hair_bedheadv3" + +/datum/sprite_accessory/hair/beehive + name = "Beehive" + icon_state = "hair_beehive" + +/datum/sprite_accessory/hair/beehive2 + name = "Beehive 2" + icon_state = "hair_beehivev2" + +/datum/sprite_accessory/hair/bob + name = "Bob Hair" + icon_state = "hair_bob" + +/datum/sprite_accessory/hair/bob2 + name = "Bob Hair 2" + icon_state = "hair_bob2" + +/datum/sprite_accessory/hair/bob3 + name = "Bob Hair 3" + icon_state = "hair_bobcut" + +/datum/sprite_accessory/hair/bobcurl + name = "Bobcurl" + icon_state = "hair_bobcurl" + +/datum/sprite_accessory/hair/boddicker + name = "Boddicker" + icon_state = "hair_boddicker" + +/datum/sprite_accessory/hair/bowl + name = "Bowl" + icon_state = "hair_bowlcut" + +/datum/sprite_accessory/hair/braid + name = "Braid (Floorlength)" + icon_state = "hair_braid" + +/datum/sprite_accessory/hair/braided + name = "Braided" + icon_state = "hair_braided" + +/datum/sprite_accessory/hair/front_braid + name = "Braided Front" + icon_state = "hair_braidfront" + +/datum/sprite_accessory/hair/not_floorlength_braid + name = "Braid (High)" + icon_state = "hair_braid2" + +/datum/sprite_accessory/hair/lowbraid + name = "Braid (Low)" + icon_state = "hair_hbraid" + +/datum/sprite_accessory/hair/shortbraid + name = "Braid (Short)" + icon_state = "hair_shortbraid" + +/datum/sprite_accessory/hair/braidtail + name = "Braided Tail" + icon_state = "hair_braidtail" + +/datum/sprite_accessory/hair/bun + name = "Bun Head" + icon_state = "hair_bun" + +/datum/sprite_accessory/hair/bun2 + name = "Bun Head 2" + icon_state = "hair_bunhead2" + +/datum/sprite_accessory/hair/largebun + name = "Bun (Large)" + icon_state = "hair_largebun" + +/datum/sprite_accessory/hair/business + name = "Business Hair" + icon_state = "hair_business" + +/datum/sprite_accessory/hair/business2 + name = "Business Hair 2" + icon_state = "hair_business2" + +/datum/sprite_accessory/hair/business3 + name = "Business Hair 3" + icon_state = "hair_business3" + +/datum/sprite_accessory/hair/business4 + name = "Business Hair 4" + icon_state = "hair_business4" + +/datum/sprite_accessory/hair/buzz + name = "Buzzcut" + icon_state = "hair_buzzcut" + +/datum/sprite_accessory/hair/combover + name = "Combover" + icon_state = "hair_combover" + +/datum/sprite_accessory/hair/crew + name = "Crewcut" + icon_state = "hair_crewcut" + +/datum/sprite_accessory/hair/curls + name = "Curls" + icon_state = "hair_curls" + +/datum/sprite_accessory/hair/cut + name = "Cut Hair" + icon_state = "hair_c" + +/datum/sprite_accessory/hair/devillock + name = "Devil Lock" + icon_state = "hair_devilock" + +/datum/sprite_accessory/hair/dreadlocks + name = "Dreadlocks" + icon_state = "hair_dreads" + +/datum/sprite_accessory/hair/drillhair + name = "Drill Hair" + icon_state = "hair_drillhair" + +/datum/sprite_accessory/hair/drillhairextended + name = "Drill Hair (Extended)" + icon_state = "hair_drillhairextended" + +/datum/sprite_accessory/hair/emo + name = "Emo" + icon_state = "hair_emo" + +/datum/sprite_accessory/hair/feather + name = "Feather" + icon_state = "hair_feather" + +/datum/sprite_accessory/hair/sargeant + name = "Flat Top" + icon_state = "hair_sargeant" + +/datum/sprite_accessory/hair/bigflattop + name = "Flat Top (Big)" + icon_state = "hair_bigflattop" + +/datum/sprite_accessory/hair/fag + name = "Flow Hair" + icon_state = "hair_f" + +/datum/sprite_accessory/hair/gelled + name = "Gelled Back" + icon_state = "hair_gelled" + +/datum/sprite_accessory/hair/gentle + name = "Gentle" + icon_state = "hair_gentle" + +/datum/sprite_accessory/hair/halfbang + name = "Half-banged Hair" + icon_state = "hair_halfbang" + +/datum/sprite_accessory/hair/halfbang2 + name = "Half-banged Hair 2" + icon_state = "hair_halfbang2" + +/datum/sprite_accessory/hair/hedgehog + name = "Hedgehog Hair" + icon_state = "hair_hedgehog" + +/datum/sprite_accessory/hair/himecut + name = "Hime Cut" + icon_state = "hair_himecut" + +/datum/sprite_accessory/hair/himecut2 + name = "Hime Cut 2" + icon_state = "hair_himecut2" + +/datum/sprite_accessory/hair/himeup + name = "Hime Updo" + icon_state = "hair_himeup" + +/datum/sprite_accessory/hair/hitop + name = "Hitop" + icon_state = "hair_hitop" + +/datum/sprite_accessory/hair/jensen + name = "Jensen Hair" + icon_state = "hair_jensen" + +/datum/sprite_accessory/hair/keanu + name = "Keanu Hair" + icon_state = "hair_keanu" + +/datum/sprite_accessory/hair/kusangi + name = "Kusanagi Hair" + icon_state = "hair_kusanagi" + +/datum/sprite_accessory/hair/long + name = "Long Hair 1" + icon_state = "hair_long" + +/datum/sprite_accessory/hair/long2 + name = "Long Hair 2" + icon_state = "hair_long2" + +/datum/sprite_accessory/hair/long3 + name = "Long Hair 3" + icon_state = "hair_long3" + +/datum/sprite_accessory/hair/long_over_eye + name = "Long Over Eye" + icon_state = "hair_longovereye" + +/datum/sprite_accessory/hair/longbangs + name = "Long Bangs" + icon_state = "hair_lbangs" + +/datum/sprite_accessory/hair/longemo + name = "Long Emo" + icon_state = "hair_longemo" + +/datum/sprite_accessory/hair/longfringe + name = "Long Fringe" + icon_state = "hair_longfringe" + +/datum/sprite_accessory/hair/sidepartlongalt + name = "Long Side Part" + icon_state = "hair_longsidepart" + +/datum/sprite_accessory/hair/megaeyebrows + name = "Mega Eyebrows" + icon_state = "hair_megaeyebrows" + +/datum/sprite_accessory/hair/messy + name = "Messy" + icon_state = "hair_messy" + +/datum/sprite_accessory/hair/mohawk + name = "Mohawk" + icon_state = "hair_d" + +/datum/sprite_accessory/hair/reversemohawk + name = "Mohawk (Reverse)" + icon_state = "hair_reversemohawk" + +/datum/sprite_accessory/hair/odango + name = "Odango" + icon_state = "hair_odango" + +/datum/sprite_accessory/hair/ombre + name = "Ombre" + icon_state = "hair_ombre" + +/datum/sprite_accessory/hair/oneshoulder + name = "One Shoulder" + icon_state = "hair_oneshoulder" + +/datum/sprite_accessory/hair/over_eye + name = "Over Eye" + icon_state = "hair_shortovereye" + +//Donator item - fractious +/datum/sprite_accessory/hair/over_eye_fr + name = "Over Eye (fract)" + icon_state = "hair_shortovereye_1f" + ckeys_allowed = list("fractious") + +/datum/sprite_accessory/hair/parted + name = "Parted" + icon_state = "hair_parted" + +/datum/sprite_accessory/hair/partedside + name = "Parted (Side)" + icon_state = "hair_part" + +/datum/sprite_accessory/hair/kagami + name = "Pigtails" + icon_state = "hair_kagami" + +/datum/sprite_accessory/hair/pigtail + name = "Pigtails 2" + icon_state = "hair_pigtails" + +/datum/sprite_accessory/hair/pigtail2 + name = "Pigtails 3" + icon_state = "hair_pigtails2" + +/datum/sprite_accessory/hair/pixie + name = "Pixie Cut" + icon_state = "hair_pixie" + +/datum/sprite_accessory/hair/pompadour + name = "Pompadour" + icon_state = "hair_pompadour" + +/datum/sprite_accessory/hair/bigpompadour + name = "Pompadour (Big)" + icon_state = "hair_bigpompadour" + +/datum/sprite_accessory/hair/ponytail1 + name = "Ponytail" + icon_state = "hair_ponytail" + +/datum/sprite_accessory/hair/ponytail2 + name = "Ponytail 2" + icon_state = "hair_ponytail2" + +/datum/sprite_accessory/hair/ponytail3 + name = "Ponytail 3" + icon_state = "hair_ponytail3" + +/datum/sprite_accessory/hair/ponytail4 + name = "Ponytail 4" + icon_state = "hair_ponytail4" + +/datum/sprite_accessory/hair/ponytail5 + name = "Ponytail 5" + icon_state = "hair_ponytail5" + +/datum/sprite_accessory/hair/highponytail + name = "Ponytail (High)" + icon_state = "hair_highponytail" + +/datum/sprite_accessory/hair/longponytail + name = "Ponytail (Long)" + icon_state = "hair_longstraightponytail" + +/datum/sprite_accessory/hair/sidetail + name = "Ponytail (Side)" + icon_state = "hair_sidetail" + +/datum/sprite_accessory/hair/sidetail2 + name = "Ponytail (Side) 2" + icon_state = "hair_sidetail2" + +/datum/sprite_accessory/hair/sidetail3 + name = "Ponytail (Side) 3" + icon_state = "hair_sidetail3" + +/datum/sprite_accessory/hair/sidetail4 + name = "Ponytail (Side) 4" + icon_state = "hair_sidetail4" + +/datum/sprite_accessory/hair/quiff + name = "Quiff" + icon_state = "hair_quiff" + +/datum/sprite_accessory/hair/short + name = "Short Hair" + icon_state = "hair_a" + +/datum/sprite_accessory/hair/shorthair2 + name = "Short Hair 2" + icon_state = "hair_shorthair2" + +/datum/sprite_accessory/hair/shorthair3 + name = "Short Hair 3" + icon_state = "hair_shorthair3" + +/datum/sprite_accessory/hair/shoulderlength + name = "Shoulder-length Hair" + icon_state = "hair_b" + +/datum/sprite_accessory/hair/sidecut + name = "Sidecut" + icon_state = "hair_sidecut" + +/datum/sprite_accessory/hair/skinhead + name = "Skinhead" + icon_state = "hair_skinhead" + +/datum/sprite_accessory/hair/protagonist + name = "Slightly Long Hair" + icon_state = "hair_protagonist" + +/datum/sprite_accessory/hair/spiky + name = "Spiky" + icon_state = "hair_spikey" + +/datum/sprite_accessory/hair/spiky2 + name = "Spiky 2" + icon_state = "hair_spiky" + +/datum/sprite_accessory/hair/spiky3 + name = "Spiky 3" + icon_state = "hair_spiky2" + +/datum/sprite_accessory/hair/swept + name = "Swept Back Hair" + icon_state = "hair_swept" + +/datum/sprite_accessory/hair/swept2 + name = "Swept Back Hair 2" + icon_state = "hair_swept2" + +/datum/sprite_accessory/hair/tressshoulder + name = "Tress Shoulder" + icon_state = "hair_tressshoulder" + +/datum/sprite_accessory/hair/longtwintails + name = "Twintails (Long)" + icon_state = "hair_longstraighttwintails" + +/datum/sprite_accessory/hair/updo + name = "Updo" + icon_state = "hair_updo" + +/datum/sprite_accessory/hair/longer + name = "Very Long Hair" + icon_state = "hair_vlong" + +/datum/sprite_accessory/hair/longest + name = "Very Long Hair 2" + icon_state = "hair_longest" + +/datum/sprite_accessory/hair/longest2 + name = "Very Long Over Eye" + icon_state = "hair_longest2" + +/datum/sprite_accessory/hair/longestalt + name = "Very Long with Fringe" + icon_state = "hair_vlongfringe" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/horns.dm b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm new file mode 100644 index 0000000000..607ad650e3 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm @@ -0,0 +1,26 @@ +/datum/sprite_accessory/horns + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/horns/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/horns/simple + name = "Simple" + icon_state = "simple" + +/datum/sprite_accessory/horns/short + name = "Short" + icon_state = "short" + +/datum/sprite_accessory/horns/curled + name = "Curled" + icon_state = "curled" + +/datum/sprite_accessory/horns/ram + name = "Ram" + icon_state = "ram" + +/datum/sprite_accessory/horns/angler + name = "Angeler" + icon_state = "angler" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/legs.dm b/code/modules/mob/dead/new_player/sprite_accessories/legs.dm new file mode 100644 index 0000000000..7663100822 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/legs.dm @@ -0,0 +1,8 @@ +/datum/sprite_accessory/legs //legs are a special case, they aren't actually sprite_accessories but are updated with them. + icon = null //These datums exist for selecting legs on preference, and little else + +/datum/sprite_accessory/legs/none + name = "Normal Legs" + +/datum/sprite_accessory/legs/digitigrade_lizard + name = "Digitigrade Legs" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/moth_wings.dm b/code/modules/mob/dead/new_player/sprite_accessories/moth_wings.dm new file mode 100644 index 0000000000..6b8036bd69 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/moth_wings.dm @@ -0,0 +1,68 @@ +/datum/sprite_accessory/moth_wings + icon = 'icons/mob/wings.dmi' + color_src = null + +/datum/sprite_accessory/moth_wings/plain + name = "Plain" + icon_state = "plain" + +/datum/sprite_accessory/moth_wings/monarch + name = "Monarch" + icon_state = "monarch" + +/datum/sprite_accessory/moth_wings/luna + name = "Luna" + icon_state = "luna" + +/datum/sprite_accessory/moth_wings/atlas + name = "Atlas" + icon_state = "atlas" + +/datum/sprite_accessory/moth_wings/reddish + name = "Reddish" + icon_state = "redish" + +/datum/sprite_accessory/moth_wings/royal + name = "Royal" + icon_state = "royal" + +/datum/sprite_accessory/moth_wings/gothic + name = "Gothic" + icon_state = "gothic" + +/datum/sprite_accessory/moth_wings/lovers + name = "Lovers" + icon_state = "lovers" + +/datum/sprite_accessory/moth_wings/whitefly + name = "White Fly" + icon_state = "whitefly" + +/datum/sprite_accessory/moth_wings/punished + name = "Burnt Off" + icon_state = "punished" + locked = TRUE + +/datum/sprite_accessory/moth_wings/firewatch + name = "Firewatch" + icon_state = "firewatch" + +/datum/sprite_accessory/moth_wings/deathhead + name = "Deathshead" + icon_state = "deathhead" + +/datum/sprite_accessory/moth_wings/poison + name = "Poison" + icon_state = "poison" + +/datum/sprite_accessory/moth_wings/ragged + name = "Ragged" + icon_state = "ragged" + +/datum/sprite_accessory/moth_wings/moonfly + name = "Moon Fly" + icon_state = "moonfly" + +/datum/sprite_accessory/moth_wings/snow + name = "Snow" + icon_state = "snow" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/pines.dm b/code/modules/mob/dead/new_player/sprite_accessories/pines.dm new file mode 100644 index 0000000000..4ccbc3d9ea --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/pines.dm @@ -0,0 +1,53 @@ +/datum/sprite_accessory/spines + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/spines_animated + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/spines/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/spines_animated/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/spines/short + name = "Short" + icon_state = "short" + +/datum/sprite_accessory/spines_animated/short + name = "Short" + icon_state = "short" + +/datum/sprite_accessory/spines/shortmeme + name = "Short + Membrane" + icon_state = "shortmeme" + +/datum/sprite_accessory/spines_animated/shortmeme + name = "Short + Membrane" + icon_state = "shortmeme" + +/datum/sprite_accessory/spines/long + name = "Long" + icon_state = "long" + +/datum/sprite_accessory/spines_animated/long + name = "Long" + icon_state = "long" + +/datum/sprite_accessory/spines/longmeme + name = "Long + Membrane" + icon_state = "longmeme" + +/datum/sprite_accessory/spines_animated/longmeme + name = "Long + Membrane" + icon_state = "longmeme" + +/datum/sprite_accessory/spines/aqautic + name = "Aquatic" + icon_state = "aqua" + +/datum/sprite_accessory/spines_animated/aqautic + name = "Aquatic" + icon_state = "aqua" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm new file mode 100644 index 0000000000..c663c08d69 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm @@ -0,0 +1,18 @@ +/datum/sprite_accessory/snouts + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/snouts/sharp + name = "Sharp" + icon_state = "sharp" + +/datum/sprite_accessory/snouts/round + name = "Round" + icon_state = "round" + +/datum/sprite_accessory/snouts/sharplight + name = "Sharp + Light" + icon_state = "sharplight" + +/datum/sprite_accessory/snouts/roundlight + name = "Round + Light" + icon_state = "roundlight" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/socks.dm b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm new file mode 100644 index 0000000000..5a5d37d4e7 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/socks.dm @@ -0,0 +1,96 @@ +/////////////////////// +// Socks Definitions // +/////////////////////// + +/datum/sprite_accessory/socks + icon = 'icons/mob/underwear.dmi' + +/datum/sprite_accessory/socks/nude + name = "Nude" + icon_state = null + +// please make sure they're sorted alphabetically and categorized + +/datum/sprite_accessory/socks/black_knee + name = "Knee-high (Black)" + icon_state = "black_knee" + +/datum/sprite_accessory/socks/commie_knee + name = "Knee-High (Commie)" + icon_state = "commie_knee" + +/datum/sprite_accessory/socks/usa_knee + name = "Knee-High (Freedom)" + icon_state = "assblastusa_knee" + +/datum/sprite_accessory/socks/rainbow_knee + name = "Knee-high (Rainbow)" + icon_state = "rainbow_knee" + +/datum/sprite_accessory/socks/striped_knee + name = "Knee-high (Striped)" + icon_state = "striped_knee" + +/datum/sprite_accessory/socks/thin_knee + name = "Knee-high (Thin)" + icon_state = "thin_knee" + +/datum/sprite_accessory/socks/uk_knee + name = "Knee-High (UK)" + icon_state = "uk_knee" + +/datum/sprite_accessory/socks/white_knee + name = "Knee-high (White)" + icon_state = "white_knee" + +/datum/sprite_accessory/socks/black_norm + name = "Normal (Black)" + icon_state = "black_norm" + +/datum/sprite_accessory/socks/white_norm + name = "Normal (White)" + icon_state = "white_norm" + +/datum/sprite_accessory/socks/pantyhose + name = "Pantyhose" + icon_state = "pantyhose" + +/datum/sprite_accessory/socks/black_short + name = "Short (Black)" + icon_state = "black_short" + +/datum/sprite_accessory/socks/white_short + name = "Short (White)" + icon_state = "white_short" + +/datum/sprite_accessory/socks/black_thigh + name = "Thigh-high (Black)" + icon_state = "black_thigh" + +/datum/sprite_accessory/socks/commie_thigh + name = "Thigh-high (Commie)" + icon_state = "commie_thigh" + +/datum/sprite_accessory/socks/usa_thigh + name = "Thigh-high (Freedom)" + icon_state = "assblastusa_thigh" + +/datum/sprite_accessory/socks/rainbow_thigh + name = "Thigh-high (Rainbow)" + icon_state = "rainbow_thigh" + +/datum/sprite_accessory/socks/striped_thigh + name = "Thigh-high (Striped)" + icon_state = "striped_thigh" + +/datum/sprite_accessory/socks/thin_thigh + name = "Thigh-high (Thin)" + icon_state = "thin_thigh" + +/datum/sprite_accessory/socks/uk_thigh + name = "Thigh-high (UK)" + icon_state = "uk_thigh" + +/datum/sprite_accessory/socks/white_thigh + name = "Thigh-high (White)" + icon_state = "white_thigh" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm new file mode 100644 index 0000000000..31faabf663 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm @@ -0,0 +1,55 @@ +/datum/sprite_accessory/tails + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/tails_animated + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/tails/lizard/smooth + name = "Smooth" + icon_state = "smooth" + +/datum/sprite_accessory/tails_animated/lizard/smooth + name = "Smooth" + icon_state = "smooth" + +/datum/sprite_accessory/tails/lizard/dtiger + name = "Dark Tiger" + icon_state = "dtiger" + +/datum/sprite_accessory/tails_animated/lizard/dtiger + name = "Dark Tiger" + icon_state = "dtiger" + +/datum/sprite_accessory/tails/lizard/ltiger + name = "Light Tiger" + icon_state = "ltiger" + +/datum/sprite_accessory/tails_animated/lizard/ltiger + name = "Light Tiger" + icon_state = "ltiger" + +/datum/sprite_accessory/tails/lizard/spikes + name = "Spikes" + icon_state = "spikes" + +/datum/sprite_accessory/tails_animated/lizard/spikes + name = "Spikes" + icon_state = "spikes" + +/datum/sprite_accessory/tails/human/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/tails_animated/human/none + name = "None" + icon_state = "none" +/* +/datum/sprite_accessory/tails/human/cat + name = "Cat" + icon_state = "cat" + color_src = HAIR + +/datum/sprite_accessory/tails_animated/human/cat + name = "Cat" + icon_state = "cat" + color_src = HAIR*/ \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm new file mode 100644 index 0000000000..7c66ef51e3 --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm @@ -0,0 +1,308 @@ +//////////////////////////// +// Undershirt Definitions // +//////////////////////////// + +/datum/sprite_accessory/undershirt + icon = 'icons/mob/underwear.dmi' + gender = NEUTER + +/datum/sprite_accessory/undershirt/nude + name = "Nude" + icon_state = null + +// please make sure they're sorted alphabetically and categorized + +/datum/sprite_accessory/undershirt/bluejersey + name = "Shirt, Jersey - Blue" + icon_state = "shirt_bluejersey" + +/datum/sprite_accessory/undershirt/redjersey + name = "Shirt, Jersey - Red" + icon_state = "shirt_redjersey" + +/datum/sprite_accessory/undershirt/bluepolo + name = "Shirt, Polo - Blue" + icon_state = "bluepolo" + +/datum/sprite_accessory/undershirt/grayyellowpolo + name = "Shirt, Polo - Gray, Yellow" + icon_state = "grayyellowpolo" + +/datum/sprite_accessory/undershirt/redpolo + name = "Shirt, Polo - Red" + icon_state = "redpolo" + +/datum/sprite_accessory/undershirt/whitepolo + name = "Shirt, Polo - White" + icon_state = "whitepolo" + +/datum/sprite_accessory/undershirt/alienshirt + name = "Shirt - Alien" + icon_state = "shirt_alien" + +/datum/sprite_accessory/undershirt/mondmondjaja + name = "Shirt - Band" + icon_state = "band" + +/datum/sprite_accessory/undershirt/shirt_black + name = "Shirt - Black" + icon_state = "shirt_black" + +/datum/sprite_accessory/undershirt/blueshirt + name = "Shirt - Blue" + icon_state = "shirt_blue" + +/datum/sprite_accessory/undershirt/clownshirt + name = "Shirt - Clown" + icon_state = "shirt_clown" + +/datum/sprite_accessory/undershirt/commie + name = "Shirt - Commie" + icon_state = "shirt_commie" + +/datum/sprite_accessory/undershirt/greenshirt + name = "Shirt - Green" + icon_state = "shirt_green" + +/datum/sprite_accessory/undershirt/shirt_grey + name = "Shirt - Grey" + icon_state = "shirt_grey" + +/datum/sprite_accessory/undershirt/ian + name = "Shirt - Ian" + icon_state = "ian" + +/datum/sprite_accessory/undershirt/ilovent + name = "Shirt - I Love NT" + icon_state = "ilovent" + +/datum/sprite_accessory/undershirt/lover + name = "Shirt - Lover" + icon_state = "lover" + +/datum/sprite_accessory/undershirt/matroska + name = "Shirt - Matroska" + icon_state = "matroska" + +/datum/sprite_accessory/undershirt/meat + name = "Shirt - Meat" + icon_state = "shirt_meat" + +/datum/sprite_accessory/undershirt/nano + name = "Shirt - Nanotrasen" + icon_state = "shirt_nano" + +/datum/sprite_accessory/undershirt/peace + name = "Shirt - Peace" + icon_state = "peace" + +/datum/sprite_accessory/undershirt/pacman + name = "Shirt - Pogoman" + icon_state = "pogoman" + +/datum/sprite_accessory/undershirt/question + name = "Shirt - Question" + icon_state = "shirt_question" + +/datum/sprite_accessory/undershirt/redshirt + name = "Shirt - Red" + icon_state = "shirt_red" + +/datum/sprite_accessory/undershirt/skull + name = "Shirt - Skull" + icon_state = "shirt_skull" + +/datum/sprite_accessory/undershirt/ss13 + name = "Shirt - SS13" + icon_state = "shirt_ss13" + +/datum/sprite_accessory/undershirt/stripe + name = "Shirt - Striped" + icon_state = "shirt_stripes" + +/datum/sprite_accessory/undershirt/tiedye + name = "Shirt - Tie-dye" + icon_state = "shirt_tiedye" + +/datum/sprite_accessory/undershirt/uk + name = "Shirt - UK" + icon_state = "uk" + +/datum/sprite_accessory/undershirt/usa + name = "Shirt - USA" + icon_state = "shirt_assblastusa" + +/datum/sprite_accessory/undershirt/shirt_white + name = "Shirt - White" + icon_state = "shirt_white" + +/datum/sprite_accessory/undershirt/blackshortsleeve + name = "Shirt, Short Sleeved - Black" + icon_state = "blackshortsleeve" + +/datum/sprite_accessory/undershirt/blueshortsleeve + name = "Shirt, Short Sleeved - Blue" + icon_state = "blueshortsleeve" + +/datum/sprite_accessory/undershirt/greenshortsleeve + name = "Shirt, Short Sleeved - Green" + icon_state = "greenshortsleeve" + +/datum/sprite_accessory/undershirt/purpleshortsleeve + name = "Shirt, Short Sleeved - Purple" + icon_state = "purpleshortsleeve" + +/datum/sprite_accessory/undershirt/whiteshortsleeve + name = "Shirt, Short Sleeved - White" + icon_state = "whiteshortsleeve" + +/datum/sprite_accessory/undershirt/blueshirtsport + name = "Shirt, Sports - Blue" + icon_state = "blueshirtsport" + gender = NEUTER + +/datum/sprite_accessory/undershirt/greenshirtsport + name = "Shirt, Sports - Green" + icon_state = "greenshirtsport" + gender = NEUTER + +/datum/sprite_accessory/undershirt/redshirtsport + name = "Shirt, Sports - Red" + icon_state = "redshirtsport" + gender = NEUTER + +/datum/sprite_accessory/undershirt/redtop + name = "Shirt, Short - Red" + icon_state = "redtop" + +/datum/sprite_accessory/undershirt/whitetop + name = "Shirt, Short - White" + icon_state = "whitetop" + +/datum/sprite_accessory/undershirt/tshirt_blue + name = "T-Shirt - Blue" + icon_state = "blueshirt" + +/datum/sprite_accessory/undershirt/tshirt_green + name = "T-Shirt - Green" + icon_state = "greenshirt" + +/datum/sprite_accessory/undershirt/tshirt_red + name = "T-Shirt - Red" + icon_state = "redshirt" + +/datum/sprite_accessory/undershirt/yellowshirt + name = "T-Shirt - Yellow" + icon_state = "yellowshirt" + +/datum/sprite_accessory/undershirt/tank_black + name = "Tank Top - Black" + icon_state = "tank_black" + +/datum/sprite_accessory/undershirt/tankfire + name = "Tank Top - Fire" + icon_state = "tank_fire" + +/datum/sprite_accessory/undershirt/tank_grey + name = "Tank Top - Grey" + icon_state = "tank_grey" + +/datum/sprite_accessory/undershirt/female_midriff + name = "Tank Top - Midriff" + icon_state = "tank_midriff" + +/datum/sprite_accessory/undershirt/tank_red + name = "Tank Top - Red" + icon_state = "tank_red" + +/datum/sprite_accessory/undershirt/tankstripe + name = "Tank Top - Striped" + icon_state = "tank_stripes" + +/datum/sprite_accessory/undershirt/tank_white + name = "Tank Top - White" + icon_state = "tank_white" + +/datum/sprite_accessory/undershirt/female_red + name = "Bra - Red" + icon_state = "bra_red" + +/datum/sprite_accessory/undershirt/female_pink + name = "Bra - Pink" + icon_state = "bra_pink" + +/datum/sprite_accessory/undershirt/female_kinky + name = "Bra - Kinky Black" + icon_state = "bra_kinky" + +/datum/sprite_accessory/undershirt/female_green + name = "Bra - Green" + icon_state = "bra_green" + +/datum/sprite_accessory/undershirt/female_commie + name = "Bra - Freedom" + icon_state = "bra_assblastusa" + +/datum/sprite_accessory/undershirt/female_commie + name = "Bra - Commie" + icon_state = "bra_commie" + +/datum/sprite_accessory/undershirt/female_babyblue + name = "Bra, Baby Blue" + icon_state = "bra_babyblue" + +/datum/sprite_accessory/undershirt/female_black + name = "Bra - Black" + icon_state = "bra_black" + +/datum/sprite_accessory/undershirt/female_uk + name = "Bra - UK" + icon_state = "bra_uk" + +/datum/sprite_accessory/undershirt/female_white + name = "Bra - White" + icon_state = "bra_white" + +/datum/sprite_accessory/undershirt/female_white_neko + name = "Bra, Neko - white" + icon_state = "bra_neko_white" + +/datum/sprite_accessory/undershirt/female_black_neko + name = "Bra, Neko - Black" + icon_state = "bra_neko_black" + +/datum/sprite_accessory/undershirt/female_blackalt + name = "Bra, Sports - Black" + icon_state = "bra_sports_black" + +/datum/sprite_accessory/undershirt/sports_bra + name = "Bra, Sports 1 - White" + icon_state = "sports_bra" + +/datum/sprite_accessory/undershirt/female_whitealt + name = "Bra, Sports 2 - White" + icon_state = "bra_sports_white" + +/datum/sprite_accessory/undershirt/sports_bra2 + name = "Bra, Sports 3 - White" + icon_state = "sports_bra_alt" + +/datum/sprite_accessory/undershirt/female_yellow + name = "Bra - Yellow" + icon_state = "bra_yellow" + +/datum/sprite_accessory/undershirt/female_thong + name = "Bra, Strapless - Pink" + icon_state = "bra_strapless_pink" + +/datum/sprite_accessory/undershirt/female_blue + name = "Bra, Strapless - Blue" + icon_state = "bra_blue" + +/datum/sprite_accessory/undershirt/swimsuit_green + name = "Swimsuit, Top - Green" + icon_state = "bra_swimming_green" + +/datum/sprite_accessory/undershirt/swimsuit_purple + name = "Swimsuit, Top - Purple" + icon_state = "bra_swimming_purple" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm new file mode 100644 index 0000000000..6beed231aa --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm @@ -0,0 +1,171 @@ +/////////////////////////// +// Underwear Definitions // +/////////////////////////// +/datum/sprite_accessory/underwear + icon = 'icons/mob/underwear.dmi' + gender = NEUTER + +/datum/sprite_accessory/underwear/nude + name = "Nude" + icon_state = null + +/datum/sprite_accessory/underwear/mankini + name = "Mankini - Green" + icon_state = "mankini_green" + +/datum/sprite_accessory/underwear/male_kinky + name = "Jockstrap - White" + icon_state = "jockstrap_white" + +/datum/sprite_accessory/underwear/male_white + name = "Briefs - White" + icon_state = "briefs_white" + +/datum/sprite_accessory/underwear/male_black + name = "Briefs - Black" + icon_state = "briefs_black" + +/datum/sprite_accessory/underwear/male_grey + name = "Briefs - Grey" + icon_state = "briefs_grey" + +/datum/sprite_accessory/underwear/male_red + name = "Briefs - Red" + icon_state = "briefs_red" + +/datum/sprite_accessory/underwear/male_green + name = "Briefs - Green" + icon_state = "briefs_green" + +/datum/sprite_accessory/underwear/male_blue + name = "Briefs - Blue" + icon_state = "briefs_blue" + +/datum/sprite_accessory/underwear/male_blackalt + name = "Boxers - Black" + icon_state = "boxers_black" + +/datum/sprite_accessory/underwear/male_greyalt + name = "Boxers - Grey" + icon_state = "boxers_grey" + +/datum/sprite_accessory/underwear/male_hearts + name = "Boxers - Heart" + icon_state = "boxers_heart" + +/datum/sprite_accessory/underwear/male_stripe + name = "Boxers - Striped" + icon_state = "boxers_striped" + +/datum/sprite_accessory/underwear/male_commie + name = "Boxers - Striped Communist" + icon_state = "boxers_commie" + +/datum/sprite_accessory/underwear/male_usastripe + name = "Boxers - Striped Freedom" + icon_state = "boxers_assblastusa" + +/datum/sprite_accessory/underwear/male_uk + name = "Boxers - Striped UK" + icon_state = "boxers_uk" + + +/datum/sprite_accessory/underwear/female_whitealt + name = "Boxer Briefs - White" + icon_state = "boxer_briefs_white" + +/datum/sprite_accessory/underwear/female_blackalt + name = "Boxer Briefs - Black" + icon_state = "boxer_briefs_black" + +/datum/sprite_accessory/underwear/female_pink + name = "Boxer Briefs - Pink" + icon_state = "boxer_briefs_pink" + +/datum/sprite_accessory/underwear/female_babyblue + name = "Boxer Briefs - Baby Blue" + icon_state = "boxer_briefs_babyblue" + +/datum/sprite_accessory/underwear/female_yellow + name = "Boxer Briefs - Yellow" + icon_state = "boxer_briefs_yellow" + + +/datum/sprite_accessory/underwear/female_black + name = "Panties - Black" + icon_state = "panties_black" + +/datum/sprite_accessory/underwear/female_blue + name = "Panties - Blue" + icon_state = "panties_blue" + +/datum/sprite_accessory/underwear/female_commie + name = "Panties - Commie" + icon_state = "panties_commie" + +/datum/sprite_accessory/underwear/female_usastripe + name = "Panties - Freedom" + icon_state = "panties_assblastusa" + +/datum/sprite_accessory/underwear/female_green + name = "Panties - Green" + icon_state = "panties_green" + +/datum/sprite_accessory/underwear/female_kinky + name = "Panties - Kinky Black" + icon_state = "panties_kinky" + +/datum/sprite_accessory/underwear/female_red + name = "Panties - Red" + icon_state = "panties_red" + +/datum/sprite_accessory/underwear/female_uk + name = "Panties - UK" + icon_state = "panties_uk" + +/datum/sprite_accessory/underwear/female_white + name = "Panties - White" + icon_state = "panties_white" + +/datum/sprite_accessory/underwear/female_white_neko + name = "Panties, Neko - White" + icon_state = "panties_neko_white" + +/datum/sprite_accessory/underwear/female_black_neko + name = "Panties, Neko - Black" + icon_state = "panties_neko_black" + + +/datum/sprite_accessory/underwear/swimsuit_red + name = "Swimsuit, One Piece - Red" + icon_state = "swimming_red" + +/datum/sprite_accessory/underwear/swimsuit + name = "Swimsuit, One Piece - Black" + icon_state = "swimming_black" + +/datum/sprite_accessory/underwear/swimsuit_blue + name = "Swimsuit, One Piece - Striped Blue" + icon_state = "swimming_blue" + +/datum/sprite_accessory/underwear/swimsuit_green + name = "Swimsuit, Bottom - Green" + icon_state = "panties_swimming_green" + +/datum/sprite_accessory/underwear/swimsuit_purple + name = "Swimsuit, Bottom - Purple" + icon_state = "panties_swimming_purple" + +/datum/sprite_accessory/underwear/female_thong_black + name = "Thong - Black" + icon_state = "thong_black" + +/datum/sprite_accessory/underwear/female_thong + name = "Thong - Pink" + icon_state = "thong_pink" + +/datum/sprite_accessory/underwear/female_babydoll + name = "Babydoll - Black" + icon_state = "babydoll" + + diff --git a/code/modules/mob/dead/new_player/sprite_accessories/wings.dm b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm new file mode 100644 index 0000000000..d051b2f07a --- /dev/null +++ b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm @@ -0,0 +1,26 @@ +/datum/sprite_accessory/wings/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/wings_open + icon = 'icons/mob/wings.dmi' + +/datum/sprite_accessory/wings_open/angel + name = "Angel" + icon_state = "angel" + color_src = 0 + dimension_x = 46 + center = TRUE + dimension_y = 34 + +/datum/sprite_accessory/wings + icon = 'icons/mob/wings.dmi' + +/datum/sprite_accessory/wings/angel + name = "Angel" + icon_state = "angel" + color_src = 0 + dimension_x = 46 + center = TRUE + dimension_y = 34 + locked = TRUE \ No newline at end of file diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 71a12e9ff4..815184c63d 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -16,7 +16,7 @@ /mob/living/carbon/monkey/handle_blood() - if(bodytemperature >= TCRYO && !(has_trait(TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood. + if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood. //Blood regeneration if there is some space if(blood_volume < BLOOD_VOLUME_NORMAL) blood_volume += 0.1 // regenerate blood VERY slowly @@ -30,10 +30,10 @@ bleed_rate = 0 return - if(bodytemperature >= TCRYO && !(has_trait(TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood. + if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood. //Blood regeneration if there is some space - if(blood_volume < BLOOD_VOLUME_NORMAL && !has_trait(TRAIT_NOHUNGER)) + if(blood_volume < BLOOD_VOLUME_NORMAL && !HAS_TRAIT(src, TRAIT_NOHUNGER)) var/nutrition_ratio = 0 switch(nutrition) if(0 to NUTRITION_LEVEL_STARVING) @@ -69,7 +69,7 @@ Unconscious(rand(20,60)) to_chat(src, "You feel extremely [word].") if(-INFINITY to BLOOD_VOLUME_SURVIVE) - if(!has_trait(TRAIT_NODEATH)) + if(!HAS_TRAIT(src, TRAIT_NODEATH)) death() var/temp_bleed = 0 @@ -87,7 +87,7 @@ bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases - if(bleed_rate && !bleedsuppress && !(has_trait(TRAIT_FAKEDEATH))) + if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH))) bleed(bleed_rate) //Makes a blood drop, leaking amt units of blood from the mob @@ -214,13 +214,13 @@ return "blood" /mob/living/carbon/monkey/get_blood_id() - if(!(has_trait(TRAIT_NOCLONE))) + if(!(HAS_TRAIT(src, TRAIT_NOCLONE))) return "blood" /mob/living/carbon/human/get_blood_id() if(dna.species.exotic_blood) return dna.species.exotic_blood - else if((NOBLOOD in dna.species.species_traits) || (has_trait(TRAIT_NOCLONE))) + else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE))) return return "blood" diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 2f3ee10428..2ced3054c4 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -21,7 +21,7 @@ name = "brain" if(C.mind && C.mind.has_antag_datum(/datum/antagonist/changeling) && !no_id_transfer) //congrats, you're trapped in a body you don't control - if(brainmob && !(C.stat == DEAD || (C.has_trait(TRAIT_DEATHCOMA)))) + if(brainmob && !(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_DEATHCOMA)))) to_chat(brainmob, "You can't feel your body! You're still just a brain!") forceMove(C) C.update_hair() @@ -64,7 +64,7 @@ name = "[L.name]'s brain" if(brainmob) return - + if(!L.mind) return brainmob = new(src) @@ -76,7 +76,7 @@ if(!brainmob.stored_dna) brainmob.stored_dna = new /datum/dna/stored(brainmob) C.dna.copy_dna(brainmob.stored_dna) - if(L.has_trait(TRAIT_NOCLONE)) + if(HAS_TRAIT(L, TRAIT_NOCLONE)) brainmob.status_traits[TRAIT_NOCLONE] = L.status_traits[TRAIT_NOCLONE] var/obj/item/organ/zombie_infection/ZI = L.getorganslot(ORGAN_SLOT_ZOMBIE) if(ZI) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 10fddfcb20..c8ece3f656 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -105,7 +105,7 @@ Des: Gives the client of the alien an image on each infected mob. if (client) for (var/i in GLOB.mob_living_list) var/mob/living/L = i - if(L.has_trait(TRAIT_XENO_HOST)) + if(HAS_TRAIT(L, TRAIT_XENO_HOST)) var/obj/item/organ/body_egg/alien_embryo/A = L.getorgan(/obj/item/organ/body_egg/alien_embryo) if(A) var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[A.stage]") diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 383edd566a..01a52b3b80 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -18,7 +18,7 @@ if(health<= -maxHealth || !getorgan(/obj/item/organ/brain)) death() return - if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (has_trait(TRAIT_DEATHCOMA)) || health <= crit_threshold) + if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || health <= crit_threshold) if(stat == CONSCIOUS) stat = UNCONSCIOUS blind_eyes(1) diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 543fda9fd0..b8edd34ee9 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -15,25 +15,23 @@ var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/list/breath_gases = breath.gases - breath.assert_gases(/datum/gas/plasma, /datum/gas/oxygen) - //Partial pressure of the toxins in our breath - var/Toxins_pp = (breath_gases[/datum/gas/plasma][MOLES]/breath.total_moles())*breath_pressure + var/Toxins_pp = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure if(Toxins_pp > tox_detect_threshold) // Detect toxins in air - adjustPlasma(breath_gases[/datum/gas/plasma][MOLES]*250) + adjustPlasma(breath_gases[/datum/gas/plasma]*250) throw_alert("alien_tox", /obj/screen/alert/alien_tox) - toxins_used = breath_gases[/datum/gas/plasma][MOLES] + toxins_used = breath_gases[/datum/gas/plasma] else clear_alert("alien_tox") //Breathe in toxins and out oxygen - breath_gases[/datum/gas/plasma][MOLES] -= toxins_used - breath_gases[/datum/gas/oxygen][MOLES] += toxins_used + breath_gases[/datum/gas/plasma] -= toxins_used + breath_gases[/datum/gas/oxygen] += toxins_used - breath.garbage_collect() + GAS_GARBAGE_COLLECT(breath.gases) //BREATH TEMPERATURE handle_breath_temperature(breath) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index ea13255dfe..fb09de7ec2 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -167,7 +167,7 @@ if(!throwable_mob.buckled) thrown_thing = throwable_mob stop_pulling() - if(has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(src, TRAIT_PACIFISM)) to_chat(src, "You gently let go of [throwable_mob].") adjustStaminaLossBuffered(25)//CIT CHANGE - throwing an entire person shall be very tiring var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors @@ -179,7 +179,7 @@ thrown_thing = I dropItemToGround(I) - if(has_trait(TRAIT_PACIFISM) && I.throwforce) + if(HAS_TRAIT(src, TRAIT_PACIFISM) && I.throwforce) to_chat(src, "You set [I] down gently on the ground.") return @@ -416,7 +416,7 @@ var/modifier = 0 - if(has_trait(TRAIT_CLUMSY)) + if(HAS_TRAIT(src, TRAIT_CLUMSY)) modifier -= 40 //Clumsy people are more likely to hit themselves -Honk! //CIT CHANGES START HERE @@ -462,7 +462,7 @@ return ..() /mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, toxic = FALSE) - if(has_trait(TRAIT_NOHUNGER)) + if(HAS_TRAIT(src, TRAIT_NOHUNGER)) return 1 if(nutrition < 100 && !blood) @@ -759,14 +759,14 @@ if(status_flags & GODMODE) return if(stat != DEAD) - if(health <= HEALTH_THRESHOLD_DEAD && !has_trait(TRAIT_NODEATH)) + if(health <= HEALTH_THRESHOLD_DEAD && !HAS_TRAIT(src, TRAIT_NODEATH)) death() return - if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (has_trait(TRAIT_DEATHCOMA)) || (health <= HEALTH_THRESHOLD_FULLCRIT && !has_trait(TRAIT_NOHARDCRIT))) + if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || (health <= HEALTH_THRESHOLD_FULLCRIT && !HAS_TRAIT(src, TRAIT_NOHARDCRIT))) stat = UNCONSCIOUS blind_eyes(1) else - if(health <= crit_threshold && !has_trait(TRAIT_NOSOFTCRIT)) + if(health <= crit_threshold && !HAS_TRAIT(src, TRAIT_NOSOFTCRIT)) stat = SOFT_CRIT else stat = CONSCIOUS diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index d8bb90460a..e96bb7f121 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -224,7 +224,7 @@ /mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE) if(tesla_shock && (flags_1 & TESLA_IGNORE_1)) return FALSE - if(has_trait(TRAIT_SHOCKIMMUNE)) + if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE)) return FALSE shock_damage *= siemens_coeff if(dna && dna.species) @@ -261,7 +261,7 @@ to_chat(M, "You can't put [p_them()] out with just your bare hands!") return - if(health >= 0 && !(has_trait(TRAIT_FAKEDEATH))) + if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH))) if(lying) if(buckled) @@ -277,6 +277,12 @@ M.visible_message("[M] gives [H] a pat on the head to make [p_them()] feel better!", \ "You give [H] a pat on the head to make [p_them()] feel better!") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat) + if(HAS_TRAIT(M, TRAIT_FRIENDLY)) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if (mood.sanity >= SANITY_GREAT) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M) + else if (mood.sanity >= SANITY_DISTURBED) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/betterhug, M) if(H.dna.species.can_wag_tail(H)) if("tail_human" in pref_species.default_features) if(H.dna.features["tail_human"] == "None") @@ -306,6 +312,12 @@ M.visible_message("[M] hugs [src] to make [p_them()] feel better!", \ "You hug [src] to make [p_them()] feel better!") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug) + if(HAS_TRAIT(M, TRAIT_FRIENDLY)) + GET_COMPONENT_FROM(mood, /datum/component/mood, M) + if (mood.sanity >= SANITY_GREAT) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M) + else if (mood.sanity >= SANITY_DISTURBED) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/betterhug, M) AdjustStun(-60) AdjustKnockdown(-60) @@ -350,12 +362,12 @@ if(eyes.eye_damage > 20) if(prob(eyes.eye_damage - 20)) - if(!has_trait(TRAIT_NEARSIGHT)) + if(!HAS_TRAIT(src, TRAIT_NEARSIGHT)) to_chat(src, "Your eyes start to burn badly!") become_nearsighted(EYE_DAMAGE) else if(prob(eyes.eye_damage - 25)) - if(!has_trait(TRAIT_BLIND)) + if(!HAS_TRAIT(src, TRAIT_BLIND)) to_chat(src, "You can't see anything!") become_blind(EYE_DAMAGE) diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm index 37b888a6b8..8e6c888c40 100644 --- a/code/modules/mob/living/carbon/carbon_movement.dm +++ b/code/modules/mob/living/carbon/carbon_movement.dm @@ -37,7 +37,7 @@ /mob/living/carbon/Move(NewLoc, direct) . = ..() if(. && mob_has_gravity()) //floating is easy - if(has_trait(TRAIT_NOHUNGER)) + if(HAS_TRAIT(src, TRAIT_NOHUNGER)) nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous else if(nutrition && stat != DEAD) nutrition -= HUNGER_FACTOR/10 diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index c21f9ce213..749ae3b5b0 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -83,7 +83,7 @@ return amount /mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) - if(!forced && has_trait(TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage + if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage amount = -amount if(amount > 0) blood_volume -= 5*amount diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index c42bd82797..22da46346c 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -67,7 +67,7 @@ else msg += "[t_He] [t_is] severely deformed!\n" - if(has_trait(TRAIT_DUMB)) + if(HAS_TRAIT(src, TRAIT_DUMB)) msg += "[t_He] seem[p_s()] to be clumsy and unable to think.\n" if(fire_stacks > 0) @@ -88,7 +88,7 @@ if(digitalcamo) msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner.\n" - + if(combatmode) msg += "[t_He] [t_is] visibly tense[resting ? "." : ", and [t_is] standing in combative stance."]\n" diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 0b4d5f6098..64b75bc801 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -42,13 +42,13 @@ INVOKE_ASYNC(is_devil(src), /datum/antagonist/devil.proc/beginResurrectionCheck, src) /mob/living/carbon/human/proc/makeSkeleton() - add_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC) set_species(/datum/species/skeleton) return 1 /mob/living/carbon/proc/Drain() become_husk(CHANGELING_DRAIN) - add_trait(TRAIT_NOCLONE, CHANGELING_DRAIN) + ADD_TRAIT(src, TRAIT_NOCLONE, CHANGELING_DRAIN) blood_volume = 0 return 1 diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 950ac5fb8b..d1d5fb7cd4 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -39,6 +39,19 @@ restraint_check = TRUE emote_type = EMOTE_AUDIBLE +/datum/emote/living/carbon/human/mawp + key = "mawp" + key_third_person = "mawps" + message = "mawps annoyingly." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/carbon/human/mawp/run_emote(mob/living/user, params) + . = ..() + if(.) + if(ishuman(user)) + if(prob(10)) + user.adjustEarDamage(-5, -5) + /datum/emote/living/carbon/human/mumble key = "mumble" key_third_person = "mumbles" diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index c6ba900b13..d814893053 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -10,7 +10,7 @@ if(isliving(user)) var/mob/living/L = user - if(L.has_trait(TRAIT_PROSOPAGNOSIA)) + if(HAS_TRAIT(L, TRAIT_PROSOPAGNOSIA)) obscure_name = TRUE var/msg = "*---------*\nThis is [!obscure_name ? name : "Unknown"]!\n" @@ -18,6 +18,16 @@ var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) + if(ishuman(src)) //user just returned, y'know, the user's own species. dumb. + var/mob/living/carbon/human/H = src + var/datum/species/pref_species = H.dna.species + if(get_visible_name() == "Unknown") // same as flavor text, but hey it works. + msg += "You can't make out what species they are.\n" + else if(skipface) + msg += "You can't make out what species they are.\n" + else + msg += "[t_He] [t_is] a [H.dna.custom_species ? H.dna.custom_species : pref_species.name]!\n" + //uniform if(w_uniform && !(SLOT_W_UNIFORM in obscured)) //accessory @@ -83,7 +93,7 @@ if(!(SLOT_GLASSES in obscured)) if(glasses) msg += "[t_He] [t_has] [glasses.get_examine_string(user)] covering [t_his] eyes.\n" - else if(eye_color == BLOODCULT_EYE && iscultist(src) && has_trait(CULT_EYES)) + else if(eye_color == BLOODCULT_EYE && iscultist(src) && HAS_TRAIT(src, TRAIT_CULT_EYES)) msg += "[t_His] eyes are glowing an unnatural red!\n" //ears @@ -116,7 +126,7 @@ msg += "[t_He] [t_is] twitching ever so slightly.\n" var/appears_dead = 0 - if(stat == DEAD || (has_trait(TRAIT_FAKEDEATH))) + if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) appears_dead = 1 if(suiciding) msg += "[t_He] appear[p_s()] to have committed suicide... there is no hope of recovery.\n" @@ -271,13 +281,34 @@ if(91.01 to INFINITY) msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n" + if(isliving(user)) + var/mob/living/L = user + if(src != user && HAS_TRAIT(L, TRAIT_EMPATH) && !appears_dead) + if (a_intent != INTENT_HELP) + msg += "[t_He] seem[p_s()] to be on guard.\n" + if (getOxyLoss() >= 10) + msg += "[t_He] seem[p_s()] winded.\n" + if (getToxLoss() >= 10) + msg += "[t_He] seem[p_s()] sickly.\n" + GET_COMPONENT_FROM(mood, /datum/component/mood, src) + if(mood.sanity <= SANITY_DISTURBED) + msg += "[t_He] seem[p_s()] distressed.\n" + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empath", /datum/mood_event/sad_empath, src) + if(mood.mood >= 5) //So roundstart people aren't all "happy" + msg += "[t_He] seem[p_s()] to have had something nice happen to them recently.\n" + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empathH", /datum/mood_event/happy_empath, src) + if (HAS_TRAIT(src, TRAIT_BLIND)) + msg += "[t_He] appear[p_s()] to be staring off into space.\n" + if (HAS_TRAIT(src, TRAIT_DEAF)) + msg += "[t_He] appear[p_s()] to not be responding to noises.\n" + msg += "" if(!appears_dead) if(stat == UNCONSCIOUS) msg += "[t_He] [t_is]n't responding to anything around [t_him] and seem[p_s()] to be asleep.\n" else - if(has_trait(TRAIT_DUMB)) + if(HAS_TRAIT(src, TRAIT_DUMB)) msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" if(InCritical()) msg += "[t_He] [t_is] barely conscious.\n" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 49d2722323..0f962d7b0f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -260,7 +260,7 @@ else return - if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator)) //placing an item into the pocket is 4 times faster + if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator, ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster if(pocket_item) if(pocket_item == (pocket_id == SLOT_R_STORE ? r_store : l_store)) //item still in the pocket we search dropItemToGround(pocket_item) @@ -499,7 +499,7 @@ . = 1 // Default to returning true. if(user && !target_zone) target_zone = user.zone_selected - if(has_trait(TRAIT_PIERCEIMMUNE) && !bypass_immunity) + if(HAS_TRAIT(src, TRAIT_PIERCEIMMUNE) && !bypass_immunity) . = 0 // If targeting the head, see if the head item is thin enough. // If targeting anything else, see if the wear suit is thin enough. @@ -604,7 +604,7 @@ threatcount += 4 //fuk u antags <3 //no you //mindshield implants imply trustworthyness - if(has_trait(TRAIT_MINDSHIELD)) + if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) threatcount -= 1 //Agent cards lower threatlevel. @@ -640,7 +640,7 @@ /mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C) CHECK_DNA_AND_SPECIES(C) - if(C.stat == DEAD || (C.has_trait(TRAIT_FAKEDEATH))) + if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH))) to_chat(src, "[C.name] is dead!") return if(is_mouth_covered()) @@ -657,7 +657,7 @@ to_chat(src, "You fail to perform CPR on [C]!") return 0 - var/they_breathe = !C.has_trait(TRAIT_NOBREATH) + var/they_breathe = !HAS_TRAIT(C, TRAIT_NOBREATH) var/they_lung = C.getorganslot(ORGAN_SLOT_LUNGS) if(C.health > C.crit_threshold) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index b66ebdb001..2a75119841 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -138,7 +138,7 @@ else if(I) if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD) if(can_embed(I)) - if(prob(I.embedding.embed_chance) && !has_trait(TRAIT_PIERCEIMMUNE)) + if(prob(I.embedding.embed_chance) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE)) throw_alert("embeddedobject", /obj/screen/alert/embeddedobject) var/obj/item/bodypart/L = pick(bodyparts) L.embedded_objects |= I @@ -153,7 +153,7 @@ return ..() /mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0) - if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (has_trait(TRAIT_FAT)) && ismonkey(pulling)) + if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (HAS_TRAIT(src, TRAIT_FAT)) && ismonkey(pulling)) devour_mob(pulling) else ..() @@ -256,7 +256,7 @@ var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor_block = run_armor_check(affecting, "melee","","",10) + var/armor_block = run_armor_check(affecting, "melee", null, null,10) playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) visible_message("[M] has slashed at [src]!", \ @@ -614,7 +614,7 @@ facial_hair_style = "Shaved" hair_style = "Bald" update_hair() - add_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC) update_damage_overlays() @@ -668,7 +668,7 @@ if(prob(30)) burndamage += rand(30,40) - if(has_trait(TRAIT_SELF_AWARE)) + if(HAS_TRAIT(src, TRAIT_SELF_AWARE)) status = "[brutedamage] brute damage and [burndamage] burn damage" if(!brutedamage && !burndamage) status = "no damage" @@ -695,7 +695,7 @@ var/no_damage if(status == "OK" || status == "no damage") no_damage = TRUE - to_chat(src, "\t Your [LB.name] [has_trait(TRAIT_SELF_AWARE) ? "has" : "is"] [status].") + to_chat(src, "\t Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].") for(var/obj/item/I in LB.embedded_objects) to_chat(src, "\t There is \a [I] embedded in your [LB.name]!") @@ -710,7 +710,7 @@ to_chat(src, "You're completely exhausted.") else to_chat(src, "You feel fatigued.") - if(has_trait(TRAIT_SELF_AWARE)) + if(HAS_TRAIT(src, TRAIT_SELF_AWARE)) if(toxloss) if(toxloss > 10) to_chat(src, "You feel sick.") diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 4f168d97fc..d1ec7f3e4b 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -47,6 +47,8 @@ var/nameless = FALSE //For drones of both the insectoid and robotic kind. And other types of nameless critters. + var/custom_species = null + var/datum/personal_crafting/handcrafting var/datum/physiology/physiology diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index dd37563f8f..0b40d3d26a 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -56,7 +56,7 @@ if( head && (head.flags_inv&HIDEFACE) ) return if_no_face //Likewise for hats var/obj/item/bodypart/O = get_bodypart(BODY_ZONE_HEAD) - if( !O || (has_trait(TRAIT_DISFIGURED)) || (O.brutestate+O.burnstate)>2 || cloneloss>50 || !real_name || nameless) //disfigured. use id-name if possible + if( !O || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (O.brutestate+O.burnstate)>2 || cloneloss>50 || !real_name || nameless) //disfigured. use id-name if possible return if_no_face return real_name @@ -92,7 +92,7 @@ /mob/living/carbon/human/IsAdvancedToolUser() - if(has_trait(TRAIT_MONKEYLIKE)) + if(HAS_TRAIT(src, TRAIT_MONKEYLIKE)) return FALSE return TRUE//Humans can use guns and such @@ -138,7 +138,7 @@ if(src.dna.check_mutation(HULK)) to_chat(src, "Your meaty finger is much too large for the trigger guard!") return FALSE - if(has_trait(TRAIT_NOGUNS)) + if(HAS_TRAIT(src, TRAIT_NOGUNS)) to_chat(src, "Your fingers don't fit in the trigger guard!") return FALSE if(mind) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 1addb3615c..6ea9c985e2 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -1,7 +1,7 @@ /mob/living/carbon/human/get_movespeed_modifiers() var/list/considering = ..() . = considering - if(has_trait(TRAIT_IGNORESLOWDOWN)) + if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN)) for(var/id in .) var/list/data = .[id] if(data[MOVESPEED_DATA_INDEX_FLAGS] & IGNORE_NOSLOW) @@ -13,10 +13,10 @@ . += dna.species.movement_delay(src) /mob/living/carbon/human/slip(knockdown_amount, obj/O, lube) - if(has_trait(TRAIT_NOSLIPALL)) + if(HAS_TRAIT(src, TRAIT_NOSLIPALL)) return 0 if (!(lube&GALOSHES_DONT_HELP)) - if(has_trait(TRAIT_NOSLIPWATER)) + if(HAS_TRAIT(src, TRAIT_NOSLIPWATER)) return 0 if(shoes && istype(shoes, /obj/item/clothing)) var/obj/item/clothing/CS = shoes diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 7e2545f93e..176d967d52 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -187,7 +187,7 @@ if(G.tint) update_tint() if(G.vision_correction) - if(has_trait(TRAIT_NEARSIGHT)) + if(HAS_TRAIT(src, TRAIT_NEARSIGHT)) overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1) adjust_eye_damage(0) if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index a50fb4fe79..1af9dbc5f5 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -63,7 +63,7 @@ /mob/living/carbon/human/handle_traits() if(eye_blind) //blindness, heals slowly over time - if(has_trait(TRAIT_BLIND, EYES_COVERED)) //covering your eyes heals blurry eyes faster + if(HAS_TRAIT_FROM(src, TRAIT_BLIND, EYES_COVERED)) //covering your eyes heals blurry eyes faster adjust_blindness(-3) else adjust_blindness(-1) @@ -95,7 +95,7 @@ if(!L) if(health >= crit_threshold) adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1) - else if(!has_trait(TRAIT_NOCRITDAMAGE)) + else if(!HAS_TRAIT(src, TRAIT_NOCRITDAMAGE)) adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS) failed_last_breath = 1 @@ -332,7 +332,7 @@ HM.on_life(src) /mob/living/carbon/human/proc/handle_heart() - var/we_breath = !has_trait(TRAIT_NOBREATH, SPECIES_TRAIT) + var/we_breath = !HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT) if(!undergoing_cardiac_arrest()) return diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 3cdaf71e68..673249b186 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,9 +1,14 @@ /mob/living/carbon/human/say_mod(input, message_mode) verb_say = dna.species.say_mod - if(slurring) - return "slurs" - else - . = ..() + switch(slurring) + if(10 to 25) + return "jumbles" + if(25 to 50) + return "slurs" + if(50 to INFINITY) + return "garbles" + else + . = ..() /mob/living/carbon/human/treat_message(message) message = dna.species.handle_speech(message,src) @@ -49,7 +54,7 @@ /mob/living/carbon/human/IsVocal() // how do species that don't breathe talk? magic, that's what. - if(!has_trait(TRAIT_NOBREATH, SPECIES_TRAIT) && !getorganslot(ORGAN_SLOT_LUNGS)) + if(!HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT) && !getorganslot(ORGAN_SLOT_LUNGS)) return FALSE if(mind) return !mind.miming diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index ba1ad9e0da..458a319ecd 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -286,7 +286,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) C.put_in_hands(new mutanthands()) for(var/X in inherent_traits) - C.add_trait(X, SPECIES_TRAIT) + ADD_TRAIT(C, X, SPECIES_TRAIT) if(TRAIT_VIRUSIMMUNE in inherent_traits) for(var/datum/disease/A in C.diseases) @@ -300,6 +300,11 @@ GLOBAL_LIST_EMPTY(roundstart_races) else if(C.client) C.canbearoused = C.client.prefs.arousable + if(ishuman(C)) + var/mob/living/carbon/human/H = C + if(NOGENITALS in H.dna.species.species_traits) + H.give_genitals(TRUE) //call the clean up proc to delete anything on the mob then return. + // EDIT ENDS /datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) @@ -308,7 +313,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(DIGITIGRADE in species_traits) C.Digitigrade_Leg_Swap(TRUE) for(var/X in inherent_traits) - C.remove_trait(X, SPECIES_TRAIT) + REMOVE_TRAIT(C, X, SPECIES_TRAIT) SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src) @@ -317,7 +322,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) if(!HD) //Decapitated return - if(H.has_trait(TRAIT_HUSK)) + if(HAS_TRAIT(H, TRAIT_HUSK)) return var/datum/sprite_accessory/S @@ -457,7 +462,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) - if(HD && !(H.has_trait(TRAIT_HUSK))) + if(HD && !(HAS_TRAIT(H, TRAIT_HUSK))) // lipstick if(H.lip_style && (LIPS in species_traits)) var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER) @@ -752,9 +757,11 @@ GLOBAL_LIST_EMPTY(roundstart_races) for(var/index=1, index<=colorlist.len, index++) colorlist[index] = colorlist[index]/255 - if(!(H.has_trait(TRAIT_HUSK))) + if(!HAS_TRAIT(H, TRAIT_HUSK)) if(!forced_colour) switch(S.color_src) + if(SKINTONE) + accessory_overlay.color = "#[skintone2hex(H.skin_tone)]" if(MUTCOLORS) if(fixed_mut_color) accessory_overlay.color = "#[fixed_mut_color]" @@ -909,11 +916,11 @@ GLOBAL_LIST_EMPTY(roundstart_races) /datum/species/proc/spec_life(mob/living/carbon/human/H) - if(H.has_trait(TRAIT_NOBREATH)) + if(HAS_TRAIT(H, TRAIT_NOBREATH)) H.setOxyLoss(0) H.losebreath = 0 - var/takes_crit_damage = (!H.has_trait(TRAIT_NOCRITDAMAGE)) + var/takes_crit_damage = !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE) if((H.health < H.crit_threshold) && takes_crit_damage) H.adjustBruteLoss(1) @@ -1151,21 +1158,21 @@ GLOBAL_LIST_EMPTY(roundstart_races) /datum/species/proc/handle_digestion(mob/living/carbon/human/H) //The fucking TRAIT_FAT mutation is the dumbest shit ever. It makes the code so difficult to work with - if(H.has_trait(TRAIT_FAT))//I share your pain, past coder. + if(HAS_TRAIT(H, TRAIT_FAT))//I share your pain, past coder. if(H.overeatduration < 100) to_chat(H, "You feel fit again!") - H.remove_trait(TRAIT_FAT, OBESITY) + REMOVE_TRAIT(H, TRAIT_FAT, OBESITY) H.update_inv_w_uniform() H.update_inv_wear_suit() else if(H.overeatduration >= 100) to_chat(H, "You suddenly feel blubbery!") - H.add_trait(TRAIT_FAT, OBESITY) + ADD_TRAIT(H, TRAIT_FAT, OBESITY) H.update_inv_w_uniform() H.update_inv_wear_suit() // nutrition decrease and satiety - if (H.nutrition > 0 && H.stat != DEAD && !H.has_trait(TRAIT_NOHUNGER)) + if (H.nutrition > 0 && H.stat != DEAD && !HAS_TRAIT(H, TRAIT_NOHUNGER)) // THEY HUNGER var/hunger_rate = HUNGER_FACTOR GET_COMPONENT_FROM(mood, /datum/component/mood, H) @@ -1194,7 +1201,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(H.nutrition > NUTRITION_LEVEL_FAT) H.metabolism_efficiency = 1 else if(H.nutrition > NUTRITION_LEVEL_FED && H.satiety > 80) - if(H.metabolism_efficiency != 1.25 && !H.has_trait(TRAIT_NOHUNGER)) + if(H.metabolism_efficiency != 1.25 && !HAS_TRAIT(H, TRAIT_NOHUNGER)) to_chat(H, "You feel vigorous.") H.metabolism_efficiency = 1.25 else if(H.nutrition < NUTRITION_LEVEL_STARVING + 50) @@ -1223,7 +1230,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) . = FALSE var/radiation = H.radiation - if(H.has_trait(TRAIT_RADIMMUNE)) + if(HAS_TRAIT(H, TRAIT_RADIMMUNE)) radiation = 0 return TRUE @@ -1270,17 +1277,17 @@ GLOBAL_LIST_EMPTY(roundstart_races) gravity = H.has_gravity() if(gravity && !flight) //Check for chemicals and innate speedups and slowdowns if we're on the ground - if(H.has_trait(TRAIT_GOTTAGOFAST)) + if(HAS_TRAIT(H, TRAIT_GOTTAGOFAST)) . -= 1 - if(H.has_trait(TRAIT_GOTTAGOREALLYFAST)) + if(HAS_TRAIT(H, TRAIT_GOTTAGOREALLYFAST)) . -= 2 . += speedmod . += H.physiology.speed_mod - if (H.m_intent == MOVE_INTENT_WALK && H.has_trait(TRAIT_SPEEDY_STEP)) + if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP)) . -= 1 - if(H.has_trait(TRAIT_IGNORESLOWDOWN)) + if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN)) ignoreslow = 1 if(!gravity) @@ -1331,9 +1338,9 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(SANITY_UNSTABLE to SANITY_DISTURBED) . += 0.5 - if(H.has_trait(TRAIT_FAT)) + if(HAS_TRAIT(H, TRAIT_FAT)) . += (1.5 - flight) - if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !H.has_trait(TRAIT_RESISTCOLD)) + if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD)) . += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR return . @@ -1346,13 +1353,13 @@ GLOBAL_LIST_EMPTY(roundstart_races) ////////////////// /datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) - if(target.health >= 0 && !(target.has_trait(TRAIT_FAKEDEATH))) + if(target.health >= 0 && !HAS_TRAIT(target, TRAIT_FAKEDEATH)) target.help_shake_act(user) if(target != user) log_combat(user, target, "shaked") return 1 else - var/we_breathe = !user.has_trait(TRAIT_NOBREATH) + var/we_breathe = !HAS_TRAIT(user, TRAIT_NOBREATH) var/we_lung = user.getorganslot(ORGAN_SLOT_LUNGS) if(we_breathe && we_lung) @@ -1377,7 +1384,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) /datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) - if(user.has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to harm [target]!") return FALSE if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) //CITADEL CHANGE - makes it impossible to punch while in stamina softcrit @@ -1449,25 +1456,65 @@ GLOBAL_LIST_EMPTY(roundstart_races) target.forcesay(GLOB.hit_appends) /datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) - // CITADEL EDIT slap mouthy gits - var/aim_for_mouth = user.zone_selected == "mouth" - var/target_on_help_and_unarmed = target.a_intent == INTENT_HELP && !target.get_active_held_item() + // CITADEL EDIT slap mouthy gits and booty + var/aim_for_mouth = user.zone_selected == "mouth" + var/target_on_help = target.a_intent == INTENT_HELP var/target_aiming_for_mouth = target.zone_selected == "mouth" var/target_restrained = target.restrained() - if(aim_for_mouth && ( target_on_help_and_unarmed || target_restrained || target_aiming_for_mouth)) - playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1) - user.visible_message("[user] slaps [target] in the face!", - "You slap [target] in the face! ",\ - "You hear a slap.") - stop_wagging_tail(target) - return FALSE - else if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) - to_chat(user, "You're too exhausted.") - return FALSE - else if(target.check_block()) //END EDIT + var/same_dir = (target.dir & user.dir) + var/aim_for_groin = user.zone_selected == "groin" + var/target_aiming_for_groin = target.zone_selected == "groin" + + if(target.check_block()) //END EDIT target.visible_message("[target] blocks [user]'s disarm attempt!") return 0 - if(attacker_style && attacker_style.disarm_act(user,target)) + else if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) + to_chat(user, "You're too exhausted!") + return FALSE + + else if(aim_for_mouth && ( target_on_help || target_restrained || target_aiming_for_mouth)) + playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1) + + user.visible_message(\ + "\The [user] slaps \the [target] in the face!",\ + "You slap [user == target ? "yourself" : "\the [target]"] in the face! ",\ + "You hear a slap." + ) + if (!HAS_TRAIT(target, TRAIT_NYMPHO)) + stop_wagging_tail(target) + user.do_attack_animation(target, ATTACK_EFFECT_FACE_SLAP) + user.adjustStaminaLossBuffered(3) + return FALSE + else if(aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin)) + user.do_attack_animation(target, ATTACK_EFFECT_ASS_SLAP) + user.adjustStaminaLossBuffered(3) + if(HAS_TRAIT(target, TRAIT_ASSBLASTUSA)) + var/hit_zone = (user.held_index_to_dir(user.active_hand_index) == "l" ? "l_":"r_") + "arm" + user.adjustStaminaLoss(20, affected_zone = hit_zone) + user.visible_message(\ + "\The [user] slaps \the [target]'s ass, but their hand bounces off like they hit metal!",\ + "You slap [user == target ? "your" : "\the [target]'s"] ass, but feel an intense amount of pain as you realise their buns are harder than steel!",\ + "You hear a slap." + ) + playsound(target.loc, 'sound/weapons/tap.ogg', 50, 1, -1) + user.emote("scream") + return FALSE + + playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1) + user.visible_message(\ + "\The [user] slaps \the [target]'s ass!",\ + "You slap [user == target ? "your" : "\the [target]'s"] ass!",\ + "You hear a slap." + ) + if (target.canbearoused) + target.adjustArousalLoss(5) + if (target.getArousalLoss() >= 100 && ishuman(target) && HAS_TRAIT(target, TRAIT_MASO) && target.has_dna()) + target.mob_climax(forced_climax=TRUE) + if (!HAS_TRAIT(target, TRAIT_NYMPHO)) + stop_wagging_tail(target) + + return FALSE + else if(attacker_style && attacker_style.disarm_act(user,target)) return 1 else user.do_attack_animation(target, ATTACK_EFFECT_DISARM) @@ -1598,7 +1645,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) //dismemberment var/probability = I.get_dismemberment_chance(affecting) - if(prob(probability) || (H.has_trait(TRAIT_EASYDISMEMBER) && prob(probability))) //try twice + if(prob(probability) || (HAS_TRAIT(H, TRAIT_EASYDISMEMBER) && prob(probability))) //try twice if(affecting.dismember(I.damtype)) I.add_mob_blood(H) playsound(get_turf(H), I.get_dismember_sound(), 80, 1) @@ -1632,8 +1679,11 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(H.stat == CONSCIOUS && H != user && prob(I.force + ((100 - H.health) * 0.5))) // rev deconversion through blunt trauma. var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev) + var/datum/antagonist/gang/gang = H.mind.has_antag_datum(/datum/antagonist/gang/) if(rev) rev.remove_revolutionary(FALSE, user) + if(gang) + H.mind.remove_antag_datum(/datum/antagonist/gang) if(bloody) //Apply blood if(H.wear_mask) @@ -1693,6 +1743,11 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(BP) if(damage > 0 ? BP.receive_damage(damage * hit_percent * brutemod * H.physiology.brute_mod, 0) : BP.heal_damage(abs(damage * hit_percent * brutemod * H.physiology.brute_mod), 0)) H.update_damage_overlays() + if(HAS_TRAIT(H, TRAIT_MASO)) + H.adjustArousalLoss(damage * brutemod * H.physiology.brute_mod) + if (H.getArousalLoss() >= 100 && ishuman(H) && H.has_dna()) + H.mob_climax(forced_climax=TRUE) + else//no bodypart, we deal damage with a more general method. H.adjustBruteLoss(damage * hit_percent * brutemod * H.physiology.brute_mod) if(BURN) @@ -1737,7 +1792,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) ///////////// /datum/species/proc/breathe(mob/living/carbon/human/H) - if(H.has_trait(TRAIT_NOBREATH)) + if(HAS_TRAIT(H, TRAIT_NOBREATH)) return TRUE @@ -1785,7 +1840,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) H.throw_alert("temp", /obj/screen/alert/hot, 3) // +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt. - if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !H.has_trait(TRAIT_RESISTHEAT)) + if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTHEAT)) //Body temperature is too hot. SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold") @@ -1803,7 +1858,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) H.emote("scream") H.apply_damage(burn_damage, BURN) - else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !H.has_trait(TRAIT_RESISTCOLD)) + else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD)) SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot") SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold) switch(H.bodytemperature) @@ -1822,7 +1877,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. switch(adjusted_pressure) if(HAZARD_HIGH_PRESSURE to INFINITY) - if(!H.has_trait(TRAIT_RESISTHIGHPRESSURE)) + if(!HAS_TRAIT(H, TRAIT_RESISTHIGHPRESSURE)) H.adjustBruteLoss(min(((adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 ) * PRESSURE_DAMAGE_COEFFICIENT, MAX_HIGH_PRESSURE_DAMAGE) * H.physiology.pressure_mod) H.throw_alert("pressure", /obj/screen/alert/highpressure, 2) else @@ -1834,7 +1889,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) H.throw_alert("pressure", /obj/screen/alert/lowpressure, 1) else - if(H.has_trait(TRAIT_RESISTLOWPRESSURE)) + if(HAS_TRAIT(H, TRAIT_RESISTLOWPRESSURE)) H.clear_alert("pressure") else H.adjustBruteLoss(LOW_PRESSURE_DAMAGE * H.physiology.pressure_mod) @@ -1845,7 +1900,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) ////////// /datum/species/proc/handle_fire(mob/living/carbon/human/H, no_protection = FALSE) - if(H.has_trait(TRAIT_NOFIRE)) + if(HAS_TRAIT(H, TRAIT_NOFIRE)) return if(H.on_fire) //the fire tries to damage the exposed clothes and items @@ -1913,7 +1968,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire) /datum/species/proc/CanIgniteMob(mob/living/carbon/human/H) - if(H.has_trait(TRAIT_NOFIRE)) + if(HAS_TRAIT(H, TRAIT_NOFIRE)) return FALSE return TRUE diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm index 5d3ca54d12..ad1f5c9190 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -3,7 +3,7 @@ id = "abductor" say_mod = "gibbers" sexes = FALSE - species_traits = list(NOBLOOD,NOEYES) + species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL) inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH) mutanttongue = /obj/item/organ/tongue/abductor var/scientist = FALSE // vars to not pollute spieces list with castes diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm index c4665b5d6d..9f2c07694c 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -2,7 +2,7 @@ name = "Android" id = "android" say_mod = "states" - species_traits = list(NOBLOOD) + species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL) inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT) inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID) meat = null diff --git a/code/modules/mob/living/carbon/human/species_types/angel.dm b/code/modules/mob/living/carbon/human/species_types/angel.dm index 5122294956..c1c848106c 100644 --- a/code/modules/mob/living/carbon/human/species_types/angel.dm +++ b/code/modules/mob/living/carbon/human/species_types/angel.dm @@ -23,7 +23,7 @@ if(ishuman(H) && !fly) fly = new fly.Grant(H) - H.add_trait(TRAIT_HOLY, SPECIES_TRAIT) + ADD_TRAIT(H, TRAIT_HOLY, SPECIES_TRAIT) /datum/species/angel/on_species_loss(mob/living/carbon/human/H) if(fly) @@ -36,7 +36,7 @@ H.dna.species.mutant_bodyparts -= "wings" H.dna.features["wings"] = "None" H.update_body() - H.remove_trait(TRAIT_HOLY, SPECIES_TRAIT) + REMOVE_TRAIT(H, TRAIT_HOLY, SPECIES_TRAIT) ..() /datum/species/angel/spec_life(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species_types/corporate.dm b/code/modules/mob/living/carbon/human/species_types/corporate.dm index e9761aac75..620f0b2543 100644 --- a/code/modules/mob/living/carbon/human/species_types/corporate.dm +++ b/code/modules/mob/living/carbon/human/species_types/corporate.dm @@ -15,6 +15,6 @@ attack_sound = 'sound/weapons/resonator_blast.ogg' blacklisted = 1 use_skintones = 0 - species_traits = list(NOBLOOD,EYECOLOR) + species_traits = list(NOBLOOD,EYECOLOR,NOGENITALS) inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER) sexes = 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index afc3fa2d04..ff90929c4b 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -2,7 +2,7 @@ // Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck. name = "Golem" id = "iron golem" - species_traits = list(NOBLOOD,MUTCOLORS,NO_UNDERWEAR) + species_traits = list(NOBLOOD,MUTCOLORS,NO_UNDERWEAR,NOGENITALS,NOAROUSAL) inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER) inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID) mutant_organs = list(/obj/item/organ/adamantine_resonator) @@ -74,10 +74,10 @@ /datum/species/golem/adamantine/on_species_gain(mob/living/carbon/C, datum/species/old_species) ..() - C.add_trait(TRAIT_ANTIMAGIC, SPECIES_TRAIT) + ADD_TRAIT(C, TRAIT_ANTIMAGIC, SPECIES_TRAIT) /datum/species/golem/adamantine/on_species_loss(mob/living/carbon/C) - C.remove_trait(TRAIT_ANTIMAGIC, SPECIES_TRAIT) + REMOVE_TRAIT(C, TRAIT_ANTIMAGIC, SPECIES_TRAIT) ..() //The suicide bombers of golemkind @@ -175,10 +175,10 @@ /datum/species/golem/silver/on_species_gain(mob/living/carbon/C, datum/species/old_species) ..() - C.add_trait(TRAIT_HOLY, SPECIES_TRAIT) + ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT) /datum/species/golem/silver/on_species_loss(mob/living/carbon/C) - C.remove_trait(TRAIT_HOLY, SPECIES_TRAIT) + REMOVE_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT) ..() //Harder to stun, deals more damage, but it's even slower @@ -698,10 +698,10 @@ /datum/species/golem/cloth/on_species_gain(mob/living/carbon/C, datum/species/old_species) ..() - C.add_trait(TRAIT_HOLY, SPECIES_TRAIT) + ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT) /datum/species/golem/cloth/on_species_loss(mob/living/carbon/C) - C.remove_trait(TRAIT_HOLY, SPECIES_TRAIT) + REMOVE_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT) ..() /datum/species/golem/cloth/check_roundstart_eligible() @@ -768,7 +768,7 @@ /obj/structure/cloth_pile/proc/revive() if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime return - if(cloth_golem.suiciding || cloth_golem.has_trait(TRAIT_NOCLONE)) + if(cloth_golem.suiciding || HAS_TRAIT(cloth_golem, TRAIT_NOCLONE)) QDEL_NULL(cloth_golem) return 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 0461fb9b79..b218b2cefc 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -594,7 +594,7 @@ /datum/species/jelly/stargazer/proc/link_mob(mob/living/M) if(QDELETED(M) || M.stat == DEAD) return FALSE - if(M.has_trait(TRAIT_MINDSHIELD)) //mindshield implant, no dice + if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) //mindshield implant, no dice return FALSE if(M in linked_mobs) return FALSE diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index c5a64ebd13..30bf705547 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -97,6 +97,7 @@ brutemod = 0.9 /datum/species/lizard/ashwalker/on_species_gain(mob/living/carbon/human/C, datum/species/old_species) - if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines - C.dna.features["tail"] = "Smooth" + if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail_lizard"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines + C.dna.features["tail_lizard"] = "Smooth" + C.update_body() return ..() diff --git a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm index 80b2838167..7be0265cba 100644 --- a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm @@ -9,7 +9,7 @@ nojumpsuit = TRUE say_mod = "poofs" //what does a mushroom sound like - species_traits = list(MUTCOLORS, NOEYES, NO_UNDERWEAR) + species_traits = list(MUTCOLORS, NOEYES, NO_UNDERWEAR,NOGENITALS,NOAROUSAL) inherent_traits = list(TRAIT_NOBREATH) speedmod = 1.5 //faster than golems but not by much 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 6f5ae6f4eb..afd6e4e7f5 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -4,7 +4,7 @@ say_mod = "rattles" sexes = 0 meat = /obj/item/stack/sheet/mineral/plasma - species_traits = list(NOBLOOD,NOTRANSSTING) + species_traits = list(NOBLOOD,NOTRANSSTING,NOGENITALS) inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER) inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID) mutantlungs = /obj/item/organ/lungs/plasmaman @@ -33,7 +33,7 @@ if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed) if(environment) if(environment.total_moles()) - if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen][MOLES]) >= 1) //Same threshhold that extinguishes fire + if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen]) >= 1) //Same threshhold that extinguishes fire H.adjust_fire_stacks(0.5) if(!H.on_fire && H.fire_stacks > 0) H.visible_message("[H]'s body reacts with the atmosphere and bursts into flames!","Your body reacts with the atmosphere and bursts into flame!") diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index 3e238f8a53..c3d1e1aedb 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -12,6 +12,11 @@ meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/plant disliked_food = MEAT | DAIRY liked_food = VEGETABLES | FRUIT | GRAIN + var/light_nutrition_gain_factor = 10 + var/light_toxheal = 1 + var/light_oxyheal = 1 + var/light_burnheal = 1 + var/light_bruteheal = 1 /datum/species/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() @@ -30,13 +35,13 @@ if(isturf(H.loc)) //else, there's considered to be no light var/turf/T = H.loc light_amount = min(1,T.get_lumcount()) - 0.5 - H.nutrition += light_amount * 10 + H.nutrition += light_amount * light_nutrition_gain_factor if(H.nutrition > NUTRITION_LEVEL_FULL) H.nutrition = NUTRITION_LEVEL_FULL if(light_amount > 0.2) //if there's enough light, heal - H.heal_overall_damage(1,1) - H.adjustToxLoss(-1) - H.adjustOxyLoss(-1) + H.heal_overall_damage(light_bruteheal, light_burnheal) + H.adjustToxLoss(-light_toxheal) + H.adjustOxyLoss(-light_oxyheal) if(H.nutrition < NUTRITION_LEVEL_STARVING + 50) H.take_overall_damage(2,0) @@ -64,3 +69,11 @@ H.show_message("The radiation beam singes you!") if(/obj/item/projectile/energy/florayield) H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL) + +/datum/species/pod/pseudo_weak + id = "podweak" + limbs_id = "pod" + light_nutrition_gain_factor = 7.5 + light_bruteheal = 0.2 + light_burnheal = 0.2 + light_toxheal = 0.7 diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index 3d42fb32cf..b574df7d79 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -38,7 +38,7 @@ burnmod = 1.5 blacklisted = TRUE no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM, SLOT_S_STORE) - species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYES) + species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYES,NOGENITALS,NOAROUSAL) inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER) mutanteyes = /obj/item/organ/eyes/night_vision/nightmare mutant_organs = list(/obj/item/organ/heart/nightmare) 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 d778aa50f2..5c2b01a179 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -6,7 +6,7 @@ blacklisted = 1 sexes = 0 meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton - species_traits = list(NOBLOOD) + species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL) inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH) inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID) mutanttongue = /obj/item/organ/tongue/bone diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm index 51c23fd21a..7e838c857f 100644 --- a/code/modules/mob/living/carbon/human/species_types/synths.dm +++ b/code/modules/mob/living/carbon/human/species_types/synths.dm @@ -3,7 +3,7 @@ id = "synth" say_mod = "beep boops" //inherited from a user's real species sexes = 0 - species_traits = list(NOTRANSSTING) //all of these + whatever we inherit from the real species + species_traits = list(NOTRANSSTING,NOGENITALS,NOAROUSAL) //all of these + whatever we inherit from the real species inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOBREATH) inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID) dangerous_existence = 1 diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index 844545a748..5c20b0ce75 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -9,12 +9,12 @@ /mob/living/carbon/human/Unconscious(amount, updating = 1, ignore_canunconscious = 0) amount = dna.species.spec_stun(src,amount) - if(has_trait(TRAIT_HEAVY_SLEEPER)) + if(HAS_TRAIT(src, TRAIT_HEAVY_SLEEPER)) amount *= rand(1.25, 1.3) return ..() /mob/living/carbon/human/Sleeping(amount, updating = 1, ignore_sleepimmune = 0) - if(has_trait(TRAIT_HEAVY_SLEEPER)) + if(HAS_TRAIT(src, TRAIT_HEAVY_SLEEPER)) amount *= rand(1.25, 1.3) return ..() diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 9b5375035e..feb80e8d2c 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -660,8 +660,10 @@ generate/load female uniform sprites matching all previously decided variables . += "-[BP.dmg_overlay_type]" if(BP.body_markings) . += "-[BP.body_markings]" + else + . += "-no_marking" - if(has_trait(TRAIT_HUSK)) + if(HAS_TRAIT(src, TRAIT_HUSK)) . += "-husk" /mob/living/carbon/human/load_limb_from_cache() @@ -703,7 +705,7 @@ generate/load female uniform sprites matching all previously decided variables add_overlay(HD.get_limb_icon()) update_damage_overlays() - if(HD && !(has_trait(TRAIT_HUSK))) + if(HD && !(HAS_TRAIT(src, TRAIT_HUSK))) // lipstick if(lip_style && (LIPS in dna.species.species_traits)) var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[lip_style]", -BODY_LAYER) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 48a401802b..571775d541 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -116,7 +116,7 @@ air_update_turf() /mob/living/carbon/proc/has_smoke_protection() - if(has_trait(TRAIT_NOBREATH)) + if(HAS_TRAIT(src, TRAIT_NOBREATH)) return TRUE return FALSE @@ -150,10 +150,9 @@ var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/list/breath_gases = breath.gases - breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz) - var/O2_partialpressure = (breath_gases[/datum/gas/oxygen][MOLES]/breath.total_moles())*breath_pressure - var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma][MOLES]/breath.total_moles())*breath_pressure - var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide][MOLES]/breath.total_moles())*breath_pressure + var/O2_partialpressure = (breath_gases[/datum/gas/oxygen]/breath.total_moles())*breath_pressure + var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure + var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide]/breath.total_moles())*breath_pressure //OXYGEN @@ -177,7 +176,7 @@ var/ratio = 1 - O2_partialpressure/safe_oxy_min adjustOxyLoss(min(5*ratio, 3)) failed_last_breath = 1 - oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]*ratio + oxygen_used = breath_gases[/datum/gas/oxygen]*ratio else adjustOxyLoss(3) failed_last_breath = 1 @@ -189,12 +188,12 @@ o2overloadtime = 0 //reset our counter for this too if(health >= crit_threshold) adjustOxyLoss(-5) - oxygen_used = breath_gases[/datum/gas/oxygen][MOLES] + oxygen_used = breath_gases[/datum/gas/oxygen] clear_alert("not_enough_oxy") SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation") - breath_gases[/datum/gas/oxygen][MOLES] -= oxygen_used - breath_gases[/datum/gas/carbon_dioxide][MOLES] += oxygen_used + breath_gases[/datum/gas/oxygen] -= oxygen_used + breath_gases[/datum/gas/carbon_dioxide] += oxygen_used //CARBON DIOXIDE if(CO2_partialpressure > safe_co2_max) @@ -213,7 +212,7 @@ //TOXINS/PLASMA if(Toxins_partialpressure > safe_tox_max) - var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_tox_max) * 10 + var/ratio = (breath_gases[/datum/gas/plasma]/safe_tox_max) * 10 adjustToxLoss(CLAMP(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) else @@ -221,7 +220,7 @@ //NITROUS OXIDE if(breath_gases[/datum/gas/nitrous_oxide]) - var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide][MOLES]/breath.total_moles())*breath_pressure + var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide]/breath.total_moles())*breath_pressure if(SA_partialpressure > SA_para_min) Unconscious(60) if(SA_partialpressure > SA_sleep_min) @@ -232,7 +231,7 @@ //BZ (Facepunch port of their Agent B) if(breath_gases[/datum/gas/bz]) - var/bz_partialpressure = (breath_gases[/datum/gas/bz][MOLES]/breath.total_moles())*breath_pressure + var/bz_partialpressure = (breath_gases[/datum/gas/bz]/breath.total_moles())*breath_pressure if(bz_partialpressure > 1) hallucination += 10 else if(bz_partialpressure > 0.01) @@ -240,17 +239,17 @@ //TRITIUM if(breath_gases[/datum/gas/tritium]) - var/tritium_partialpressure = (breath_gases[/datum/gas/tritium][MOLES]/breath.total_moles())*breath_pressure + var/tritium_partialpressure = (breath_gases[/datum/gas/tritium]/breath.total_moles())*breath_pressure radiation += tritium_partialpressure/10 //NITRYL if(breath_gases[/datum/gas/nitryl]) - var/nitryl_partialpressure = (breath_gases[/datum/gas/nitryl][MOLES]/breath.total_moles())*breath_pressure + var/nitryl_partialpressure = (breath_gases[/datum/gas/nitryl]/breath.total_moles())*breath_pressure adjustFireLoss(nitryl_partialpressure/4) //MIASMA if(breath_gases[/datum/gas/miasma]) - var/miasma_partialpressure = (breath_gases[/datum/gas/miasma][MOLES]/breath.total_moles())*breath_pressure + var/miasma_partialpressure = (breath_gases[/datum/gas/miasma]/breath.total_moles())*breath_pressure if(prob(1 * miasma_partialpressure)) var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) @@ -292,7 +291,7 @@ - breath.garbage_collect() + GAS_GARBAGE_COLLECT(breath.gases) //BREATH TEMPERATURE handle_breath_temperature(breath) @@ -324,7 +323,7 @@ return // No decay if formaldehyde in corpse or when the corpse is charred - if(reagents.has_reagent("formaldehyde", 15) || has_trait(TRAIT_HUSK)) + if(reagents.has_reagent("formaldehyde", 15) || HAS_TRAIT(src, TRAIT_HUSK)) return // Also no decay if corpse chilled or not organic/undead @@ -345,8 +344,7 @@ var/list/cached_gases = miasma_turf.air.gases - ASSERT_GAS(/datum/gas/miasma, miasma_turf.air) - cached_gases[/datum/gas/miasma][MOLES] += 0.02 + cached_gases[/datum/gas/miasma] += 0.02 /mob/living/carbon/proc/handle_blood() return @@ -531,8 +529,8 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put if(stuttering) stuttering = max(stuttering-1, 0) - if(slurring) - slurring = max(slurring-1,0) + if(slurring || drunkenness) + slurring = max(slurring-1,0,drunkenness) if(cultslurring) cultslurring = max(cultslurring-1, 0) @@ -550,16 +548,11 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put drunkenness = max(drunkenness - (drunkenness * 0.04), 0) if(drunkenness >= 6) SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "drunk", /datum/mood_event/drunk) - if(prob(25)) - slurring += 2 jitteriness = max(jitteriness - 3, 0) - if(has_trait(TRAIT_DRUNK_HEALING)) + if(HAS_TRAIT(src, TRAIT_DRUNK_HEALING)) adjustBruteLoss(-0.12, FALSE) adjustFireLoss(-0.06, FALSE) - if(drunkenness >= 11 && slurring < 5) - slurring += 1.2 - if(mind && (mind.assigned_role == "Scientist" || mind.assigned_role == "Research Director")) if(SSresearch.science_tech) if(drunkenness >= 12.9 && drunkenness <= 13.8) @@ -581,7 +574,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put if(prob(25)) confused += 2 Dizzy(10) - if(has_trait(TRAIT_DRUNK_HEALING)) // effects stack with lower tiers + if(HAS_TRAIT(src, TRAIT_DRUNK_HEALING)) // effects stack with lower tiers adjustBruteLoss(-0.3, FALSE) adjustFireLoss(-0.15, FALSE) @@ -594,7 +587,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put if(drunkenness >= 61) if(prob(50)) blur_eyes(5) - if(has_trait(TRAIT_DRUNK_HEALING)) + if(HAS_TRAIT(src, TRAIT_DRUNK_HEALING)) adjustBruteLoss(-0.4, FALSE) adjustFireLoss(-0.2, FALSE) @@ -662,7 +655,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put /mob/living/carbon/proc/liver_failure() reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE) - if(has_trait(TRAIT_STABLEHEART)) + if(HAS_TRAIT(src, TRAIT_STABLEHEART)) return adjustToxLoss(4, TRUE, TRUE) if(prob(30)) @@ -698,7 +691,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put return TRUE /mob/living/carbon/proc/needs_heart() - if(has_trait(TRAIT_STABLEHEART)) + if(HAS_TRAIT(src, TRAIT_STABLEHEART)) return FALSE if(dna && dna.species && (NOBLOOD in dna.species.species_traits)) //not all carbons have species! return FALSE diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 901fb48b20..4c1c235fe1 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -119,7 +119,7 @@ cuff_resist(I) /mob/living/carbon/monkey/proc/should_target(var/mob/living/L) - if(has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(src, TRAIT_PACIFISM)) return FALSE if(enemies[L]) @@ -143,7 +143,7 @@ pickupTimer = 0 else INVOKE_ASYNC(src, .proc/walk2derpless, pickupTarget.loc) - if(Adjacent(pickupTarget) || Adjacent(pickupTarget.loc)) // next to target + if(Adjacent(pickupTarget) || Adjacent(pickupTarget.loc)) // next to target drop_all_held_items() // who cares about these items, i want that one! if(isturf(pickupTarget.loc)) // on floor equip_item(pickupTarget) @@ -167,7 +167,7 @@ battle_screech() retaliate(L) return TRUE - else + else bodyDisposal = locate(/obj/machinery/disposal/) in around if(bodyDisposal) target = L diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 55b5d67c24..906e138b0a 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -81,7 +81,7 @@ adjust_bodytemperature(min((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX)) - if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !has_trait(TRAIT_RESISTHEAT)) + if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(src, TRAIT_RESISTHEAT)) switch(bodytemperature) if(360 to 400) throw_alert("temp", /obj/screen/alert/hot, 1) @@ -96,7 +96,7 @@ else apply_damage(HEAT_DAMAGE_LEVEL_2, BURN) - else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !has_trait(TRAIT_RESISTCOLD)) + else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(src, TRAIT_RESISTCOLD)) if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell)) switch(bodytemperature) if(200 to 260) diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 1ffa3316ab..f1a6b58cd1 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -147,7 +147,7 @@ threatcount += 4 //trigger look_for_perp() since they're nonhuman and very likely hostile //mindshield implants imply trustworthyness - if(has_trait(TRAIT_MINDSHIELD)) + if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) threatcount -= 1 return threatcount diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm index c807251af4..6311776596 100644 --- a/code/modules/mob/living/carbon/monkey/update_icons.dm +++ b/code/modules/mob/living/carbon/monkey/update_icons.dm @@ -19,7 +19,7 @@ if(!HD) //Decapitated return - if(has_trait(TRAIT_HUSK)) + if(HAS_TRAIT(src, TRAIT_HUSK)) return var/hair_hidden = 0 diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index 212b96e6d9..87bf662c4f 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -279,7 +279,7 @@ else . += "-robotic" - if(has_trait(TRAIT_HUSK)) + if(HAS_TRAIT(src, TRAIT_HUSK)) . += "-husk" diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 4e5c7decc5..b2eed2d19e 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -101,14 +101,14 @@ if(EFFECT_SLUR) slurring = max(slurring,(effect * hit_percent)) if(EFFECT_STUTTER) - if((status_flags & CANSTUN) && !has_trait(TRAIT_STUNIMMUNE)) // stun is usually associated with stutter + if((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) // stun is usually associated with stutter stuttering = max(stuttering,(effect * hit_percent)) if(EFFECT_EYE_BLUR) blur_eyes(effect * hit_percent) if(EFFECT_DROWSY) drowsyness = max(drowsyness,(effect * hit_percent)) if(EFFECT_JITTER) - if((status_flags & CANSTUN) && !has_trait(TRAIT_STUNIMMUNE)) + if((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) jitteriness = max(jitteriness,(effect * hit_percent)) return 1 diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 9ef4c1567a..201e5fea24 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -109,7 +109,7 @@ ExtinguishMob() return var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment - if(!G.gases[/datum/gas/oxygen] || G.gases[/datum/gas/oxygen][MOLES] < 1) + if(G.gases[/datum/gas/oxygen] < 1) ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire return var/turf/location = get_turf(src) @@ -126,7 +126,7 @@ /mob/living/proc/handle_traits() //Eyes if(eye_blind) //blindness, heals slowly over time - if(!stat && !(has_trait(TRAIT_BLIND))) + if(!stat && !(HAS_TRAIT(src, TRAIT_BLIND))) eye_blind = max(eye_blind-1,0) if(client && !eye_blind) clear_alert("blind") diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b9b6424092..65ed57a6f1 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -103,21 +103,23 @@ //CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks without a short delay if(resting && !L.resting) - if(attemptingcrawl) - return TRUE - if(getStaminaLoss() >= STAMINA_SOFTCRIT) - to_chat(src, "You're too exhausted to crawl under [L].") - return TRUE - attemptingcrawl = TRUE var/origtargetloc = L.loc - visible_message("[src] is attempting to crawl under [L].", "You are now attempting to crawl under [L].") - if(do_after(src, CRAWLUNDER_DELAY, target = src)) - if(resting) - var/src_passmob = (pass_flags & PASSMOB) - pass_flags |= PASSMOB - Move(origtargetloc) - if(!src_passmob) - pass_flags &= ~PASSMOB + if(!pulledby) + if(attemptingcrawl) + return TRUE + if(getStaminaLoss() >= STAMINA_SOFTCRIT) + to_chat(src, "You're too exhausted to crawl under [L].") + return TRUE + attemptingcrawl = TRUE + visible_message("[src] is attempting to crawl under [L].", "You are now attempting to crawl under [L].") + if(!do_after(src, CRAWLUNDER_DELAY, target = src) || !resting) + attemptingcrawl = FALSE + return TRUE + var/src_passmob = (pass_flags & PASSMOB) + pass_flags |= PASSMOB + Move(origtargetloc) + if(!src_passmob) + pass_flags &= ~PASSMOB attemptingcrawl = FALSE return TRUE //END OF CIT CHANGES @@ -168,7 +170,7 @@ return 1 if(isliving(M)) var/mob/living/L = M - if(L.has_trait(TRAIT_PUSHIMMUNE)) + 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)) @@ -304,7 +306,7 @@ /mob/living/pointed(atom/A as mob|obj|turf in view()) if(incapacitated()) return FALSE - if(has_trait(TRAIT_DEATHCOMA)) + if(HAS_TRAIT(src, TRAIT_DEATHCOMA)) return FALSE if(!..()) return FALSE @@ -698,7 +700,7 @@ who.visible_message("[src] tries to remove [who]'s [what.name].", \ "[src] tries to remove [who]'s [what.name].") what.add_fingerprint(src) - if(do_mob(src, who, what.strip_delay)) + if(do_mob(src, who, what.strip_delay, ignorehelditem = TRUE)) if(what && Adjacent(who)) if(islist(where)) var/list/L = where @@ -887,7 +889,7 @@ /mob/living/rad_act(amount) . = ..() - if(!amount || (amount < RAD_MOB_SKIN_PROTECTION) || has_trait(TRAIT_RADIMMUNE)) + if(!amount || (amount < RAD_MOB_SKIN_PROTECTION) || HAS_TRAIT(src, TRAIT_RADIMMUNE)) return amount -= RAD_BACKGROUND_RADIATION // This will always be at least 1 because of how skin protection is calculated @@ -903,7 +905,7 @@ . = ..() if(.) return - if((magic && has_trait(TRAIT_ANTIMAGIC)) || (holy && has_trait(TRAIT_HOLY))) + if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (holy && HAS_TRAIT(src, TRAIT_HOLY))) return src /mob/living/proc/fakefireextinguish() @@ -986,7 +988,7 @@ //Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it. //Robots, animals and brains have their own version so don't worry about them /mob/living/proc/update_canmove() - var/ko = IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (has_trait(TRAIT_DEATHCOMA)) + var/ko = IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) var/move_and_fall = stat == SOFT_CRIT && !pulledby var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK var/buckle_lying = !(buckled && !buckled.buckle_lying) @@ -1180,3 +1182,32 @@ update_transform() if("lighting_alpha") sync_lighting_plane_alpha() + +/mob/living/proc/do_adrenaline( + stamina_boost = 150, + put_on_feet = TRUE, + clamp_unconscious_to = 0, + clamp_immobility_to = 0, + reset_misc = TRUE, + healing_chems = list("inaprovaline" = 3, "synaptizine" = 10, "omnizine" = 10, "stimulants" = 10), + message = "You feel a surge of energy!" + ) + if(AmountSleeping() > clamp_unconscious_to) + SetSleeping(clamp_unconscious_to) + if(AmountUnconscious() > clamp_unconscious_to) + SetUnconscious(clamp_unconscious_to) + if(AmountStun() > clamp_immobility_to) + SetStun(clamp_immobility_to) + if(AmountKnockdown() > clamp_immobility_to) + SetKnockdown(clamp_immobility_to) + adjustStaminaLoss(max(0, -stamina_boost)) + if(put_on_feet) + resting = FALSE + lying = FALSE + if(reset_misc) + stuttering = 0 + updatehealth() + update_stamina() + update_canmove() + for(var/chem in healing_chems) + reagents.add_reagent(chem, healing_chems[chem]) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 643c91b95a..449bbe361f 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -1,24 +1,18 @@ -/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = null, soften_text = null, armour_penetration, penetrated_text) +/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = "Your armor absorbs the blow!", soften_text = "Your armor softens the blow!", armour_penetration, penetrated_text = "Your armor was penetrated!") var/armor = getarmor(def_zone, attack_flag) //the if "armor" check is because this is used for everything on /living, including humans if(armor && armour_penetration) armor = max(0, armor - armour_penetration) if(penetrated_text) - to_chat(src, "[penetrated_text]") - else - to_chat(src, "Your armor was penetrated!") + to_chat(src, "[penetrated_text]") else if(armor >= 100) if(absorb_text) - to_chat(src, "[absorb_text]") - else - to_chat(src, "Your armor absorbs the blow!") + to_chat(src, "[absorb_text]") else if(armor > 0) if(soften_text) - to_chat(src, "[soften_text]") - else - to_chat(src, "Your armor softens the blow!") + to_chat(src, "[soften_text]") return armor @@ -43,7 +37,7 @@ return /mob/living/bullet_act(obj/item/projectile/P, def_zone) - var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration) + var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null) if(!P.nodamage) apply_damage(P.damage, P.damage_type, def_zone, armor) if(P.dismemberment) @@ -143,11 +137,11 @@ user.start_pulling(src, supress_message) return - if(!(status_flags & CANPUSH) || has_trait(TRAIT_PUSHIMMUNE)) + if(!(status_flags & CANPUSH) || HAS_TRAIT(src, TRAIT_PUSHIMMUNE)) to_chat(user, "[src] can't be grabbed more aggressively!") return FALSE - if(user.has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to risk hurting [src]!") return FALSE @@ -210,7 +204,7 @@ M.Feedstop() return // can't attack while eating! - if(has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(src, TRAIT_PACIFISM)) to_chat(M, "You don't want to hurt anyone!") return FALSE @@ -227,7 +221,7 @@ M.visible_message("\The [M] [M.friendly] [src]!") return FALSE else - if(M.has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(M, TRAIT_PACIFISM)) to_chat(M, "You don't want to hurt anyone!") return FALSE @@ -246,7 +240,7 @@ return FALSE if (M.a_intent == INTENT_HARM) - if(M.has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(M, TRAIT_PACIFISM)) to_chat(M, "You don't want to hurt anyone!") return FALSE @@ -272,7 +266,7 @@ return FALSE else - if(L.has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(L, TRAIT_PACIFISM)) to_chat(L, "You don't want to hurt anyone!") return @@ -297,7 +291,7 @@ grabbedby(M) return FALSE if("harm") - if(M.has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(M, TRAIT_PACIFISM)) to_chat(M, "You don't want to hurt anyone!") return FALSE M.do_attack_animation(src) @@ -321,7 +315,7 @@ SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage) if(tesla_shock && (flags_1 & TESLA_IGNORE_1)) return FALSE - if(has_trait(TRAIT_SHOCKIMMUNE)) + if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE)) return FALSE if(shock_damage > 0) if(!illusion) @@ -391,7 +385,7 @@ //called when the mob receives a bright flash /mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash) - if(get_eye_protection() < intensity && (override_blindness_check || !(has_trait(TRAIT_BLIND)))) + if(get_eye_protection() < intensity && (override_blindness_check || !(HAS_TRAIT(src, TRAIT_BLIND)))) overlay_fullscreen("flash", type) addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25) return TRUE diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 0ba5b4c56d..3b0af53866 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -33,8 +33,6 @@ var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas //and INCORPOREAL_MOVE_JAUNT is blocked by holy water/salt - var/list/status_traits = list() - var/list/roundstart_quirks = list() var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them. diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index a0f619a7d6..e2f62b054c 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -301,7 +301,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( return 1 /mob/living/proc/can_speak_vocal(message) //Check AFTER handling of xeno and ling channels - if(has_trait(TRAIT_MUTE)) + if(HAS_TRAIT(src, TRAIT_MUTE)) return 0 if(is_muzzled()) @@ -334,7 +334,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( message = stutter(message) if(slurring) - message = slur(message) + message = slur(message,slurring) if(cultslurring) message = cultslur(message) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index b4524a54e6..46576a357f 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -86,12 +86,13 @@ var/datum/action/innate/deploy_last_shell/redeploy_action = new var/chnotify = 0 - + var/multicam_on = FALSE var/obj/screen/movable/pic_in_pic/ai/master_multicam var/list/multicam_screens = list() var/list/all_eyes = list() var/max_multicams = 6 + var/display_icon_override /mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai) . = ..() @@ -127,6 +128,8 @@ create_eye() apply_pref_name("ai") + set_core_display_icon() + holo_icon = getHologramIcon(icon('icons/mob/ai.dmi',"default")) spark_system = new /datum/effect_system/spark_spread() @@ -172,81 +175,34 @@ fire_stacks = 0 . = ..() +/mob/living/silicon/ai/proc/set_core_display_icon(input, client/C) + if(client && !C) + C = client + if(!input && !C?.prefs?.preferred_ai_core_display) + icon_state = initial(icon_state) + else + var/preferred_icon = input ? input : C.prefs.preferred_ai_core_display + icon_state = resolve_ai_icon(preferred_icon) + /mob/living/silicon/ai/verb/pick_icon() set category = "AI Commands" set name = "Set AI Core Display" if(incapacitated()) return + var/list/iconstates = GLOB.ai_core_display_screens + for(var/option in iconstates) + if(option == "Random") + iconstates[option] = image(icon = src.icon, icon_state = "ai-random") + continue + iconstates[option] = image(icon = src.icon, icon_state = resolve_ai_icon(option)) - var/icontype = input("Please, select a display!", "AI", null/*, null*/) in list("Clown", ":thinking:", "Monochrome", "Blue", "Inverted", "Firewall", "Green", "Red", "Static", "Red October", "House", "Heartline", "Hades", "Helios", "President", "Syndicat Meow", "Alien", "Too Deep", "Triumvirate", "Triumvirate-M", "Text", "Matrix", "Dorf", "Bliss", "Not Malf", "Fuzzy", "Goon", "Database", "Glitchman", "Murica", "Nanotrasen", "Gentoo", "Angel", "TechDemon") //CIT CHANGE - adds 'TechDemon - if(icontype == "Clown") - icon_state = "ai-clown2" - else if (icontype == ":thinking:") - icon_state = "ai-:thinking:" - else if(icontype == "Monochrome") - icon_state = "ai-mono" - else if(icontype == "Blue") - icon_state = "ai" - else if(icontype == "Inverted") - icon_state = "ai-u" - else if(icontype == "Firewall") - icon_state = "ai-magma" - else if(icontype == "Green") - icon_state = "ai-wierd" - else if(icontype == "Red") - icon_state = "ai-malf" - else if(icontype == "Static") - icon_state = "ai-static" - else if(icontype == "Red October") - icon_state = "ai-redoctober" - else if(icontype == "House") - icon_state = "ai-house" - else if(icontype == "Heartline") - icon_state = "ai-heartline" - else if(icontype == "Hades") - icon_state = "ai-hades" - else if(icontype == "Helios") - icon_state = "ai-helios" - else if(icontype == "President") - icon_state = "ai-pres" - else if(icontype == "Syndicat Meow") - icon_state = "ai-syndicatmeow" - else if(icontype == "Alien") - icon_state = "ai-alien" - else if(icontype == "Too Deep") - icon_state = "ai-toodeep" - else if(icontype == "Triumvirate") - icon_state = "ai-triumvirate" - else if(icontype == "Triumvirate-M") - icon_state = "ai-triumvirate-malf" - else if(icontype == "Text") - icon_state = "ai-text" - else if(icontype == "Matrix") - icon_state = "ai-matrix" - else if(icontype == "Dorf") - icon_state = "ai-dorf" - else if(icontype == "Bliss") - icon_state = "ai-bliss" - else if(icontype == "Not Malf") - icon_state = "ai-notmalf" - else if(icontype == "Fuzzy") - icon_state = "ai-fuzz" - else if(icontype == "Goon") - icon_state = "ai-goon" - else if(icontype == "Database") - icon_state = "ai-database" - else if(icontype == "Glitchman") - icon_state = "ai-glitchman" - else if(icontype == "Murica") - icon_state = "ai-murica" - else if(icontype == "Nanotrasen") - icon_state = "ai-nanotrasen" - else if(icontype == "Gentoo") - icon_state = "ai-gentoo" - else if(icontype == "Angel") - icon_state = "ai-angel" - else if(icontype == "TechDemon") //CIT CHANGE - adds 'TechDemon - icon_state = "ai-techdemon" + view_core() + var/ai_core_icon = show_radial_menu(src, src , iconstates, radius = 42) + + if(!ai_core_icon || incapacitated()) + return + display_icon_override = ai_core_icon + set_core_display_icon(ai_core_icon) /mob/living/silicon/ai/Stat() ..() @@ -915,9 +871,9 @@ clear_fullscreen("remote_view", 0) /mob/living/silicon/ai/revive(full_heal = 0, admin_revive = 0) - if(..()) //successfully ressuscitated from death - icon_state = "ai" - . = 1 + . = ..() + if(.) //successfully ressuscitated from death + set_core_display_icon(display_icon_override) /mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc) malfhack = null diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 9b982d4bd5..301d2bd218 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -4,10 +4,13 @@ . = ..() - if("[icon_state]_dead" in icon_states(src.icon,1)) + var/old_icon = icon_state + if("[icon_state]_dead" in icon_states(icon)) icon_state = "[icon_state]_dead" else icon_state = "ai_dead" + if("[old_icon]_death_transition" in icon_states(icon)) + flick("[old_icon]_death_transition", src) cameraFollow = null diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 90070f1d5d..0e8d37a807 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -544,9 +544,9 @@ if (total_moles) for(var/id in env_gases) - var/gas_level = env_gases[id][MOLES]/total_moles + var/gas_level = env_gases[id]/total_moles if(gas_level > 0.01) - dat += "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_level*100)]%
" + dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100)]%
" dat += "Temperature: [round(environment.temperature-T0C)]°C
" dat += "Refresh Reading
" dat += "
" diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index a92c1ff9e1..793df63c87 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -15,7 +15,7 @@ grabbedby(M) if("harm", "disarm") - if(M.has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(M, TRAIT_PACIFISM)) to_chat(M, "You don't want to hurt [src]!") return M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) @@ -29,7 +29,7 @@ /mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) if(user.a_intent == INTENT_HARM) - if(user.has_trait(TRAIT_PACIFISM)) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to hurt [src]!") return FALSE ..(user, 1) diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 56d37f667c..9db21f13e0 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -505,3 +505,33 @@ to_chat(user, "You unbolt [src]'s energy swords") for(var/IS in 1 to swordamt) new /obj/item/melee/transforming/energy/sword/saber(Tsec) + +//Firebot Assembly +/obj/item/bot_assembly/firebot + name = "incomplete firebot assembly" + desc = "A fire extinguisher with an arm attached to it." + icon_state = "firebot_arm" + created_name = "Firebot" + +/obj/item/bot_assembly/firebot/attackby(obj/item/I, mob/user, params) + ..() + switch(build_step) + if(ASSEMBLY_FIRST_STEP) + if(istype(I, /obj/item/clothing/head/hardhat/red)) + if(!user.temporarilyRemoveItemFromInventory(I)) + return + to_chat(user,"You add the [I] to [src]!") + icon_state = "firebot_helmet" + desc = "An incomplete firebot assembly with a fire helmet." + qdel(I) + build_step++ + + if(ASSEMBLY_SECOND_STEP) + if(isprox(I)) + if(!can_finish_build(I, user)) + return + to_chat(user, "You add the [I] to [src]! Beep Boop!") + var/mob/living/simple_animal/bot/firebot/F = new(drop_location()) + F.name = created_name + qdel(I) + qdel(src) diff --git a/code/modules/mob/living/simple_animal/bot/firebot.dm b/code/modules/mob/living/simple_animal/bot/firebot.dm new file mode 100644 index 0000000000..d8c3bca72a --- /dev/null +++ b/code/modules/mob/living/simple_animal/bot/firebot.dm @@ -0,0 +1,325 @@ +//Firebot + +#define SPEECH_INTERVAL 300 // Time between idle speeches +#define DETECTED_VOICE_INTERVAL 300 // Time between fire detected callouts +#define FOAM_INTERVAL 50 // Time between deployment of fire fighting foam + +/mob/living/simple_animal/bot/firebot + name = "\improper Firebot" + desc = "A little fire extinguishing bot. He looks rather anxious." + icon = 'icons/mob/aibots.dmi' + icon_state = "firebot" + density = FALSE + anchored = FALSE + health = 25 + maxHealth = 25 + spacewalk = TRUE + + radio_key = /obj/item/encryptionkey/headset_eng + radio_channel = "Engineering" + bot_type = FIRE_BOT + model = "Firebot" + bot_core = /obj/machinery/bot_core/firebot + window_id = "autoextinguisher" + window_name = "Mobile Fire Extinguisher v1.0" + path_image_color = "#FFA500" + + var/atom/target_fire + var/atom/old_target_fire + + var/obj/item/extinguisher/internal_ext + + var/last_found = 0 + + var/speech_cooldown = 0 + var/detected_cooldown = 0 + var/foam_cooldown = 0 + + var/extinguish_people = TRUE + var/extinguish_fires = TRUE + var/stationary_mode = FALSE + +/mob/living/simple_animal/bot/firebot/Initialize() + . = ..() + update_icon() + var/datum/job/engineer/J = new/datum/job/engineer + access_card.access += J.get_access() + prev_access = access_card.access + + create_extinguisher() + +/mob/living/simple_animal/bot/firebot/bot_reset() + create_extinguisher() + +/mob/living/simple_animal/bot/firebot/proc/create_extinguisher() + internal_ext = new /obj/item/extinguisher(src) + internal_ext.safety = FALSE + internal_ext.precision = TRUE + internal_ext.max_water = INFINITY + internal_ext.refill() + +/mob/living/simple_animal/bot/firebot/UnarmedAttack(atom/A) + if(!on) + return + if(internal_ext) + internal_ext.afterattack(A, src) + else + return ..() + +/mob/living/simple_animal/bot/firebot/RangedAttack(atom/A) + if(!on) + return + if(internal_ext) + internal_ext.afterattack(A, src) + else + return ..() + +/mob/living/simple_animal/bot/firebot/turn_on() + . = ..() + update_icon() + +/mob/living/simple_animal/bot/firebot/turn_off() + ..() + update_icon() + +/mob/living/simple_animal/bot/firebot/bot_reset() + ..() + target_fire = null + old_target_fire = null + ignore_list = list() + anchored = FALSE + update_icon() + +/mob/living/simple_animal/bot/firebot/proc/soft_reset() + path = list() + target_fire = null + mode = BOT_IDLE + last_found = world.time + update_icon() + +/mob/living/simple_animal/bot/firebot/set_custom_texts() + text_hack = "You corrupt [name]'s safety protocols." + text_dehack = "You detect errors in [name] and reset his programming." + text_dehack_fail = "[name] is not responding to reset commands!" + +/mob/living/simple_animal/bot/firebot/get_controls(mob/user) + var/dat + dat += hack(user) + dat += showpai(user) + dat += "Mobile Fire Extinguisher v1.0

" + dat += "Status: [on ? "On" : "Off"]
" + dat += "Maintenance panel panel is [open ? "opened" : "closed"]
" + + dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
" + if(!locked || issilicon(user) || IsAdminGhost(user)) + dat += "Extinguish Fires: [extinguish_fires ? "Yes" : "No"]
" + dat += "Extinguish People: [extinguish_people ? "Yes" : "No"]
" + dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" + dat += "Stationary Mode: [stationary_mode ? "Yes" : "No"]
" + + return dat + +/mob/living/simple_animal/bot/firebot/emag_act(mob/user) + ..() + if(emagged == 1) + if(user) + to_chat(user, "[src] buzzes and beeps.") + audible_message("[src] buzzes oddly!") + playsound(src, "sparks", 75, TRUE) + if(user) + old_target_fire = user + extinguish_fires = FALSE + extinguish_people = TRUE + + internal_ext.chem = "clf3" //Refill the internal extinguisher with liquid fire + internal_ext.power = 3 + internal_ext.safety = FALSE + internal_ext.precision = FALSE + internal_ext.max_water = INFINITY + internal_ext.refill() + +/mob/living/simple_animal/bot/firebot/Topic(href, href_list) + if(..()) + return TRUE + + switch(href_list["operation"]) + if("extinguish_fires") + extinguish_fires = !extinguish_fires + if("extinguish_people") + extinguish_people = !extinguish_people + if("stationary_mode") + stationary_mode = !stationary_mode + + update_controls() + update_icon() + +/mob/living/simple_animal/bot/firebot/proc/is_burning(atom/target) + if(ismob(target)) + var/mob/living/M = target + if(M.on_fire || (emagged == 1 && !M.on_fire)) + return TRUE + + else if(isturf(target)) + var/turf/open/T = target + if(T.active_hotspot) + return TRUE + + return FALSE + +/mob/living/simple_animal/bot/firebot/handle_automated_action() + if(!..()) + return + + if(IsStun()) + old_target_fire = target_fire + target_fire = null + mode = BOT_IDLE + return + + if(prob(1) && target_fire == null) + var/list/messagevoice = list("No fires detected." = 'sound/voice/firebot/nofires.ogg', + "Only you can prevent station fires." = 'sound/voice/firebot/onlyyou.ogg', + "Temperature nominal." = 'sound/voice/firebot/tempnominal.ogg', + "Keep it cool." = 'sound/voice/firebot/keepitcool.ogg') + var/message = pick(messagevoice) + speak(message) + playsound(src, messagevoice[message], 50) + + // Couldn't reach the target, reset and try again ignoring the old one + if(frustration > 8) + old_target_fire = target_fire + soft_reset() + + // We extinguished our target or it was deleted + if(QDELETED(target_fire) || !is_burning(target_fire) || isdead(target_fire)) + target_fire = null + var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE) + + if(extinguish_people) + target_fire = scan(/mob/living, old_target_fire, scan_range) // Scan for burning humans first + + if(target_fire == null && extinguish_fires) + target_fire = scan(/turf/open, old_target_fire, scan_range) // Scan for burning turfs second + + old_target_fire = target_fire + + // Target reached ENGAGE WATER CANNON + if(target_fire && (get_dist(src, target_fire) <= (emagged == 1 ? 1 : 2))) // Make the bot spray water from afar when not emagged + if((speech_cooldown + SPEECH_INTERVAL) < world.time) + if(ishuman(target_fire)) + speak("Stop, drop and roll!") + playsound(src, "sound/voice/firebot/stopdropnroll.ogg", 50, 0) + else + speak("Extinguishing!") + playsound(src, "sound/voice/firebot/extinguishing.ogg", 50, 0) + speech_cooldown = world.time + + flick("firebot1_use", src) + spray_water(target_fire, src) + + soft_reset() + + // Target ran away + else if(target_fire && path.len && (get_dist(target_fire,path[path.len]) > 2)) + path = list() + mode = BOT_IDLE + last_found = world.time + + else if(target_fire && stationary_mode) + soft_reset() + return + + if(target_fire && (get_dist(src, target_fire) > 2)) + + path = get_path_to(src, get_turf(target_fire), /turf/proc/Distance_cardinal, 0, 30, 1, id=access_card) + mode = BOT_MOVING + if(!path.len) + soft_reset() + + if(path.len > 0 && target_fire) + if(!bot_move(path[path.len])) + old_target_fire = target_fire + soft_reset() + return + + // We got a target but it's too far away from us + if(path.len > 8 && target_fire) + frustration++ + + if(auto_patrol && !target_fire && !stationary_mode) + if(mode == BOT_IDLE || mode == BOT_START_PATROL) + start_patrol() + + if(mode == BOT_PATROL) + bot_patrol() + + +//Look for burning people or turfs around the bot +/mob/living/simple_animal/bot/firebot/process_scan(atom/scan_target) + var/result + + if(scan_target == src) + return result + + if(is_burning(scan_target)) + if((detected_cooldown + DETECTED_VOICE_INTERVAL) < world.time) + speak("Fire detected!") + playsound(src, "sound/voice/firebot/detected.ogg", 50, 0) + detected_cooldown = world.time + result = scan_target + + return result + +/mob/living/simple_animal/bot/firebot/temperature_expose(datum/gas_mixture/air, temperature, volume) + if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && foam_cooldown + FOAM_INTERVAL < world.time) + new /obj/effect/particle_effect/foam/firefighting(loc) + foam_cooldown = world.time + ..() + +/mob/living/simple_animal/bot/firebot/proc/spray_water(atom/target, mob/user) + if(stationary_mode) + flick("firebots_use", user) + else + flick("firebot1_use", user) + internal_ext.afterattack(target, user, null) + +/mob/living/simple_animal/bot/firebot/update_icon() + if(!on) + icon_state = "firebot0" + return + if(IsStun()) + icon_state = "firebots1" + else if(stationary_mode) //Bot has yellow light to indicate stationary mode. + icon_state = "firebots1" + else + icon_state = "firebot1" + + +/mob/living/simple_animal/bot/firebot/explode() + on = FALSE + visible_message("[src] blows apart!") + + var/atom/Tsec = drop_location() + + new /obj/item/assembly/prox_sensor(Tsec) + new /obj/item/clothing/head/hardhat/red(Tsec) + + var/turf/T = get_turf(Tsec) + + if(isopenturf(T)) + var/turf/open/theturf = T + theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS) + + if(prob(50)) + drop_part(robot_arm, Tsec) + + do_sparks(3, TRUE, src) + ..() + +/obj/machinery/bot_core/firebot + req_one_access = list(ACCESS_CONSTRUCTION, ACCESS_ROBOTICS) + +#undef SPEECH_INTERVAL +#undef DETECTED_VOICE_INTERVAL +#undef FOAM_INTERVAL + diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 7167d87bde..5a21d33d5a 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -343,7 +343,7 @@ /mob/living/simple_animal/bot/medbot/proc/assess_patient(mob/living/carbon/C) //Time to see if they need medical help! - if(C.stat == DEAD || (C.has_trait(TRAIT_FAKEDEATH))) + if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH))) return FALSE //welp too late for them! if(!(loc == C.loc) && !(isturf(C.loc) && isturf(loc))) @@ -421,7 +421,7 @@ soft_reset() return - if(C.stat == DEAD || (C.has_trait(TRAIT_FAKEDEATH))) + if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH))) var/list/messagevoice = list("No! Stay with me!" = 'sound/voice/medbot/no.ogg',"Live, damnit! LIVE!" = 'sound/voice/medbot/live.ogg',"I...I've never lost a patient before. Not today, I mean." = 'sound/voice/medbot/lost.ogg') var/message = pick(messagevoice) speak(message) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index ff91ca7dc3..3cc8822d02 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -343,7 +343,7 @@ /mob/living/simple_animal/hostile/construct/harvester/AttackingTarget() if(iscarbon(target)) var/mob/living/carbon/C = target - if(C.has_trait(TRAIT_NODISMEMBER)) + if(HAS_TRAIT(C, TRAIT_NODISMEMBER)) return ..() //ATTACK! var/list/parts = list() var/undismembermerable_limbs = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 646987b155..80e0172f45 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -43,7 +43,7 @@ // Changeling egg can survive in aliens! var/mob/living/carbon/C = target if(C.stat == DEAD) - if(C.has_trait(TRAIT_XENO_HOST)) + if(HAS_TRAIT(C, TRAIT_XENO_HOST)) to_chat(src, "A foreign presence repels us from this body. Perhaps we should try to infest another?") return Infect(target) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 0a8c0431bc..a70ca2a8e6 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -353,6 +353,10 @@ vore_attack(src,L,src) else return L.attack_animal(src) + else + return L.attack_animal(src) //literally every single fucking one of these need this I guess. + else + return target.attack_animal(src) else return target.attack_animal(src) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index c491b3e78d..7cf8defc0f 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -558,7 +558,7 @@ Difficulty: Very Hard H.regenerate_limbs() H.regenerate_organs() H.revive(1,0) - H.add_trait(TRAIT_NOCLONE, MAGIC_TRAIT) //Free revives, but significantly limits your options for reviving except via the crystal + ADD_TRAIT(H, TRAIT_NOCLONE, MAGIC_TRAIT) //Free revives, but significantly limits your options for reviving except via the crystal H.grab_ghost(force = TRUE) /obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans @@ -721,7 +721,7 @@ Difficulty: Very Hard if(isliving(A) && holder_animal) var/mob/living/L = A L.notransform = 1 - L.add_trait(TRAIT_MUTE, STASIS_MUTE) + ADD_TRAIT(L, TRAIT_MUTE, STASIS_MUTE) L.status_flags |= GODMODE L.mind.transfer_to(holder_animal) var/obj/effect/proc_holder/spell/targeted/exit_possession/P = new /obj/effect/proc_holder/spell/targeted/exit_possession @@ -731,7 +731,7 @@ Difficulty: Very Hard /obj/structure/closet/stasis/dump_contents(var/kill = 1) STOP_PROCESSING(SSobj, src) for(var/mob/living/L in src) - L.remove_trait(TRAIT_MUTE, STASIS_MUTE) + REMOVE_TRAIT(L, TRAIT_MUTE, STASIS_MUTE) L.status_flags &= ~GODMODE L.notransform = 0 if(holder_animal) 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 293e3e21fd..6577553a6a 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -30,7 +30,7 @@ Cross Blasts and the AoE burst gain additional range as Hierophant loses health, When Hierophant dies, it stops trying to murder you and shrinks into a small form, which, while much weaker, is still quite effective. - The smaller club can place a teleport beacon, allowing the user to teleport themself and their allies to the beacon. -Difficulty: Hard +Difficulty: Normal */ @@ -47,11 +47,11 @@ Difficulty: Hard icon = 'icons/mob/lavaland/hierophant_new.dmi' faction = list("boss") //asteroid mobs? get that shit out of my beautiful square house speak_emote = list("preaches") - armour_penetration = 50 + armour_penetration = 75 melee_damage_lower = 15 - melee_damage_upper = 15 + melee_damage_upper = 20 speed = 1 - move_to_delay = 10 + move_to_delay = 11 ranged = 1 ranged_cooldown_time = 40 aggro_vision_range = 21 //so it can see to one side of the arena to the other 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 23f08ab234..15f2a0a834 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 @@ -187,12 +187,12 @@ var/mob/living/carbon/C = L var/obj/item/clothing/S = C.get_item_by_slot(SLOT_WEAR_SUIT) if(S && S.resistance_flags & GOLIATH_RESISTANCE) - L.Stun(75) + L.Stun(25) else if(S && S.resistance_flags & GOLIATH_WEAKNESS) - L.Stun(125) + L.Stun(115) else - L.Stun(100) - L.adjustBruteLoss(rand(10,15)) + L.Stun(75) + L.adjustBruteLoss(rand(15,20)) // Less stun more harm latched = TRUE if(!latched) retract() 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 12c98b8b5d..82f85766c2 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 @@ -290,7 +290,7 @@ gloves = /obj/item/clothing/gloves/color/black mask = /obj/item/clothing/mask/gas/explorer if(prob(20)) - suit = pickweight(list(/obj/item/clothing/suit/hooded/explorer = 6, /obj/item/clothing/suit/hooded/cloak/goliath = 2, /obj/item/clothing/suit/hooded/explorer/exo = 6, /obj/item/clothing/suit/hooded/explorer/seva = 6)) + suit = pickweight(list(/obj/item/clothing/suit/hooded/explorer/standard = 6, /obj/item/clothing/suit/hooded/cloak/goliath = 2, /obj/item/clothing/suit/hooded/explorer/exo = 6, /obj/item/clothing/suit/hooded/explorer/seva = 6)) if(prob(30)) r_pocket = pickweight(list(/obj/item/stack/marker_beacon = 20, /obj/item/stack/spacecash/c1000 = 7, /obj/item/reagent_containers/hypospray/medipen/survival = 2, /obj/item/borg/upgrade/modkit/damage = 1 )) if(prob(10)) diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 2c45743c55..dd08a009d4 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -130,7 +130,7 @@ /mob/living/simple_animal/hostile/syndicate/melee/bullet_act(obj/item/projectile/Proj) if(!Proj) return - if(prob(50)) + if(prob(25)) return ..() else visible_message("[src] blocks [Proj] with its shield!") diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 3d10bfd121..fc51b9afe4 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -1,71 +1,71 @@ -/mob/living/simple_animal/hostile/tree - name = "pine tree" - desc = "A pissed off tree-like alien. It seems annoyed with the festivities..." - icon = 'icons/obj/flora/pinetrees.dmi' - icon_state = "pine_1" - icon_living = "pine_1" - icon_dead = "pine_1" - icon_gib = "pine_1" - gender = NEUTER - speak_chance = 0 - turns_per_move = 5 - response_help = "brushes" - response_disarm = "pushes" - response_harm = "hits" - speed = 1 - maxHealth = 250 - health = 250 - mob_size = MOB_SIZE_LARGE - - pixel_x = -16 - - harm_intent_damage = 5 - melee_damage_lower = 8 - melee_damage_upper = 12 - attacktext = "bites" - attack_sound = 'sound/weapons/bite.ogg' - speak_emote = list("pines") - emote_taunt = list("growls") - taunt_chance = 20 - - atmos_requirements = list("min_oxy" = 2, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - unsuitable_atmos_damage = 5 - minbodytemp = 0 - maxbodytemp = 1200 - - faction = list("hostile") - deathmessage = "is hacked into pieces!" - loot = list(/obj/item/stack/sheet/mineral/wood) - gold_core_spawnable = HOSTILE_SPAWN - del_on_death = 1 - -/mob/living/simple_animal/hostile/tree/Life() - ..() - if(isopenturf(loc)) - var/turf/open/T = src.loc - if(T.air && T.air.gases[/datum/gas/carbon_dioxide]) - var/co2 = T.air.gases[/datum/gas/carbon_dioxide][MOLES] - if(co2 > 0) - if(prob(25)) - var/amt = min(co2, 9) - T.air.gases[/datum/gas/carbon_dioxide][MOLES] -= amt - T.atmos_spawn_air("o2=[amt]") - -/mob/living/simple_animal/hostile/tree/AttackingTarget() - . = ..() - if(iscarbon(target)) - var/mob/living/carbon/C = target - if(prob(15)) - C.Knockdown(60) - C.visible_message("\The [src] knocks down \the [C]!", \ - "\The [src] knocks you down!") - -/mob/living/simple_animal/hostile/tree/festivus - name = "festivus pole" - desc = "Serenity now... SERENITY NOW!" - icon_state = "festivus_pole" - icon_living = "festivus_pole" - icon_dead = "festivus_pole" - icon_gib = "festivus_pole" - loot = list(/obj/item/stack/rods) - speak_emote = list("polls") +/mob/living/simple_animal/hostile/tree + name = "pine tree" + desc = "A pissed off tree-like alien. It seems annoyed with the festivities..." + icon = 'icons/obj/flora/pinetrees.dmi' + icon_state = "pine_1" + icon_living = "pine_1" + icon_dead = "pine_1" + icon_gib = "pine_1" + gender = NEUTER + speak_chance = 0 + turns_per_move = 5 + response_help = "brushes" + response_disarm = "pushes" + response_harm = "hits" + speed = 1 + maxHealth = 250 + health = 250 + mob_size = MOB_SIZE_LARGE + + pixel_x = -16 + + harm_intent_damage = 5 + melee_damage_lower = 8 + melee_damage_upper = 12 + attacktext = "bites" + attack_sound = 'sound/weapons/bite.ogg' + speak_emote = list("pines") + emote_taunt = list("growls") + taunt_chance = 20 + + atmos_requirements = list("min_oxy" = 2, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + unsuitable_atmos_damage = 5 + minbodytemp = 0 + maxbodytemp = 1200 + + faction = list("hostile") + deathmessage = "is hacked into pieces!" + loot = list(/obj/item/stack/sheet/mineral/wood) + gold_core_spawnable = HOSTILE_SPAWN + del_on_death = 1 + +/mob/living/simple_animal/hostile/tree/Life() + ..() + if(isopenturf(loc)) + var/turf/open/T = src.loc + if(T.air && T.air.gases[/datum/gas/carbon_dioxide]) + var/co2 = T.air.gases[/datum/gas/carbon_dioxide] + if(co2 > 0) + if(prob(25)) + var/amt = min(co2, 9) + T.air.gases[/datum/gas/carbon_dioxide] -= amt + T.atmos_spawn_air("o2=[amt]") + +/mob/living/simple_animal/hostile/tree/AttackingTarget() + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/C = target + if(prob(15)) + C.Knockdown(60) + C.visible_message("\The [src] knocks down \the [C]!", \ + "\The [src] knocks you down!") + +/mob/living/simple_animal/hostile/tree/festivus + name = "festivus pole" + desc = "Serenity now... SERENITY NOW!" + icon_state = "festivus_pole" + icon_living = "festivus_pole" + icon_dead = "festivus_pole" + icon_gib = "festivus_pole" + loot = list(/obj/item/stack/rods) + speak_emote = list("polls") diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index fcb201d0ad..2517d2438d 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -1,589 +1,588 @@ -/mob/living/simple_animal - name = "animal" - icon = 'icons/mob/animal.dmi' - health = 20 - maxHealth = 20 - gender = PLURAL //placeholder - - status_flags = CANPUSH - - var/icon_living = "" - var/icon_dead = "" //icon when the animal is dead. Don't use animated icons for this. - var/icon_gib = null //We only try to show a gibbing animation if this exists. - - var/list/speak = list() - var/list/speak_emote = list()// Emotes while speaking IE: Ian [emote], [text] -- Ian barks, "WOOF!". Spoken text is generated from the speak variable. - var/speak_chance = 0 - var/list/emote_hear = list() //Hearable emotes - var/list/emote_see = list() //Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps - - var/turns_per_move = 1 - var/turns_since_move = 0 - var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals. - var/wander = 1 // Does the mob wander around when idle? - var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it. - - //Interaction - var/response_help = "pokes" - var/response_disarm = "shoves" - var/response_harm = "hits" - var/harm_intent_damage = 3 - var/force_threshold = 0 //Minimum force required to deal any damage - - //Temperature effect - var/minbodytemp = 250 - var/maxbodytemp = 350 - - //Healable by medical stacks? Defaults to yes. - var/healable = 1 - - //Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage - var/list/atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) //Leaving something at 0 means it's off - has no maximum - var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above - - //LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly - var/melee_damage_lower = 0 - var/melee_damage_upper = 0 - var/obj_damage = 0 //how much damage this simple animal does to objects, if any - var/armour_penetration = 0 //How much armour they ignore, as a flat reduction from the targets armour value - var/melee_damage_type = BRUTE //Damage type of a simple mob's melee attack, should it do damage. - var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) // 1 for full damage , 0 for none , -1 for 1:1 heal from that source - var/attacktext = "attacks" - var/attack_sound = null - var/friendly = "nuzzles" //If the mob does no damage with it's attack - var/environment_smash = ENVIRONMENT_SMASH_NONE //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls - - var/speed = 1 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster - - //Hot simple_animal baby making vars - var/list/childtype = null - var/next_scan_time = 0 - var/animal_species //Sorry, no spider+corgi buttbabies. - - //simple_animal access - var/obj/item/card/id/access_card = null //innate access uses an internal ID card - var/buffed = 0 //In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to 1, so we have something to check against - var/gold_core_spawnable = NO_SPAWN //If the mob can be spawned with a gold slime core. HOSTILE_SPAWN are spawned with plasma, FRIENDLY_SPAWN are spawned with blood - - var/mob/living/simple_animal/hostile/spawner/nest - - var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions - - var/list/loot = list() //list of things spawned at mob's loc when it dies - var/del_on_death = 0 //causes mob to be deleted on death, useful for mobs that spawn lootable corpses - var/deathmessage = "" - var/death_sound = null //The sound played on death - - var/allow_movement_on_non_turfs = FALSE - - var/attacked_sound = "punch" //Played when someone punches the creature - - var/dextrous = FALSE //If the creature has, and can use, hands - var/dextrous_hud_type = /datum/hud/dextrous - var/datum/personal_crafting/handcrafting - - var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players) - - var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check. - - //domestication - var/tame = 0 - - var/my_z // I don't want to confuse this with client registered_z - - var/do_footstep = FALSE - -/mob/living/simple_animal/Initialize() - . = ..() - GLOB.simple_animals[AIStatus] += src - handcrafting = new() - if(gender == PLURAL) - gender = pick(MALE,FEMALE) - if(!real_name) - real_name = name - if(!loc) - stack_trace("Simple animal being instantiated in nullspace") - update_simplemob_varspeed() - -/mob/living/simple_animal/Destroy() - GLOB.simple_animals[AIStatus] -= src - if (SSnpcpool.state == SS_PAUSED && LAZYLEN(SSnpcpool.currentrun)) - SSnpcpool.currentrun -= src - - if(nest) - nest.spawned_mobs -= src - nest = null - - var/turf/T = get_turf(src) - if (T && AIStatus == AI_Z_OFF) - SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src - - return ..() - -/mob/living/simple_animal/initialize_footstep() - if(do_footstep) - ..() - -/mob/living/simple_animal/updatehealth() - ..() - health = CLAMP(health, 0, maxHealth) - -/mob/living/simple_animal/update_stat() - if(status_flags & GODMODE) - return - if(stat != DEAD) - if(health <= 0) - death() - else - stat = CONSCIOUS - med_hud_set_status() - - -/mob/living/simple_animal/handle_status_effects() - ..() - if(stuttering) - stuttering = 0 - -/mob/living/simple_animal/proc/handle_automated_action() - set waitfor = FALSE - return - -/mob/living/simple_animal/proc/handle_automated_movement() - set waitfor = FALSE - if(!stop_automated_movement && wander) - if((isturf(src.loc) || allow_movement_on_non_turfs) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc. - turns_since_move++ - if(turns_since_move >= turns_per_move) - if(!(stop_automated_movement_when_pulled && pulledby)) //Some animals don't move when pulled - var/anydir = pick(GLOB.cardinals) - if(Process_Spacemove(anydir)) - Move(get_step(src, anydir), anydir) - turns_since_move = 0 - return 1 - -/mob/living/simple_animal/proc/handle_automated_speech(var/override) - set waitfor = FALSE - if(speak_chance) - if(prob(speak_chance) || override) - if(speak && speak.len) - if((emote_hear && emote_hear.len) || (emote_see && emote_see.len)) - var/length = speak.len - if(emote_hear && emote_hear.len) - length += emote_hear.len - if(emote_see && emote_see.len) - length += emote_see.len - var/randomValue = rand(1,length) - if(randomValue <= speak.len) - say(pick(speak), forced = "poly") - else - randomValue -= speak.len - if(emote_see && randomValue <= emote_see.len) - emote("me [pick(emote_see)]", 1) - else - emote("me [pick(emote_hear)]", 2) - else - say(pick(speak), forced = "poly") - else - if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len)) - emote("me", 1, pick(emote_see)) - if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len)) - emote("me", 2, pick(emote_hear)) - if((emote_hear && emote_hear.len) && (emote_see && emote_see.len)) - var/length = emote_hear.len + emote_see.len - var/pick = rand(1,length) - if(pick <= emote_see.len) - emote("me", 1, pick(emote_see)) - else - emote("me", 2, pick(emote_hear)) - - -/mob/living/simple_animal/proc/environment_is_safe(datum/gas_mixture/environment, check_temp = FALSE) - . = TRUE - - if(pulledby && pulledby.grab_state >= GRAB_KILL && atmos_requirements["min_oxy"]) - . = FALSE //getting choked - - if(isturf(src.loc) && isopenturf(src.loc)) - var/turf/open/ST = src.loc - if(ST.air) - var/ST_gases = ST.air.gases - ST.air.assert_gases(arglist(GLOB.hardcoded_gases)) - - var/tox = ST_gases[/datum/gas/plasma][MOLES] - var/oxy = ST_gases[/datum/gas/oxygen][MOLES] - var/n2 = ST_gases[/datum/gas/nitrogen][MOLES] - var/co2 = ST_gases[/datum/gas/carbon_dioxide][MOLES] - - ST.air.garbage_collect() - - if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"]) - . = FALSE - else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"]) - . = FALSE - else if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"]) - . = FALSE - else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"]) - . = FALSE - else if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"]) - . = FALSE - else if(atmos_requirements["max_n2"] && n2 > atmos_requirements["max_n2"]) - . = FALSE - else if(atmos_requirements["min_co2"] && co2 < atmos_requirements["min_co2"]) - . = FALSE - else if(atmos_requirements["max_co2"] && co2 > atmos_requirements["max_co2"]) - . = FALSE - else - if(atmos_requirements["min_oxy"] || atmos_requirements["min_tox"] || atmos_requirements["min_n2"] || atmos_requirements["min_co2"]) - . = FALSE - - if(check_temp) - var/areatemp = get_temperature(environment) - if((areatemp < minbodytemp) || (areatemp > maxbodytemp)) - . = FALSE - - -/mob/living/simple_animal/handle_environment(datum/gas_mixture/environment) - var/atom/A = src.loc - if(isturf(A)) - var/areatemp = get_temperature(environment) - if( abs(areatemp - bodytemperature) > 5) - var/diff = areatemp - bodytemperature - diff = diff / 5 - adjust_bodytemperature(diff) - - if(!environment_is_safe(environment)) - adjustHealth(unsuitable_atmos_damage) - - handle_temperature_damage() - -/mob/living/simple_animal/proc/handle_temperature_damage() - if((bodytemperature < minbodytemp) || (bodytemperature > maxbodytemp)) - adjustHealth(unsuitable_atmos_damage) - -/mob/living/simple_animal/gib() - if(butcher_results) - var/atom/Tsec = drop_location() - for(var/path in butcher_results) - for(var/i in 1 to butcher_results[path]) - new path(Tsec) - ..() - -/mob/living/simple_animal/gib_animation() - if(icon_gib) - new /obj/effect/temp_visual/gib_animation/animal(loc, icon_gib) - -/mob/living/simple_animal/say_mod(input, message_mode) - if(speak_emote && speak_emote.len) - verb_say = pick(speak_emote) - . = ..() - -/mob/living/simple_animal/emote(act, m_type=1, message = null, intentional = FALSE) - if(stat) - return - if(act == "scream") - message = "makes a loud and pained whimper." //ugly hack to stop animals screaming when crushed :P - act = "me" - ..(act, m_type, message) - -/mob/living/simple_animal/proc/set_varspeed(var_value) - speed = var_value - update_simplemob_varspeed() - -/mob/living/simple_animal/proc/update_simplemob_varspeed() - if(speed == 0) - remove_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE) - add_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE, 100, multiplicative_slowdown = speed, override = TRUE) - -/mob/living/simple_animal/Stat() - ..() - if(statpanel("Status")) - stat(null, "Health: [round((health / maxHealth) * 100)]%") - return 1 - -/mob/living/simple_animal/proc/drop_loot() - if(loot.len) - for(var/i in loot) - new i(loc) - -/mob/living/simple_animal/death(gibbed) - movement_type &= ~FLYING - if(nest) - nest.spawned_mobs -= src - nest = null - drop_loot() - if(dextrous) - drop_all_held_items() - if(!gibbed) - if(death_sound) - playsound(get_turf(src),death_sound, 200, 1) - if(deathmessage || !del_on_death) - emote("deathgasp") - if(del_on_death) - ..() - //Prevent infinite loops if the mob Destroy() is overridden in such - //a manner as to cause a call to death() again - del_on_death = FALSE - qdel(src) - else - health = 0 - icon_state = icon_dead - density = FALSE - lying = 1 - ..() - -/mob/living/simple_animal/proc/CanAttack(atom/the_target) - if(see_invisible < the_target.invisibility) - return FALSE - if(ismob(the_target)) - var/mob/M = the_target - if(M.status_flags & GODMODE) - return FALSE - if (isliving(the_target)) - var/mob/living/L = the_target - if(L.stat != CONSCIOUS) - return FALSE - if (ismecha(the_target)) - var/obj/mecha/M = the_target - if (M.occupant) - return FALSE - return TRUE - -/mob/living/simple_animal/handle_fire() - return - -/mob/living/simple_animal/IgniteMob() - return FALSE - -/mob/living/simple_animal/ExtinguishMob() - return - -/mob/living/simple_animal/revive(full_heal = 0, admin_revive = 0) - if(..()) //successfully ressuscitated from death - icon = initial(icon) - icon_state = icon_living - density = initial(density) - lying = 0 - . = 1 - movement_type = initial(movement_type) - -/mob/living/simple_animal/proc/make_babies() // <3 <3 <3 - if(gender != FEMALE || stat || next_scan_time > world.time || !childtype || !animal_species || !SSticker.IsRoundInProgress()) - return - next_scan_time = world.time + 400 - var/alone = 1 - var/mob/living/simple_animal/partner - var/children = 0 - for(var/mob/M in view(7, src)) - if(M.stat != CONSCIOUS) //Check if it's conscious FIRST. - continue - else if(istype(M, childtype)) //Check for children SECOND. - children++ - else if(istype(M, animal_species)) - if(M.ckey) - continue - else if(!istype(M, childtype) && M.gender == MALE) //Better safe than sorry ;_; - partner = M - - else if(isliving(M) && !faction_check_mob(M)) //shyness check. we're not shy in front of things that share a faction with us. - return //we never mate when not alone, so just abort early - - if(alone && partner && children < 3) - var/childspawn = pickweight(childtype) - var/turf/target = get_turf(loc) - if(target) - return new childspawn(target) - -/mob/living/simple_animal/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) - if(incapacitated()) - to_chat(src, "You can't do that right now!") - return FALSE - if(be_close && !in_range(M, src)) - to_chat(src, "You are too far away!") - return FALSE - if(!(no_dextery || dextrous)) - to_chat(src, "You don't have the dexterity to do this!") - return FALSE - return TRUE - -/mob/living/simple_animal/stripPanelUnequip(obj/item/what, mob/who, where) - if(!canUseTopic(who, BE_CLOSE)) - return - else - ..() - -/mob/living/simple_animal/stripPanelEquip(obj/item/what, mob/who, where) - if(!canUseTopic(who, BE_CLOSE)) - return - else - ..() - -/mob/living/simple_animal/update_canmove(value_otherwise = TRUE) - if(IsUnconscious() || IsStun() || IsKnockdown() || stat || resting) - drop_all_held_items() - canmove = FALSE - else if(buckled) - canmove = FALSE - else - canmove = value_otherwise - update_transform() - update_action_buttons_icon() - return canmove - -/mob/living/simple_animal/update_transform() - var/matrix/ntransform = matrix(transform) //aka transform.Copy() - var/changed = 0 - - if(resize != RESIZE_DEFAULT_SIZE) - changed++ - ntransform.Scale(resize) - resize = RESIZE_DEFAULT_SIZE - - if(changed) - animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT) - -/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion - toggle_ai(AI_OFF) // To prevent any weirdness. - -/mob/living/simple_animal/update_sight() - if(!client) - return - if(stat == DEAD) - sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS) - see_in_dark = 8 - see_invisible = SEE_INVISIBLE_OBSERVER - return - - see_invisible = initial(see_invisible) - see_in_dark = initial(see_in_dark) - sight = initial(sight) - - if(client.eye != src) - var/atom/A = client.eye - if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates. - return - sync_lighting_plane_alpha() - -/mob/living/simple_animal/get_idcard() - return access_card - -/mob/living/simple_animal/OpenCraftingMenu() - if(dextrous) - handcrafting.ui_interact(src) - -/mob/living/simple_animal/can_hold_items() - return dextrous - -/mob/living/simple_animal/IsAdvancedToolUser() - return dextrous - -/mob/living/simple_animal/activate_hand(selhand) - if(!dextrous) - return ..() - if(!selhand) - selhand = (active_hand_index % held_items.len)+1 - if(istext(selhand)) - selhand = lowertext(selhand) - if(selhand == "right" || selhand == "r") - selhand = 2 - if(selhand == "left" || selhand == "l") - selhand = 1 - if(selhand != active_hand_index) - swap_hand(selhand) - else - mode() - -/mob/living/simple_animal/swap_hand(hand_index) - if(!dextrous) - return ..() - if(!hand_index) - hand_index = (active_hand_index % held_items.len)+1 - var/obj/item/held_item = get_active_held_item() - if(held_item) - if(istype(held_item, /obj/item/twohanded)) - var/obj/item/twohanded/T = held_item - if(T.wielded == 1) - to_chat(usr, "Your other hand is too busy holding the [T.name].") - return - var/oindex = active_hand_index - active_hand_index = hand_index - if(hud_used) - var/obj/screen/inventory/hand/H - H = hud_used.hand_slots["[hand_index]"] - if(H) - H.update_icon() - H = hud_used.hand_slots["[oindex]"] - if(H) - H.update_icon() - -/mob/living/simple_animal/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE) - . = ..(I, del_on_fail, merge_stacks) - update_inv_hands() - -/mob/living/simple_animal/update_inv_hands() - if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - var/obj/item/l_hand = get_item_for_held_index(1) - var/obj/item/r_hand = get_item_for_held_index(2) - if(r_hand) - r_hand.layer = ABOVE_HUD_LAYER - r_hand.plane = ABOVE_HUD_PLANE - r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) - client.screen |= r_hand - if(l_hand) - l_hand.layer = ABOVE_HUD_LAYER - l_hand.plane = ABOVE_HUD_PLANE - l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) - client.screen |= l_hand - -//ANIMAL RIDING - -/mob/living/simple_animal/user_buckle_mob(mob/living/M, mob/user) - GET_COMPONENT(riding_datum, /datum/component/riding) - if(riding_datum) - if(user.incapacitated()) - return - for(var/atom/movable/A in get_turf(src)) - if(A != src && A != M && A.density) - return - M.forceMove(get_turf(src)) - return ..() - -/mob/living/simple_animal/relaymove(mob/user, direction) - GET_COMPONENT(riding_datum, /datum/component/riding) - if(tame && riding_datum) - riding_datum.handle_ride(user, direction) - -/mob/living/simple_animal/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1) - . = ..() - LoadComponent(/datum/component/riding) - -/mob/living/simple_animal/proc/toggle_ai(togglestatus) - if (AIStatus != togglestatus) - if (togglestatus > 0 && togglestatus < 5) - if (togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF) - var/turf/T = get_turf(src) - if (AIStatus == AI_Z_OFF) - SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src - else - SSidlenpcpool.idle_mobs_by_zlevel[T.z] += src - GLOB.simple_animals[AIStatus] -= src - GLOB.simple_animals[togglestatus] += src - AIStatus = togglestatus - else - stack_trace("Something attempted to set simple animals AI to an invalid state: [togglestatus]") - -/mob/living/simple_animal/proc/consider_wakeup() - if (pulledby || shouldwakeup) - toggle_ai(AI_ON) - -/mob/living/simple_animal/adjustHealth(amount, updating_health = TRUE, forced = FALSE) - . = ..() - if(!ckey && !stat)//Not unconscious - if(AIStatus == AI_IDLE) - toggle_ai(AI_ON) - - -/mob/living/simple_animal/onTransitZ(old_z, new_z) - ..() - if (AIStatus == AI_Z_OFF) - SSidlenpcpool.idle_mobs_by_zlevel[old_z] -= src - toggle_ai(initial(AIStatus)) +/mob/living/simple_animal + name = "animal" + icon = 'icons/mob/animal.dmi' + health = 20 + maxHealth = 20 + gender = PLURAL //placeholder + + status_flags = CANPUSH + + var/icon_living = "" + var/icon_dead = "" //icon when the animal is dead. Don't use animated icons for this. + var/icon_gib = null //We only try to show a gibbing animation if this exists. + + var/list/speak = list() + var/list/speak_emote = list()// Emotes while speaking IE: Ian [emote], [text] -- Ian barks, "WOOF!". Spoken text is generated from the speak variable. + var/speak_chance = 0 + var/list/emote_hear = list() //Hearable emotes + var/list/emote_see = list() //Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps + + var/turns_per_move = 1 + var/turns_since_move = 0 + var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals. + var/wander = 1 // Does the mob wander around when idle? + var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it. + + //Interaction + var/response_help = "pokes" + var/response_disarm = "shoves" + var/response_harm = "hits" + var/harm_intent_damage = 3 + var/force_threshold = 0 //Minimum force required to deal any damage + + //Temperature effect + var/minbodytemp = 250 + var/maxbodytemp = 350 + + //Healable by medical stacks? Defaults to yes. + var/healable = 1 + + //Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage + var/list/atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) //Leaving something at 0 means it's off - has no maximum + var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above + + //LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly + var/melee_damage_lower = 0 + var/melee_damage_upper = 0 + var/obj_damage = 0 //how much damage this simple animal does to objects, if any + var/armour_penetration = 0 //How much armour they ignore, as a flat reduction from the targets armour value + var/melee_damage_type = BRUTE //Damage type of a simple mob's melee attack, should it do damage. + var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) // 1 for full damage , 0 for none , -1 for 1:1 heal from that source + var/attacktext = "attacks" + var/attack_sound = null + var/friendly = "nuzzles" //If the mob does no damage with it's attack + var/environment_smash = ENVIRONMENT_SMASH_NONE //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls + + var/speed = 1 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster + + //Hot simple_animal baby making vars + var/list/childtype = null + var/next_scan_time = 0 + var/animal_species //Sorry, no spider+corgi buttbabies. + + //simple_animal access + var/obj/item/card/id/access_card = null //innate access uses an internal ID card + var/buffed = 0 //In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to 1, so we have something to check against + var/gold_core_spawnable = NO_SPAWN //If the mob can be spawned with a gold slime core. HOSTILE_SPAWN are spawned with plasma, FRIENDLY_SPAWN are spawned with blood + + var/mob/living/simple_animal/hostile/spawner/nest + + var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions + + var/list/loot = list() //list of things spawned at mob's loc when it dies + var/del_on_death = 0 //causes mob to be deleted on death, useful for mobs that spawn lootable corpses + var/deathmessage = "" + var/death_sound = null //The sound played on death + + var/allow_movement_on_non_turfs = FALSE + + var/attacked_sound = "punch" //Played when someone punches the creature + + var/dextrous = FALSE //If the creature has, and can use, hands + var/dextrous_hud_type = /datum/hud/dextrous + var/datum/personal_crafting/handcrafting + + var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players) + + var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check. + + //domestication + var/tame = 0 + + var/my_z // I don't want to confuse this with client registered_z + + var/do_footstep = FALSE + +/mob/living/simple_animal/Initialize() + . = ..() + GLOB.simple_animals[AIStatus] += src + handcrafting = new() + if(gender == PLURAL) + gender = pick(MALE,FEMALE) + if(!real_name) + real_name = name + if(!loc) + stack_trace("Simple animal being instantiated in nullspace") + update_simplemob_varspeed() + +/mob/living/simple_animal/Destroy() + GLOB.simple_animals[AIStatus] -= src + if (SSnpcpool.state == SS_PAUSED && LAZYLEN(SSnpcpool.currentrun)) + SSnpcpool.currentrun -= src + + if(nest) + nest.spawned_mobs -= src + nest = null + + var/turf/T = get_turf(src) + if (T && AIStatus == AI_Z_OFF) + SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src + + return ..() + +/mob/living/simple_animal/initialize_footstep() + if(do_footstep) + ..() + +/mob/living/simple_animal/updatehealth() + ..() + health = CLAMP(health, 0, maxHealth) + +/mob/living/simple_animal/update_stat() + if(status_flags & GODMODE) + return + if(stat != DEAD) + if(health <= 0) + death() + else + stat = CONSCIOUS + med_hud_set_status() + + +/mob/living/simple_animal/handle_status_effects() + ..() + if(stuttering) + stuttering = 0 + +/mob/living/simple_animal/proc/handle_automated_action() + set waitfor = FALSE + return + +/mob/living/simple_animal/proc/handle_automated_movement() + set waitfor = FALSE + if(!stop_automated_movement && wander) + if((isturf(src.loc) || allow_movement_on_non_turfs) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc. + turns_since_move++ + if(turns_since_move >= turns_per_move) + if(!(stop_automated_movement_when_pulled && pulledby)) //Some animals don't move when pulled + var/anydir = pick(GLOB.cardinals) + if(Process_Spacemove(anydir)) + Move(get_step(src, anydir), anydir) + turns_since_move = 0 + return 1 + +/mob/living/simple_animal/proc/handle_automated_speech(var/override) + set waitfor = FALSE + if(speak_chance) + if(prob(speak_chance) || override) + if(speak && speak.len) + if((emote_hear && emote_hear.len) || (emote_see && emote_see.len)) + var/length = speak.len + if(emote_hear && emote_hear.len) + length += emote_hear.len + if(emote_see && emote_see.len) + length += emote_see.len + var/randomValue = rand(1,length) + if(randomValue <= speak.len) + say(pick(speak), forced = "poly") + else + randomValue -= speak.len + if(emote_see && randomValue <= emote_see.len) + emote("me [pick(emote_see)]", 1) + else + emote("me [pick(emote_hear)]", 2) + else + say(pick(speak), forced = "poly") + else + if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len)) + emote("me", 1, pick(emote_see)) + if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len)) + emote("me", 2, pick(emote_hear)) + if((emote_hear && emote_hear.len) && (emote_see && emote_see.len)) + var/length = emote_hear.len + emote_see.len + var/pick = rand(1,length) + if(pick <= emote_see.len) + emote("me", 1, pick(emote_see)) + else + emote("me", 2, pick(emote_hear)) + + +/mob/living/simple_animal/proc/environment_is_safe(datum/gas_mixture/environment, check_temp = FALSE) + . = TRUE + + if(pulledby && pulledby.grab_state >= GRAB_KILL && atmos_requirements["min_oxy"]) + . = FALSE //getting choked + + if(isturf(src.loc) && isopenturf(src.loc)) + var/turf/open/ST = src.loc + if(ST.air) + var/ST_gases = ST.air.gases + + var/tox = ST_gases[/datum/gas/plasma] + var/oxy = ST_gases[/datum/gas/oxygen] + var/n2 = ST_gases[/datum/gas/nitrogen] + var/co2 = ST_gases[/datum/gas/carbon_dioxide] + + GAS_GARBAGE_COLLECT(ST.air.gases) + + if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"]) + . = FALSE + else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"]) + . = FALSE + else if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"]) + . = FALSE + else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"]) + . = FALSE + else if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"]) + . = FALSE + else if(atmos_requirements["max_n2"] && n2 > atmos_requirements["max_n2"]) + . = FALSE + else if(atmos_requirements["min_co2"] && co2 < atmos_requirements["min_co2"]) + . = FALSE + else if(atmos_requirements["max_co2"] && co2 > atmos_requirements["max_co2"]) + . = FALSE + else + if(atmos_requirements["min_oxy"] || atmos_requirements["min_tox"] || atmos_requirements["min_n2"] || atmos_requirements["min_co2"]) + . = FALSE + + if(check_temp) + var/areatemp = get_temperature(environment) + if((areatemp < minbodytemp) || (areatemp > maxbodytemp)) + . = FALSE + + +/mob/living/simple_animal/handle_environment(datum/gas_mixture/environment) + var/atom/A = src.loc + if(isturf(A)) + var/areatemp = get_temperature(environment) + if( abs(areatemp - bodytemperature) > 5) + var/diff = areatemp - bodytemperature + diff = diff / 5 + adjust_bodytemperature(diff) + + if(!environment_is_safe(environment)) + adjustHealth(unsuitable_atmos_damage) + + handle_temperature_damage() + +/mob/living/simple_animal/proc/handle_temperature_damage() + if((bodytemperature < minbodytemp) || (bodytemperature > maxbodytemp)) + adjustHealth(unsuitable_atmos_damage) + +/mob/living/simple_animal/gib() + if(butcher_results) + var/atom/Tsec = drop_location() + for(var/path in butcher_results) + for(var/i in 1 to butcher_results[path]) + new path(Tsec) + ..() + +/mob/living/simple_animal/gib_animation() + if(icon_gib) + new /obj/effect/temp_visual/gib_animation/animal(loc, icon_gib) + +/mob/living/simple_animal/say_mod(input, message_mode) + if(speak_emote && speak_emote.len) + verb_say = pick(speak_emote) + . = ..() + +/mob/living/simple_animal/emote(act, m_type=1, message = null, intentional = FALSE) + if(stat) + return + if(act == "scream") + message = "makes a loud and pained whimper." //ugly hack to stop animals screaming when crushed :P + act = "me" + ..(act, m_type, message) + +/mob/living/simple_animal/proc/set_varspeed(var_value) + speed = var_value + update_simplemob_varspeed() + +/mob/living/simple_animal/proc/update_simplemob_varspeed() + if(speed == 0) + remove_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE) + add_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE, 100, multiplicative_slowdown = speed, override = TRUE) + +/mob/living/simple_animal/Stat() + ..() + if(statpanel("Status")) + stat(null, "Health: [round((health / maxHealth) * 100)]%") + return 1 + +/mob/living/simple_animal/proc/drop_loot() + if(loot.len) + for(var/i in loot) + new i(loc) + +/mob/living/simple_animal/death(gibbed) + movement_type &= ~FLYING + if(nest) + nest.spawned_mobs -= src + nest = null + drop_loot() + if(dextrous) + drop_all_held_items() + if(!gibbed) + if(death_sound) + playsound(get_turf(src),death_sound, 200, 1) + if(deathmessage || !del_on_death) + emote("deathgasp") + if(del_on_death) + ..() + //Prevent infinite loops if the mob Destroy() is overridden in such + //a manner as to cause a call to death() again + del_on_death = FALSE + qdel(src) + else + health = 0 + icon_state = icon_dead + density = FALSE + lying = 1 + ..() + +/mob/living/simple_animal/proc/CanAttack(atom/the_target) + if(see_invisible < the_target.invisibility) + return FALSE + if(ismob(the_target)) + var/mob/M = the_target + if(M.status_flags & GODMODE) + return FALSE + if (isliving(the_target)) + var/mob/living/L = the_target + if(L.stat != CONSCIOUS) + return FALSE + if (ismecha(the_target)) + var/obj/mecha/M = the_target + if (M.occupant) + return FALSE + return TRUE + +/mob/living/simple_animal/handle_fire() + return + +/mob/living/simple_animal/IgniteMob() + return FALSE + +/mob/living/simple_animal/ExtinguishMob() + return + +/mob/living/simple_animal/revive(full_heal = 0, admin_revive = 0) + if(..()) //successfully ressuscitated from death + icon = initial(icon) + icon_state = icon_living + density = initial(density) + lying = 0 + . = 1 + movement_type = initial(movement_type) + +/mob/living/simple_animal/proc/make_babies() // <3 <3 <3 + if(gender != FEMALE || stat || next_scan_time > world.time || !childtype || !animal_species || !SSticker.IsRoundInProgress()) + return + next_scan_time = world.time + 400 + var/alone = 1 + var/mob/living/simple_animal/partner + var/children = 0 + for(var/mob/M in view(7, src)) + if(M.stat != CONSCIOUS) //Check if it's conscious FIRST. + continue + else if(istype(M, childtype)) //Check for children SECOND. + children++ + else if(istype(M, animal_species)) + if(M.ckey) + continue + else if(!istype(M, childtype) && M.gender == MALE) //Better safe than sorry ;_; + partner = M + + else if(isliving(M) && !faction_check_mob(M)) //shyness check. we're not shy in front of things that share a faction with us. + return //we never mate when not alone, so just abort early + + if(alone && partner && children < 3) + var/childspawn = pickweight(childtype) + var/turf/target = get_turf(loc) + if(target) + return new childspawn(target) + +/mob/living/simple_animal/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE) + if(incapacitated()) + to_chat(src, "You can't do that right now!") + return FALSE + if(be_close && !in_range(M, src)) + to_chat(src, "You are too far away!") + return FALSE + if(!(no_dextery || dextrous)) + to_chat(src, "You don't have the dexterity to do this!") + return FALSE + return TRUE + +/mob/living/simple_animal/stripPanelUnequip(obj/item/what, mob/who, where) + if(!canUseTopic(who, BE_CLOSE)) + return + else + ..() + +/mob/living/simple_animal/stripPanelEquip(obj/item/what, mob/who, where) + if(!canUseTopic(who, BE_CLOSE)) + return + else + ..() + +/mob/living/simple_animal/update_canmove(value_otherwise = TRUE) + if(IsUnconscious() || IsStun() || IsKnockdown() || stat || resting) + drop_all_held_items() + canmove = FALSE + else if(buckled) + canmove = FALSE + else + canmove = value_otherwise + update_transform() + update_action_buttons_icon() + return canmove + +/mob/living/simple_animal/update_transform() + var/matrix/ntransform = matrix(transform) //aka transform.Copy() + var/changed = 0 + + if(resize != RESIZE_DEFAULT_SIZE) + changed++ + ntransform.Scale(resize) + resize = RESIZE_DEFAULT_SIZE + + if(changed) + animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT) + +/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion + toggle_ai(AI_OFF) // To prevent any weirdness. + +/mob/living/simple_animal/update_sight() + if(!client) + return + if(stat == DEAD) + sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS) + see_in_dark = 8 + see_invisible = SEE_INVISIBLE_OBSERVER + return + + see_invisible = initial(see_invisible) + see_in_dark = initial(see_in_dark) + sight = initial(sight) + + if(client.eye != src) + var/atom/A = client.eye + if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates. + return + sync_lighting_plane_alpha() + +/mob/living/simple_animal/get_idcard() + return access_card + +/mob/living/simple_animal/OpenCraftingMenu() + if(dextrous) + handcrafting.ui_interact(src) + +/mob/living/simple_animal/can_hold_items() + return dextrous + +/mob/living/simple_animal/IsAdvancedToolUser() + return dextrous + +/mob/living/simple_animal/activate_hand(selhand) + if(!dextrous) + return ..() + if(!selhand) + selhand = (active_hand_index % held_items.len)+1 + if(istext(selhand)) + selhand = lowertext(selhand) + if(selhand == "right" || selhand == "r") + selhand = 2 + if(selhand == "left" || selhand == "l") + selhand = 1 + if(selhand != active_hand_index) + swap_hand(selhand) + else + mode() + +/mob/living/simple_animal/swap_hand(hand_index) + if(!dextrous) + return ..() + if(!hand_index) + hand_index = (active_hand_index % held_items.len)+1 + var/obj/item/held_item = get_active_held_item() + if(held_item) + if(istype(held_item, /obj/item/twohanded)) + var/obj/item/twohanded/T = held_item + if(T.wielded == 1) + to_chat(usr, "Your other hand is too busy holding the [T.name].") + return + var/oindex = active_hand_index + active_hand_index = hand_index + if(hud_used) + var/obj/screen/inventory/hand/H + H = hud_used.hand_slots["[hand_index]"] + if(H) + H.update_icon() + H = hud_used.hand_slots["[oindex]"] + if(H) + H.update_icon() + +/mob/living/simple_animal/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE) + . = ..(I, del_on_fail, merge_stacks) + update_inv_hands() + +/mob/living/simple_animal/update_inv_hands() + if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) + var/obj/item/l_hand = get_item_for_held_index(1) + var/obj/item/r_hand = get_item_for_held_index(2) + if(r_hand) + r_hand.layer = ABOVE_HUD_LAYER + r_hand.plane = ABOVE_HUD_PLANE + r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) + client.screen |= r_hand + if(l_hand) + l_hand.layer = ABOVE_HUD_LAYER + l_hand.plane = ABOVE_HUD_PLANE + l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) + client.screen |= l_hand + +//ANIMAL RIDING + +/mob/living/simple_animal/user_buckle_mob(mob/living/M, mob/user) + GET_COMPONENT(riding_datum, /datum/component/riding) + if(riding_datum) + if(user.incapacitated()) + return + for(var/atom/movable/A in get_turf(src)) + if(A != src && A != M && A.density) + return + M.forceMove(get_turf(src)) + return ..() + +/mob/living/simple_animal/relaymove(mob/user, direction) + GET_COMPONENT(riding_datum, /datum/component/riding) + if(tame && riding_datum) + riding_datum.handle_ride(user, direction) + +/mob/living/simple_animal/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1) + . = ..() + LoadComponent(/datum/component/riding) + +/mob/living/simple_animal/proc/toggle_ai(togglestatus) + if (AIStatus != togglestatus) + if (togglestatus > 0 && togglestatus < 5) + if (togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF) + var/turf/T = get_turf(src) + if (AIStatus == AI_Z_OFF) + SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src + else + SSidlenpcpool.idle_mobs_by_zlevel[T.z] += src + GLOB.simple_animals[AIStatus] -= src + GLOB.simple_animals[togglestatus] += src + AIStatus = togglestatus + else + stack_trace("Something attempted to set simple animals AI to an invalid state: [togglestatus]") + +/mob/living/simple_animal/proc/consider_wakeup() + if (pulledby || shouldwakeup) + toggle_ai(AI_ON) + +/mob/living/simple_animal/adjustHealth(amount, updating_health = TRUE, forced = FALSE) + . = ..() + if(!ckey && !stat)//Not unconscious + if(AIStatus == AI_IDLE) + toggle_ai(AI_ON) + + +/mob/living/simple_animal/onTransitZ(old_z, new_z) + ..() + if (AIStatus == AI_Z_OFF) + SSidlenpcpool.idle_mobs_by_zlevel[old_z] -= src + toggle_ai(initial(AIStatus)) diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_animal/simple_animal_vr.dm index afb1b88d3b..4d808a11a9 100644 --- a/code/modules/mob/living/simple_animal/simple_animal_vr.dm +++ b/code/modules/mob/living/simple_animal/simple_animal_vr.dm @@ -102,20 +102,19 @@ set category = "Object" set src in oview(1) - var/datum/belly/B = vore_organs[vore_selected] - if(faction != usr.faction) - to_chat(usr,"This predator isn't friendly, and doesn't give a shit about your opinions of it digesting you.") - return - if(B.digest_mode == "Hold") + var/mob/living/carbon/human/user = usr + if(!istype(user) || user.stat) return + + if(vore_selected.digest_mode == DM_HOLD) var/confirm = alert(usr, "Enabling digestion on [name] will cause it to digest all stomach contents. Using this to break OOC prefs is against the rules. Digestion will disable itself after 20 minutes.", "Enabling [name]'s Digestion", "Enable", "Cancel") if(confirm == "Enable") - B.digest_mode = "Digest" - sleep(20 MINUTES) //12000=20 minutes - B.digest_mode = "Hold" + vore_selected.digest_mode = DM_DIGEST + sleep(20 MINUTES) + vore_selected.digest_mode = vore_default_mode else var/confirm = alert(usr, "This mob is currently set to digest all stomach contents. Do you want to disable this?", "Disabling [name]'s Digestion", "Disable", "Cancel") if(confirm == "Disable") - B.digest_mode = "Hold" + vore_selected.digest_mode = DM_HOLD // // Simple nom proc for if you get ckey'd into a simple_animal mob! Avoids grabs. diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 161362c187..ebb34fe77a 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -132,7 +132,7 @@ if(stat != DEAD) var/bz_percentage =0 if(environment.gases[/datum/gas/bz]) - bz_percentage = environment.gases[/datum/gas/bz][MOLES] / environment.total_moles() + bz_percentage = environment.gases[/datum/gas/bz] / environment.total_moles() var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis if(stat == CONSCIOUS && stasis) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 034ccc4c39..2001c61e12 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -61,6 +61,8 @@ var/mood = "" // To show its face var/mutator_used = FALSE //So you can't shove a dozen mutators into a single slime var/force_stasis = FALSE + + do_footstep = TRUE var/static/regex/slime_name_regex = new("\\w+ (baby|adult) slime \\(\\d+\\)") ///////////TIME FOR SUBSPECIES diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index d1c72069ac..5006bd2920 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -15,7 +15,7 @@ return 0 /mob/living/proc/Stun(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration - if(((status_flags & CANSTUN) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canstun) + if(((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun) if(absorb_stun(amount, ignore_canstun)) return var/datum/status_effect/incapacitating/stun/S = IsStun() @@ -26,7 +26,7 @@ return S /mob/living/proc/SetStun(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration - if(((status_flags & CANSTUN) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canstun) + if(((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun) var/datum/status_effect/incapacitating/stun/S = IsStun() if(amount <= 0) if(S) @@ -41,7 +41,7 @@ return S /mob/living/proc/AdjustStun(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration - if(((status_flags & CANSTUN) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canstun) + if(((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun) if(absorb_stun(amount, ignore_canstun)) return var/datum/status_effect/incapacitating/stun/S = IsStun() @@ -63,7 +63,7 @@ return 0 /mob/living/proc/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE) //Can't go below remaining duration - if(((status_flags & CANKNOCKDOWN) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canknockdown) + if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canknockdown) if(absorb_stun(amount, ignore_canknockdown)) return var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown() @@ -74,7 +74,7 @@ return K /mob/living/proc/SetKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE) //Sets remaining duration - if(((status_flags & CANKNOCKDOWN) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canknockdown) + if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canknockdown) var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown() if(amount <= 0) if(K) @@ -89,7 +89,7 @@ return K /mob/living/proc/AdjustKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE) //Adds to remaining duration - if(((status_flags & CANKNOCKDOWN) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canknockdown) + if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canknockdown) if(absorb_stun(amount, ignore_canknockdown)) return var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown() @@ -140,19 +140,8 @@ /////////////////////////////////// DISABILITIES //////////////////////////////////// -/mob/living/proc/add_trait(trait, source) - if(!status_traits[trait]) - status_traits[trait] = list(source) - on_add_trait(trait, source) - else - status_traits[trait] |= list(source) - -/mob/living/proc/on_add_trait(trait, source) - if(trait == TRAIT_IGNORESLOWDOWN) - update_movespeed(FALSE) - /mob/living/proc/add_quirk(quirk, spawn_effects) //separate proc due to the way these ones are handled - if(has_trait(quirk)) + if(HAS_TRAIT(src, quirk)) return if(!SSquirks || !SSquirks.quirks[quirk]) return @@ -160,119 +149,54 @@ new T (src, spawn_effects) return TRUE -/mob/living/proc/remove_trait(trait, list/sources, force) - if(!status_traits[trait]) - return - - if(locate(ROUNDSTART_TRAIT) in status_traits[trait] && !force) //mob traits applied through roundstart cannot normally be removed - return - - if(!sources) // No defined source cures the trait entirely. - status_traits -= trait - on_remove_trait(trait, sources, force) - return - - if(!islist(sources)) - sources = list(sources) - - if(LAZYLEN(sources)) - for(var/S in sources) - if(S in status_traits[trait]) - status_traits[trait] -= S - else - status_traits[trait] = list() - - if(!LAZYLEN(status_traits[trait])) - status_traits -= trait - on_remove_trait(trait, sources, force) - -/mob/living/proc/on_remove_trait(trait, list/sources, force) - if(trait == TRAIT_IGNORESLOWDOWN) - update_movespeed(FALSE) - /mob/living/proc/remove_quirk(quirk) var/datum/quirk/T = roundstart_quirks[quirk] if(T) qdel(T) return TRUE -/mob/living/proc/has_trait(trait, list/sources) - if(!status_traits[trait]) - return FALSE - - . = FALSE - - if(sources && !islist(sources)) - sources = list(sources) - if(LAZYLEN(sources)) - for(var/S in sources) - if(S in status_traits[trait]) - return TRUE - else if(LAZYLEN(status_traits[trait])) - return TRUE - /mob/living/proc/has_quirk(quirk) return roundstart_quirks[quirk] -/mob/living/proc/remove_all_traits(remove_species_traits = FALSE, remove_organ_traits = FALSE, remove_quirks = FALSE) - - var/list/blacklisted_sources = list() - if(!remove_species_traits) - blacklisted_sources += SPECIES_TRAIT - if(!remove_organ_traits) - blacklisted_sources += ORGAN_TRAIT - if(!remove_quirks) - blacklisted_sources += ROUNDSTART_TRAIT - - for(var/kebab in status_traits) - var/skip - for(var/S in blacklisted_sources) - if(S in status_traits[kebab]) - skip = TRUE - break - if(!skip) - remove_trait(kebab, null, TRUE) - CHECK_TICK - /////////////////////////////////// TRAIT PROCS //////////////////////////////////// /mob/living/proc/cure_blind(list/sources) - remove_trait(TRAIT_BLIND, sources) - if(!has_trait(TRAIT_BLIND)) + REMOVE_TRAIT(src, TRAIT_BLIND, sources) + if(!HAS_TRAIT(src, TRAIT_BLIND)) adjust_blindness(-1) /mob/living/proc/become_blind(source) - if(!has_trait(TRAIT_BLIND)) + if(!HAS_TRAIT(src, TRAIT_BLIND)) blind_eyes(1) - add_trait(TRAIT_BLIND, source) + ADD_TRAIT(src, TRAIT_BLIND, source) /mob/living/proc/cure_nearsighted(list/sources) - remove_trait(TRAIT_NEARSIGHT, sources) - if(!has_trait(TRAIT_NEARSIGHT)) + REMOVE_TRAIT(src, TRAIT_NEARSIGHT, sources) + if(!HAS_TRAIT(src, TRAIT_NEARSIGHT)) clear_fullscreen("nearsighted") /mob/living/proc/become_nearsighted(source) - if(!has_trait(TRAIT_NEARSIGHT)) + if(!HAS_TRAIT(src, TRAIT_NEARSIGHT)) overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1) - add_trait(TRAIT_NEARSIGHT, source) + ADD_TRAIT(src, TRAIT_NEARSIGHT, source) /mob/living/proc/cure_husk(list/sources) - remove_trait(TRAIT_HUSK, sources) - if(!has_trait(TRAIT_HUSK)) - remove_trait(TRAIT_DISFIGURED, "husk") + REMOVE_TRAIT(src, TRAIT_HUSK, sources) + if(!HAS_TRAIT(src, TRAIT_HUSK)) + REMOVE_TRAIT(src, TRAIT_DISFIGURED, "husk") update_body() return TRUE /mob/living/proc/become_husk(source) - if(!has_trait(TRAIT_HUSK)) - add_trait(TRAIT_DISFIGURED, "husk") + if(!HAS_TRAIT(src, TRAIT_HUSK)) + ADD_TRAIT(src, TRAIT_DISFIGURED, "husk") update_body() . = TRUE - add_trait(TRAIT_HUSK, source) + ADD_TRAIT(src, TRAIT_HUSK, source) /mob/living/proc/cure_fakedeath(list/sources) - remove_trait(TRAIT_FAKEDEATH, sources) - remove_trait(TRAIT_DEATHCOMA, sources) + REMOVE_TRAIT(src, TRAIT_FAKEDEATH, sources) + REMOVE_TRAIT(src, TRAIT_DEATHCOMA, sources) if(stat != DEAD) tod = null update_stat() @@ -282,7 +206,15 @@ return if(!silent) emote("deathgasp") - add_trait(TRAIT_FAKEDEATH, source) - add_trait(TRAIT_DEATHCOMA, source) + ADD_TRAIT(src, TRAIT_FAKEDEATH, source) + ADD_TRAIT(src, TRAIT_DEATHCOMA, source) tod = STATION_TIME_TIMESTAMP("hh:mm:ss") - update_stat() \ No newline at end of file + update_stat() + +/mob/living/proc/unignore_slowdown(list/sources) + REMOVE_TRAIT(src, TRAIT_IGNORESLOWDOWN, sources) + update_movespeed(FALSE) + +/mob/living/proc/ignore_slowdown(source) + ADD_TRAIT(src, TRAIT_IGNORESLOWDOWN, source) + update_movespeed(FALSE) \ No newline at end of file diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm index 534bf36c59..fec024cebf 100644 --- a/code/modules/mob/living/taste.dm +++ b/code/modules/mob/living/taste.dm @@ -9,7 +9,7 @@ /mob/living/carbon/get_taste_sensitivity() var/obj/item/organ/tongue/tongue = getorganslot(ORGAN_SLOT_TONGUE) - if(istype(tongue) && !has_trait(TRAIT_AGEUSIA)) + if(istype(tongue) && !HAS_TRAIT(src, TRAIT_AGEUSIA)) . = tongue.taste_sensitivity else . = 101 // can't taste anything without a tongue diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 9d662b1673..7ff8fbc0b1 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -67,8 +67,8 @@ t += "Temperature: [environment.temperature] \n" for(var/id in environment.gases) var/gas = environment.gases[id] - if(gas[MOLES]) - t+="[gas[GAS_META][META_GAS_NAME]]: [gas[MOLES]] \n" + if(gas) + t+="[GLOB.meta_gas_names[id]]: [gas] \n" to_chat(usr, t) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 35b48afa28..776bd04935 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -64,7 +64,8 @@ p++ return sanitize(t) -/proc/slur(n) +/proc/slur(n,var/strength=50) + strength = min(strength,50) var/phrase = html_decode(n) var/leng = lentext(phrase) var/counter=lentext(phrase) @@ -72,7 +73,7 @@ var/newletter="" while(counter>=1) newletter=copytext(phrase,(leng-counter)+1,(leng-counter)+2) - if(rand(1,3)==3) + if(rand(1,100)<=strength*0.5) if(lowertext(newletter)=="o") newletter="u" if(lowertext(newletter)=="s") @@ -83,17 +84,17 @@ newletter="oo" if(lowertext(newletter)=="c") newletter="k" - if(rand(1,20)==20) + if(rand(1,100) <= strength*0.25) if(newletter==" ") newletter="...huuuhhh..." if(newletter==".") newletter=" *BURP*." - switch(rand(1,20)) - if(1) + if(rand(1,100) <= strength*0.5) + if(rand(1,5) == 1) newletter+="'" - if(10) + if(rand(1,5) == 1) newletter+="[newletter]" - if(20) + if(rand(1,5) == 1) newletter+="[newletter][newletter]" newphrase+="[newletter]";counter-=1 return newphrase diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index cb532e4d5e..33f1ec81c1 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -8,7 +8,7 @@ if(ismob(mover)) if (mover in buckled_mobs) return TRUE - return (!mover.density || !density || lying) + return (!mover.density || !density || lying || (mover.throwing && mover.throwing.thrower == src && !ismob(mover))) //DO NOT USE THIS UNLESS YOU ABSOLUTELY HAVE TO. THIS IS BEING PHASED OUT FOR THE MOVESPEED MODIFICATION SYSTEM. //See mob_movespeed.dm diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index 39a0bba701..66444abf91 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -7,10 +7,10 @@ /mob/proc/update_flavor_text() set src in usr if(usr != src) - usr << "No." - var/msg = input(usr,"Set the flavor text in your 'examine' verb. Can also be used for OOC notes about your character.","Flavor Text",html_decode(flavor_text)) as message|null + to_chat(usr, "No.") + var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN*2, TRUE) - if(msg != null) + if(!isnull(msg)) msg = copytext(msg, 1, MAX_MESSAGE_LEN) msg = html_encode(msg) @@ -18,16 +18,17 @@ /mob/proc/warn_flavor_changed() if(flavor_text && flavor_text != "") // don't spam people that don't use it! - src << "

OOC Warning:

" - src << "Your flavor text is likely out of date! Change" + to_chat(src, "

OOC Warning:

") + to_chat(src, "Your flavor text is likely out of date! Change") /mob/proc/print_flavor_text() if(flavor_text && flavor_text != "") - var/msg = replacetext(flavor_text, "\n", " ") + // We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown. + var/msg = html_decode(replacetext(flavor_text, "\n", " ")) if(lentext(msg) <= 40) - return "[msg]" + return "[html_encode(msg)]" else - return "[copytext(msg, 1, 37)]... More..." + return "[html_encode(copytext(msg, 1, 37))]... More..." /mob/proc/get_top_level_mob() if(istype(src.loc,/mob)&&src.loc!=src) @@ -116,6 +117,73 @@ proc/get_top_level_mob(var/mob/S) message = null emote_type = EMOTE_VISIBLE +///////////////// SUBTLE 2: NO GHOST BOOGALOO + +/datum/emote/living/subtler + key = "subtler" + key_third_person = "subtler" + message = null + mob_type_blacklist_typecache = list(/mob/living/brain) + + +/datum/emote/living/subtler/proc/check_invalid(mob/user, input) + . = TRUE + if(copytext(input,1,5) == "says") + to_chat(user, "Invalid emote.") + else if(copytext(input,1,9) == "exclaims") + to_chat(user, "Invalid emote.") + else if(copytext(input,1,6) == "yells") + to_chat(user, "Invalid emote.") + else if(copytext(input,1,5) == "asks") + to_chat(user, "Invalid emote.") + else + . = FALSE + +/datum/emote/living/subtler/run_emote(mob/user, params, type_override = null) + if(jobban_isbanned(user, "emote")) + to_chat(user, "You cannot send subtle emotes (banned).") + return FALSE + else if(user.client && user.client.prefs.muted & MUTE_IC) + to_chat(user, "You cannot send IC messages (muted).") + return FALSE + else if(!params) + var/subtle_emote = copytext(sanitize(input("Choose an emote to display.") as message|null), 1, MAX_MESSAGE_LEN) + if(subtle_emote && !check_invalid(user, subtle_emote)) + var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable") + switch(type) + if("Visible") + emote_type = EMOTE_VISIBLE + if("Hearable") + emote_type = EMOTE_AUDIBLE + else + alert("Unable to use this emote, must be either hearable or visible.") + return + message = subtle_emote + else + return FALSE + else + message = params + if(type_override) + emote_type = type_override + . = TRUE + if(!can_run_emote(user)) + return FALSE + + user.log_message(message, INDIVIDUAL_EMOTE_LOG) + message = "[user] " + "[message]" + + for(var/mob/M) + if(M in list(/mob/living)) + M.show_message(message) + + if(emote_type == EMOTE_AUDIBLE) + user.audible_message(message=message,hearing_distance=1) + else + user.visible_message(message=message,self_message=message,vision_distance=1) + log_emote("[key_name(user)] : [message]") + + message = null + ///////////////// VERB CODE /mob/living/verb/subtle() set name = "Subtle" @@ -124,3 +192,12 @@ proc/get_top_level_mob(var/mob/S) to_chat(usr, "Speech is currently admin-disabled.") return usr.emote("subtle") + +///////////////// VERB CODE 2 +/mob/living/verb/subtler() + set name = "Subtler Anti-Ghost" + set category = "IC" + if(GLOB.say_disabled) //This is here to try to identify lag problems + to_chat(usr, "Speech is currently admin-disabled.") + return + usr.emote("subtler") diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index a1a1bbe502..606d6d4f66 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -28,7 +28,7 @@ return 0 /mob/living/proc/Unconscious(amount, updating = TRUE, ignore_canunconscious = FALSE) //Can't go below remaining duration - if(((status_flags & CANUNCONSCIOUS) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canunconscious) + if(((status_flags & CANUNCONSCIOUS) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canunconscious) var/datum/status_effect/incapacitating/unconscious/U = IsUnconscious() if(U) U.duration = max(world.time + amount, U.duration) @@ -37,7 +37,7 @@ return U /mob/living/proc/SetUnconscious(amount, updating = TRUE, ignore_canunconscious = FALSE) //Sets remaining duration - if(((status_flags & CANUNCONSCIOUS) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canunconscious) + if(((status_flags & CANUNCONSCIOUS) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canunconscious) var/datum/status_effect/incapacitating/unconscious/U = IsUnconscious() if(amount <= 0) if(U) @@ -49,7 +49,7 @@ return U /mob/living/proc/AdjustUnconscious(amount, updating = TRUE, ignore_canunconscious = FALSE) //Adds to remaining duration - if(((status_flags & CANUNCONSCIOUS) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canunconscious) + if(((status_flags & CANUNCONSCIOUS) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canunconscious) var/datum/status_effect/incapacitating/unconscious/U = IsUnconscious() if(U) U.duration += amount @@ -72,7 +72,7 @@ return 0 /mob/living/proc/Sleeping(amount, updating = TRUE, ignore_sleepimmune = FALSE) //Can't go below remaining duration - if((!has_trait(TRAIT_SLEEPIMMUNE)) || ignore_sleepimmune) + if((!HAS_TRAIT(src, TRAIT_SLEEPIMMUNE)) || ignore_sleepimmune) var/datum/status_effect/incapacitating/sleeping/S = IsSleeping() if(S) S.duration = max(world.time + amount, S.duration) @@ -81,7 +81,7 @@ return S /mob/living/proc/SetSleeping(amount, updating = TRUE, ignore_sleepimmune = FALSE) //Sets remaining duration - if((!has_trait(TRAIT_SLEEPIMMUNE)) || ignore_sleepimmune) + if((!HAS_TRAIT(src, TRAIT_SLEEPIMMUNE)) || ignore_sleepimmune) var/datum/status_effect/incapacitating/sleeping/S = IsSleeping() if(amount <= 0) if(S) @@ -93,7 +93,7 @@ return S /mob/living/proc/AdjustSleeping(amount, updating = TRUE, ignore_sleepimmune = FALSE) //Adds to remaining duration - if((!has_trait(TRAIT_SLEEPIMMUNE)) || ignore_sleepimmune) + if((!HAS_TRAIT(src, TRAIT_SLEEPIMMUNE)) || ignore_sleepimmune) var/datum/status_effect/incapacitating/sleeping/S = IsSleeping() if(S) S.duration += amount @@ -170,7 +170,7 @@ blind_minimum = 1 if(isliving(src)) var/mob/living/L = src - if(L.has_trait(TRAIT_BLIND)) + if(HAS_TRAIT(L, TRAIT_BLIND)) blind_minimum = 1 eye_blind = max(eye_blind+amount, blind_minimum) if(!eye_blind) @@ -191,7 +191,7 @@ blind_minimum = 1 if(isliving(src)) var/mob/living/L = src - if(L.has_trait(TRAIT_BLIND)) + if(HAS_TRAIT(L, TRAIT_BLIND)) blind_minimum = 1 eye_blind = blind_minimum if(!eye_blind) diff --git a/code/modules/modular_computers/file_system/programs/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/sm_monitor.dm index 138e8bb9dd..e7dd42a797 100644 --- a/code/modules/modular_computers/file_system/programs/sm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/sm_monitor.dm @@ -81,13 +81,13 @@ if(air.total_moles()) for(var/gasid in air.gases) gasdata.Add(list(list( - "name"= air.gases[gasid][GAS_META][META_GAS_NAME], - "amount" = round(100*air.gases[gasid][MOLES]/air.total_moles(),0.01)))) + "name"= GLOB.meta_gas_names[gasid], + "amount" = round(100*air.gases[gasid]/air.total_moles(),0.01)))) else for(var/gasid in air.gases) gasdata.Add(list(list( - "name"= air.gases[gasid][GAS_META][META_GAS_NAME], + "name"= GLOB.meta_gas_names[gasid], "amount" = 0))) data["gases"] = gasdata diff --git a/code/modules/ninja/suit/mask.dm b/code/modules/ninja/suit/mask.dm index 81d37886dd..2200af7cab 100644 --- a/code/modules/ninja/suit/mask.dm +++ b/code/modules/ninja/suit/mask.dm @@ -17,3 +17,44 @@ Contents: item_state = "s-ninja_mask" strip_delay = 120 resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/item/clothing/mask/gas/space_ninja/speechModification(message) + if(copytext(message, 1, 2) != "*") + var/list/temp_message = text2list(message, " ") + var/list/pick_list = list() + for(var/i = 1, i <= temp_message.len, i++) + pick_list += i + for(var/i=1, i <= abs(temp_message.len/3), i++) + var/H = pick(pick_list) + if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue + temp_message[H] = ninjaspeak(temp_message[H]) + pick_list -= H + message = list2text(temp_message, " ") + + //The Alternate speech mod is now the main one. + message = replacetext(message, "l", "r") + message = replacetext(message, "rr", "ru") + message = replacetext(message, "v", "b") + message = replacetext(message, "f", "hu") + message = replacetext(message, "'t", "") + message = replacetext(message, "t ", "to ") + message = replacetext(message, " I ", " ai ") + message = replacetext(message, "th", "z") + message = replacetext(message, "is", "izu") + message = replacetext(message, "ziz", "zis") + message = replacetext(message, "se", "su") + message = replacetext(message, "br", "bur") + message = replacetext(message, "ry", "ri") + message = replacetext(message, "you", "yuu") + message = replacetext(message, "ck", "cku") + message = replacetext(message, "eu", "uu") + message = replacetext(message, "ow", "au") + message = replacetext(message, "are", "aa") + message = replacetext(message, "ay", "ayu") + message = replacetext(message, "ea", "ii") + message = replacetext(message, "ch", "chi") + message = replacetext(message, "than", "sen") + message = replacetext(message, ".", "") + message = lowertext(message) + + return message diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm index ff1f620a3a..816ae58749 100644 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm @@ -4,12 +4,10 @@ if(!ninjacost(0,N_ADRENALINE)) var/mob/living/carbon/human/H = affecting - H.SetUnconscious(0) - H.SetStun(0) - H.SetKnockdown(0) - H.adjustStaminaLoss(-75) - H.stuttering = 0 + H.do_adrenaline(150, TRUE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "omnizine" = 10), "You feel a sudden surge of energy!") + H.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"), forced = "ninjaboost") + a_boost-- to_chat(H, "There are [a_boost] adrenaline boosts remaining.") s_coold = 3 diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm index 006151c4eb..676774ff88 100644 --- a/code/modules/paperwork/contract.dm +++ b/code/modules/paperwork/contract.dm @@ -202,7 +202,7 @@ if(!user.mind.hasSoul) to_chat(user, "You do not possess a soul.") return 0 - if(user.has_trait(TRAIT_DUMB)) + if(HAS_TRAIT(user, TRAIT_DUMB)) to_chat(user, "You quickly scrawl 'your name' on the contract.") signIncorrectly() return 0 diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index d6d0a3dc4f..37877ffb09 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -89,7 +89,7 @@ return if(ishuman(usr)) var/mob/living/carbon/human/H = usr - if(H.has_trait(TRAIT_CLUMSY) && prob(25)) + if(HAS_TRAIT(H, TRAIT_CLUMSY) && prob(25)) to_chat(H, "You cut yourself on the paper! Ahhhh! Ahhhhh!") H.damageoverlaytemp = 9001 H.update_damage_hud() @@ -314,7 +314,7 @@ to_chat(user, "You stamp the paper with your rubber stamp.") if(P.is_hot()) - if(user.has_trait(TRAIT_CLUMSY) && prob(10)) + if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10)) user.visible_message("[user] accidentally ignites [user.p_them()]self!", \ "You miss the paper and accidentally light yourself on fire!") user.dropItemToGround(P) diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index 73eadfbc45..e3ce30066a 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -65,7 +65,7 @@ update_icon() else if(P.is_hot()) - if(user.has_trait(TRAIT_CLUMSY) && prob(10)) + if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10)) user.visible_message("[user] accidentally ignites [user.p_them()]self!", \ "You miss [src] and accidentally light yourself on fire!") user.dropItemToGround(P) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index c99b094ab0..6125ac9b82 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -151,9 +151,6 @@ /* * Sleepypens */ -/obj/item/pen/sleepy - container_type = OPENCONTAINER - /obj/item/pen/sleepy/attack(mob/living/M, mob/user) if(!istype(M)) @@ -167,7 +164,7 @@ /obj/item/pen/sleepy/Initialize() . = ..() - create_reagents(45) + create_reagents(45, OPENCONTAINER) reagents.add_reagent("chloralhydratedelayed", 20) reagents.add_reagent("mutetoxin", 15) reagents.add_reagent("tirizene", 10) diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index b3f59abfae..8c51fd31ea 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -124,7 +124,7 @@ var/realcooldown = cooldown var/mob/living/carbon/human/H = user - if (H.has_trait(TRAIT_PHOTOGRAPHER)) + if (HAS_TRAIT(H, TRAIT_PHOTOGRAPHER)) realcooldown *= 0.5 addtimer(CALLBACK(src, .proc/cooldown), realcooldown) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 7b3b2ba7bd..a3dc6e7394 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -639,7 +639,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai // called when cable_coil is click on an installed obj/cable // or click on a turf that already contains a "node" cable -/obj/item/stack/cable_coil/proc/cable_join(obj/structure/cable/C, mob/user, var/showerror = TRUE) +/obj/item/stack/cable_coil/proc/cable_join(obj/structure/cable/C, mob/user, showerror = TRUE, forceddir) var/turf/U = user.loc if(!isturf(U)) return @@ -654,14 +654,14 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai return - if(U == T) //if clicked on the turf we're standing on, try to put a cable in the direction we're facing + if(U == T && !forceddir) //if clicked on the turf we're standing on and a direction wasn't supplied, try to put a cable in the direction we're facing place_turf(T,user) return var/dirn = get_dir(C, user) - // one end of the clicked cable is pointing towards us - if(C.d1 == dirn || C.d2 == dirn) + // one end of the clicked cable is pointing towards us and no direction was supplied + if((C.d1 == dirn || C.d2 == dirn) && !forceddir) if(!U.can_have_cabling()) //checking if it's a plating or catwalk if (showerror) to_chat(user, "You can only lay cables on catwalks and plating!") @@ -706,7 +706,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai return - // exisiting cable doesn't point at our position, so see if it's a stub + // exisiting cable doesn't point at our position or we have a supplied direction, so see if it's a stub else if(C.d1 == 0) // if so, make it a full cable pointing from it's old direction to our dirn var/nd1 = C.d2 // these will be the new directions diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index e43db529b8..b6473b8913 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -20,7 +20,6 @@ var/self_recharge = 0 //does it self recharge, over time, or not? var/ratingdesc = TRUE var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it. - container_type = INJECTABLE|DRAINABLE /obj/item/stock_parts/cell/get_cell() return src @@ -28,7 +27,7 @@ /obj/item/stock_parts/cell/Initialize(mapload, override_maxcharge) . = ..() START_PROCESSING(SSobj, src) - create_reagents(5) + create_reagents(5, INJECTABLE | DRAINABLE) if (override_maxcharge) maxcharge = override_maxcharge charge = maxcharge @@ -200,6 +199,10 @@ charge = 0 update_icon() +/obj/item/stock_parts/cell/lascarbine + name = "laser carbine power supply" + maxcharge = 2500 + /obj/item/stock_parts/cell/pulse //200 pulse shots name = "pulse rifle power cell" maxcharge = 40000 diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 1c05b6c11a..b77ea9d13a 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -604,7 +604,7 @@ else prot = 1 - if(prot > 0 || user.has_trait(TRAIT_RESISTHEAT) || user.has_trait(TRAIT_RESISTHEATHANDS)) + if(prot > 0 || HAS_TRAIT(user, TRAIT_RESISTHEAT) || HAS_TRAIT(user, TRAIT_RESISTHEATHANDS)) to_chat(user, "You remove the light [fitting].") else if(istype(user) && user.dna.check_mutation(TK)) to_chat(user, "You telekinetically remove the light [fitting].") diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 3b9c3a549b..4159d9898a 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -43,11 +43,10 @@ playsound(src, 'sound/machines/ding.ogg', 50, 1) eject() else - var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES]) - loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= gasdrained - loaded_tank.air_contents.assert_gas(/datum/gas/tritium) - loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] += gasdrained - loaded_tank.air_contents.garbage_collect() + var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma]) + loaded_tank.air_contents.gases[/datum/gas/plasma] -= gasdrained + loaded_tank.air_contents.gases[/datum/gas/tritium] += gasdrained + GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases) var/power_produced = RAD_COLLECTOR_OUTPUT add_avail(power_produced) @@ -58,11 +57,10 @@ eject() else var/gasdrained = bitcoinproduction_drain*drainratio - loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] -= gasdrained - loaded_tank.air_contents.gases[/datum/gas/oxygen][MOLES] -= gasdrained - loaded_tank.air_contents.assert_gas(/datum/gas/carbon_dioxide) - loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide][MOLES] += gasdrained*2 - loaded_tank.air_contents.garbage_collect() + loaded_tank.air_contents.gases[/datum/gas/tritium] -= gasdrained + loaded_tank.air_contents.gases[/datum/gas/oxygen] -= gasdrained + loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide] += gasdrained*2 + GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases) var/bitcoins_mined = RAD_COLLECTOR_OUTPUT SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, bitcoins_mined*RAD_COLLECTOR_MINING_CONVERSION_RATE) stored_power-=bitcoins_mined @@ -76,7 +74,6 @@ var/fuel if(loaded_tank) fuel = loaded_tank.air_contents.gases[/datum/gas/plasma] - fuel = fuel ? fuel[MOLES] : 0 investigate_log("turned [active?"on":"off"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"It is empty"].", INVESTIGATE_SINGULO) return else diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index ad94d577ea..d87f9821ef 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -295,6 +295,16 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) E.energy = power qdel(src) +/obj/machinery/power/supermatter_crystal/proc/consume_turf(turf/T) + var/oldtype = T.type + var/turf/newT = T.ScrapeAway() + if(newT.type == oldtype) + return + playsound(T, 'sound/effects/supermatter.ogg', 50, 1) + T.visible_message("[T] smacks into [src] and rapidly flashes to ash.",\ + "You hear a loud crack as you are washed with a wave of heat.") + T.CalculateAdjacentTurfs() + /obj/machinery/power/supermatter_crystal/process_atmos() var/turf/T = loc @@ -303,6 +313,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(!istype(T)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now. return //Yeah just stop. + if(istype(T, /turf/closed)) + consume_turf(T) if(power) soundloop.volume = min(40, (round(power/100)/50)+1) // 5 +1 volume per 20 power. 2500 power is max @@ -339,16 +351,15 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(damage > damage_archived && prob(10)) playsound(get_turf(src), 'sound/effects/empulse.ogg', 50, 1) - removed.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/nitrogen) //calculating gas related values combined_gas = max(removed.total_moles(), 0) - plasmacomp = max(removed.gases[/datum/gas/plasma][MOLES]/combined_gas, 0) - o2comp = max(removed.gases[/datum/gas/oxygen][MOLES]/combined_gas, 0) - co2comp = max(removed.gases[/datum/gas/carbon_dioxide][MOLES]/combined_gas, 0) + plasmacomp = max(removed.gases[/datum/gas/plasma]/combined_gas, 0) + o2comp = max(removed.gases[/datum/gas/oxygen]/combined_gas, 0) + co2comp = max(removed.gases[/datum/gas/carbon_dioxide]/combined_gas, 0) - n2ocomp = max(removed.gases[/datum/gas/nitrous_oxide][MOLES]/combined_gas, 0) - n2comp = max(removed.gases[/datum/gas/nitrogen][MOLES]/combined_gas, 0) + n2ocomp = max(removed.gases[/datum/gas/nitrous_oxide]/combined_gas, 0) + n2comp = max(removed.gases[/datum/gas/nitrogen]/combined_gas, 0) gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp - n2comp, 0), 1) @@ -400,9 +411,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) removed.temperature = max(0, min(removed.temperature, 2500 * dynamic_heat_modifier)) //Calculate how much gas to release - removed.gases[/datum/gas/plasma][MOLES] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0) + removed.gases[/datum/gas/plasma] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0) - removed.gases[/datum/gas/oxygen][MOLES] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0) + removed.gases[/datum/gas/oxygen] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0) if(produces_gas) env.merge(removed) diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm index d57edf154d..ab463163f0 100644 --- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm +++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm @@ -111,23 +111,23 @@ icon_state = "cshell" projectile_type = /obj/item/projectile/bullet/dart var/reagent_amount = 30 - var/reagent_react = TRUE + +/obj/item/ammo_casing/shotgun/dart/Initialize() + . = ..() + create_reagents(reagent_amount, OPENCONTAINER) + +/obj/item/ammo_casing/shotgun/dart/attackby() + return /obj/item/ammo_casing/shotgun/dart/noreact name = "cryostasis shotgun dart" desc = "A dart for use in shotguns. Uses technology similar to cryostasis beakers to keep internal reagents from reacting. Can be injected with up to 10 units of any chemical." icon_state = "cnrshell" reagent_amount = 10 - reagent_react = FALSE -/obj/item/ammo_casing/shotgun/dart/Initialize() +/obj/item/ammo_casing/shotgun/dart/noreact/Initialize() . = ..() - container_type |= OPENCONTAINER - create_reagents(reagent_amount) - reagents.set_reacting(reagent_react) - -/obj/item/ammo_casing/shotgun/dart/attackby() - return + ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) /obj/item/ammo_casing/shotgun/dart/bioterror desc = "A shotgun dart filled with deadly toxins." diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm index 9b24571d12..3f033ac904 100644 --- a/code/modules/projectiles/ammunition/energy/stun.dm +++ b/code/modules/projectiles/ammunition/energy/stun.dm @@ -21,6 +21,7 @@ /obj/item/ammo_casing/energy/disabler projectile_type = /obj/item/projectile/beam/disabler select_name = "disable" - e_cost = 50 + e_cost = 40 fire_sound = 'sound/weapons/taser2.ogg' harmful = FALSE + click_cooldown_override = 3 diff --git a/code/modules/projectiles/boxes_magazines/internal/rifle.dm b/code/modules/projectiles/boxes_magazines/internal/rifle.dm index ef83e96b1c..ae49a8cadd 100644 --- a/code/modules/projectiles/boxes_magazines/internal/rifle.dm +++ b/code/modules/projectiles/boxes_magazines/internal/rifle.dm @@ -6,10 +6,12 @@ max_ammo = 5 multiload = 1 +/obj/item/ammo_box/magazine/internal/boltaction/improvised + max_ammo = 1 + /obj/item/ammo_box/magazine/internal/boltaction/enchanted max_ammo = 1 ammo_type = /obj/item/ammo_casing/a762/enchanted /obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage ammo_type = /obj/item/ammo_casing/magic/arcane_barrage - diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index a7474fd8cb..542e4ecffa 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -162,7 +162,7 @@ //Exclude lasertag guns from the TRAIT_CLUMSY check. if(clumsy_check) if(istype(user)) - if (user.has_trait(TRAIT_CLUMSY) && prob(40)) + if (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(40)) to_chat(user, "You shoot yourself in the foot with [src]!") var/shot_leg = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) process_fire(user, user, FALSE, params, shot_leg) @@ -220,7 +220,7 @@ firing_burst = FALSE return FALSE if(chambered && chambered.BB) - if(user.has_trait(TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal. + if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal. if(chambered.harmful) // Is the bullet chambered harmful? to_chat(user, " [src] is lethally chambered! You don't want to risk harming anyone...") return @@ -259,7 +259,7 @@ var/rand_spr = rand() if(spread) randomized_gun_spread = rand(0,spread) - if(user.has_trait(TRAIT_POOR_AIM)) //nice shootin' tex + if(HAS_TRAIT(user, TRAIT_POOR_AIM)) //nice shootin' tex bonus_spread += 25 var/randomized_bonus_spread = rand(0, bonus_spread) @@ -269,7 +269,7 @@ addtimer(CALLBACK(src, .proc/process_burst, user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), fire_delay * (i - 1)) else if(chambered) - if(user.has_trait(TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal. + if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal. if(chambered.harmful) // Is the bullet chambered harmful? to_chat(user, " [src] is lethally chambered! You don't want to risk harming anyone...") return diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 8aa8d53726..4bd65a7b20 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -268,8 +268,6 @@ empty_alarm() return - - // L6 SAW // /obj/item/gun/ballistic/automatic/l6_saw @@ -292,13 +290,11 @@ /obj/item/gun/ballistic/automatic/l6_saw/unrestricted pin = /obj/item/firing_pin - /obj/item/gun/ballistic/automatic/l6_saw/examine(mob/user) ..() if(cover_open && magazine) to_chat(user, "It seems like you could use an empty hand to remove the magazine.") - /obj/item/gun/ballistic/automatic/l6_saw/attack_self(mob/user) cover_open = !cover_open to_chat(user, "You [cover_open ? "open" : "close"] [src]'s cover.") @@ -308,12 +304,10 @@ playsound(user, 'sound/weapons/sawclose.ogg', 60, 1) update_icon() - /obj/item/gun/ballistic/automatic/l6_saw/update_icon() icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEILING(get_ammo(0)/12.5, 1)*25 : "-empty"][suppressed ? "-suppressed" : ""]" item_state = "l6[cover_open ? "openmag" : "closedmag"]" - /obj/item/gun/ballistic/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays if(cover_open) to_chat(user, "[src]'s cover is open! Close it before firing!") @@ -344,8 +338,6 @@ return ..() - - // SNIPER // /obj/item/gun/ballistic/automatic/sniper_rifle @@ -367,14 +359,12 @@ slot_flags = ITEM_SLOT_BACK actions_types = list() - /obj/item/gun/ballistic/automatic/sniper_rifle/update_icon() if(magazine) icon_state = "sniper-mag" else icon_state = "sniper" - /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate name = "syndicate sniper rifle" desc = "An illegally modified .50 cal sniper rifle with suppression compatibility. Quickscoping still doesn't work." @@ -403,7 +393,6 @@ else icon_state = "surplus-e" - // Laser rifle (rechargeable magazine) // /obj/item/gun/ballistic/automatic/laser diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 2116f037a3..f455e0f138 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -351,7 +351,7 @@ clumsy_check = 0 /obj/item/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user) - if((user.has_trait(TRAIT_CLUMSY)) || (user.mind && user.mind.assigned_role == "Clown")) + if((HAS_TRAIT(user, TRAIT_CLUMSY)) || (user.mind && user.mind.assigned_role == "Clown")) return ..() if(process_fire(user, user, FALSE, null, BODY_ZONE_HEAD)) user.visible_message("[user] somehow manages to shoot [user.p_them()]self in the face!", "You somehow shoot yourself in the face! How the hell?!") diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 83ce525ac8..bb6a144c93 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -71,7 +71,6 @@ var/obj/item/ammo_casing/AC = magazine.get_round() //load next casing. chambered = AC - /obj/item/gun/ballistic/shotgun/examine(mob/user) ..() if (chambered) @@ -88,6 +87,9 @@ icon_state = "riotshotgun" mag_type = /obj/item/ammo_box/magazine/internal/shot/riot sawn_desc = "Come with me if you want to live." + unique_reskin = list("Tatical" = "riotshotgun", + "Wood Stock" = "wood_riotshotgun" + ) /obj/item/gun/ballistic/shotgun/riot/attackby(obj/item/A, mob/user, params) ..() @@ -114,6 +116,14 @@ knife_x_offset = 27 knife_y_offset = 13 +/obj/item/gun/ballistic/shotgun/boltaction/improvised + name = "Makeshift 7.62mm Rifle" + icon_state = "ishotgun" + item_state = "shotgun" + desc = "A large zip gun more or less that takes a single 7.62mm bullet" + mag_type = /obj/item/ammo_box/magazine/internal/boltaction/improvised + can_bayonet = FALSE + /obj/item/gun/ballistic/shotgun/boltaction/pump(mob/M) playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) if(bolt_open) @@ -134,7 +144,6 @@ ..() to_chat(user, "The bolt is [bolt_open ? "open" : "closed"].") - /obj/item/gun/ballistic/shotgun/boltaction/enchanted name = "enchanted bolt action rifle" desc = "Careful not to lose your head." @@ -150,10 +159,8 @@ icon_state = "arcane_barrage" item_state = "arcane_barrage" can_bayonet = FALSE - item_flags = NEEDS_PERMIT | DROPDEL flags_1 = NONE - mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage /obj/item/gun/ballistic/shotgun/boltaction/enchanted/Initialize() @@ -200,6 +207,9 @@ icon_state = "cshotgun" mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_HUGE + unique_reskin = list("Tatical" = "cshotgun", + "Slick" = "cshotgun_slick" + ) /obj/item/gun/ballistic/shotgun/automatic/combat/compact name = "compact combat shotgun" @@ -207,6 +217,9 @@ icon_state = "cshotgunc" mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact w_class = WEIGHT_CLASS_NORMAL + unique_reskin = list("Tatical" = "cshotgunc", + "Slick" = "cshotgunc_slick" + ) //Dual Feed Shotgun @@ -250,5 +263,4 @@ return pump() - // DOUBLE BARRELED SHOTGUN and IMPROVISED SHOTGUN are in revolver.dm diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index fba355d738..a4ec979a06 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -424,7 +424,7 @@ M.gets_drilled(K.firer) if(modifier) for(var/mob/living/L in range(1, target_turf) - K.firer - target) - var/armor = L.run_armor_check(K.def_zone, K.flag, "", "", K.armour_penetration) + var/armor = L.run_armor_check(K.def_zone, K.flag, null, null, K.armour_penetration) L.apply_damage(K.damage*modifier, K.damage_type, K.def_zone, armor) to_chat(L, "You're struck by a [K.name]!") @@ -530,7 +530,7 @@ var/kill_modifier = 1 if(K.pressure_decrease_active) kill_modifier *= K.pressure_decrease - var/armor = L.run_armor_check(K.def_zone, K.flag, "", "", K.armour_penetration) + var/armor = L.run_armor_check(K.def_zone, K.flag, null, null, K.armour_penetration) L.apply_damage(bounties_reaped[L.type]*kill_modifier, K.damage_type, K.def_zone, armor) /obj/item/borg/upgrade/modkit/bounty/proc/get_kill(mob/living/L) diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 066b652984..cd0dd53d48 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -39,6 +39,21 @@ selfcharge = EGUN_SELFCHARGE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF +/obj/item/gun/energy/laser/carbine + name = "laser carbine" + desc = "A ruggedized laser carbine featuring much higher capacity and improved handling when compared to a normal laser gun." + icon = 'icons/obj/guns/energy.dmi' + icon_state = "lasernew" + item_state = "laser" + force = 10 + throwforce = 10 + ammo_type = list(/obj/item/ammo_casing/energy/lasergun) + cell_type = /obj/item/stock_parts/cell/lascarbine + resistance_flags = FIRE_PROOF | ACID_PROOF + +/obj/item/gun/energy/laser/carbine/nopin + pin = null + /obj/item/gun/energy/laser/captain/scattershot name = "scatter shot laser rifle" icon_state = "lasercannon" diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index d5d5a79fde..c6f0956880 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -299,4 +299,8 @@ ammo_type = list(/obj/item/ammo_casing/energy/gravity/repulse, /obj/item/ammo_casing/energy/gravity/attract, /obj/item/ammo_casing/energy/gravity/chaos) item_state = "gravity_gun" icon_state = "gravity_gun" + pin = null var/power = 4 + +/obj/item/gun/energy/gravity_gun/security + pin = /obj/item/firing_pin diff --git a/code/modules/projectiles/guns/misc/chem_gun.dm b/code/modules/projectiles/guns/misc/chem_gun.dm index 17e3bd1876..9f65c5ec24 100644 --- a/code/modules/projectiles/guns/misc/chem_gun.dm +++ b/code/modules/projectiles/guns/misc/chem_gun.dm @@ -12,7 +12,6 @@ materials = list(MAT_METAL=2000) clumsy_check = FALSE fire_sound = 'sound/items/syringeproj.ogg' - container_type = OPENCONTAINER var/time_per_syringe = 250 var/syringes_left = 4 var/max_syringes = 4 @@ -22,7 +21,7 @@ . = ..() chambered = new /obj/item/ammo_casing/chemgun(src) START_PROCESSING(SSobj, src) - create_reagents(100) + create_reagents(100, OPENCONTAINER) /obj/item/gun/chem/Destroy() . = ..() diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 3698eb1ede..05d6367306 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -133,7 +133,7 @@ // A gun with ultra-honk pin is useful for clown and useless for everyone else. /obj/item/firing_pin/clown/ultra/pin_auth(mob/living/user) playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) - if(user && (!(user.has_trait(TRAIT_CLUMSY)) && !(user.mind && user.mind.assigned_role == "Clown"))) + if(user && (!(HAS_TRAIT(user, TRAIT_CLUMSY)) && !(user.mind && user.mind.assigned_role == "Clown"))) return FALSE return TRUE diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index f4ca82b4e6..cbd0348743 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -74,6 +74,7 @@ flag = "energy" hitsound = 'sound/weapons/tap.ogg' eyeblur = 0 + speed = 0.7 impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser light_color = LIGHT_COLOR_BLUE tracer_type = /obj/effect/projectile/tracer/disabler diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm index 023c3b9090..94d075c789 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -6,8 +6,7 @@ /obj/item/projectile/bullet/dart/Initialize() . = ..() - create_reagents(50) - reagents.set_reacting(FALSE) + create_reagents(50, NO_REACT) /obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE) if(iscarbon(target)) @@ -24,7 +23,7 @@ "You were protected against \the [src]!") ..(target, blocked) - reagents.set_reacting(TRUE) + DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) reagents.handle_reactions() return TRUE diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm index c8c4a73b3b..f9aa47c6a3 100644 --- a/code/modules/projectiles/projectile/bullets/shotgun.dm +++ b/code/modules/projectiles/projectile/bullets/shotgun.dm @@ -18,6 +18,7 @@ /obj/item/projectile/bullet/shotgun_stunslug name = "stunslug" damage = 5 + stamina = 20 knockdown = 100 stutter = 5 jitter = 20 diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index af01a0049f..047d50beaf 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -31,7 +31,7 @@ var/mob/living/carbon/C = target if(C.dna && C.dna.check_mutation(HULK)) C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - else if((C.status_flags & CANKNOCKDOWN) && !C.has_trait(TRAIT_STUNIMMUNE)) + else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE)) addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5) /obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm index db1ad403a7..895a165f49 100644 --- a/code/modules/projectiles/projectile/energy/stun.dm +++ b/code/modules/projectiles/projectile/energy/stun.dm @@ -22,7 +22,7 @@ SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK) if(C.dna && C.dna.check_mutation(HULK)) C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") - else if((C.status_flags & CANKNOCKDOWN) && !C.has_trait(TRAIT_STUNIMMUNE)) + else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE)) addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5) /obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet diff --git a/code/modules/projectiles/projectile/special/hallucination.dm b/code/modules/projectiles/projectile/special/hallucination.dm index f65ebce51f..5814e7138e 100644 --- a/code/modules/projectiles/projectile/special/hallucination.dm +++ b/code/modules/projectiles/projectile/special/hallucination.dm @@ -170,7 +170,7 @@ hal_target.stuttering += 20 if(hal_target.dna && hal_target.dna.check_mutation(HULK)) hal_target.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") - else if((hal_target.status_flags & CANKNOCKDOWN) && !hal_target.has_trait(TRAIT_STUNIMMUNE)) + else if((hal_target.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(hal_target, TRAIT_STUNIMMUNE)) addtimer(CALLBACK(hal_target, /mob/living/carbon.proc/do_jitter_animation, 20), 5) /obj/item/projectile/hallucination/disabler diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 252d0d0dc3..58c29f351b 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -53,7 +53,7 @@ var/list/datum/reagent/addiction_list = new/list() var/reagents_holder_flags -/datum/reagents/New(maximum=100) +/datum/reagents/New(maximum=100, new_flags) maximum_volume = maximum //I dislike having these here but map-objects are initialised before world/New() is called. >_> @@ -62,6 +62,8 @@ if(!GLOB.chemical_reactions_list) build_chemical_reactions_list() + reagents_holder_flags = new_flags + /datum/reagents/Destroy() . = ..() var/list/cached_reagents = reagent_list @@ -269,11 +271,11 @@ if(C.reagent_check(R) != 1) if(can_overdose) if(R.overdose_threshold) - if(R.volume >= R.overdose_threshold && !R.overdosed) + if(R.volume > R.overdose_threshold && !R.overdosed) R.overdosed = 1 need_mob_update += R.overdose_start(C) if(R.addiction_threshold) - if(R.volume >= R.addiction_threshold && !is_type_in_list(R, cached_addictions)) + if(R.volume > R.addiction_threshold && !is_type_in_list(R, cached_addictions)) var/datum/reagent/new_reagent = new R.type() cached_addictions.Add(new_reagent) if(R.overdosed) @@ -311,13 +313,6 @@ C.update_stamina() update_total() - -/datum/reagents/proc/set_reacting(react = TRUE) - if(react) - reagents_holder_flags &= ~(REAGENT_NOREACT) - else - reagents_holder_flags |= REAGENT_NOREACT - /datum/reagents/proc/conditional_update_move(atom/A, Running = 0) var/list/cached_reagents = reagent_list for(var/reagent in cached_reagents) @@ -333,11 +328,11 @@ update_total() /datum/reagents/proc/handle_reactions() + if(reagents_holder_flags & NO_REACT) + return //Yup, no reactions here. No siree. var/list/cached_reagents = reagent_list var/list/cached_reactions = GLOB.chemical_reactions_list var/datum/cached_my_atom = my_atom - if(reagents_holder_flags & REAGENT_NOREACT) - return //Yup, no reactions here. No siree. var/reaction_occurred = 0 do @@ -555,7 +550,7 @@ if(!D) WARNING("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])") return FALSE - + update_total() var/cached_total = total_volume if(cached_total + amount > maximum_volume) @@ -599,9 +594,9 @@ if(data) R.data = data R.on_new(data) - + if(isliving(my_atom)) - R.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete + R.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete update_total() if(my_atom) my_atom.on_reagent_change(ADD_REAGENT) @@ -800,10 +795,10 @@ // Convenience proc to create a reagents holder for an atom // Max vol is maximum volume of holder -/atom/proc/create_reagents(max_vol) +/atom/proc/create_reagents(max_vol, flags) if(reagents) qdel(reagents) - reagents = new/datum/reagents(max_vol) + reagents = new/datum/reagents(max_vol, flags) reagents.my_atom = src /proc/get_random_reagent_id() // Returns a random reagent ID minus blacklisted reagents diff --git a/code/modules/reagents/chemistry/readme.md b/code/modules/reagents/chemistry/readme.md index 9a9be7c5a6..20dce0e72e 100644 --- a/code/modules/reagents/chemistry/readme.md +++ b/code/modules/reagents/chemistry/readme.md @@ -230,7 +230,7 @@ By default, all atom have a reagents var - but its empty. if you want to use an 'pouring' our reagents into something else. atom/proc/is_open_container() - Checks obj/var/container_type & OPENCONTAINER. + Checks atom/var/reagents.reagents_holder_flags & OPENCONTAINER. If this returns 1 , you can use syringes, beakers etc to manipulate the contents of this object. If it's 0, you'll need to write your own custom reagent diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 6e4d5e5a7d..14963a6689 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -37,7 +37,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/on_mob_life(mob/living/carbon/C) if(C.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER) var/booze_power = boozepwr - if(C.has_trait(TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker + if(HAS_TRAIT(C, TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker booze_power *= 0.7 C.drunkenness = max((C.drunkenness + (sqrt(volume) * booze_power * ALCOHOL_RATE)), 0) //Volume, power, and server alcohol rate effect how quickly one gets drunk var/obj/item/organ/liver/L = C.getorganslot(ORGAN_SLOT_LIVER) @@ -129,7 +129,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.dizziness = max(0,M.dizziness-5) M.drowsyness = max(0,M.drowsyness-3) M.AdjustSleeping(-40, FALSE) - if(!M.has_trait(TRAIT_ALCOHOL_TOLERANCE)) + if(!HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE)) M.Jitter(5) ..() . = 1 @@ -165,7 +165,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.drowsyness = max(0,M.drowsyness-7) M.AdjustSleeping(-40) M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) - if(!M.has_trait(TRAIT_ALCOHOL_TOLERANCE)) + if(!HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE)) M.Jitter(5) return ..() @@ -186,7 +186,7 @@ All effects don't start immediately, but rather get worse over time; the rate is to_chat(M, "[pick("You have a really bad headache.", "Your eyes hurt.", "You find it hard to stay still.", "You feel your heart practically beating out of your chest.")]") if(prob(5) && iscarbon(M)) - if(M.has_trait(TRAIT_BLIND)) + if(HAS_TRAIT(M, TRAIT_BLIND)) var/obj/item/organ/eyes/eye = M.getorganslot(ORGAN_SLOT_EYES) if(istype(eye)) eye.Remove(M) @@ -364,7 +364,7 @@ All effects don't start immediately, but rather get worse over time; the rate is shot_glass_icon_state = "shotglassgreen" /datum/reagent/consumable/ethanol/absinthe/on_mob_life(mob/living/carbon/M) - if(prob(10) && !M.has_trait(TRAIT_ALCOHOL_TOLERANCE)) + if(prob(10) && !HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE)) M.hallucination += 4 //Reference to the urban myth ..() @@ -640,7 +640,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW." /datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/carbon/M) - if(M.has_trait(TRAIT_ALCOHOL_TOLERANCE)) + if(HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE)) M.Stun(30, 0) //this realistically does nothing to prevent chainstunning but will cause them to recover faster once it's out of their system else M.Stun(40, 0) @@ -674,7 +674,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/manly_dorf/on_mob_add(mob/living/M) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.dna.check_mutation(DWARFISM) || H.has_trait(TRAIT_ALCOHOL_TOLERANCE)) + if(H.dna.check_mutation(DWARFISM) || HAS_TRAIT(H, TRAIT_ALCOHOL_TOLERANCE)) to_chat(H, "Now THAT is MANLY!") boozepwr = 5 //We've had worse in the mines dorf_mode = TRUE @@ -1274,11 +1274,10 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/atomicbomb/on_mob_life(mob/living/carbon/M) M.set_drugginess(50) - if(!M.has_trait(TRAIT_ALCOHOL_TOLERANCE)) + if(!HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE)) M.confused = max(M.confused+2,0) M.Dizzy(10) - if (!M.slurring) - M.slurring = 1 + M.slurring = max(M.slurring,50) M.slurring += 3 switch(current_cycle) if(51 to 200) @@ -1306,8 +1305,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.dizziness +=1.5 switch(current_cycle) if(15 to 45) - if(!M.slurring) - M.slurring = 1 + M.slurring = max(M.slurring,50) M.slurring += 3 if(45 to 55) if(prob(50)) @@ -1336,8 +1334,7 @@ All effects don't start immediately, but rather get worse over time; the rate is M.dizziness +=2 switch(current_cycle) if(15 to 45) - if(!M.slurring) - M.slurring = 1 + M.slurring = max(M.slurring,50) M.slurring += 3 if(45 to 55) if(prob(50)) @@ -1364,8 +1361,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A drink enjoyed by people during the 1960's." /datum/reagent/consumable/ethanol/hippies_delight/on_mob_life(mob/living/carbon/M) - if (!M.slurring) - M.slurring = 1 + M.slurring = max(M.slurring,50) switch(current_cycle) if(1 to 5) M.Dizzy(10) diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 6ec37f3ec4..ac15eb6b01 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -392,10 +392,10 @@ /datum/reagent/consumable/nuka_cola/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_GOTTAGOFAST, id) + ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) /datum/reagent/consumable/nuka_cola/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_GOTTAGOFAST, id) + REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() /datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/M) diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index d77756a649..04dad3a065 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -164,13 +164,16 @@ overdose_threshold = 20 addiction_threshold = 10 metabolization_rate = 0.75 * REAGENTS_METABOLISM + var/brain_damage = TRUE + var/jitter = TRUE + var/confusion = TRUE /datum/reagent/drug/methamphetamine/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_IGNORESLOWDOWN, id) + L.ignore_slowdown(id) /datum/reagent/drug/methamphetamine/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_IGNORESLOWDOWN, id) + L.unignore_slowdown(id) ..() /datum/reagent/drug/methamphetamine/on_mob_life(mob/living/carbon/M) @@ -181,10 +184,10 @@ M.AdjustKnockdown(-40, 0) M.AdjustUnconscious(-40, 0) M.adjustStaminaLoss(-7.5 * REM, 0) - M.Jitter(2) - M.adjustBrainLoss(rand(1,4)) - if(prob(30)) - M.confused = max(1, M.confused) + if(jitter) + M.Jitter(2) + if(brain_damage) + M.adjustBrainLoss(rand(1,4)) M.heal_overall_damage(2, 2) if(prob(5)) M.emote(pick("twitch", "shiver")) @@ -240,6 +243,14 @@ ..() . = 1 +/datum/reagent/drug/methamphetamine/changeling + id = "changelingmeth" + name = "Changeling Adrenaline" + addiction_threshold = 35 + overdose_threshold = 35 + jitter = FALSE + brain_damage = FALSE + /datum/reagent/drug/bath_salts name = "Bath Salts" id = "bath_salts" @@ -253,16 +264,16 @@ /datum/reagent/drug/bath_salts/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_STUNIMMUNE, id) - L.add_trait(TRAIT_SLEEPIMMUNE, id) + ADD_TRAIT(L, TRAIT_STUNIMMUNE, id) + ADD_TRAIT(L, TRAIT_SLEEPIMMUNE, id) if(iscarbon(L)) var/mob/living/carbon/C = L rage = new() C.gain_trauma(rage, TRAUMA_RESILIENCE_ABSOLUTE) /datum/reagent/drug/bath_salts/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_STUNIMMUNE, id) - L.remove_trait(TRAIT_SLEEPIMMUNE, id) + REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id) + REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id) if(rage) QDEL_NULL(rage) ..() @@ -372,7 +383,7 @@ /datum/reagent/drug/skooma/on_mob_add(mob/living/L) . = ..() - L.add_trait(TRAIT_GOTTAGOFAST, id) + ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) L.next_move_modifier *= 2 if(ishuman(L)) var/mob/living/carbon/human/H = L @@ -383,7 +394,7 @@ /datum/reagent/drug/skooma/on_mob_delete(mob/living/L) . = ..() - L.remove_trait(TRAIT_GOTTAGOFAST, id) + REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) L.next_move_modifier *= 0.5 if(ishuman(L)) var/mob/living/carbon/human/H = L diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 52b212f8c5..afa469706a 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -22,7 +22,7 @@ /datum/reagent/consumable/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == INGEST) - if (quality && !M.has_trait(TRAIT_AGEUSIA)) + if (quality && !HAS_TRAIT(M, TRAIT_AGEUSIA)) switch(quality) if (DRINK_NICE) SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_nice) @@ -319,7 +319,7 @@ victim.blind_eyes(2) victim.confused = max(M.confused, 3) victim.damageoverlaytemp = 60 - victim.Knockdown(60) + victim.Knockdown(60, override_stamdmg = min(reac_volume * 3, 15)) return else if ( eyes_covered ) // Eye cover is better than mouth cover victim.blur_eyes(3) @@ -332,7 +332,7 @@ victim.blind_eyes(3) victim.confused = max(M.confused, 6) victim.damageoverlaytemp = 75 - victim.Knockdown(100) + victim.Knockdown(100, override_stamdmg = min(reac_volume * 5, 25)) victim.update_damage_hud() /datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/M) @@ -402,8 +402,7 @@ taste_description = "mushroom" /datum/reagent/mushroomhallucinogen/on_mob_life(mob/living/carbon/M) - if(!M.slurring) - M.slurring = 1 + M.slurring = max(M.slurring,50) switch(current_cycle) if(1 to 5) M.Dizzy(5) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 3970e8157b..07a2a9c02a 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -44,7 +44,7 @@ M.adjustToxLoss(-5, 0, TRUE) M.hallucination = 0 M.setBrainLoss(0) - M.remove_all_traits() + REMOVE_TRAITS_NOT_IN(M, list(SPECIES_TRAIT, ROUNDSTART_TRAIT, ORGAN_TRAIT)) M.set_blurriness(0) M.set_blindness(0) M.SetKnockdown(0, 0) @@ -136,7 +136,7 @@ M.adjustFireLoss(-power, 0) M.adjustToxLoss(-power, 0, TRUE) //heals TOXINLOVERs M.adjustCloneLoss(-power, 0) - M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration + REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration . = 1 metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5) ..() @@ -152,7 +152,7 @@ /datum/reagent/medicine/clonexadone/on_mob_life(mob/living/carbon/M) if(M.bodytemperature < T0C) M.adjustCloneLoss(0.00006 * (M.bodytemperature ** 2) - 6, 0) - M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) + REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) . = 1 metabolization_rate = REAGENTS_METABOLISM * (0.000015 * (M.bodytemperature ** 2) + 0.75) ..() @@ -182,7 +182,7 @@ M.adjustFireLoss(-1.5 * power, 0) M.adjustToxLoss(-power, 0, TRUE) M.adjustCloneLoss(-power, 0) - M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) + REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) . = 1 ..() @@ -198,7 +198,7 @@ /datum/reagent/medicine/rezadone/on_mob_life(mob/living/carbon/M) M.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that. M.heal_bodypart_damage(1,1) - M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) + REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) ..() . = 1 @@ -632,10 +632,10 @@ /datum/reagent/medicine/morphine/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_IGNORESLOWDOWN, id) + L.ignore_slowdown(id) /datum/reagent/medicine/morphine/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_IGNORESLOWDOWN, id) + L.unignore_slowdown(id) ..() /datum/reagent/medicine/morphine/on_mob_life(mob/living/carbon/M) @@ -702,14 +702,14 @@ var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES) if (!eyes) return - if(M.has_trait(TRAIT_BLIND, EYE_DAMAGE)) + if(HAS_TRAIT_FROM(M, TRAIT_BLIND, EYE_DAMAGE)) if(prob(20)) to_chat(M, "Your vision slowly returns...") M.cure_blind(EYE_DAMAGE) M.cure_nearsighted(EYE_DAMAGE) M.blur_eyes(35) - else if(M.has_trait(TRAIT_NEARSIGHT, EYE_DAMAGE)) + else if(HAS_TRAIT_FROM(M, TRAIT_NEARSIGHT, EYE_DAMAGE)) to_chat(M, "The blackness in your peripheral vision fades.") M.cure_nearsighted(EYE_DAMAGE) M.blur_eyes(10) @@ -800,7 +800,7 @@ M.visible_message("[M]'s body convulses a bit, and then falls still once more.") return M.visible_message("[M]'s body convulses a bit.") - if(!M.suiciding && !(M.has_trait(TRAIT_NOCLONE)) && !M.hellbound) + if(!M.suiciding && !(HAS_TRAIT(M, TRAIT_NOCLONE)) && !M.hellbound) if(!M) return if(M.notify_ghost_cloning(source = M)) @@ -877,10 +877,10 @@ /datum/reagent/medicine/stimulants/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_GOTTAGOFAST, id) + ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) /datum/reagent/medicine/stimulants/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_GOTTAGOFAST, id) + REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() /datum/reagent/medicine/stimulants/on_mob_life(mob/living/carbon/M) @@ -1171,6 +1171,7 @@ M.AdjustUnconscious(-20, 0) M.AdjustStun(-20, 0) M.AdjustKnockdown(-20, 0) + M.AdjustSleeping(-20, 0) M.adjustStaminaLoss(-30, 0) ..() return TRUE @@ -1189,10 +1190,10 @@ /datum/reagent/medicine/changelinghaste/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_GOTTAGOREALLYFAST, id) + ADD_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id) /datum/reagent/medicine/changelinghaste/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_GOTTAGOREALLYFAST, id) + REMOVE_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id) ..() /datum/reagent/medicine/changelinghaste/on_mob_life(mob/living/carbon/M) @@ -1211,10 +1212,10 @@ /datum/reagent/medicine/corazone/on_mob_add(mob/living/M) ..() - M.add_trait(TRAIT_STABLEHEART, id) + ADD_TRAIT(M, TRAIT_STABLEHEART, id) /datum/reagent/medicine/corazone/on_mob_delete(mob/living/M) - M.remove_trait(TRAIT_STABLEHEART, id) + REMOVE_TRAIT(M, TRAIT_STABLEHEART, id) ..() /datum/reagent/medicine/muscle_stimulant @@ -1224,11 +1225,11 @@ /datum/reagent/medicine/muscle_stimulant/on_mob_add(mob/living/M) . = ..() - M.add_trait(TRAIT_IGNORESLOWDOWN, id) + M.ignore_slowdown(id) /datum/reagent/medicine/muscle_stimulant/on_mob_delete(mob/living/M) . = ..() - M.remove_trait(TRAIT_IGNORESLOWDOWN, id) + M.unignore_slowdown(id) /datum/reagent/medicine/modafinil name = "Modafinil" @@ -1242,11 +1243,11 @@ var/overdose_progress = 0 // to track overdose progress /datum/reagent/medicine/modafinil/on_mob_add(mob/living/M) - M.add_trait(TRAIT_SLEEPIMMUNE, id) + ADD_TRAIT(M, TRAIT_SLEEPIMMUNE, id) ..() /datum/reagent/medicine/modafinil/on_mob_delete(mob/living/M) - M.remove_trait(TRAIT_SLEEPIMMUNE, id) + REMOVE_TRAIT(M, TRAIT_SLEEPIMMUNE, id) ..() /datum/reagent/medicine/modafinil/on_mob_life(mob/living/carbon/M) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 15a2ef1cba..40242909de 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -198,10 +198,10 @@ /datum/reagent/water/holywater/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_HOLY, id) + ADD_TRAIT(L, TRAIT_HOLY, id) /datum/reagent/water/holywater/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_HOLY, id) + REMOVE_TRAIT(L, TRAIT_HOLY, id) ..() /datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume) @@ -1243,12 +1243,12 @@ /datum/reagent/stimulum/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_STUNIMMUNE, id) - L.add_trait(TRAIT_SLEEPIMMUNE, id) + ADD_TRAIT(L, TRAIT_STUNIMMUNE, id) + ADD_TRAIT(L, TRAIT_SLEEPIMMUNE, id) /datum/reagent/stimulum/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_STUNIMMUNE, id) - L.remove_trait(TRAIT_SLEEPIMMUNE, id) + REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id) + REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id) ..() /datum/reagent/stimulum/on_mob_life(mob/living/carbon/M) @@ -1268,10 +1268,10 @@ /datum/reagent/nitryl/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_GOTTAGOFAST, id) + ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) /datum/reagent/nitryl/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_GOTTAGOFAST, id) + REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id) ..() /////////////////////////Coloured Crayon Powder//////////////////////////// @@ -1779,10 +1779,10 @@ /datum/reagent/pax/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_PACIFISM, id) + ADD_TRAIT(L, TRAIT_PACIFISM, id) /datum/reagent/pax/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_PACIFISM, id) + REMOVE_TRAIT(L, TRAIT_PACIFISM, id) ..() /datum/reagent/bz_metabolites @@ -1795,11 +1795,11 @@ /datum/reagent/bz_metabolites/on_mob_add(mob/living/L) ..() - L.add_trait(CHANGELING_HIVEMIND_MUTE, id) + ADD_TRAIT(L, CHANGELING_HIVEMIND_MUTE, id) /datum/reagent/bz_metabolites/on_mob_delete(mob/living/L) ..() - L.remove_trait(CHANGELING_HIVEMIND_MUTE, id) + REMOVE_TRAIT(L, CHANGELING_HIVEMIND_MUTE, id) /datum/reagent/bz_metabolites/on_mob_life(mob/living/L) if(L.mind) @@ -1863,3 +1863,20 @@ description = "The primary precursor for an ancient feline delicacy known as skooma. While it has no notable effects on it's own, mixing it with morphine in a chilled container may yield interesting results." color = "#FAEAFF" taste_description = "synthetic catnip" + +/datum/reagent/penis_enlargement + name = "Penis Enlargement" + id = "penis_enlargement" + description = "A patented chemical forumula by Doctor Ronald Hyatt that is guaranteed to bring maximum GROWTH and LENGTH to your penis, today!" + color = "#888888" + taste_description = "chinese dragon powder" + metabolization_rate = INFINITY //So it instantly removes all of itself. Don't want to put strain on the system. + +/datum/reagent/penis_enlargement/on_mob_life(mob/living/carbon/C) + var/obj/item/organ/genital/penis/P = C.getorganslot(ORGAN_SLOT_PENIS) + if(P) + var/added_length = round(volume/30,0.01) //Every 30u gives an extra inch. Rounded to the nearest 0.01 so float fuckery doesn't occur with the division by 30. + if(added_length >= 0.20) //Only add the length if it's greater than or equal to 0.2. This is to prevent people from smoking the reagents and causing the penis to update constantly. + P.length += added_length + P.update() + ..() \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 26edcb5b73..8be95efb83 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -97,7 +97,7 @@ /datum/reagent/toxin/lexorin/on_mob_life(mob/living/carbon/C) . = TRUE - if(C.has_trait(TRAIT_NOBREATH)) + if(HAS_TRAIT(C, TRAIT_NOBREATH)) . = FALSE if(.) @@ -135,7 +135,7 @@ taste_description = "mint" /datum/reagent/toxin/minttoxin/on_mob_life(mob/living/carbon/M) - if(M.has_trait(TRAIT_FAT)) + if(HAS_TRAIT(M, TRAIT_FAT)) M.gib() return ..() @@ -180,10 +180,10 @@ /datum/reagent/toxin/ghoulpowder/on_mob_add(mob/living/L) ..() - L.add_trait(TRAIT_FAKEDEATH, id) + ADD_TRAIT(L, TRAIT_FAKEDEATH, id) /datum/reagent/toxin/ghoulpowder/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_FAKEDEATH, id) + REMOVE_TRAIT(L, TRAIT_FAKEDEATH, id) ..() /datum/reagent/toxin/ghoulpowder/on_mob_life(mob/living/carbon/M) @@ -304,13 +304,14 @@ reagent_state = SOLID color = "#000067" // rgb: 0, 0, 103 toxpwr = 0 - metabolization_rate = 1.5 * REAGENTS_METABOLISM + metabolization_rate = 1 * REAGENTS_METABOLISM /datum/reagent/toxin/chloralhydratedelayed/on_mob_life(mob/living/carbon/M) switch(current_cycle) if(10 to 20) M.confused += 1 M.drowsyness += 1 + M.adjustStaminaLoss(7.5) if(20 to INFINITY) M.Sleeping(40, 0) ..() @@ -759,6 +760,7 @@ taste_description = "skewing" /datum/reagent/toxin/skewium/on_mob_life(mob/living/carbon/M) + /* if(M.hud_used) if(current_cycle >= 5 && current_cycle % 3 == 0) var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) @@ -774,6 +776,7 @@ for(var/whole_screen in screens) animate(whole_screen, transform = newmatrix, time = 5, easing = QUAD_EASING, loop = -1) animate(transform = -newmatrix, time = 5, easing = QUAD_EASING) + */ return ..() /datum/reagent/toxin/skewium/on_mob_delete(mob/living/M) @@ -880,7 +883,7 @@ taste_description = "stillness" /datum/reagent/toxin/mimesbane/on_mob_add(mob/living/L) - L.add_trait(TRAIT_EMOTEMUTE, id) + ADD_TRAIT(L, TRAIT_EMOTEMUTE, id) /datum/reagent/toxin/mimesbane/on_mob_delete(mob/living/L) - L.remove_trait(TRAIT_EMOTEMUTE, id) + REMOVE_TRAIT(L, TRAIT_EMOTEMUTE, id) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 98c85b875f..13e809f7cb 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -7,6 +7,7 @@ var/amount_per_transfer_from_this = 5 var/list/possible_transfer_amounts = list(5,10,15,20,25,30) var/volume = 30 + var/reagent_flags var/list/list_reagents = null var/spawned_disease = null var/disease_amount = 20 @@ -16,7 +17,7 @@ . = ..() if(isnum(vol) && vol > 0) volume = vol - create_reagents(volume) + create_reagents(volume, reagent_flags) if(spawned_disease) var/datum/disease/F = new spawned_disease() var/list/data = list("viruses"= list(F)) diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 1c75c76458..efe9c378d9 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -6,7 +6,7 @@ amount_per_transfer_from_this = 5 possible_transfer_amounts = list(1, 2, 3, 4, 5) volume = 5 - container_type = TRANSPARENT + reagent_flags = TRANSPARENT /obj/item/reagent_containers/dropper/afterattack(obj/target, mob/user , proximity) . = ..() diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 05f30a7092..9bc6bef8a5 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -3,7 +3,7 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50) volume = 50 - container_type = OPENCONTAINER + reagent_flags = OPENCONTAINER spillable = TRUE resistance_flags = ACID_PROOF @@ -194,13 +194,10 @@ reactions. Can hold up to 50 units." icon_state = "beakernoreact" materials = list(MAT_METAL=3000) + reagent_flags = OPENCONTAINER | NO_REACT volume = 50 amount_per_transfer_from_this = 10 -/obj/item/reagent_containers/glass/beaker/noreact/Initialize() - . = ..() - reagents.set_reacting(FALSE) - /obj/item/reagent_containers/glass/beaker/bluespace name = "bluespace beaker" desc = "A bluespace beaker, powered by experimental bluespace technology \ @@ -291,11 +288,11 @@ to_chat(user, "[src]'s contents spill all over you!") reagents.reaction(user, TOUCH) reagents.clear_reagents() - container_type = NONE + reagent_flags = NONE /obj/item/reagent_containers/glass/bucket/dropped(mob/user) . = ..() - container_type = initial(container_type) + reagent_flags = initial(reagent_flags) /obj/item/reagent_containers/glass/bucket/equip_to_best_slot(var/mob/M) if(reagents.total_volume) //If there is water in a bucket, don't quick equip it to the head diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index f59f00a4b8..82d95cea40 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -10,7 +10,7 @@ volume = 30 possible_transfer_amounts = list() resistance_flags = ACID_PROOF - container_type = OPENCONTAINER + reagent_flags = OPENCONTAINER slot_flags = ITEM_SLOT_BELT var/ignore_flags = 0 var/infinite = FALSE @@ -73,7 +73,7 @@ desc = "A modified air-needle autoinjector with a small single-use reservoir. It contains an experimental serum." icon_state = "combat_hypo" volume = 5 - container_type = NONE + reagent_flags = NONE list_reagents = list("magillitis" = 5) //MediPens @@ -88,7 +88,7 @@ amount_per_transfer_from_this = 10 volume = 10 ignore_flags = 1 //so you can medipen through hardsuits - container_type = DRAWABLE + reagent_flags = DRAWABLE flags_1 = null list_reagents = list("epinephrine" = 10) @@ -103,7 +103,7 @@ ..() if(!iscyborg(user)) reagents.maximum_volume = 0 //Makes them useless afterwards - container_type = NONE + reagent_flags = NONE update_icon() addtimer(CALLBACK(src, .proc/cyborg_recharge, user), 80) diff --git a/code/modules/reagents/reagent_containers/medspray.dm b/code/modules/reagents/reagent_containers/medspray.dm index 8631c14ac0..54a38eef86 100644 --- a/code/modules/reagents/reagent_containers/medspray.dm +++ b/code/modules/reagents/reagent_containers/medspray.dm @@ -8,7 +8,7 @@ righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi' item_flags = NOBLUDGEON obj_flags = UNIQUE_RENAME - container_type = OPENCONTAINER + reagent_flags = OPENCONTAINER slot_flags = ITEM_SLOT_BELT throwforce = 0 w_class = WEIGHT_CLASS_SMALL diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 38d47d5185..ed2ca66aae 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -233,3 +233,7 @@ /obj/item/reagent_containers/pill/get_belt_overlay() return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch") + +/obj/item/reagent_containers/pill/penis_enlargement + name = "penis enlargement pill" + list_reagents = list("penis_enlargement" = 30) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index a51134f84d..d2e3f95bdc 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -7,7 +7,7 @@ lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' item_flags = NOBLUDGEON - container_type = OPENCONTAINER + reagent_flags = OPENCONTAINER slot_flags = ITEM_SLOT_BELT throwforce = 0 w_class = WEIGHT_CLASS_SMALL @@ -18,6 +18,7 @@ var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode. var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode. var/stream_amount = 10 //the amount of reagents transfered when in stream mode. + var/spray_delay = 3 //The amount of sleep() delay between each chempuff step. var/can_fill_from_container = TRUE amount_per_transfer_from_this = 5 volume = 250 @@ -64,7 +65,7 @@ /obj/item/reagent_containers/spray/proc/spray(atom/A) - var/range = max(min(current_range, get_dist(src, A)), 1) + var/range = CLAMP(get_dist(src, A), 1, current_range) var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src)) D.create_reagents(amount_per_transfer_from_this) var/puff_reagent_left = range //how many turf, mob or dense objet we can react with before we consider the chem puff consumed @@ -74,7 +75,7 @@ else reagents.trans_to(D, amount_per_transfer_from_this, 1/range) D.color = mix_color_from_reagents(D.reagents.reagent_list) - var/wait_step = max(round(2+3/range), 2) + var/wait_step = max(round(2+ spray_delay * INVERSE(range)), 2) do_spray(A, wait_step, D, range, puff_reagent_left) /obj/item/reagent_containers/spray/proc/do_spray(atom/A, wait_step, obj/effect/decal/chempuff/D, range, puff_reagent_left) @@ -166,7 +167,7 @@ user.visible_message("[user] decided life was worth living.") return -//Drying Agent +//Drying Agent /obj/item/reagent_containers/spray/drying_agent name = "drying agent spray" desc = "A spray bottle for drying agent." @@ -194,6 +195,7 @@ righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' volume = 40 stream_range = 4 + spray_delay = 1 amount_per_transfer_from_this = 5 list_reagents = list("condensedcapsaicin" = 40) @@ -222,7 +224,7 @@ return /obj/item/reagent_containers/spray/waterflower/cyborg - container_type = NONE + reagent_flags = NONE volume = 100 list_reagents = list("water" = 100) var/generate_amount = 5 diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index b2b7ab88a7..4947ddde6f 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -13,7 +13,7 @@ var/busy = FALSE // needed for delayed drawing of blood var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun materials = list(MAT_METAL=10, MAT_GLASS=20) - container_type = TRANSPARENT + reagent_flags = TRANSPARENT /obj/item/reagent_containers/syringe/Initialize() . = ..() @@ -249,10 +249,7 @@ name = "cryo syringe" desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units." volume = 20 - -/obj/item/reagent_containers/syringe/noreact/Initialize() - . = ..() - reagents.set_reacting(FALSE) + reagent_flags = TRANSPARENT | NO_REACT /obj/item/reagent_containers/syringe/piercing name = "piercing syringe" diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 45154a70f4..19afab2e6e 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -5,7 +5,6 @@ icon_state = "water" density = TRUE anchored = FALSE - container_type = DRAINABLE | AMOUNT_VISIBLE pressure_resistance = 2*ONE_ATMOSPHERE max_integrity = 300 var/tank_volume = 1000 //In units, how much the dispenser can hold @@ -24,7 +23,7 @@ return ..() /obj/structure/reagent_dispensers/Initialize() - create_reagents(tank_volume) + create_reagents(tank_volume, DRAINABLE | AMOUNT_VISIBLE) reagents.add_reagent(reagent_id, tank_volume) . = ..() diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm deleted file mode 100644 index 7ceeda2c64..0000000000 --- a/code/modules/research/designs/autolathe_designs.dm +++ /dev/null @@ -1,872 +0,0 @@ -/////////////////////////////////// -//////////Autolathe Designs /////// -/////////////////////////////////// - -/datum/design/bucket - name = "Bucket" - id = "bucket" - build_type = AUTOLATHE - materials = list(MAT_METAL = 200) - build_path = /obj/item/reagent_containers/glass/bucket - category = list("initial","Tools") - -/datum/design/crowbar - name = "Pocket Crowbar" - id = "crowbar" - build_type = AUTOLATHE - materials = list(MAT_METAL = 50) - build_path = /obj/item/crowbar - category = list("initial","Tools") - -/datum/design/flashlight - name = "Flashlight" - id = "flashlight" - build_type = AUTOLATHE - materials = list(MAT_METAL = 50, MAT_GLASS = 20) - build_path = /obj/item/flashlight - category = list("initial","Tools") - -/datum/design/extinguisher - name = "Fire Extinguisher" - id = "extinguisher" - build_type = AUTOLATHE - materials = list(MAT_METAL = 90) - build_path = /obj/item/extinguisher - category = list("initial","Tools") - -/datum/design/pocketfireextinguisher - name = "Pocket Fire Extinguisher" - id = "pocketfireextinguisher" - build_type = AUTOLATHE - materials = list(MAT_METAL = 50, MAT_GLASS = 40) - build_path = /obj/item/extinguisher/mini - category = list("initial","Tools") - -/datum/design/multitool - name = "Multitool" - id = "multitool" - build_type = AUTOLATHE - materials = list(MAT_METAL = 50, MAT_GLASS = 20) - build_path = /obj/item/multitool - category = list("initial","Tools") - -/datum/design/analyzer - name = "Analyzer" - id = "analyzer" - build_type = AUTOLATHE - materials = list(MAT_METAL = 30, MAT_GLASS = 20) - build_path = /obj/item/analyzer - category = list("initial","Tools") - -/datum/design/tscanner - name = "T-Ray Scanner" - id = "tscanner" - build_type = AUTOLATHE - materials = list(MAT_METAL = 150) - build_path = /obj/item/t_scanner - category = list("initial","Tools") - -/datum/design/weldingtool - name = "Welding Tool" - id = "welding_tool" - build_type = AUTOLATHE - materials = list(MAT_METAL = 70, MAT_GLASS = 20) - build_path = /obj/item/weldingtool - category = list("initial","Tools") - -/datum/design/mini_weldingtool - name = "Emergency Welding Tool" - id = "mini_welding_tool" - build_type = AUTOLATHE - materials = list(MAT_METAL = 30, MAT_GLASS = 10) - build_path = /obj/item/weldingtool/mini - category = list("initial","Tools") - -/datum/design/screwdriver - name = "Screwdriver" - id = "screwdriver" - build_type = AUTOLATHE - materials = list(MAT_METAL = 75) - build_path = /obj/item/screwdriver - category = list("initial","Tools") - -/datum/design/wirecutters - name = "Wirecutters" - id = "wirecutters" - build_type = AUTOLATHE - materials = list(MAT_METAL = 80) - build_path = /obj/item/wirecutters - category = list("initial","Tools") - -/datum/design/wrench - name = "Wrench" - id = "wrench" - build_type = AUTOLATHE - materials = list(MAT_METAL = 150) - build_path = /obj/item/wrench - category = list("initial","Tools") - -/datum/design/welding_helmet - name = "Welding Helmet" - id = "welding_helmet" - build_type = AUTOLATHE - materials = list(MAT_METAL = 1750, MAT_GLASS = 400) - build_path = /obj/item/clothing/head/welding - category = list("initial","Tools") - -/datum/design/cable_coil - name = "Cable Coil" - id = "cable_coil" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10, MAT_GLASS = 5) - build_path = /obj/item/stack/cable_coil/random - category = list("initial","Tools") - maxstack = 30 - -/datum/design/toolbox - name = "Toolbox" - id = "tool_box" - build_type = AUTOLATHE - materials = list(MAT_METAL = 500) - build_path = /obj/item/storage/toolbox - category = list("initial","Tools") - -/datum/design/apc_board - name = "APC Module" - id = "power control" - build_type = AUTOLATHE | PROTOLATHE - materials = list(MAT_METAL = 100, MAT_GLASS = 100) - build_path = /obj/item/electronics/apc - category = list("initial", "Electronics") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/airlock_board - name = "Airlock Electronics" - id = "airlock_board" - build_type = AUTOLATHE | PROTOLATHE - materials = list(MAT_METAL = 50, MAT_GLASS = 50) - build_path = /obj/item/electronics/airlock - category = list("initial", "Electronics") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/firelock_board - name = "Firelock Circuitry" - id = "firelock_board" - build_type = AUTOLATHE | PROTOLATHE - materials = list(MAT_METAL = 50, MAT_GLASS = 50) - build_path = /obj/item/electronics/firelock - category = list("initial", "Electronics") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/airalarm_electronics - name = "Air Alarm Electronics" - id = "airalarm_electronics" - build_type = AUTOLATHE | PROTOLATHE - materials = list(MAT_METAL = 50, MAT_GLASS = 50) - build_path = /obj/item/electronics/airalarm - category = list("initial", "Electronics") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/firealarm_electronics - name = "Fire Alarm Electronics" - id = "firealarm_electronics" - build_type = AUTOLATHE | PROTOLATHE - materials = list(MAT_METAL = 50, MAT_GLASS = 50) - build_path = /obj/item/electronics/firealarm - category = list("initial", "Electronics") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/camera - name = "Camera" - id = "camera" - build_type = AUTOLATHE - materials = list(MAT_METAL = 50, MAT_GLASS = 100) - build_path = /obj/item/camera - category = list("initial", "Misc") - -/datum/design/camera_film - name = "Camera Film Cartridge" - id = "camera_film" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10, MAT_GLASS = 10) - build_path = /obj/item/camera_film - category = list("initial", "Misc") - -/datum/design/earmuffs - name = "Earmuffs" - id = "earmuffs" - build_type = AUTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/ears/earmuffs - category = list("initial", "Misc") - -/datum/design/pipe_painter - name = "Pipe Painter" - id = "pipe_painter" - build_type = AUTOLATHE - materials = list(MAT_METAL = 5000, MAT_GLASS = 2000) - build_path = /obj/item/pipe_painter - category = list("initial", "Misc") - -/datum/design/airlock_painter - name = "Airlock Painter" - id = "airlock_painter" - build_type = AUTOLATHE - materials = list(MAT_METAL = 50, MAT_GLASS = 50) - build_path = /obj/item/airlock_painter - category = list("initial", "Misc") - -/datum/design/metal - name = "Metal" - id = "metal" - build_type = AUTOLATHE - materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT) - build_path = /obj/item/stack/sheet/metal - category = list("initial","Construction") - maxstack = 50 - -/datum/design/glass - name = "Glass" - id = "glass" - build_type = AUTOLATHE - materials = list(MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - build_path = /obj/item/stack/sheet/glass - category = list("initial","Construction") - maxstack = 50 - -/datum/design/rglass - name = "Reinforced Glass" - id = "rglass" - build_type = AUTOLATHE | SMELTER | PROTOLATHE - materials = list(MAT_METAL = 1000, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) - build_path = /obj/item/stack/sheet/rglass - category = list("initial","Construction","Stock Parts") - maxstack = 50 - -/datum/design/rods - name = "Metal Rod" - id = "rods" - build_type = AUTOLATHE - materials = list(MAT_METAL = 1000) - build_path = /obj/item/stack/rods - category = list("initial","Construction") - maxstack = 50 - -/datum/design/rcd_ammo - name = "Compressed Matter Cartridge" - id = "rcd_ammo" - build_type = AUTOLATHE - materials = list(MAT_METAL = 12000, MAT_GLASS=8000) - build_path = /obj/item/rcd_ammo - category = list("initial","Construction") - -/datum/design/kitchen_knife - name = "Kitchen Knife" - id = "kitchen_knife" - build_type = AUTOLATHE - materials = list(MAT_METAL = 12000) - build_path = /obj/item/kitchen/knife - category = list("initial","Dinnerware") - -/datum/design/fork - name = "Fork" - id = "fork" - build_type = AUTOLATHE - materials = list(MAT_METAL = 80) - build_path = /obj/item/kitchen/fork - category = list("initial","Dinnerware") - -/datum/design/tray - name = "Tray" - id = "tray" - build_type = AUTOLATHE - materials = list(MAT_METAL = 3000) - build_path = /obj/item/storage/bag/tray - category = list("initial","Dinnerware") - -/datum/design/bowl - name = "Bowl" - id = "bowl" - build_type = AUTOLATHE - materials = list(MAT_GLASS = 500) - build_path = /obj/item/reagent_containers/glass/bowl - category = list("initial","Dinnerware") - -/datum/design/drinking_glass - name = "Drinking Glass" - id = "drinking_glass" - build_type = AUTOLATHE - materials = list(MAT_GLASS = 500) - build_path = /obj/item/reagent_containers/food/drinks/drinkingglass - category = list("initial","Dinnerware") - -/datum/design/shot_glass - name = "Shot Glass" - id = "shot_glass" - build_type = AUTOLATHE - materials = list(MAT_GLASS = 100) - build_path = /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass - category = list("initial","Dinnerware") - -/datum/design/shaker - name = "Shaker" - id = "shaker" - build_type = AUTOLATHE - materials = list(MAT_METAL = 1500) - build_path = /obj/item/reagent_containers/food/drinks/shaker - category = list("initial","Dinnerware") - -/datum/design/cultivator - name = "Cultivator" - id = "cultivator" - build_type = AUTOLATHE - materials = list(MAT_METAL=50) - build_path = /obj/item/cultivator - category = list("initial","Misc") - -/datum/design/plant_analyzer - name = "Plant Analyzer" - id = "plant_analyzer" - build_type = AUTOLATHE - materials = list(MAT_METAL = 30, MAT_GLASS = 20) - build_path = /obj/item/plant_analyzer - category = list("initial","Misc") - -/datum/design/shovel - name = "Shovel" - id = "shovel" - build_type = AUTOLATHE - materials = list(MAT_METAL = 50) - build_path = /obj/item/shovel - category = list("initial","Misc") - -/datum/design/spade - name = "Spade" - id = "spade" - build_type = AUTOLATHE - materials = list(MAT_METAL = 50) - build_path = /obj/item/shovel/spade - category = list("initial","Misc") - -/datum/design/hatchet - name = "Hatchet" - id = "hatchet" - build_type = AUTOLATHE - materials = list(MAT_METAL = 15000) - build_path = /obj/item/hatchet - category = list("initial","Misc") - -/datum/design/foilhat - name = "Tinfoil Hat" - id = "tinfoil_hat" - build_type = AUTOLATHE - materials = list(MAT_METAL = 5500) - build_path = /obj/item/clothing/head/foilhat - category = list("hacked", "Misc") - -/datum/design/scalpel - name = "Scalpel" - id = "scalpel" - build_type = AUTOLATHE - materials = list(MAT_METAL = 4000, MAT_GLASS = 1000) - build_path = /obj/item/scalpel - category = list("initial", "Medical") - -/datum/design/circular_saw - name = "Circular Saw" - id = "circular_saw" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10000, MAT_GLASS = 6000) - build_path = /obj/item/circular_saw - category = list("initial", "Medical") - -/datum/design/surgicaldrill - name = "Surgical Drill" - id = "surgicaldrill" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10000, MAT_GLASS = 6000) - build_path = /obj/item/surgicaldrill - category = list("initial", "Medical") - -/datum/design/retractor - name = "Retractor" - id = "retractor" - build_type = AUTOLATHE - materials = list(MAT_METAL = 6000, MAT_GLASS = 3000) - build_path = /obj/item/retractor - category = list("initial", "Medical") - -/datum/design/cautery - name = "Cautery" - id = "cautery" - build_type = AUTOLATHE - materials = list(MAT_METAL = 2500, MAT_GLASS = 750) - build_path = /obj/item/cautery - category = list("initial", "Medical") - -/datum/design/hemostat - name = "Hemostat" - id = "hemostat" - build_type = AUTOLATHE - materials = list(MAT_METAL = 5000, MAT_GLASS = 2500) - build_path = /obj/item/hemostat - category = list("initial", "Medical") - -/datum/design/beaker - name = "Beaker" - id = "beaker" - build_type = AUTOLATHE - materials = list(MAT_GLASS = 500) - build_path = /obj/item/reagent_containers/glass/beaker - category = list("initial", "Medical") - -/datum/design/large_beaker - name = "Large Beaker" - id = "large_beaker" - build_type = AUTOLATHE - materials = list(MAT_GLASS = 2500) - build_path = /obj/item/reagent_containers/glass/beaker/large - category = list("initial", "Medical") - -/datum/design/healthanalyzer - name = "Health Analyzer" - id = "healthanalyzer" - build_type = AUTOLATHE | PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 50) - build_path = /obj/item/healthanalyzer - category = list("initial", "Medical") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/pillbottle - name = "Pill Bottle" - id = "pillbottle" - build_type = AUTOLATHE - materials = list(MAT_METAL = 20, MAT_GLASS = 100) - build_path = /obj/item/storage/pill_bottle - category = list("initial", "Medical") - -/datum/design/beanbag_slug - name = "Beanbag Slug" - id = "beanbag_slug" - build_type = AUTOLATHE - materials = list(MAT_METAL = 250) - build_path = /obj/item/ammo_casing/shotgun/beanbag - category = list("initial", "Security") - -/datum/design/rubbershot - name = "Rubber Shot" - id = "rubber_shot" - build_type = AUTOLATHE - materials = list(MAT_METAL = 4000) - build_path = /obj/item/ammo_casing/shotgun/rubbershot - category = list("initial", "Security") - -/datum/design/c38 - name = "Speed Loader (.38 rubber)" - id = "c38" - build_type = AUTOLATHE - materials = list(MAT_METAL = 20000) - build_path = /obj/item/ammo_box/c38 - category = list("initial", "Security") - -/datum/design/recorder - name = "Universal Recorder" - id = "recorder" - build_type = AUTOLATHE - materials = list(MAT_METAL = 60, MAT_GLASS = 30) - build_path = /obj/item/taperecorder/empty - category = list("initial", "Misc") - -/datum/design/tape - name = "Tape" - id = "tape" - build_type = AUTOLATHE - materials = list(MAT_METAL = 20, MAT_GLASS = 5) - build_path = /obj/item/tape/random - category = list("initial", "Misc") - -/datum/design/igniter - name = "Igniter" - id = "igniter" - build_type = AUTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 50) - build_path = /obj/item/assembly/igniter - category = list("initial", "Misc") - -/datum/design/signaler - name = "Remote Signaling Device" - id = "signaler" - build_type = AUTOLATHE - materials = list(MAT_METAL = 400, MAT_GLASS = 120) - build_path = /obj/item/assembly/signaler - category = list("initial", "T-Comm") - -/datum/design/radio_headset - name = "Radio Headset" - id = "radio_headset" - build_type = AUTOLATHE - materials = list(MAT_METAL = 75) - build_path = /obj/item/radio/headset - category = list("initial", "T-Comm") - -/datum/design/bounced_radio - name = "Station Bounced Radio" - id = "bounced_radio" - build_type = AUTOLATHE - materials = list(MAT_METAL = 75, MAT_GLASS = 25) - build_path = /obj/item/radio/off - category = list("initial", "T-Comm") - -/datum/design/intercom_frame - name = "Intercom Frame" - id = "intercom_frame" - build_type = AUTOLATHE - materials = list(MAT_METAL = 75, MAT_GLASS = 25) - build_path = /obj/item/wallframe/intercom - category = list("initial", "T-Comm") - -/datum/design/infrared_emitter - name = "Infrared Emitter" - id = "infrared_emitter" - build_type = AUTOLATHE - materials = list(MAT_METAL = 1000, MAT_GLASS = 500) - build_path = /obj/item/assembly/infra - category = list("initial", "Misc") - -/datum/design/health_sensor - name = "Health Sensor" - id = "health_sensor" - build_type = AUTOLATHE - materials = list(MAT_METAL = 800, MAT_GLASS = 200) - build_path = /obj/item/assembly/health - category = list("initial", "Medical") - -/datum/design/timer - name = "Timer" - id = "timer" - build_type = AUTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 50) - build_path = /obj/item/assembly/timer - category = list("initial", "Misc") - -/datum/design/voice_analyser - name = "Voice Analyser" - id = "voice_analyser" - build_type = AUTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 50) - build_path = /obj/item/assembly/voice - category = list("initial", "Misc") - -/datum/design/light_tube - name = "Light Tube" - id = "light_tube" - build_type = AUTOLATHE - materials = list(MAT_GLASS = 100) - build_path = /obj/item/light/tube - category = list("initial", "Construction") - -/datum/design/light_bulb - name = "Light Bulb" - id = "light_bulb" - build_type = AUTOLATHE - materials = list(MAT_GLASS = 100) - build_path = /obj/item/light/bulb - category = list("initial", "Construction") - -/datum/design/camera_assembly - name = "Camera Assembly" - id = "camera_assembly" - build_type = AUTOLATHE - materials = list(MAT_METAL = 400, MAT_GLASS = 250) - build_path = /obj/item/wallframe/camera - category = list("initial", "Construction") - -/datum/design/newscaster_frame - name = "Newscaster Frame" - id = "newscaster_frame" - build_type = AUTOLATHE - materials = list(MAT_METAL = 14000, MAT_GLASS = 8000) - build_path = /obj/item/wallframe/newscaster - category = list("initial", "Construction") - -/datum/design/syringe - name = "Syringe" - id = "syringe" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10, MAT_GLASS = 20) - build_path = /obj/item/reagent_containers/syringe - category = list("initial", "Medical") - -/datum/design/prox_sensor - name = "Proximity Sensor" - id = "prox_sensor" - build_type = AUTOLATHE - materials = list(MAT_METAL = 800, MAT_GLASS = 200) - build_path = /obj/item/assembly/prox_sensor - category = list("initial", "Misc") - -/datum/design/foam_dart - name = "Box of Foam Darts" - id = "foam_dart" - build_type = AUTOLATHE - materials = list(MAT_METAL = 500) - build_path = /obj/item/ammo_box/foambox - category = list("initial", "Misc") - -//hacked autolathe recipes -/datum/design/flamethrower - name = "Flamethrower" - id = "flamethrower" - build_type = AUTOLATHE - materials = list(MAT_METAL = 500) - build_path = /obj/item/flamethrower/full - category = list("hacked", "Security") - -/datum/design/rcd - name = "Rapid Construction Device (RCD)" - id = "rcd" - build_type = AUTOLATHE - materials = list(MAT_METAL = 30000) - build_path = /obj/item/construction/rcd - category = list("hacked", "Construction") - -/datum/design/rpd - name = "Rapid Pipe Dispenser (RPD)" - id = "rpd" - build_type = AUTOLATHE - materials = list(MAT_METAL = 75000, MAT_GLASS = 37500) - build_path = /obj/item/pipe_dispenser - category = list("hacked", "Construction") - -/datum/design/electropack - name = "Electropack" - id = "electropack" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10000, MAT_GLASS = 2500) - build_path = /obj/item/electropack - category = list("hacked", "Tools") - -/datum/design/large_welding_tool - name = "Industrial Welding Tool" - id = "large_welding_tool" - build_type = AUTOLATHE - materials = list(MAT_METAL = 70, MAT_GLASS = 60) - build_path = /obj/item/weldingtool/largetank - category = list("hacked", "Tools") - -/datum/design/handcuffs - name = "Handcuffs" - id = "handcuffs" - build_type = AUTOLATHE - materials = list(MAT_METAL = 500) - build_path = /obj/item/restraints/handcuffs - category = list("hacked", "Security") - -/datum/design/receiver - name = "Modular Receiver" - id = "receiver" - build_type = AUTOLATHE - materials = list(MAT_METAL = 15000) - build_path = /obj/item/weaponcrafting/receiver - category = list("hacked", "Security") - -/datum/design/shotgun_slug - name = "Shotgun Slug" - id = "shotgun_slug" - build_type = AUTOLATHE - materials = list(MAT_METAL = 4000) - build_path = /obj/item/ammo_casing/shotgun - category = list("hacked", "Security") - -/datum/design/buckshot_shell - name = "Buckshot Shell" - id = "buckshot_shell" - build_type = AUTOLATHE - materials = list(MAT_METAL = 4000) - build_path = /obj/item/ammo_casing/shotgun/buckshot - category = list("hacked", "Security") - -/datum/design/shotgun_dart - name = "Shotgun Dart" - id = "shotgun_dart" - build_type = AUTOLATHE - materials = list(MAT_METAL = 4000) - build_path = /obj/item/ammo_casing/shotgun/dart - category = list("hacked", "Security") - -/datum/design/incendiary_slug - name = "Incendiary Slug" - id = "incendiary_slug" - build_type = AUTOLATHE - materials = list(MAT_METAL = 4000) - build_path = /obj/item/ammo_casing/shotgun/incendiary - category = list("hacked", "Security") - -/datum/design/riot_dart - name = "Foam Riot Dart" - id = "riot_dart" - build_type = AUTOLATHE - materials = list(MAT_METAL = 1000) //Discount for making individually - no box = less metal! - build_path = /obj/item/ammo_casing/caseless/foam_dart/riot - category = list("hacked", "Security") - -/datum/design/riot_darts - name = "Foam Riot Dart Box" - id = "riot_darts" - build_type = AUTOLATHE - materials = list(MAT_METAL = 50000) //Comes with 40 darts - build_path = /obj/item/ammo_box/foambox/riot - category = list("hacked", "Security") - -/datum/design/a357 - name = "Speed Loader (.357)" - id = "a357" - build_type = AUTOLATHE - materials = list(MAT_METAL = 30000) - build_path = /obj/item/ammo_box/a357 - category = list("hacked", "Security") - -/datum/design/c10mm - name = "Ammo Box (10mm)" - id = "c10mm" - build_type = AUTOLATHE - materials = list(MAT_METAL = 30000) - build_path = /obj/item/ammo_box/c10mm - category = list("hacked", "Security") - -/datum/design/c45 - name = "Ammo Box (.45)" - id = "c45" - build_type = AUTOLATHE - materials = list(MAT_METAL = 30000) - build_path = /obj/item/ammo_box/c45 - category = list("hacked", "Security") - -/datum/design/c9mm - name = "Ammo Box (9mm)" - id = "c9mm" - build_type = AUTOLATHE - materials = list(MAT_METAL = 30000) - build_path = /obj/item/ammo_box/c9mm - category = list("hacked", "Security") - -/datum/design/cleaver - name = "Butcher's Cleaver" - id = "cleaver" - build_type = AUTOLATHE - materials = list(MAT_METAL = 18000) - build_path = /obj/item/kitchen/knife/butcher - category = list("hacked", "Dinnerware") - -/datum/design/spraycan - name = "Spraycan" - id = "spraycan" - build_type = AUTOLATHE - materials = list(MAT_METAL = 100, MAT_GLASS = 100) - build_path = /obj/item/toy/crayon/spraycan - category = list("initial", "Tools") - -/datum/design/desttagger - name = "Destination Tagger" - id = "desttagger" - build_type = AUTOLATHE - materials = list(MAT_METAL = 250, MAT_GLASS = 125) - build_path = /obj/item/destTagger - category = list("initial", "Electronics") - -/datum/design/handlabeler - name = "Hand Labeler" - id = "handlabel" - build_type = AUTOLATHE - materials = list(MAT_METAL = 150, MAT_GLASS = 125) - build_path = /obj/item/hand_labeler - category = list("initial", "Electronics") - -/datum/design/geiger - name = "Geiger Counter" - id = "geigercounter" - build_type = AUTOLATHE - materials = list(MAT_METAL = 150, MAT_GLASS = 150) - build_path = /obj/item/geiger_counter - category = list("initial", "Tools") - -/datum/design/turret_control_frame - name = "Turret Control Frame" - id = "turret_control" - build_type = AUTOLATHE - materials = list(MAT_METAL = 12000) - build_path = /obj/item/wallframe/turret_control - category = list("initial", "Construction") - -/datum/design/conveyor_belt - name = "Conveyor Belt" - id = "conveyor_belt" - build_type = AUTOLATHE - materials = list(MAT_METAL = 5000) - build_path = /obj/item/conveyor_construct - category = list("initial", "Construction") - -/datum/design/conveyor_switch - name = "Conveyor Belt Switch" - id = "conveyor_switch" - build_type = AUTOLATHE - materials = list(MAT_METAL = 450, MAT_GLASS = 190) - build_path = /obj/item/conveyor_switch_construct - category = list("initial", "Construction") - -/datum/design/laptop - name = "Laptop Frame" - id = "laptop" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10000, MAT_GLASS = 1000) - build_path = /obj/item/modular_computer/laptop/buildable - category = list("initial","Misc") - -/datum/design/tablet - name = "Tablet Frame" - id = "tablet" - build_type = AUTOLATHE - materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) - build_path = /obj/item/modular_computer/tablet - category = list("initial","Misc") - -/datum/design/slime_scanner - name = "Slime Scanner" - id = "slime_scanner" - build_type = AUTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 200) - build_path = /obj/item/slime_scanner - category = list("initial", "Misc") - -/datum/design/pet_carrier - name = "Pet Carrier" - id = "pet_carrier" - build_type = AUTOLATHE - materials = list(MAT_METAL = 7500, MAT_GLASS = 100) - build_path = /obj/item/pet_carrier - category = list("initial", "Misc") - -/datum/design/miniature_power_cell - name = "Light Fixture Battery" - id = "miniature_power_cell" - build_type = AUTOLATHE - materials = list(MAT_GLASS = 20) - build_path = /obj/item/stock_parts/cell/emergency_light - category = list("initial", "Electronics") - -/datum/design/packageWrap - name = "Package Wrapping" - id = "packagewrap" - build_type = AUTOLATHE - materials = list(MAT_METAL = 200, MAT_GLASS = 200) - build_path = /obj/item/stack/packageWrap - category = list("initial", "Misc") - maxstack = 30 - -/datum/design/holodisk - name = "Holodisk" - id = "holodisk" - build_type = AUTOLATHE - materials = list(MAT_METAL = 100, MAT_GLASS = 100) - build_path = /obj/item/disk/holodisk - category = list("initial", "Misc") diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm new file mode 100644 index 0000000000..1ae1d3813b --- /dev/null +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm @@ -0,0 +1,108 @@ +/////////////////////////////////// +//////////Autolathe Designs /////// +/////////////////////////////////// + + +//////////////// +///Construction// +//////////////// + +/datum/design/rods + name = "Metal Rod" + id = "rods" + build_type = AUTOLATHE + materials = list(MAT_METAL = 1000) + build_path = /obj/item/stack/rods + category = list("initial","Construction") + maxstack = 50 + +/datum/design/metal + name = "Metal" + id = "metal" + build_type = AUTOLATHE + materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT) + build_path = /obj/item/stack/sheet/metal + category = list("initial","Construction") + maxstack = 50 + +/datum/design/glass + name = "Glass" + id = "glass" + build_type = AUTOLATHE + materials = list(MAT_GLASS = MINERAL_MATERIAL_AMOUNT) + build_path = /obj/item/stack/sheet/glass + category = list("initial","Construction") + maxstack = 50 + +/datum/design/rglass + name = "Reinforced Glass" + id = "rglass" + build_type = AUTOLATHE | SMELTER | PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) + build_path = /obj/item/stack/sheet/rglass + category = list("initial","Construction","Stock Parts") + maxstack = 50 + +/datum/design/light_tube + name = "Light Tube" + id = "light_tube" + build_type = AUTOLATHE + materials = list(MAT_GLASS = 100) + build_path = /obj/item/light/tube + category = list("initial", "Construction") + +/datum/design/light_bulb + name = "Light Bulb" + id = "light_bulb" + build_type = AUTOLATHE + materials = list(MAT_GLASS = 100) + build_path = /obj/item/light/bulb + category = list("initial", "Construction") + +/datum/design/camera_assembly + name = "Camera Assembly" + id = "camera_assembly" + build_type = AUTOLATHE + materials = list(MAT_METAL = 400, MAT_GLASS = 250) + build_path = /obj/item/wallframe/camera + category = list("initial", "Construction") + +/datum/design/newscaster_frame + name = "Newscaster Frame" + id = "newscaster_frame" + build_type = AUTOLATHE + materials = list(MAT_METAL = 14000, MAT_GLASS = 8000) + build_path = /obj/item/wallframe/newscaster + category = list("initial", "Construction") + +/datum/design/turret_control_frame + name = "Turret Control Frame" + id = "turret_control" + build_type = AUTOLATHE + materials = list(MAT_METAL = 12000) + build_path = /obj/item/wallframe/turret_control + category = list("initial", "Construction") + +/datum/design/conveyor_belt + name = "Conveyor Belt" + id = "conveyor_belt" + build_type = AUTOLATHE + materials = list(MAT_METAL = 5000) + build_path = /obj/item/conveyor_construct + category = list("initial", "Construction") + +/datum/design/conveyor_switch + name = "Conveyor Belt Switch" + id = "conveyor_switch" + build_type = AUTOLATHE + materials = list(MAT_METAL = 450, MAT_GLASS = 190) + build_path = /obj/item/conveyor_switch_construct + category = list("initial", "Construction") + +/datum/design/rcd_ammo + name = "Compressed Matter Cartridge" + id = "rcd_ammo" + build_type = AUTOLATHE + materials = list(MAT_METAL = 12000, MAT_GLASS=8000) + build_path = /obj/item/rcd_ammo + category = list("initial","Construction") diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm new file mode 100644 index 0000000000..5b247efe74 --- /dev/null +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm @@ -0,0 +1,76 @@ +/////////////////////////////////// +//////////Autolathe Designs /////// +/////////////////////////////////// + +//////////////// +///Electronics// +//////////////// + +/datum/design/apc_board + name = "APC Module" + id = "power control" + build_type = AUTOLATHE | PROTOLATHE + materials = list(MAT_METAL = 100, MAT_GLASS = 100) + build_path = /obj/item/electronics/apc + category = list("initial", "Electronics") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/airlock_board + name = "Airlock Electronics" + id = "airlock_board" + build_type = AUTOLATHE | PROTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 50) + build_path = /obj/item/electronics/airlock + category = list("initial", "Electronics") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/firelock_board + name = "Firelock Circuitry" + id = "firelock_board" + build_type = AUTOLATHE | PROTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 50) + build_path = /obj/item/electronics/firelock + category = list("initial", "Electronics") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/airalarm_electronics + name = "Air Alarm Electronics" + id = "airalarm_electronics" + build_type = AUTOLATHE | PROTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 50) + build_path = /obj/item/electronics/airalarm + category = list("initial", "Electronics") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/firealarm_electronics + name = "Fire Alarm Electronics" + id = "firealarm_electronics" + build_type = AUTOLATHE | PROTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 50) + build_path = /obj/item/electronics/firealarm + category = list("initial", "Electronics") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/desttagger + name = "Destination Tagger" + id = "desttagger" + build_type = AUTOLATHE + materials = list(MAT_METAL = 250, MAT_GLASS = 125) + build_path = /obj/item/destTagger + category = list("initial", "Electronics") + +/datum/design/handlabeler + name = "Hand Labeler" + id = "handlabel" + build_type = AUTOLATHE + materials = list(MAT_METAL = 150, MAT_GLASS = 125) + build_path = /obj/item/hand_labeler + category = list("initial", "Electronics") + +/datum/design/miniature_power_cell + name = "Light Fixture Battery" + id = "miniature_power_cell" + build_type = AUTOLATHE + materials = list(MAT_GLASS = 20) + build_path = /obj/item/stock_parts/cell/emergency_light + category = list("initial", "Electronics") \ No newline at end of file diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm new file mode 100644 index 0000000000..27852b2798 --- /dev/null +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm @@ -0,0 +1,179 @@ +/////////////////////////////////// +//////////Autolathe Designs /////// +/////////////////////////////////// +//////////////// +////Dinnerware// +//////////////// + +/datum/design/kitchen_knife + name = "Kitchen Knife" + id = "kitchen_knife" + build_type = AUTOLATHE + materials = list(MAT_METAL = 12000) + build_path = /obj/item/kitchen/knife + category = list("initial","Dinnerware") + +/datum/design/fork + name = "Fork" + id = "fork" + build_type = AUTOLATHE + materials = list(MAT_METAL = 80) + build_path = /obj/item/kitchen/fork + category = list("initial","Dinnerware") + +/datum/design/tray + name = "Tray" + id = "tray" + build_type = AUTOLATHE + materials = list(MAT_METAL = 3000) + build_path = /obj/item/storage/bag/tray + category = list("initial","Dinnerware") + +/datum/design/bowl + name = "Bowl" + id = "bowl" + build_type = AUTOLATHE + materials = list(MAT_GLASS = 500) + build_path = /obj/item/reagent_containers/glass/bowl + category = list("initial","Dinnerware") + +/datum/design/drinking_glass + name = "Drinking Glass" + id = "drinking_glass" + build_type = AUTOLATHE + materials = list(MAT_GLASS = 500) + build_path = /obj/item/reagent_containers/food/drinks/drinkingglass + category = list("initial","Dinnerware") + +/datum/design/shot_glass + name = "Shot Glass" + id = "shot_glass" + build_type = AUTOLATHE + materials = list(MAT_GLASS = 100) + build_path = /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass + category = list("initial","Dinnerware") + +/datum/design/shaker + name = "Shaker" + id = "shaker" + build_type = AUTOLATHE + materials = list(MAT_METAL = 1500) + build_path = /obj/item/reagent_containers/food/drinks/shaker + category = list("initial","Dinnerware") + +//////////// +///Medical// +//////////// + +/datum/design/scalpel + name = "Scalpel" + id = "scalpel" + build_type = AUTOLATHE + materials = list(MAT_METAL = 4000, MAT_GLASS = 1000) + build_path = /obj/item/scalpel + category = list("initial", "Medical") + +/datum/design/circular_saw + name = "Circular Saw" + id = "circular_saw" + build_type = AUTOLATHE + materials = list(MAT_METAL = 10000, MAT_GLASS = 6000) + build_path = /obj/item/circular_saw + category = list("initial", "Medical") + +/datum/design/surgicaldrill + name = "Surgical Drill" + id = "surgicaldrill" + build_type = AUTOLATHE + materials = list(MAT_METAL = 10000, MAT_GLASS = 6000) + build_path = /obj/item/surgicaldrill + category = list("initial", "Medical") + +/datum/design/retractor + name = "Retractor" + id = "retractor" + build_type = AUTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 3000) + build_path = /obj/item/retractor + category = list("initial", "Medical") + +/datum/design/cautery + name = "Cautery" + id = "cautery" + build_type = AUTOLATHE + materials = list(MAT_METAL = 2500, MAT_GLASS = 750) + build_path = /obj/item/cautery + category = list("initial", "Medical") + +/datum/design/hemostat + name = "Hemostat" + id = "hemostat" + build_type = AUTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 2500) + build_path = /obj/item/hemostat + category = list("initial", "Medical") + +/datum/design/beaker + name = "Beaker" + id = "beaker" + build_type = AUTOLATHE + materials = list(MAT_GLASS = 500) + build_path = /obj/item/reagent_containers/glass/beaker + category = list("initial", "Medical") + +/datum/design/large_beaker + name = "Large Beaker" + id = "large_beaker" + build_type = AUTOLATHE + materials = list(MAT_GLASS = 2500) + build_path = /obj/item/reagent_containers/glass/beaker/large + category = list("initial", "Medical") + +/datum/design/healthanalyzer + name = "Health Analyzer" + id = "healthanalyzer" + build_type = AUTOLATHE | PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 50) + build_path = /obj/item/healthanalyzer + category = list("initial", "Medical") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/pillbottle + name = "Pill Bottle" + id = "pillbottle" + build_type = AUTOLATHE + materials = list(MAT_METAL = 20, MAT_GLASS = 100) + build_path = /obj/item/storage/pill_bottle + category = list("initial", "Medical") + +/datum/design/syringe + name = "Syringe" + id = "syringe" + build_type = AUTOLATHE + materials = list(MAT_METAL = 10, MAT_GLASS = 20) + build_path = /obj/item/reagent_containers/syringe + category = list("initial", "Medical") + +/datum/design/health_sensor + name = "Health Sensor" + id = "health_sensor" + build_type = AUTOLATHE + materials = list(MAT_METAL = 800, MAT_GLASS = 200) + build_path = /obj/item/assembly/health + category = list("initial", "Medical") + +/datum/design/hypovialsmall + name = "Hypovial" + id = "hypovial" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500) + build_path = /obj/item/reagent_containers/glass/bottle/vial/small + category = list("initial","Medical") + +/datum/design/hypoviallarge + name = "Large Hypovial" + id = "large_hypovial" + build_type = AUTOLATHE + materials = list(MAT_METAL = 2500) + build_path = /obj/item/reagent_containers/glass/bottle/vial/large + category = list("initial","Medical") diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm new file mode 100644 index 0000000000..e5e3a6bb4f --- /dev/null +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm @@ -0,0 +1,186 @@ +/////////////////////////////////// +//////////Autolathe Designs /////// +/////////////////////////////////// +///////////// +////Secgear// +///////////// + +/datum/design/beanbag_slug + name = "Beanbag Slug" + id = "beanbag_slug" + build_type = AUTOLATHE + materials = list(MAT_METAL = 250) + build_path = /obj/item/ammo_casing/shotgun/beanbag + category = list("initial", "Security") + +/datum/design/rubbershot + name = "Rubber Shot" + id = "rubber_shot" + build_type = AUTOLATHE + materials = list(MAT_METAL = 4000) + build_path = /obj/item/ammo_casing/shotgun/rubbershot + category = list("initial", "Security") + +/datum/design/c38 + name = "Speed Loader (.38 rubber)" + id = "c38" + build_type = AUTOLATHE + materials = list(MAT_METAL = 20000) + build_path = /obj/item/ammo_box/c38 + category = list("initial", "Security") + +///////////////// +///Hacked Gear // +///////////////// + +/datum/design/large_welding_tool + name = "Industrial Welding Tool" + id = "large_welding_tool" + build_type = AUTOLATHE + materials = list(MAT_METAL = 70, MAT_GLASS = 60) + build_path = /obj/item/weldingtool/largetank + category = list("hacked", "Tools") + +/datum/design/flamethrower + name = "Flamethrower" + id = "flamethrower" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500) + build_path = /obj/item/flamethrower/full + category = list("hacked", "Security") + +/datum/design/rcd + name = "Rapid Construction Device (RCD)" + id = "rcd" + build_type = AUTOLATHE + materials = list(MAT_METAL = 30000) + build_path = /obj/item/construction/rcd + category = list("hacked", "Construction") + +/datum/design/rpd + name = "Rapid Pipe Dispenser (RPD)" + id = "rpd" + build_type = AUTOLATHE + materials = list(MAT_METAL = 75000, MAT_GLASS = 37500) + build_path = /obj/item/pipe_dispenser + category = list("hacked", "Construction") + +/datum/design/handcuffs + name = "Handcuffs" + id = "handcuffs" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500) + build_path = /obj/item/restraints/handcuffs + category = list("hacked", "Security") + +/datum/design/receiver + name = "Modular Receiver" + id = "receiver" + build_type = AUTOLATHE + materials = list(MAT_METAL = 15000) + build_path = /obj/item/weaponcrafting/receiver + category = list("hacked", "Security") + +/datum/design/shotgun_slug + name = "Shotgun Slug" + id = "shotgun_slug" + build_type = AUTOLATHE + materials = list(MAT_METAL = 4000) + build_path = /obj/item/ammo_casing/shotgun + category = list("hacked", "Security") + +/datum/design/buckshot_shell + name = "Buckshot Shell" + id = "buckshot_shell" + build_type = AUTOLATHE + materials = list(MAT_METAL = 4000) + build_path = /obj/item/ammo_casing/shotgun/buckshot + category = list("hacked", "Security") + +/datum/design/shotgun_dart + name = "Shotgun Dart" + id = "shotgun_dart" + build_type = AUTOLATHE + materials = list(MAT_METAL = 4000) + build_path = /obj/item/ammo_casing/shotgun/dart + category = list("hacked", "Security") + +/datum/design/incendiary_slug + name = "Incendiary Slug" + id = "incendiary_slug" + build_type = AUTOLATHE + materials = list(MAT_METAL = 4000) + build_path = /obj/item/ammo_casing/shotgun/incendiary + category = list("hacked", "Security") + +/datum/design/riot_dart + name = "Foam Riot Dart" + id = "riot_dart" + build_type = AUTOLATHE + materials = list(MAT_METAL = 1000) //Discount for making individually - no box = less metal! + build_path = /obj/item/ammo_casing/caseless/foam_dart/riot + category = list("hacked", "Security") + +/datum/design/riot_darts + name = "Foam Riot Dart Box" + id = "riot_darts" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50000) //Comes with 40 darts + build_path = /obj/item/ammo_box/foambox/riot + category = list("hacked", "Security") + +/datum/design/a357 + name = "Speed Loader (.357)" + id = "a357" + build_type = AUTOLATHE + materials = list(MAT_METAL = 30000) + build_path = /obj/item/ammo_box/a357 + category = list("hacked", "Security") + +/datum/design/c10mm + name = "Ammo Box (10mm)" + id = "c10mm" + build_type = AUTOLATHE + materials = list(MAT_METAL = 30000) + build_path = /obj/item/ammo_box/c10mm + category = list("hacked", "Security") + +/datum/design/c45 + name = "Ammo Box (.45)" + id = "c45" + build_type = AUTOLATHE + materials = list(MAT_METAL = 30000) + build_path = /obj/item/ammo_box/c45 + category = list("hacked", "Security") + +/datum/design/c9mm + name = "Ammo Box (9mm)" + id = "c9mm" + build_type = AUTOLATHE + materials = list(MAT_METAL = 30000) + build_path = /obj/item/ammo_box/c9mm + category = list("hacked", "Security") + +/datum/design/electropack + name = "Electropack" + id = "electropack" + build_type = AUTOLATHE + materials = list(MAT_METAL = 10000, MAT_GLASS = 2500) + build_path = /obj/item/electropack + category = list("hacked", "Security") + +/datum/design/cleaver + name = "Butcher's Cleaver" + id = "cleaver" + build_type = AUTOLATHE + materials = list(MAT_METAL = 18000) + build_path = /obj/item/kitchen/knife/butcher + category = list("hacked", "Dinnerware") + +/datum/design/foilhat + name = "Tinfoil Hat" + id = "tinfoil_hat" + build_type = AUTOLATHE + materials = list(MAT_METAL = 5500) + build_path = /obj/item/clothing/head/foilhat + category = list("hacked", "Misc") \ No newline at end of file diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm new file mode 100644 index 0000000000..29d28b7132 --- /dev/null +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm @@ -0,0 +1,251 @@ +/////////////////////////////////// +//////////Autolathe Designs /////// +/////////////////////////////////// +///////////// +////T-Comms// +///////////// + +/datum/design/signaler + name = "Remote Signaling Device" + id = "signaler" + build_type = AUTOLATHE + materials = list(MAT_METAL = 400, MAT_GLASS = 120) + build_path = /obj/item/assembly/signaler + category = list("initial", "T-Comm") + +/datum/design/radio_headset + name = "Radio Headset" + id = "radio_headset" + build_type = AUTOLATHE + materials = list(MAT_METAL = 75) + build_path = /obj/item/radio/headset + category = list("initial", "T-Comm") + +/datum/design/bounced_radio + name = "Station Bounced Radio" + id = "bounced_radio" + build_type = AUTOLATHE + materials = list(MAT_METAL = 75, MAT_GLASS = 25) + build_path = /obj/item/radio/off + category = list("initial", "T-Comm") + +/datum/design/intercom_frame + name = "Intercom Frame" + id = "intercom_frame" + build_type = AUTOLATHE + materials = list(MAT_METAL = 75, MAT_GLASS = 25) + build_path = /obj/item/wallframe/intercom + category = list("initial", "T-Comm") + +///////////// +////MISC///// +///////////// + +/datum/design/camera + name = "Camera" + id = "camera" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 100) + build_path = /obj/item/camera + category = list("initial", "Misc") + +/datum/design/camera_film + name = "Camera Film Cartridge" + id = "camera_film" + build_type = AUTOLATHE + materials = list(MAT_METAL = 10, MAT_GLASS = 10) + build_path = /obj/item/camera_film + category = list("initial", "Misc") + +/datum/design/earmuffs + name = "Earmuffs" + id = "earmuffs" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/ears/earmuffs + category = list("initial", "Misc") + +/datum/design/pipe_painter + name = "Pipe Painter" + id = "pipe_painter" + build_type = AUTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 2000) + build_path = /obj/item/pipe_painter + category = list("initial", "Misc") + +/datum/design/airlock_painter + name = "Airlock Painter" + id = "airlock_painter" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 50) + build_path = /obj/item/airlock_painter + category = list("initial", "Misc") + +/datum/design/cultivator + name = "Cultivator" + id = "cultivator" + build_type = AUTOLATHE + materials = list(MAT_METAL=50) + build_path = /obj/item/cultivator + category = list("initial","Misc") + +/datum/design/plant_analyzer + name = "Plant Analyzer" + id = "plant_analyzer" + build_type = AUTOLATHE + materials = list(MAT_METAL = 30, MAT_GLASS = 20) + build_path = /obj/item/plant_analyzer + category = list("initial","Misc") + +/datum/design/shovel + name = "Shovel" + id = "shovel" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50) + build_path = /obj/item/shovel + category = list("initial","Misc") + +/datum/design/spade + name = "Spade" + id = "spade" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50) + build_path = /obj/item/shovel/spade + category = list("initial","Misc") + +/datum/design/hatchet + name = "Hatchet" + id = "hatchet" + build_type = AUTOLATHE + materials = list(MAT_METAL = 15000) + build_path = /obj/item/hatchet + category = list("initial","Misc") + +/datum/design/recorder + name = "Universal Recorder" + id = "recorder" + build_type = AUTOLATHE + materials = list(MAT_METAL = 60, MAT_GLASS = 30) + build_path = /obj/item/taperecorder/empty + category = list("initial", "Misc") + +/datum/design/tape + name = "Tape" + id = "tape" + build_type = AUTOLATHE + materials = list(MAT_METAL = 20, MAT_GLASS = 5) + build_path = /obj/item/tape/random + category = list("initial", "Misc") + +/datum/design/igniter + name = "Igniter" + id = "igniter" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 50) + build_path = /obj/item/assembly/igniter + category = list("initial", "Misc") + +/datum/design/infrared_emitter + name = "Infrared Emitter" + id = "infrared_emitter" + build_type = AUTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = 500) + build_path = /obj/item/assembly/infra + category = list("initial", "Misc") + +/datum/design/timer + name = "Timer" + id = "timer" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 50) + build_path = /obj/item/assembly/timer + category = list("initial", "Misc") + +/datum/design/voice_analyser + name = "Voice Analyser" + id = "voice_analyser" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 50) + build_path = /obj/item/assembly/voice + category = list("initial", "Misc") + +/datum/design/prox_sensor + name = "Proximity Sensor" + id = "prox_sensor" + build_type = AUTOLATHE + materials = list(MAT_METAL = 800, MAT_GLASS = 200) + build_path = /obj/item/assembly/prox_sensor + category = list("initial", "Misc") + +/datum/design/foam_dart + name = "Box of Foam Darts" + id = "foam_dart" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500) + build_path = /obj/item/ammo_box/foambox + category = list("initial", "Misc") + +/datum/design/laptop + name = "Laptop Frame" + id = "laptop" + build_type = AUTOLATHE + materials = list(MAT_METAL = 10000, MAT_GLASS = 1000) + build_path = /obj/item/modular_computer/laptop/buildable + category = list("initial","Misc") + +/datum/design/tablet + name = "Tablet Frame" + id = "tablet" + build_type = AUTOLATHE + materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) + build_path = /obj/item/modular_computer/tablet + category = list("initial","Misc") + +/datum/design/slime_scanner + name = "Slime Scanner" + id = "slime_scanner" + build_type = AUTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 200) + build_path = /obj/item/slime_scanner + category = list("initial", "Misc") + +/datum/design/pet_carrier + name = "Pet Carrier" + id = "pet_carrier" + build_type = AUTOLATHE + materials = list(MAT_METAL = 7500, MAT_GLASS = 100) + build_path = /obj/item/pet_carrier + category = list("initial", "Misc") + +/datum/design/packageWrap + name = "Package Wrapping" + id = "packagewrap" + build_type = AUTOLATHE + materials = list(MAT_METAL = 200, MAT_GLASS = 200) + build_path = /obj/item/stack/packageWrap + category = list("initial", "Misc") + maxstack = 30 + +/datum/design/holodisk + name = "Holodisk" + id = "holodisk" + build_type = AUTOLATHE + materials = list(MAT_METAL = 100, MAT_GLASS = 100) + build_path = /obj/item/disk/holodisk + category = list("initial", "Misc") + +/datum/design/lock_collar + name = "Lockable Collar" + id = "lock_collar" + build_type = AUTOLATHE + materials = list(MAT_METAL = 1200, MAT_GLASS = 100) + build_path = /obj/item/clothing/neck/petcollar/locked + category = list("initial", "Misc") + +/datum/design/collar_key + name = "Collar Key" + id = "collar_key" + build_type = AUTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 150) + build_path = /obj/item/key/collar + category = list("initial", "Misc") \ No newline at end of file diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm new file mode 100644 index 0000000000..435af80aea --- /dev/null +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm @@ -0,0 +1,150 @@ +/////////////////////////////////// +//////////Autolathe Designs /////// +/////////////////////////////////// +/////////// +///Tools // +/////////// +/datum/design/bucket + name = "Bucket" + id = "bucket" + build_type = AUTOLATHE + materials = list(MAT_METAL = 200) + build_path = /obj/item/reagent_containers/glass/bucket + category = list("initial","Tools") + +/datum/design/crowbar + name = "Pocket Crowbar" + id = "crowbar" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50) + build_path = /obj/item/crowbar + category = list("initial","Tools") + +/datum/design/flashlight + name = "Flashlight" + id = "flashlight" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 20) + build_path = /obj/item/flashlight + category = list("initial","Tools") + +/datum/design/extinguisher + name = "Fire Extinguisher" + id = "extinguisher" + build_type = AUTOLATHE + materials = list(MAT_METAL = 90) + build_path = /obj/item/extinguisher + category = list("initial","Tools") + +/datum/design/pocketfireextinguisher + name = "Pocket Fire Extinguisher" + id = "pocketfireextinguisher" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 40) + build_path = /obj/item/extinguisher/mini + category = list("initial","Tools") + +/datum/design/multitool + name = "Multitool" + id = "multitool" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 20) + build_path = /obj/item/multitool + category = list("initial","Tools") + +/datum/design/analyzer + name = "Analyzer" + id = "analyzer" + build_type = AUTOLATHE + materials = list(MAT_METAL = 30, MAT_GLASS = 20) + build_path = /obj/item/analyzer + category = list("initial","Tools") + +/datum/design/tscanner + name = "T-Ray Scanner" + id = "tscanner" + build_type = AUTOLATHE + materials = list(MAT_METAL = 150) + build_path = /obj/item/t_scanner + category = list("initial","Tools") + +/datum/design/weldingtool + name = "Welding Tool" + id = "welding_tool" + build_type = AUTOLATHE + materials = list(MAT_METAL = 70, MAT_GLASS = 20) + build_path = /obj/item/weldingtool + category = list("initial","Tools") + +/datum/design/mini_weldingtool + name = "Emergency Welding Tool" + id = "mini_welding_tool" + build_type = AUTOLATHE + materials = list(MAT_METAL = 30, MAT_GLASS = 10) + build_path = /obj/item/weldingtool/mini + category = list("initial","Tools") + +/datum/design/screwdriver + name = "Screwdriver" + id = "screwdriver" + build_type = AUTOLATHE + materials = list(MAT_METAL = 75) + build_path = /obj/item/screwdriver + category = list("initial","Tools") + +/datum/design/wirecutters + name = "Wirecutters" + id = "wirecutters" + build_type = AUTOLATHE + materials = list(MAT_METAL = 80) + build_path = /obj/item/wirecutters + category = list("initial","Tools") + +/datum/design/wrench + name = "Wrench" + id = "wrench" + build_type = AUTOLATHE + materials = list(MAT_METAL = 150) + build_path = /obj/item/wrench + category = list("initial","Tools") + +/datum/design/welding_helmet + name = "Welding Helmet" + id = "welding_helmet" + build_type = AUTOLATHE + materials = list(MAT_METAL = 1750, MAT_GLASS = 400) + build_path = /obj/item/clothing/head/welding + category = list("initial","Tools") + +/datum/design/cable_coil + name = "Cable Coil" + id = "cable_coil" + build_type = AUTOLATHE + materials = list(MAT_METAL = 10, MAT_GLASS = 5) + build_path = /obj/item/stack/cable_coil/random + category = list("initial","Tools") + maxstack = 30 + +/datum/design/toolbox + name = "Toolbox" + id = "tool_box" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500) + build_path = /obj/item/storage/toolbox + category = list("initial","Tools") + +/datum/design/spraycan + name = "Spraycan" + id = "spraycan" + build_type = AUTOLATHE + materials = list(MAT_METAL = 100, MAT_GLASS = 100) + build_path = /obj/item/toy/crayon/spraycan + category = list("initial", "Tools") + +/datum/design/geiger + name = "Geiger Counter" + id = "geigercounter" + build_type = AUTOLATHE + materials = list(MAT_METAL = 150, MAT_GLASS = 150) + build_path = /obj/item/geiger_counter + category = list("initial", "Tools") \ No newline at end of file diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm index 3d48dd51ec..05e4c667f6 100644 --- a/code/modules/research/designs/biogenerator_designs.dm +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -59,6 +59,14 @@ build_path = /obj/item/reagent_containers/food/snacks/monkeycube category = list("initial", "Food") +/datum/design/smeat + name = "Biomass Meat Slab" + id = "smeat" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 175) + build_path = /obj/item/reagent_containers/food/snacks/meat/slab/synthmeat + category = list("initial", "Food") + /datum/design/ez_nut name = "E-Z Nutrient" id = "ez_nut" diff --git a/code/modules/research/designs/bluespace_designs.dm b/code/modules/research/designs/bluespace_designs.dm index 2dc0ed77b3..c9d11a5a3e 100644 --- a/code/modules/research/designs/bluespace_designs.dm +++ b/code/modules/research/designs/bluespace_designs.dm @@ -24,6 +24,17 @@ dangerous_construction = TRUE departmental_flags = DEPARTMENTAL_FLAG_SCIENCE +/datum/design/satchel_holding + name = "Satchel of Holding" + desc = "A satchel that opens into a localized pocket of bluespace." + id = "satchel_holding" + build_type = PROTOLATHE + materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 1500, MAT_URANIUM = 250, MAT_BLUESPACE = 2000) + build_path = /obj/item/storage/backpack/holding/satchel + category = list("Bluespace Designs") + dangerous_construction = TRUE + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + /datum/design/biobag_holding name = "Bio Bag of Holding" desc = "A chemical holding thingy. Mostly used for xenobiology." diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm deleted file mode 100644 index 68aee66d62..0000000000 --- a/code/modules/research/designs/comp_board_designs.dm +++ /dev/null @@ -1,305 +0,0 @@ -///////////////////Computer Boards/////////////////////////////////// - -/datum/design/board - name = "Computer Design ( NULL ENTRY )" - desc = "I promise this doesn't give you syndicate goodies!" - build_type = IMPRINTER - materials = list(MAT_GLASS = 1000) - -/datum/design/board/arcade_battle - name = "Computer Design (Battle Arcade Machine)" - desc = "Allows for the construction of circuit boards used to build a new arcade machine." - id = "arcade_battle" - build_path = /obj/item/circuitboard/computer/arcade/battle - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/orion_trail - name = "Computer Design (Orion Trail Arcade Machine)" - desc = "Allows for the construction of circuit boards used to build a new Orion Trail machine." - id = "arcade_orion" - build_path = /obj/item/circuitboard/computer/arcade/orion_trail - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/seccamera - name = "Computer Design (Security Camera)" - desc = "Allows for the construction of circuit boards used to build security camera computers." - id = "seccamera" - build_path = /obj/item/circuitboard/computer/security - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/board/rdcamera - name = "Computer Design (Research Monitor)" - desc = "Allows for the construction of circuit boards used to build research camera computers." - id = "rdcamera" - build_path = /obj/item/circuitboard/computer/research - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/xenobiocamera - name = "Computer Design (Xenobiology Console)" - desc = "Allows for the construction of circuit boards used to build xenobiology camera computers." - id = "xenobioconsole" - build_path = /obj/item/circuitboard/computer/xenobiology - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/aiupload - name = "Computer Design (AI Upload)" - desc = "Allows for the construction of circuit boards used to build an AI Upload Console." - id = "aiupload" - materials = list(MAT_GLASS = 1000, MAT_GOLD = 2000) - build_path = /obj/item/circuitboard/computer/aiupload - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/borgupload - name = "Computer Design (Cyborg Upload)" - desc = "Allows for the construction of circuit boards used to build a Cyborg Upload Console." - id = "borgupload" - materials = list(MAT_GLASS = 1000, MAT_GOLD = 2000) - build_path = /obj/item/circuitboard/computer/borgupload - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/med_data - name = "Computer Design (Medical Records)" - desc = "Allows for the construction of circuit boards used to build a medical records console." - id = "med_data" - build_path = /obj/item/circuitboard/computer/med_data - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/board/operating - name = "Computer Design (Operating Computer)" - desc = "Allows for the construction of circuit boards used to build an operating computer console." - id = "operating" - build_path = /obj/item/circuitboard/computer/operating - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/pandemic - name = "Computer Design (PanD.E.M.I.C. 2200)" - desc = "Allows for the construction of circuit boards used to build a PanD.E.M.I.C. 2200 console." - id = "pandemic" - build_path = /obj/item/circuitboard/computer/pandemic - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/board/scan_console - name = "Computer Design (DNA Machine)" - desc = "Allows for the construction of circuit boards used to build a new DNA scanning console." - id = "scan_console" - build_path = /obj/item/circuitboard/computer/scan_consolenew - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/comconsole - name = "Computer Design (Communications)" - desc = "Allows for the construction of circuit boards used to build a communications console." - id = "comconsole" - build_path = /obj/item/circuitboard/computer/communications - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SECURITY //Honestly should have a bridge techfab for this sometime. - -/datum/design/board/idcardconsole - name = "Computer Design (ID Console)" - desc = "Allows for the construction of circuit boards used to build an ID computer." - id = "idcardconsole" - build_path = /obj/item/circuitboard/computer/card - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SECURITY //Honestly should have a bridge techfab for this sometime. - -/datum/design/board/crewconsole - name = "Computer Design (Crew monitoring computer)" - desc = "Allows for the construction of circuit boards used to build a Crew monitoring computer." - id = "crewconsole" - build_path = /obj/item/circuitboard/computer/crew - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/board/secdata - name = "Computer Design (Security Records Console)" - desc = "Allows for the construction of circuit boards used to build a security records console." - id = "secdata" - build_path = /obj/item/circuitboard/computer/secure_data - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/board/atmosalerts - name = "Computer Design (Atmosphere Alert)" - desc = "Allows for the construction of circuit boards used to build an atmosphere alert console." - id = "atmosalerts" - build_path = /obj/item/circuitboard/computer/atmos_alert - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/atmos_control - name = "Computer Design (Atmospheric Monitor)" - desc = "Allows for the construction of circuit boards used to build an Atmospheric Monitor." - id = "atmos_control" - build_path = /obj/item/circuitboard/computer/atmos_control - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/robocontrol - name = "Computer Design (Robotics Control Console)" - desc = "Allows for the construction of circuit boards used to build a Robotics Control console." - id = "robocontrol" - build_path = /obj/item/circuitboard/computer/robotics - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/slot_machine - name = "Computer Design (Slot Machine)" - desc = "Allows for the construction of circuit boards used to build a new slot machine." - id = "slotmachine" - build_path = /obj/item/circuitboard/computer/slot_machine - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/powermonitor - name = "Computer Design (Power Monitor)" - desc = "Allows for the construction of circuit boards used to build a new power monitor." - id = "powermonitor" - build_path = /obj/item/circuitboard/computer/powermonitor - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/solarcontrol - name = "Computer Design (Solar Control)" - desc = "Allows for the construction of circuit boards used to build a solar control console." - id = "solarcontrol" - build_path = /obj/item/circuitboard/computer/solar_control - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/prisonmanage - name = "Computer Design (Prisoner Management Console)" - desc = "Allows for the construction of circuit boards used to build a prisoner management console." - id = "prisonmanage" - build_path = /obj/item/circuitboard/computer/prisoner - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/board/mechacontrol - name = "Computer Design (Exosuit Control Console)" - desc = "Allows for the construction of circuit boards used to build an exosuit control console." - id = "mechacontrol" - build_path = /obj/item/circuitboard/computer/mecha_control - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/mechapower - name = "Computer Design (Mech Bay Power Control Console)" - desc = "Allows for the construction of circuit boards used to build a mech bay power control console." - id = "mechapower" - build_path = /obj/item/circuitboard/computer/mech_bay_power_console - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/rdconsole - name = "Computer Design (R&D Console)" - desc = "Allows for the construction of circuit boards used to build a new R&D console." - id = "rdconsole" - build_path = /obj/item/circuitboard/computer/rdconsole - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/cargo - name = "Computer Design (Supply Console)" - desc = "Allows for the construction of circuit boards used to build a Supply Console." - id = "cargo" - build_path = /obj/item/circuitboard/computer/cargo - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_CARGO - -/datum/design/board/cargorequest - name = "Computer Design (Supply Request Console)" - desc = "Allows for the construction of circuit boards used to build a Supply Request Console." - id = "cargorequest" - build_path = /obj/item/circuitboard/computer/cargo/request - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_CARGO - -/datum/design/board/bounty - name = "Computer Design (Bounty Console)" - desc = "Allows for the construction of circuit boards used to build a Bounty Console." - id = "bounty" - build_path = /obj/item/circuitboard/computer/bounty - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_CARGO - -/datum/design/board/mining - name = "Computer Design (Outpost Status Display)" - desc = "Allows for the construction of circuit boards used to build an outpost status display console." - id = "mining" - build_path = /obj/item/circuitboard/computer/mining - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SECURITY - -/datum/design/board/comm_monitor - name = "Computer Design (Telecommunications Monitoring Console)" - desc = "Allows for the construction of circuit boards used to build a telecommunications monitor." - id = "comm_monitor" - build_path = /obj/item/circuitboard/computer/comm_monitor - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/comm_server - name = "Computer Design (Telecommunications Server Monitoring Console)" - desc = "Allows for the construction of circuit boards used to build a telecommunication server browser and monitor." - id = "comm_server" - build_path = /obj/item/circuitboard/computer/comm_server - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/message_monitor - name = "Computer Design (Messaging Monitor Console)" - desc = "Allows for the construction of circuit boards used to build a messaging monitor console." - id = "message_monitor" - build_path = /obj/item/circuitboard/computer/message_monitor - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/aifixer - name = "Computer Design (AI Integrity Restorer)" - desc = "Allows for the construction of circuit boards used to build an AI Integrity Restorer." - id = "aifixer" - build_path = /obj/item/circuitboard/computer/aifixer - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/libraryconsole - name = "Computer Design (Library Console)" - desc = "Allows for the construction of circuit boards used to build a new library console." - id = "libraryconsole" - build_path = /obj/item/circuitboard/computer/libraryconsole - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/apc_control - name = "Computer Design (APC Control)" - desc = "Allows for the construction of circuit boards used to build a new APC control console." - id = "apc_control" - build_path = /obj/item/circuitboard/computer/apc_control - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/nanite_chamber_control - name = "Computer Design (Nanite Chamber Control)" - desc = "Allows for the construction of circuit boards used to build a new nanite chamber control console." - id = "nanite_chamber_control" - build_path = /obj/item/circuitboard/computer/nanite_chamber_control - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/nanite_cloud_control - name = "Computer Design (Nanite Cloud Control)" - desc = "Allows for the construction of circuit boards used to build a new nanite cloud control console." - id = "nanite_cloud_control" - build_path = /obj/item/circuitboard/computer/nanite_cloud_controller - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/comp_board_designs/comp_board_designs_all_misc.dm b/code/modules/research/designs/comp_board_designs/comp_board_designs_all_misc.dm new file mode 100644 index 0000000000..780a1bc97d --- /dev/null +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_all_misc.dm @@ -0,0 +1,38 @@ +///////////////////Computer Boards/////////////////////////////////// +/datum/design/board + name = "Computer Design ( NULL ENTRY )" + desc = "A blank compurter board!" + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000) + +/datum/design/board/arcade_battle + name = "Computer Design (Battle Arcade Machine)" + desc = "Allows for the construction of circuit boards used to build a new arcade machine." + id = "arcade_battle" + build_path = /obj/item/circuitboard/computer/arcade/battle + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/orion_trail + name = "Computer Design (Orion Trail Arcade Machine)" + desc = "Allows for the construction of circuit boards used to build a new Orion Trail machine." + id = "arcade_orion" + build_path = /obj/item/circuitboard/computer/arcade/orion_trail + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/slot_machine + name = "Computer Design (Slot Machine)" + desc = "Allows for the construction of circuit boards used to build a new slot machine." + id = "slotmachine" + build_path = /obj/item/circuitboard/computer/slot_machine + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/libraryconsole + name = "Computer Design (Library Console)" + desc = "Allows for the construction of circuit boards used to build a new library console." + id = "libraryconsole" + build_path = /obj/item/circuitboard/computer/libraryconsole + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ALL \ No newline at end of file diff --git a/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo .dm b/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo .dm new file mode 100644 index 0000000000..fd548adc76 --- /dev/null +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo .dm @@ -0,0 +1,35 @@ +/////////////////// +///CARGO Boards//// +/////////////////// + +/datum/design/board/cargo + name = "Computer Design (Supply Console)" + desc = "Allows for the construction of circuit boards used to build a Supply Console." + id = "cargo" + build_path = /obj/item/circuitboard/computer/cargo + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/board/cargorequest + name = "Computer Design (Supply Request Console)" + desc = "Allows for the construction of circuit boards used to build a Supply Request Console." + id = "cargorequest" + build_path = /obj/item/circuitboard/computer/cargo/request + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/board/bounty + name = "Computer Design (Bounty Console)" + desc = "Allows for the construction of circuit boards used to build a Bounty Console." + id = "bounty" + build_path = /obj/item/circuitboard/computer/bounty + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/board/mining + name = "Computer Design (Outpost Status Display)" + desc = "Allows for the construction of circuit boards used to build an outpost status display console." + id = "mining" + build_path = /obj/item/circuitboard/computer/mining + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SECURITY \ No newline at end of file diff --git a/code/modules/research/designs/comp_board_designs/comp_board_designs_engi.dm b/code/modules/research/designs/comp_board_designs/comp_board_designs_engi.dm new file mode 100644 index 0000000000..5767588178 --- /dev/null +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_engi.dm @@ -0,0 +1,75 @@ +/////////////////// +///ENGINE Boards/// +/////////////////// + +/datum/design/board/comm_monitor + name = "Computer Design (Telecommunications Monitoring Console)" + desc = "Allows for the construction of circuit boards used to build a telecommunications monitor." + id = "comm_monitor" + build_path = /obj/item/circuitboard/computer/comm_monitor + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/comm_server + name = "Computer Design (Telecommunications Server Monitoring Console)" + desc = "Allows for the construction of circuit boards used to build a telecommunication server browser and monitor." + id = "comm_server" + build_path = /obj/item/circuitboard/computer/comm_server + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/message_monitor + name = "Computer Design (Messaging Monitor Console)" + desc = "Allows for the construction of circuit boards used to build a messaging monitor console." + id = "message_monitor" + build_path = /obj/item/circuitboard/computer/message_monitor + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/apc_control + name = "Computer Design (APC Control)" + desc = "Allows for the construction of circuit boards used to build a new APC control console." + id = "apc_control" + build_path = /obj/item/circuitboard/computer/apc_control + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/meteor_console + name = "Computer Design (Meteor Satellite Console)" + desc = "Allows for the construction of circuit boards used to build a new Meteor Satellite monitor console." + id = "meteor_console" + build_path = /obj/item/circuitboard/computer/sat_control + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/atmosalerts + name = "Computer Design (Atmosphere Alert)" + desc = "Allows for the construction of circuit boards used to build an atmosphere alert console." + id = "atmosalerts" + build_path = /obj/item/circuitboard/computer/atmos_alert + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/atmos_control + name = "Computer Design (Atmospheric Monitor)" + desc = "Allows for the construction of circuit boards used to build an Atmospheric Monitor." + id = "atmos_control" + build_path = /obj/item/circuitboard/computer/atmos_control + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/powermonitor + name = "Computer Design (Power Monitor)" + desc = "Allows for the construction of circuit boards used to build a new power monitor." + id = "powermonitor" + build_path = /obj/item/circuitboard/computer/powermonitor + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/solarcontrol + name = "Computer Design (Solar Control)" + desc = "Allows for the construction of circuit boards used to build a solar control console." + id = "solarcontrol" + build_path = /obj/item/circuitboard/computer/solar_control + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING \ No newline at end of file diff --git a/code/modules/research/designs/comp_board_designs/comp_board_designs_medical.dm b/code/modules/research/designs/comp_board_designs/comp_board_designs_medical.dm new file mode 100644 index 0000000000..05632fad69 --- /dev/null +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_medical.dm @@ -0,0 +1,43 @@ +/////////////////// +///MEDICAL Boards// +/////////////////// + +/datum/design/board/pandemic + name = "Computer Design (PanD.E.M.I.C. 2200)" + desc = "Allows for the construction of circuit boards used to build a PanD.E.M.I.C. 2200 console." + id = "pandemic" + build_path = /obj/item/circuitboard/computer/pandemic + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/board/operating + name = "Computer Design (Operating Computer)" + desc = "Allows for the construction of circuit boards used to build an operating computer console." + id = "operating" + build_path = /obj/item/circuitboard/computer/operating + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/scan_console + name = "Computer Design (DNA Machine)" + desc = "Allows for the construction of circuit boards used to build a new DNA scanning console." + id = "scan_console" + build_path = /obj/item/circuitboard/computer/scan_consolenew + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/crewconsole + name = "Computer Design (Crew monitoring computer)" + desc = "Allows for the construction of circuit boards used to build a Crew monitoring computer." + id = "crewconsole" + build_path = /obj/item/circuitboard/computer/crew + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SECURITY + +/datum/design/board/med_data + name = "Computer Design (Medical Records)" + desc = "Allows for the construction of circuit boards used to build a medical records console." + id = "med_data" + build_path = /obj/item/circuitboard/computer/med_data + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SECURITY diff --git a/code/modules/research/designs/comp_board_designs/comp_board_designs_sci.dm b/code/modules/research/designs/comp_board_designs/comp_board_designs_sci.dm new file mode 100644 index 0000000000..e0b0a22be6 --- /dev/null +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_sci.dm @@ -0,0 +1,93 @@ +/////////////////// +///SCI Boards////// +/////////////////// + +/datum/design/board/rdcamera + name = "Computer Design (Research Monitor)" + desc = "Allows for the construction of circuit boards used to build research camera computers." + id = "rdcamera" + build_path = /obj/item/circuitboard/computer/research + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/xenobiocamera + name = "Computer Design (Xenobiology Console)" + desc = "Allows for the construction of circuit boards used to build xenobiology camera computers." + id = "xenobioconsole" + build_path = /obj/item/circuitboard/computer/xenobiology + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/aiupload + name = "Computer Design (AI Upload)" + desc = "Allows for the construction of circuit boards used to build an AI Upload Console." + id = "aiupload" + materials = list(MAT_GLASS = 1000, MAT_GOLD = 2000) + build_path = /obj/item/circuitboard/computer/aiupload + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/borgupload + name = "Computer Design (Cyborg Upload)" + desc = "Allows for the construction of circuit boards used to build a Cyborg Upload Console." + id = "borgupload" + materials = list(MAT_GLASS = 1000, MAT_GOLD = 2000) + build_path = /obj/item/circuitboard/computer/borgupload + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/robocontrol + name = "Computer Design (Robotics Control Console)" + desc = "Allows for the construction of circuit boards used to build a Robotics Control console." + id = "robocontrol" + build_path = /obj/item/circuitboard/computer/robotics + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/mechacontrol + name = "Computer Design (Exosuit Control Console)" + desc = "Allows for the construction of circuit boards used to build an exosuit control console." + id = "mechacontrol" + build_path = /obj/item/circuitboard/computer/mecha_control + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/mechapower + name = "Computer Design (Mech Bay Power Control Console)" + desc = "Allows for the construction of circuit boards used to build a mech bay power control console." + id = "mechapower" + build_path = /obj/item/circuitboard/computer/mech_bay_power_console + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/rdconsole + name = "Computer Design (R&D Console)" + desc = "Allows for the construction of circuit boards used to build a new R&D console." + id = "rdconsole" + build_path = /obj/item/circuitboard/computer/rdconsole + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/nanite_chamber_control + name = "Computer Design (Nanite Chamber Control)" + desc = "Allows for the construction of circuit boards used to build a new nanite chamber control console." + id = "nanite_chamber_control" + build_path = /obj/item/circuitboard/computer/nanite_chamber_control + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/nanite_cloud_control + name = "Computer Design (Nanite Cloud Control)" + desc = "Allows for the construction of circuit boards used to build a new nanite cloud control console." + id = "nanite_cloud_control" + build_path = /obj/item/circuitboard/computer/nanite_cloud_controller + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/aifixer + name = "Computer Design (AI Integrity Restorer)" + desc = "Allows for the construction of circuit boards used to build an AI Integrity Restorer." + id = "aifixer" + build_path = /obj/item/circuitboard/computer/aifixer + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE \ No newline at end of file diff --git a/code/modules/research/designs/comp_board_designs/comp_board_designs_sec.dm b/code/modules/research/designs/comp_board_designs/comp_board_designs_sec.dm new file mode 100644 index 0000000000..0e93481f66 --- /dev/null +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_sec.dm @@ -0,0 +1,43 @@ +/////////////////// +///SECURITY Boards/ +/////////////////// + +/datum/design/board/seccamera + name = "Computer Design (Security Camera)" + desc = "Allows for the construction of circuit boards used to build security camera computers." + id = "seccamera" + build_path = /obj/item/circuitboard/computer/security + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/board/secdata + name = "Computer Design (Security Records Console)" + desc = "Allows for the construction of circuit boards used to build a security records console." + id = "secdata" + build_path = /obj/item/circuitboard/computer/secure_data + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/board/prisonmanage + name = "Computer Design (Prisoner Management Console)" + desc = "Allows for the construction of circuit boards used to build a prisoner management console." + id = "prisonmanage" + build_path = /obj/item/circuitboard/computer/prisoner + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/board/comconsole + name = "Computer Design (Communications)" + desc = "Allows for the construction of circuit boards used to build a communications console." + id = "comconsole" + build_path = /obj/item/circuitboard/computer/communications + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_ENGINEERING //Honestly should have a bridge techfab for this sometime. + +/datum/design/board/idcardconsole + name = "Computer Design (ID Console)" + desc = "Allows for the construction of circuit boards used to build an ID computer." + id = "idcardconsole" + build_path = /obj/item/circuitboard/computer/card + category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_ENGINEERING //Honestly should have a bridge techfab for this sometime. diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm deleted file mode 100644 index 93dfd3d2bb..0000000000 --- a/code/modules/research/designs/machine_designs.dm +++ /dev/null @@ -1,572 +0,0 @@ -//////////////////////////////////////// -//////////////MISC Boards/////////////// -//////////////////////////////////////// - -/datum/design/board/smes - name = "Machine Design (SMES Board)" - desc = "The circuit board for a SMES." - id = "smes" - build_path = /obj/item/circuitboard/machine/smes - category = list ("Engineering Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/circulator - name = "Machine Design (Circulator Board)" - desc = "The circuit board for a circulator." - id = "circulator" - build_path = /obj/item/circuitboard/machine/circulator - category = list ("Engineering Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/teg - name = "Machine Design (TEG Board)" - desc = "The circuit board for a TEG." - id = "teg" - build_path = /obj/item/circuitboard/machine/generator - category = list ("Engineering Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/announcement_system - name = "Machine Design (Automated Announcement System Board)" - desc = "The circuit board for an automated announcement system." - id = "automated_announcement" - build_path = /obj/item/circuitboard/machine/announcement_system - category = list("Subspace Telecomms") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/turbine_computer - name = "Computer Design (Power Turbine Console Board)" - desc = "The circuit board for a power turbine console." - id = "power_turbine_console" - build_path = /obj/item/circuitboard/computer/turbine_computer - category = list ("Engineering Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/emitter - name = "Machine Design (Emitter Board)" - desc = "The circuit board for an emitter." - id = "emitter" - build_path = /obj/item/circuitboard/machine/emitter - category = list ("Engineering Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/power_compressor - name = "Machine Design (Power Compressor Board)" - desc = "The circuit board for a power compressor." - id = "power_compressor" - build_path = /obj/item/circuitboard/machine/power_compressor - category = list ("Engineering Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/power_turbine - name = "Machine Design (Power Turbine Board)" - desc = "The circuit board for a power turbine." - id = "power_turbine" - build_path = /obj/item/circuitboard/machine/power_turbine - category = list ("Engineering Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/thermomachine - name = "Machine Design (Freezer/Heater Board)" - desc = "The circuit board for a freezer/heater." - id = "thermomachine" - build_path = /obj/item/circuitboard/machine/thermomachine - category = list ("Engineering Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/space_heater - name = "Machine Design (Space Heater Board)" - desc = "The circuit board for a space heater." - id = "space_heater" - build_path = /obj/item/circuitboard/machine/space_heater - category = list ("Engineering Machinery") - departmental_flags = ALL - -/datum/design/board/teleport_station - name = "Machine Design (Teleportation Station Board)" - desc = "The circuit board for a teleportation station." - id = "tele_station" - build_path = /obj/item/circuitboard/machine/teleporter_station - category = list ("Teleportation Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/teleport_hub - name = "Machine Design (Teleportation Hub Board)" - desc = "The circuit board for a teleportation hub." - id = "tele_hub" - build_path = /obj/item/circuitboard/machine/teleporter_hub - category = list ("Teleportation Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/quantumpad - name = "Machine Design (Quantum Pad Board)" - desc = "The circuit board for a quantum telepad." - id = "quantumpad" - build_path = /obj/item/circuitboard/machine/quantumpad - category = list ("Teleportation Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/launchpad - name = "Machine Design (Bluespace Launchpad Board)" - desc = "The circuit board for a bluespace Launchpad." - id = "launchpad" - build_path = /obj/item/circuitboard/machine/launchpad - category = list ("Teleportation Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/launchpad_console - name = "Machine Design (Bluespace Launchpad Console Board)" - desc = "The circuit board for a bluespace launchpad Console." - id = "launchpad_console" - build_path = /obj/item/circuitboard/computer/launchpad_console - category = list ("Teleportation Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/teleconsole - name = "Computer Design (Teleporter Console)" - desc = "Allows for the construction of circuit boards used to build a teleporter control console." - id = "teleconsole" - build_path = /obj/item/circuitboard/computer/teleporter - category = list("Teleportation Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/sleeper - name = "Machine Design (Sleeper Board)" - desc = "The circuit board for a sleeper." - id = "sleeper" - build_path = /obj/item/circuitboard/machine/sleeper - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL - category = list ("Medical Machinery") - -/datum/design/board/vr_sleeper - name = "Machine Design (VR Sleeper Board)" - desc = "The circuit board for a VR sleeper." - id = "vr_sleeper" - build_path = /obj/item/circuitboard/machine/vr_sleeper - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - category = list ("Medical Machinery") - -/datum/design/board/cryotube - name = "Machine Design (Cryotube Board)" - desc = "The circuit board for a cryotube." - id = "cryotube" - build_path = /obj/item/circuitboard/machine/cryo_tube - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL - category = list ("Medical Machinery") - -/datum/design/board/chem_dispenser - name = "Machine Design (Portable Chem Dispenser Board)" - desc = "The circuit board for a portable chem dispenser." - id = "chem_dispenser" - build_path = /obj/item/circuitboard/machine/chem_dispenser - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL - category = list ("Medical Machinery") - -/datum/design/board/chem_master - name = "Machine Design (Chem Master Board)" - desc = "The circuit board for a Chem Master 3000." - id = "chem_master" - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL - build_path = /obj/item/circuitboard/machine/chem_master - category = list ("Medical Machinery") - -/datum/design/board/chem_heater - name = "Machine Design (Chemical Heater Board)" - desc = "The circuit board for a chemical heater." - id = "chem_heater" - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL - build_path = /obj/item/circuitboard/machine/chem_heater - category = list ("Medical Machinery") - -/datum/design/board/smoke_machine - name = "Machine Design (Smoke Machine)" - desc = "The circuit board for a smoke machine." - id = "smoke_machine" - build_path = /obj/item/circuitboard/machine/smoke_machine - category = list ("Medical Machinery") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/board/reagentgrinder - name = "Machine Design (All-In-One Grinder)" - desc = "The circuit board for an All-In-One Grinder." - id = "reagentgrinder" - build_path = /obj/item/circuitboard/machine/reagentgrinder - category = list ("Medical Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/clonecontrol - name = "Computer Design (Cloning Machine Console)" - desc = "Allows for the construction of circuit boards used to build a new Cloning Machine console." - id = "clonecontrol" - build_path = /obj/item/circuitboard/computer/cloning - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - category = list("Medical Machinery") - -/datum/design/board/clonepod - name = "Machine Design (Clone Pod)" - desc = "Allows for the construction of circuit boards used to build a Cloning Pod." - id = "clonepod" - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - build_path = /obj/item/circuitboard/machine/clonepod - category = list("Medical Machinery") - -/datum/design/board/clonescanner - name = "Machine Design (Cloning Scanner)" - desc = "Allows for the construction of circuit boards used to build a Cloning Scanner." - id = "clonescanner" - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - build_path = /obj/item/circuitboard/machine/clonescanner - category = list("Medical Machinery") - -/datum/design/board/biogenerator - name = "Machine Design (Biogenerator Board)" - desc = "The circuit board for a biogenerator." - id = "biogenerator" - build_path = /obj/item/circuitboard/machine/biogenerator - category = list ("Hydroponics Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/board/hydroponics - name = "Machine Design (Hydroponics Tray Board)" - desc = "The circuit board for a hydroponics tray." - id = "hydro_tray" - build_path = /obj/item/circuitboard/machine/hydroponics - category = list ("Hydroponics Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/board/destructive_analyzer - name = "Machine Design (Destructive Analyzer Board)" - desc = "The circuit board for a destructive analyzer." - id = "destructive_analyzer" - build_path = /obj/item/circuitboard/machine/destructive_analyzer - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/experimentor - name = "Machine Design (E.X.P.E.R.I-MENTOR Board)" - desc = "The circuit board for an E.X.P.E.R.I-MENTOR." - id = "experimentor" - build_path = /obj/item/circuitboard/machine/experimentor - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/protolathe - name = "Machine Design (Protolathe Board)" - desc = "The circuit board for a protolathe." - id = "protolathe" - build_path = /obj/item/circuitboard/machine/protolathe - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/circuit_imprinter - name = "Machine Design (Circuit Imprinter Board)" - desc = "The circuit board for a circuit imprinter." - id = "circuit_imprinter" - build_path = /obj/item/circuitboard/machine/circuit_imprinter - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/rdservercontrol - name = "Computer Design (R&D Server Control Console Board)" - desc = "The circuit board for an R&D Server Control Console." - id = "rdservercontrol" - build_path = /obj/item/circuitboard/computer/rdservercontrol - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/rdserver - name = "Machine Design (R&D Server Board)" - desc = "The circuit board for an R&D Server." - id = "rdserver" - build_path = /obj/item/circuitboard/machine/rdserver - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/mechfab - name = "Machine Design (Exosuit Fabricator Board)" - desc = "The circuit board for an Exosuit Fabricator." - id = "mechfab" - build_path = /obj/item/circuitboard/machine/mechfab - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/cyborgrecharger - name = "Machine Design (Cyborg Recharger Board)" - desc = "The circuit board for a Cyborg Recharger." - id = "cyborgrecharger" - build_path = /obj/item/circuitboard/machine/cyborgrecharger - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/mech_recharger - name = "Machine Design (Mechbay Recharger Board)" - desc = "The circuit board for a Mechbay Recharger." - id = "mech_recharger" - build_path = /obj/item/circuitboard/machine/mech_recharger - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/nanite_chamber - name = "Machine Design (Nanite Chamber Board)" - desc = "The circuit board for a Nanite Chamber." - id = "nanite_chamber" - build_path = /obj/item/circuitboard/machine/nanite_chamber - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/public_nanite_chamber - name = "Machine Design (Public Nanite Chamber Board)" - desc = "The circuit board for a Public Nanite Chamber." - id = "public_nanite_chamber" - build_path = /obj/item/circuitboard/machine/public_nanite_chamber - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/nanite_programmer - name = "Machine Design (Nanite Programmer Board)" - desc = "The circuit board for a Nanite Programmer." - id = "nanite_programmer" - build_path = /obj/item/circuitboard/machine/nanite_programmer - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/nanite_program_hub - name = "Machine Design (Nanite Program Hub Board)" - desc = "The circuit board for a Nanite Program Hub." - id = "nanite_program_hub" - build_path = /obj/item/circuitboard/machine/nanite_program_hub - category = list("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/microwave - name = "Machine Design (Microwave Board)" - desc = "The circuit board for a microwave." - id = "microwave" - build_path = /obj/item/circuitboard/machine/microwave - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/gibber - name = "Machine Design (Gibber Board)" - desc = "The circuit board for a gibber." - id = "gibber" - build_path = /obj/item/circuitboard/machine/gibber - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/board/smartfridge - name = "Machine Design (Smartfridge Board)" - desc = "The circuit board for a smartfridge." - id = "smartfridge" - build_path = /obj/item/circuitboard/machine/smartfridge - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/monkey_recycler - name = "Machine Design (Monkey Recycler Board)" - desc = "The circuit board for a monkey recycler." - id = "monkey_recycler" - build_path = /obj/item/circuitboard/machine/monkey_recycler - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SERVICE - -/datum/design/board/seed_extractor - name = "Machine Design (Seed Extractor Board)" - desc = "The circuit board for a seed extractor." - id = "seed_extractor" - build_path = /obj/item/circuitboard/machine/seed_extractor - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/board/processor - name = "Machine Design (Food/Slime Processor Board)" - desc = "The circuit board for a processing unit. Screwdriver the circuit to switch between food (default) or slime processing." - id = "processor" - build_path = /obj/item/circuitboard/machine/processor - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SERVICE - -/datum/design/board/soda_dispenser - name = "Machine Design (Portable Soda Dispenser Board)" - desc = "The circuit board for a portable soda dispenser." - id = "soda_dispenser" - build_path = /obj/item/circuitboard/machine/chem_dispenser/drinks - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - category = list ("Misc. Machinery") - -/datum/design/board/beer_dispenser - name = "Machine Design (Portable Booze Dispenser Board)" - desc = "The circuit board for a portable booze dispenser." - id = "beer_dispenser" - build_path = /obj/item/circuitboard/machine/chem_dispenser/drinks/beer - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - category = list ("Misc. Machinery") - -/datum/design/board/recycler - name = "Machine Design (Recycler Board)" - desc = "The circuit board for a recycler." - id = "recycler" - build_path = /obj/item/circuitboard/machine/recycler - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/holopad - name = "Machine Design (AI Holopad Board)" - desc = "The circuit board for a holopad." - id = "holopad" - build_path = /obj/item/circuitboard/machine/holopad - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/autolathe - name = "Machine Design (Autolathe Board)" - desc = "The circuit board for an autolathe." - id = "autolathe" - build_path = /obj/item/circuitboard/machine/autolathe - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL //Lets be honest here half the maps have public ones. - -/datum/design/board/recharger - name = "Machine Design (Weapon Recharger Board)" - desc = "The circuit board for a Weapon Recharger." - id = "recharger" - materials = list(MAT_GLASS = 1000, MAT_GOLD = 2000) - build_path = /obj/item/circuitboard/machine/recharger - category = list("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/vendor - name = "Machine Design (Vendor Board)" - desc = "The circuit board for a Vendor." - id = "vendor" - build_path = /obj/item/circuitboard/machine/vendor - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/ore_redemption - name = "Machine Design (Ore Redemption Board)" - desc = "The circuit board for an Ore Redemption machine." - id = "ore_redemption" - build_path = /obj/item/circuitboard/machine/ore_redemption - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/mining_equipment_vendor - name = "Machine Design (Mining Rewards Vender Board)" - desc = "The circuit board for a Mining Rewards Vender." - id = "mining_equipment_vendor" - build_path = /obj/item/circuitboard/machine/mining_equipment_vendor - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_CARGO - -/datum/design/board/tesla_coil - name = "Machine Design (Tesla Coil Board)" - desc = "The circuit board for a tesla coil." - id = "tesla_coil" - build_path = /obj/item/circuitboard/machine/tesla_coil - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/rad_collector - name = "Machine Design (Radiation Collector Board)" - desc = "The circuit board for a radiation collector array." - id = "rad_collector" - build_path = /obj/item/circuitboard/machine/rad_collector - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/grounding_rod - name = "Machine Design (Grounding Rod Board)" - desc = "The circuit board for a grounding rod." - id = "grounding_rod" - build_path = /obj/item/circuitboard/machine/grounding_rod - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/plantgenes - name = "Machine Design (Plant DNA Manipulator Board)" - desc = "The circuit board for a plant DNA manipulator." - id = "plantgenes" - build_path = /obj/item/circuitboard/machine/plantgenes - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/board/ntnet_relay - name = "Machine Design (NTNet Relay Board)" - desc = "The circuit board for a wireless network relay." - id = "ntnet_relay" - build_path = /obj/item/circuitboard/machine/ntnet_relay - category = list("Subspace Telecomms") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/board/limbgrower - name = "Machine Design (Limb Grower Board)" - desc = "The circuit board for a limb grower." - id = "limbgrower" - build_path = /obj/item/circuitboard/machine/limbgrower - category = list("Medical Machinery") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/board/harvester - name = "Machine Design (Organ Harvester Board)" - desc = "The circuit board for an organ harvester." - id = "harvester" - build_path = /obj/item/circuitboard/machine/harvester - category = list("Medical Machinery") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/board/deepfryer - name = "Machine Design (Deep Fryer)" - desc = "The circuit board for a Deep Fryer." - id = "deepfryer" - build_path = /obj/item/circuitboard/machine/deep_fryer - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/board/donksofttoyvendor - name = "Machine Design (Donksoft Toy Vendor Board)" - desc = "The circuit board for a Donksoft Toy Vendor." - id = "donksofttoyvendor" - build_path = /obj/item/circuitboard/machine/vending/donksofttoyvendor - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL //Toys!! - -/datum/design/board/cell_charger - name = "Machine Design (Cell Charger Board)" - desc = "The circuit board for a cell charger." - id = "cell_charger" - build_path = /obj/item/circuitboard/machine/cell_charger - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_ALL - -/datum/design/board/dish_drive - name = "Machine Design (Dish Drive)" - desc = "The circuit board for a dish drive." - id = "dish_drive" - build_path = /obj/item/circuitboard/machine/dish_drive - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/board/stacking_unit_console - name = "Machine Design (Stacking Machine Console)" - desc = "The circuit board for a Stacking Machine Console." - id = "stack_console" - build_path = /obj/item/circuitboard/machine/stacking_unit_console - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/stacking_machine - name = "Machine Design (Stacking Machine)" - desc = "The circuit board for a Stacking Machine." - id = "stack_machine" - build_path = /obj/item/circuitboard/machine/stacking_machine - category = list ("Misc. Machinery") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/board/ore_silo - name = "Machine Design (Ore Silo)" - desc = "The circuit board for an ore silo." - id = "ore_silo" - build_path = /obj/item/circuitboard/machine/ore_silo - category = list ("Research Machinery") - departmental_flags = DEPARTMENTAL_FLAG_CARGO diff --git a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm new file mode 100644 index 0000000000..31723cde07 --- /dev/null +++ b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm @@ -0,0 +1,100 @@ +//////////////////////////////////////// +//////////////MISC Boards/////////////// +//////////////////////////////////////// + +/datum/design/board/recycler + name = "Machine Design (Recycler Board)" + desc = "The circuit board for a recycler." + id = "recycler" + build_path = /obj/item/circuitboard/machine/recycler + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/holopad + name = "Machine Design (AI Holopad Board)" + desc = "The circuit board for a holopad." + id = "holopad" + build_path = /obj/item/circuitboard/machine/holopad + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/autolathe + name = "Machine Design (Autolathe Board)" + desc = "The circuit board for an autolathe." + id = "autolathe" + build_path = /obj/item/circuitboard/machine/autolathe + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/recharger + name = "Machine Design (Weapon Recharger Board)" + desc = "The circuit board for a Weapon Recharger." + id = "recharger" + materials = list(MAT_GLASS = 1000, MAT_GOLD = 2000) + build_path = /obj/item/circuitboard/machine/recharger + category = list("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/vendor + name = "Machine Design (Vendor Board)" + desc = "The circuit board for a Vendor." + id = "vendor" + build_path = /obj/item/circuitboard/machine/vendor + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/donksofttoyvendor + name = "Machine Design (Donksoft Toy Vendor Board)" + desc = "The circuit board for a Donksoft Toy Vendor." + id = "donksofttoyvendor" + build_path = /obj/item/circuitboard/machine/vending/donksofttoyvendor + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/space_heater + name = "Machine Design (Space Heater Board)" + desc = "The circuit board for a space heater." + id = "space_heater" + build_path = /obj/item/circuitboard/machine/space_heater + category = list ("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/reagentgrinder + name = "Machine Design (All-In-One Grinder)" + desc = "The circuit board for an All-In-One Grinder." + id = "reagentgrinder" + build_path = /obj/item/circuitboard/machine/reagentgrinder + category = list ("Medical Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/microwave + name = "Machine Design (Microwave Board)" + desc = "The circuit board for a microwave." + id = "microwave" + build_path = /obj/item/circuitboard/machine/microwave + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/smartfridge + name = "Machine Design (Smartfridge Board)" + desc = "The circuit board for a smartfridge." + id = "smartfridge" + build_path = /obj/item/circuitboard/machine/smartfridge + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/cell_charger + name = "Machine Design (Cell Charger Board)" + desc = "The circuit board for a cell charger." + id = "cell_charger" + build_path = /obj/item/circuitboard/machine/cell_charger + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/board/vr_sleeper + name = "Machine Design (VR Sleeper Board)" + desc = "The circuit board for a VR sleeper." + id = "vr_sleeper" + build_path = /obj/item/circuitboard/machine/vr_sleeper + departmental_flags = DEPARTMENTAL_FLAG_ALL + category = list ("Medical Machinery") diff --git a/code/modules/research/designs/machine_desings/machine_designs_cargo.dm b/code/modules/research/designs/machine_desings/machine_designs_cargo.dm new file mode 100644 index 0000000000..a6cc2271c8 --- /dev/null +++ b/code/modules/research/designs/machine_desings/machine_designs_cargo.dm @@ -0,0 +1,42 @@ +/////////////////// +///CARGO Boards// +/////////////////// +/datum/design/board/ore_silo + name = "Machine Design (Ore Silo)" + desc = "The circuit board for an ore silo." + id = "ore_silo" + build_path = /obj/item/circuitboard/machine/ore_silo + category = list ("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/board/mining_equipment_vendor + name = "Machine Design (Mining Rewards Vender Board)" + desc = "The circuit board for a Mining Rewards Vender." + id = "mining_equipment_vendor" + build_path = /obj/item/circuitboard/machine/mining_equipment_vendor + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/stacking_unit_console + name = "Machine Design (Stacking Machine Console)" + desc = "The circuit board for a Stacking Machine Console." + id = "stack_console" + build_path = /obj/item/circuitboard/machine/stacking_unit_console + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/stacking_machine + name = "Machine Design (Stacking Machine)" + desc = "The circuit board for a Stacking Machine." + id = "stack_machine" + build_path = /obj/item/circuitboard/machine/stacking_machine + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/ore_redemption + name = "Machine Design (Ore Redemption Board)" + desc = "The circuit board for an Ore Redemption machine." + id = "ore_redemption" + build_path = /obj/item/circuitboard/machine/ore_redemption + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING \ No newline at end of file diff --git a/code/modules/research/designs/machine_desings/machine_designs_engi.dm b/code/modules/research/designs/machine_desings/machine_designs_engi.dm new file mode 100644 index 0000000000..eb9e00be05 --- /dev/null +++ b/code/modules/research/designs/machine_desings/machine_designs_engi.dm @@ -0,0 +1,106 @@ +/////////////////// +///ENGINE Boards/// +/////////////////// +/datum/design/board/smes + name = "Machine Design (SMES Board)" + desc = "The circuit board for a SMES." + id = "smes" + build_path = /obj/item/circuitboard/machine/smes + category = list ("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/circulator + name = "Machine Design (Circulator Board)" + desc = "The circuit board for a circulator." + id = "circulator" + build_path = /obj/item/circuitboard/machine/circulator + category = list ("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/teg + name = "Machine Design (TEG Board)" + desc = "The circuit board for a TEG." + id = "teg" + build_path = /obj/item/circuitboard/machine/generator + category = list ("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/announcement_system + name = "Machine Design (Automated Announcement System Board)" + desc = "The circuit board for an automated announcement system." + id = "automated_announcement" + build_path = /obj/item/circuitboard/machine/announcement_system + category = list("Subspace Telecomms") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/turbine_computer + name = "Computer Design (Power Turbine Console Board)" + desc = "The circuit board for a power turbine console." + id = "power_turbine_console" + build_path = /obj/item/circuitboard/computer/turbine_computer + category = list ("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/emitter + name = "Machine Design (Emitter Board)" + desc = "The circuit board for an emitter." + id = "emitter" + build_path = /obj/item/circuitboard/machine/emitter + category = list ("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/power_compressor + name = "Machine Design (Power Compressor Board)" + desc = "The circuit board for a power compressor." + id = "power_compressor" + build_path = /obj/item/circuitboard/machine/power_compressor + category = list ("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/power_turbine + name = "Machine Design (Power Turbine Board)" + desc = "The circuit board for a power turbine." + id = "power_turbine" + build_path = /obj/item/circuitboard/machine/power_turbine + category = list ("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/tesla_coil + name = "Machine Design (Tesla Coil Board)" + desc = "The circuit board for a tesla coil." + id = "tesla_coil" + build_path = /obj/item/circuitboard/machine/tesla_coil + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/rad_collector + name = "Machine Design (Radiation Collector Board)" + desc = "The circuit board for a radiation collector array." + id = "rad_collector" + build_path = /obj/item/circuitboard/machine/rad_collector + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/grounding_rod + name = "Machine Design (Grounding Rod Board)" + desc = "The circuit board for a grounding rod." + id = "grounding_rod" + build_path = /obj/item/circuitboard/machine/grounding_rod + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/ntnet_relay + name = "Machine Design (NTNet Relay Board)" + desc = "The circuit board for a wireless network relay." + id = "ntnet_relay" + build_path = /obj/item/circuitboard/machine/ntnet_relay + category = list("Subspace Telecomms") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/thermomachine + name = "Machine Design (Freezer/Heater Board)" + desc = "The circuit board for a freezer/heater." + id = "thermomachine" + build_path = /obj/item/circuitboard/machine/thermomachine + category = list ("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE \ No newline at end of file diff --git a/code/modules/research/designs/machine_desings/machine_designs_medical.dm b/code/modules/research/designs/machine_desings/machine_designs_medical.dm new file mode 100644 index 0000000000..65b3d74f71 --- /dev/null +++ b/code/modules/research/designs/machine_desings/machine_designs_medical.dm @@ -0,0 +1,91 @@ +/////////////////// +///MEDICAL Boards// +/////////////////// + +/datum/design/board/limbgrower + name = "Machine Design (Limb Grower Board)" + desc = "The circuit board for a limb grower." + id = "limbgrower" + build_path = /obj/item/circuitboard/machine/limbgrower + category = list("Medical Machinery") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/board/harvester + name = "Machine Design (Organ Harvester Board)" + desc = "The circuit board for an organ harvester." + id = "harvester" + build_path = /obj/item/circuitboard/machine/harvester + category = list("Medical Machinery") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/board/sleeper + name = "Machine Design (Sleeper Board)" + desc = "The circuit board for a sleeper." + id = "sleeper" + build_path = /obj/item/circuitboard/machine/sleeper + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + category = list ("Medical Machinery") + +/datum/design/board/cryotube + name = "Machine Design (Cryotube Board)" + desc = "The circuit board for a cryotube." + id = "cryotube" + build_path = /obj/item/circuitboard/machine/cryo_tube + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + category = list ("Medical Machinery") + +/datum/design/board/chem_dispenser + name = "Machine Design (Portable Chem Dispenser Board)" + desc = "The circuit board for a portable chem dispenser." + id = "chem_dispenser" + build_path = /obj/item/circuitboard/machine/chem_dispenser + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + category = list ("Medical Machinery") + +/datum/design/board/chem_master + name = "Machine Design (Chem Master Board)" + desc = "The circuit board for a Chem Master 3000." + id = "chem_master" + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + build_path = /obj/item/circuitboard/machine/chem_master + category = list ("Medical Machinery") + +/datum/design/board/chem_heater + name = "Machine Design (Chemical Heater Board)" + desc = "The circuit board for a chemical heater." + id = "chem_heater" + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + build_path = /obj/item/circuitboard/machine/chem_heater + category = list ("Medical Machinery") + +/datum/design/board/smoke_machine + name = "Machine Design (Smoke Machine)" + desc = "The circuit board for a smoke machine." + id = "smoke_machine" + build_path = /obj/item/circuitboard/machine/smoke_machine + category = list ("Medical Machinery") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/clonecontrol + name = "Computer Design (Cloning Machine Console)" + desc = "Allows for the construction of circuit boards used to build a new Cloning Machine console." + id = "clonecontrol" + build_path = /obj/item/circuitboard/computer/cloning + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + category = list("Medical Machinery") + +/datum/design/board/clonepod + name = "Machine Design (Clone Pod)" + desc = "Allows for the construction of circuit boards used to build a Cloning Pod." + id = "clonepod" + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + build_path = /obj/item/circuitboard/machine/clonepod + category = list("Medical Machinery") + +/datum/design/board/clonescanner + name = "Machine Design (Cloning Scanner)" + desc = "Allows for the construction of circuit boards used to build a Cloning Scanner." + id = "clonescanner" + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + build_path = /obj/item/circuitboard/machine/clonescanner + category = list("Medical Machinery") diff --git a/code/modules/research/designs/machine_desings/machine_designs_sci.dm b/code/modules/research/designs/machine_desings/machine_designs_sci.dm new file mode 100644 index 0000000000..183977b455 --- /dev/null +++ b/code/modules/research/designs/machine_desings/machine_designs_sci.dm @@ -0,0 +1,155 @@ +/////////////////// +///SCI Boards////// +/////////////////// + +/datum/design/board/teleport_station + name = "Machine Design (Teleportation Station Board)" + desc = "The circuit board for a teleportation station." + id = "tele_station" + build_path = /obj/item/circuitboard/machine/teleporter_station + category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/teleport_hub + name = "Machine Design (Teleportation Hub Board)" + desc = "The circuit board for a teleportation hub." + id = "tele_hub" + build_path = /obj/item/circuitboard/machine/teleporter_hub + category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/quantumpad + name = "Machine Design (Quantum Pad Board)" + desc = "The circuit board for a quantum telepad." + id = "quantumpad" + build_path = /obj/item/circuitboard/machine/quantumpad + category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/launchpad + name = "Machine Design (Bluespace Launchpad Board)" + desc = "The circuit board for a bluespace Launchpad." + id = "launchpad" + build_path = /obj/item/circuitboard/machine/launchpad + category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/launchpad_console + name = "Machine Design (Bluespace Launchpad Console Board)" + desc = "The circuit board for a bluespace launchpad Console." + id = "launchpad_console" + build_path = /obj/item/circuitboard/computer/launchpad_console + category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/teleconsole + name = "Computer Design (Teleporter Console)" + desc = "Allows for the construction of circuit boards used to build a teleporter control console." + id = "teleconsole" + build_path = /obj/item/circuitboard/computer/teleporter + category = list("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/destructive_analyzer + name = "Machine Design (Destructive Analyzer Board)" + desc = "The circuit board for a destructive analyzer." + id = "destructive_analyzer" + build_path = /obj/item/circuitboard/machine/destructive_analyzer + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/experimentor + name = "Machine Design (E.X.P.E.R.I-MENTOR Board)" + desc = "The circuit board for an E.X.P.E.R.I-MENTOR." + id = "experimentor" + build_path = /obj/item/circuitboard/machine/experimentor + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/protolathe + name = "Machine Design (Protolathe Board)" + desc = "The circuit board for a protolathe." + id = "protolathe" + build_path = /obj/item/circuitboard/machine/protolathe + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/rdservercontrol + name = "Computer Design (R&D Server Control Console Board)" + desc = "The circuit board for an R&D Server Control Console." + id = "rdservercontrol" + build_path = /obj/item/circuitboard/computer/rdservercontrol + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/rdserver + name = "Machine Design (R&D Server Board)" + desc = "The circuit board for an R&D Server." + id = "rdserver" + build_path = /obj/item/circuitboard/machine/rdserver + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/mechfab + name = "Machine Design (Exosuit Fabricator Board)" + desc = "The circuit board for an Exosuit Fabricator." + id = "mechfab" + build_path = /obj/item/circuitboard/machine/mechfab + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/cyborgrecharger + name = "Machine Design (Cyborg Recharger Board)" + desc = "The circuit board for a Cyborg Recharger." + id = "cyborgrecharger" + build_path = /obj/item/circuitboard/machine/cyborgrecharger + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/mech_recharger + name = "Machine Design (Mechbay Recharger Board)" + desc = "The circuit board for a Mechbay Recharger." + id = "mech_recharger" + build_path = /obj/item/circuitboard/machine/mech_recharger + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/nanite_chamber + name = "Machine Design (Nanite Chamber Board)" + desc = "The circuit board for a Nanite Chamber." + id = "nanite_chamber" + build_path = /obj/item/circuitboard/machine/nanite_chamber + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/public_nanite_chamber + name = "Machine Design (Public Nanite Chamber Board)" + desc = "The circuit board for a Public Nanite Chamber." + id = "public_nanite_chamber" + build_path = /obj/item/circuitboard/machine/public_nanite_chamber + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/nanite_programmer + name = "Machine Design (Nanite Programmer Board)" + desc = "The circuit board for a Nanite Programmer." + id = "nanite_programmer" + build_path = /obj/item/circuitboard/machine/nanite_programmer + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/nanite_program_hub + name = "Machine Design (Nanite Program Hub Board)" + desc = "The circuit board for a Nanite Program Hub." + id = "nanite_program_hub" + build_path = /obj/item/circuitboard/machine/nanite_program_hub + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/circuit_imprinter + name = "Machine Design (Circuit Imprinter Board)" + desc = "The circuit board for a circuit imprinter." + id = "circuit_imprinter" + build_path = /obj/item/circuitboard/machine/circuit_imprinter + category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/machine_desings/machine_designs_service.dm b/code/modules/research/designs/machine_desings/machine_designs_service.dm new file mode 100644 index 0000000000..895ad032ba --- /dev/null +++ b/code/modules/research/designs/machine_desings/machine_designs_service.dm @@ -0,0 +1,90 @@ +/////////////////// +///CIV Boards/// +/////////////////// +/datum/design/board/gibber + name = "Machine Design (Gibber Board)" + desc = "The circuit board for a gibber." + id = "gibber" + build_path = /obj/item/circuitboard/machine/gibber + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/board/seed_extractor + name = "Machine Design (Seed Extractor Board)" + desc = "The circuit board for a seed extractor." + id = "seed_extractor" + build_path = /obj/item/circuitboard/machine/seed_extractor + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/board/soda_dispenser + name = "Machine Design (Portable Soda Dispenser Board)" + desc = "The circuit board for a portable soda dispenser." + id = "soda_dispenser" + build_path = /obj/item/circuitboard/machine/chem_dispenser/drinks + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + category = list ("Misc. Machinery") + +/datum/design/board/beer_dispenser + name = "Machine Design (Portable Booze Dispenser Board)" + desc = "The circuit board for a portable booze dispenser." + id = "beer_dispenser" + build_path = /obj/item/circuitboard/machine/chem_dispenser/drinks/beer + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + category = list ("Misc. Machinery") + +/datum/design/board/plantgenes + name = "Machine Design (Plant DNA Manipulator Board)" + desc = "The circuit board for a plant DNA manipulator." + id = "plantgenes" + build_path = /obj/item/circuitboard/machine/plantgenes + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/board/deepfryer + name = "Machine Design (Deep Fryer)" + desc = "The circuit board for a Deep Fryer." + id = "deepfryer" + build_path = /obj/item/circuitboard/machine/deep_fryer + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/board/dish_drive + name = "Machine Design (Dish Drive)" + desc = "The circuit board for a dish drive." + id = "dish_drive" + build_path = /obj/item/circuitboard/machine/dish_drive + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/board/biogenerator + name = "Machine Design (Biogenerator Board)" + desc = "The circuit board for a biogenerator." + id = "biogenerator" + build_path = /obj/item/circuitboard/machine/biogenerator + category = list ("Hydroponics Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/board/hydroponics + name = "Machine Design (Hydroponics Tray Board)" + desc = "The circuit board for a hydroponics tray." + id = "hydro_tray" + build_path = /obj/item/circuitboard/machine/hydroponics + category = list ("Hydroponics Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/board/monkey_recycler + name = "Machine Design (Monkey Recycler Board)" + desc = "The circuit board for a monkey recycler." + id = "monkey_recycler" + build_path = /obj/item/circuitboard/machine/monkey_recycler + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/board/processor + name = "Machine Design (Food/Slime Processor Board)" + desc = "The circuit board for a processing unit. Screwdriver the circuit to switch between food (default) or slime processing." + id = "processor" + build_path = /obj/item/circuitboard/machine/processor + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index aea3a3755f..7224d0e4e8 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -44,16 +44,6 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL -/datum/design/medicalkit - name = "Empty Medkit" - desc = "A plastic medical kit for storging medical items." - id = "medicalkit" - build_type = PROTOLATHE - materials = list(MAT_PLASTIC = 5000) - build_path = /obj/item/storage/firstaid //So we dont spawn medical items in it - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - /datum/design/xlarge_beaker name = "X-large Beaker" id = "xlarge_beaker" @@ -82,16 +72,6 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE -/datum/design/cloning_disk - name = "Cloning Data Disk" - desc = "Produce additional disks for storing genetic data." - id = "cloning_disk" - build_type = PROTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=50) - build_path = /obj/item/disk/data - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - /datum/design/noreactsyringe name = "Cryo Syringe" desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units." @@ -162,6 +142,16 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/medicalkit + name = "Empty Medkit" + desc = "A plastic medical kit for storging medical items." + id = "medicalkit" + build_type = PROTOLATHE + materials = list(MAT_PLASTIC = 5000) + build_path = /obj/item/storage/firstaid //So we dont spawn medical items in it + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + /datum/design/blood_bag name = "Empty Blood Bag" desc = "A small sterilized plastic bag for blood." @@ -172,6 +162,16 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/cloning_disk + name = "Cloning Data Disk" + desc = "Produce additional disks for storing genetic data." + id = "cloning_disk" + build_type = PROTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=50) + build_path = /obj/item/disk/data + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + //////////////////////////////////////// //////////Defibrillator Tech//////////// //////////////////////////////////////// @@ -196,8 +196,8 @@ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/defib_heal - name = "Defibrillartor Healing disk" - desc = "A disk allowing for greater amounts of healing" + name = "Defibrillator Healing disk" + desc = "An upgrade which increases the healing power of the defibrillator" id = "defib_heal" build_type = PROTOLATHE materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000) @@ -207,8 +207,8 @@ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/defib_shock - name = "Defibrillartor Anit-Shock Disk" - desc = "A disk that helps agains shocking anyone, other then the intented target" + name = "Defibrillator Anti-Shock Disk" + desc = "A safety upgrade that guarantees only the patient will get shocked" id = "defib_shock" build_type = PROTOLATHE materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000) @@ -218,8 +218,8 @@ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/defib_decay - name = "Defibrillartor Body-Decay extender Disk" - desc = "A disk that helps defibrillator revive the longer decayed dead" + name = "Defibrillator Body-Decay Extender Disk" + desc = "An upgrade allowing the defibrillator to work on more decayed bodies" id = "defib_decay" build_type = PROTOLATHE materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 16000, MAT_SILVER = 6000, MAT_TITANIUM = 2000) @@ -229,8 +229,8 @@ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/defib_speed - name = "Defibrllartor Pre-Primer Disk" - desc = "A disk that cuts the time charg time in half for defibrillator use" + name = "Defibrillator Fast Charge Disk" + desc = "An upgrade to the defibrillator capacitors, which let it charge faster" id = "defib_speed" build_type = PROTOLATHE build_path = /obj/item/disk/medical/defib_speed @@ -239,72 +239,6 @@ category = list("Misc") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -///////////////////////////////////////// -//////////Alien Surgery Tools//////////// -///////////////////////////////////////// - -/datum/design/alienscalpel - name = "Alien Scalpel" - desc = "An advanced scalpel obtained through Abductor technology." - id = "alien_scalpel" - build_path = /obj/item/scalpel/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/alienhemostat - name = "Alien Hemostat" - desc = "An advanced hemostat obtained through Abductor technology." - id = "alien_hemostat" - build_path = /obj/item/hemostat/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/alienretractor - name = "Alien Retractor" - desc = "An advanced retractor obtained through Abductor technology." - id = "alien_retractor" - build_path = /obj/item/retractor/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/aliensaw - name = "Alien Circular Saw" - desc = "An advanced surgical saw obtained through Abductor technology." - id = "alien_saw" - build_path = /obj/item/circular_saw/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/aliendrill - name = "Alien Drill" - desc = "An advanced drill obtained through Abductor technology." - id = "alien_drill" - build_path = /obj/item/surgicaldrill/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/aliencautery - name = "Alien Cautery" - desc = "An advanced cautery obtained through Abductor technology." - id = "alien_cautery" - build_path = /obj/item/cautery/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - - ///////////////////////////////////////// //////////Cybernetic Implants//////////// ///////////////////////////////////////// @@ -654,9 +588,74 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE +///////////////////////////////////////// +//////////Alien Surgery Tools//////////// +///////////////////////////////////////// + +/datum/design/alienscalpel + name = "Alien Scalpel" + desc = "An advanced scalpel obtained through Abductor technology." + id = "alien_scalpel" + build_path = /obj/item/scalpel/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/alienhemostat + name = "Alien Hemostat" + desc = "An advanced hemostat obtained through Abductor technology." + id = "alien_hemostat" + build_path = /obj/item/hemostat/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/alienretractor + name = "Alien Retractor" + desc = "An advanced retractor obtained through Abductor technology." + id = "alien_retractor" + build_path = /obj/item/retractor/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/aliensaw + name = "Alien Circular Saw" + desc = "An advanced surgical saw obtained through Abductor technology." + id = "alien_saw" + build_path = /obj/item/circular_saw/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/aliendrill + name = "Alien Drill" + desc = "An advanced drill obtained through Abductor technology." + id = "alien_drill" + build_path = /obj/item/surgicaldrill/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/aliencautery + name = "Alien Cautery" + desc = "An advanced cautery obtained through Abductor technology." + id = "alien_cautery" + build_path = /obj/item/cautery/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + ///////////////////// ///Surgery Designs/// ///////////////////// + /datum/design/surgery name = "Surgery Design" desc = "what" diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index d567334998..0d699a1d67 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -94,39 +94,15 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE -///////////////////////////////////////// -//////////////////Misc/////////////////// -///////////////////////////////////////// - -/datum/design/welding_mask - name = "Welding Gas Mask" - desc = "A gas mask with built in welding goggles and face shield. Looks like a skull, clearly designed by a nerd." - id = "weldingmask" +/datum/design/sci_goggles + name = "Science Goggles" + desc = "Goggles fitted with a portable analyzer capable of determining the research worth of an item or components of a machine." + id = "scigoggles" build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 1000) - build_path = /obj/item/clothing/mask/gas/welding + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/science category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/portaseeder - name = "Portable Seed Extractor" - desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." - id = "portaseeder" - build_type = PROTOLATHE - materials = list(MAT_METAL = 1000, MAT_GLASS = 400) - build_path = /obj/item/storage/bag/plants/portaseeder - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SERVICE - -/datum/design/air_horn - name = "Air Horn" - desc = "Damn son, where'd you find this?" - id = "air_horn" - build_type = PROTOLATHE - materials = list(MAT_METAL = 4000, MAT_BANANIUM = 1000) - build_path = /obj/item/bikehorn/airhorn - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ALL //HONK! + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/mesons name = "Optical Meson Scanners" @@ -218,6 +194,40 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING +///////////////////////////////////////// +//////////////////Misc/////////////////// +///////////////////////////////////////// + +/datum/design/welding_mask + name = "Welding Gas Mask" + desc = "A gas mask with built in welding goggles and face shield. Looks like a skull, clearly designed by a nerd." + id = "weldingmask" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000) + build_path = /obj/item/clothing/mask/gas/welding + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/portaseeder + name = "Portable Seed Extractor" + desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." + id = "portaseeder" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = 400) + build_path = /obj/item/storage/bag/plants/portaseeder + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/air_horn + name = "Air Horn" + desc = "Damn son, where'd you find this?" + id = "air_horn" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_BANANIUM = 1000) + build_path = /obj/item/bikehorn/airhorn + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ALL //HONK! + /datum/design/magboots name = "Magnetic Boots" desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle." @@ -228,26 +238,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING -/datum/design/forcefield_projector - name = "Forcefield Projector" - desc = "A device which can project temporary forcefields to seal off an area." - id = "forcefield_projector" - build_type = PROTOLATHE - materials = list(MAT_METAL = 2500, MAT_GLASS = 1000) - build_path = /obj/item/forcefield_projector - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/sci_goggles - name = "Science Goggles" - desc = "Goggles fitted with a portable analyzer capable of determining the research worth of an item or components of a machine." - id = "scigoggles" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/science - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - /datum/design/diskplantgene name = "Plant Data Disk" desc = "A disk for storing plant genetic data." @@ -312,6 +302,10 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SERVICE +///////////////////////////////////////// +////////////Holosign Designs///////////// +///////////////////////////////////////// + /datum/design/holosign name = "Holographic Sign Projector" desc = "A holograpic projector used to project various warning signs." @@ -352,9 +346,19 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING -///////////////////////////////////////// +/datum/design/forcefield_projector + name = "Forcefield Projector" + desc = "A device which can project temporary forcefields to seal off an area." + id = "forcefield_projector" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2500, MAT_GLASS = 1000) + build_path = /obj/item/forcefield_projector + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/////////////////////////////// ////////////Tools////////////// -///////////////////////////////////////// +/////////////////////////////// /datum/design/exwelder name = "Experimental Welding Tool" @@ -457,7 +461,7 @@ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING ///////////////////////////////////////// -////////////Armour////////////// +////////////Armour/////////////////////// ///////////////////////////////////////// /datum/design/reactive_armour diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm index e1648559a7..f8122c16e3 100644 --- a/code/modules/research/designs/power_designs.dm +++ b/code/modules/research/designs/power_designs.dm @@ -77,6 +77,16 @@ category = list("Power Designs") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/inducercombat + name = "Combat Ready Inducer" + desc = "The improved NT-8475 Electromagnetic Power Inducer can this one has been SCIENCED to allow for combat. It still comes printed with SCIENCED colors!" + id = "combatinducer" + build_type = PROTOLATHE + materials = list(MAT_METAL = 13000, MAT_GLASS = 10000, MAT_SILVER = 1500, MAT_GOLD = 1250, MAT_DIAMOND = 500, MAT_TITANIUM = 1200) + build_path = /obj/item/inducer/sci/combat/dry + category = list("Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + /datum/design/board/pacman name = "Machine Design (PACMAN-type Generator Board)" desc = "The circuit board that for a PACMAN-type portable generator." diff --git a/code/modules/research/designs/smelting_designs.dm b/code/modules/research/designs/smelting_designs.dm index f2f21396d2..8ddf975c54 100644 --- a/code/modules/research/designs/smelting_designs.dm +++ b/code/modules/research/designs/smelting_designs.dm @@ -10,7 +10,6 @@ departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING maxstack = 50 - /datum/design/plastitanium_alloy name = "Plasma + Titanium alloy" id = "plastitanium" diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 9b42709fe2..03c0582245 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -1,6 +1,10 @@ -///////////////////////////////////////// -/////////////////Weapons///////////////// -///////////////////////////////////////// +/////////////////////////////// +///////Weapons & Ammo////////// +/////////////////////////////// + +////////////// +//Ammo Boxes// +////////////// /datum/design/c38/sec id = "sec_38" @@ -13,6 +17,40 @@ id = "sec_38lethal" build_path = /obj/item/ammo_box/c38/lethal +////////////// +//WT550 Mags// +////////////// + +/datum/design/mag_oldsmg + name = "WT-550 Semi-Auto SMG Magazine (4.6x30mm)" + desc = "A 20 round magazine for the out of date security WT-550 Semi-Auto SMG." + id = "mag_oldsmg" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000) + build_path = /obj/item/ammo_box/magazine/wt550m9 + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_oldsmg/ap_mag + name = "WT-550 Semi-Auto SMG Armour Piercing Magazine (4.6x30mm AP)" + desc = "A 20 round armour piercing magazine for the out of date security WT-550 Semi-Auto SMG." + id = "mag_oldsmg_ap" + materials = list(MAT_METAL = 6000, MAT_SILVER = 600) + build_path = /obj/item/ammo_box/magazine/wt550m9/wtap + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_oldsmg/ic_mag + name = "WT-550 Semi-Auto SMG Incendiary Magazine (4.6x30mm IC)" + desc = "A 20 round armour piercing magazine for the out of date security WT-550 Semi-Auto SMG." + id = "mag_oldsmg_ic" + materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_GLASS = 1000) + build_path = /obj/item/ammo_box/magazine/wt550m9/wtic + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +////////////// +//Ammo Shells/ +////////////// + /datum/design/rubbershot/sec id = "sec_rshot" build_type = PROTOLATHE @@ -43,6 +81,40 @@ category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY +/datum/design/stunshell + name = "Stun Shell" + desc = "A stunning shell for a shotgun." + id = "stunshell" + build_type = PROTOLATHE + materials = list(MAT_METAL = 200) + build_path = /obj/item/ammo_casing/shotgun/stunslug + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/techshell + name = "Unloaded Technological Shotshell" + desc = "A high-tech shotgun shell which can be loaded with materials to produce unique effects." + id = "techshotshell" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = 200) + build_path = /obj/item/ammo_casing/shotgun/techshell + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/cryostatis_shotgun_dart + name = "Cryostasis Shotgun Dart" + desc = "A shotgun dart designed with similar internals to that of a cryostatis beaker, allowing reagents to not react when inside." + id = "shotgundartcryostatis" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3500) + build_path = /obj/item/ammo_casing/shotgun/dart/noreact + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +////////////// +//Firing Pins/ +////////////// + /datum/design/pin_testing name = "Test-Range Firing Pin" desc = "This safety firing pin allows firearms to be operated within proximity to a firing range." @@ -63,6 +135,20 @@ category = list("Firing Pins") departmental_flags = DEPARTMENTAL_FLAG_SECURITY +////////////// +//Guns//////// +////////////// + +/datum/design/lasercarbine + name = "Laser Carbine" + desc = "Beefed up version of a standard laser gun." + id = "lasercarbine" + build_type = PROTOLATHE + materials = list(MAT_METAL = 15000, MAT_GLASS = 10000, MAT_GOLD = 2500, MAT_SILVER = 2500) + build_path = /obj/item/gun/energy/laser/carbine/nopin + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + /datum/design/stunrevolver name = "Tesla Revolver" desc = "A high-tech revolver that fires internal, reusable shock cartridges in a revolving cylinder. The cartridges can be recharged using conventional rechargers." @@ -83,16 +169,6 @@ category = list("Weapons") departmental_flags = DEPARTMENTAL_FLAG_SECURITY -/datum/design/tele_shield - name = "Telescopic Riot Shield" - desc = "An advanced riot shield made of lightweight materials that collapses for easy storage." - id = "tele_shield" - build_type = PROTOLATHE - materials = list(MAT_METAL = 4000, MAT_GLASS = 4000, MAT_SILVER = 300, MAT_TITANIUM = 200) - build_path = /obj/item/shield/riot/tele - category = list("Weapons") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - /datum/design/beamrifle name = "Beam Marksman Rifle" desc = "A powerful long ranged anti-material rifle that fires charged particle beams to obliterate targets." @@ -122,11 +198,11 @@ materials = list(MAT_METAL = 5000, MAT_GLASS = 1000) build_path = /obj/item/gun/syringe/rapidsyringe category = list("Weapons") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL //uwu + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/temp_gun name = "Temperature Gun" - desc = "A gun that shoots temperature bullet energythings to change temperature."//Change it if you want + desc = "A gun that shoots temperature beam like projectiles to change temperature." id = "temp_gun" build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 500, MAT_SILVER = 3000) @@ -145,46 +221,6 @@ category = list("Weapons") departmental_flags = DEPARTMENTAL_FLAG_SERVICE -/datum/design/large_grenade - name = "Large Grenade" - desc = "A grenade that affects a larger area and use larger containers." - id = "large_Grenade" - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000) - build_path = /obj/item/grenade/chem_grenade/large - category = list("Weapons") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE //Citadel edit added to science - -/datum/design/pyro_grenade - name = "Pyro Grenade" - desc = "An advanced grenade that is able to self ignite its mixture." - id = "pyro_Grenade" - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_PLASMA = 500) - build_path = /obj/item/grenade/chem_grenade/pyro - category = list("Weapons") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/cryo_grenade - name = "Cryo Grenade" - desc = "An advanced grenade that rapidly cools its contents upon detonation." - id = "cryo_Grenade" - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 500) - build_path = /obj/item/grenade/chem_grenade/cryo - category = list("Weapons") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/adv_grenade - name = "Advanced Release Grenade" - desc = "An advanced grenade that can be detonated several times, best used with a repeating igniter." - id = "adv_Grenade" - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 500) - build_path = /obj/item/grenade/chem_grenade/adv_release - category = list("Weapons") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL - /datum/design/xray name = "X-ray Laser Gun" desc = "Not quite as menacing as it sounds" @@ -215,64 +251,6 @@ category = list("Weapons") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE -//WT550 Mags - -/datum/design/mag_oldsmg - name = "WT-550 Semi-Auto SMG Magazine (4.6x30mm)" - desc = "A 20 round magazine for the out of date security WT-550 Semi-Auto SMG." - id = "mag_oldsmg" - build_type = PROTOLATHE - materials = list(MAT_METAL = 4000) - build_path = /obj/item/ammo_box/magazine/wt550m9 - category = list("Ammo") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/mag_oldsmg/ap_mag - name = "WT-550 Semi-Auto SMG Armour Piercing Magazine (4.6x30mm AP)" - desc = "A 20 round armour piercing magazine for the out of date security WT-550 Semi-Auto SMG." - id = "mag_oldsmg_ap" - materials = list(MAT_METAL = 6000, MAT_SILVER = 600) - build_path = /obj/item/ammo_box/magazine/wt550m9/wtap - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/mag_oldsmg/ic_mag - name = "WT-550 Semi-Auto SMG Incendiary Magazine (4.6x30mm IC)" - desc = "A 20 round armour piercing magazine for the out of date security WT-550 Semi-Auto SMG." - id = "mag_oldsmg_ic" - materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_GLASS = 1000) - build_path = /obj/item/ammo_box/magazine/wt550m9/wtic - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/stunshell - name = "Stun Shell" - desc = "A stunning shell for a shotgun." - id = "stunshell" - build_type = PROTOLATHE - materials = list(MAT_METAL = 200) - build_path = /obj/item/ammo_casing/shotgun/stunslug - category = list("Ammo") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - -/datum/design/techshell - name = "Unloaded Technological Shotshell" - desc = "A high-tech shotgun shell which can be loaded with materials to produce unique effects." - id = "techshotshell" - build_type = PROTOLATHE - materials = list(MAT_METAL = 1000, MAT_GLASS = 200) - build_path = /obj/item/ammo_casing/shotgun/techshell - category = list("Ammo") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/suppressor - name = "Universal Suppressor" - desc = "A reverse-engineered universal suppressor that fits on most small arms with threaded barrels." - id = "suppressor" - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 500) - build_path = /obj/item/suppressor - category = list("Weapons") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - /datum/design/gravitygun name = "One-point Bluespace-gravitational Manipulator" desc = "A multi-mode device that blasts one-point bluespace-gravitational bolts that locally distort gravity." @@ -293,12 +271,70 @@ category = list("Weapons") departmental_flags = DEPARTMENTAL_FLAG_SECURITY -/datum/design/cryostatis_shotgun_dart - name = "Cryostasis Shotgun Dart" - desc = "A shotgun dart designed with similar internals to that of a cryostatis beaker, allowing reagents to not react when inside." - id = "shotgundartcryostatis" +/////////// +//Grenades/ +/////////// + +/datum/design/large_grenade + name = "Large Grenade" + desc = "A grenade that affects a larger area and use larger containers." + id = "large_Grenade" build_type = PROTOLATHE - materials = list(MAT_METAL = 3500) - build_path = /obj/item/ammo_casing/shotgun/dart/noreact - category = list("Ammo") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + materials = list(MAT_METAL = 3000) + build_path = /obj/item/grenade/chem_grenade/large + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/pyro_grenade + name = "Pyro Grenade" + desc = "An advanced grenade that is able to self ignite its mixture." + id = "pyro_Grenade" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_PLASMA = 500) + build_path = /obj/item/grenade/chem_grenade/pyro + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/cryo_grenade + name = "Cryo Grenade" + desc = "An advanced grenade that rapidly cools its contents upon detonation." + id = "cryo_Grenade" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 500) + build_path = /obj/item/grenade/chem_grenade/cryo + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/adv_grenade + name = "Advanced Release Grenade" + desc = "An advanced grenade that can be detonated several times, best used with a repeating igniter." + id = "adv_Grenade" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 500) + build_path = /obj/item/grenade/chem_grenade/adv_release + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL + +////////// +//MISC//// +////////// + +/datum/design/tele_shield + name = "Telescopic Riot Shield" + desc = "An advanced riot shield made of lightweight materials that collapses for easy storage." + id = "tele_shield" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_GLASS = 4000, MAT_SILVER = 300, MAT_TITANIUM = 200) + build_path = /obj/item/shield/riot/tele + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/suppressor + name = "Universal Suppressor" + desc = "A reverse-engineered universal suppressor that fits on most small arms with threaded barrels." + id = "suppressor" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 500) + build_path = /obj/item/suppressor + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index 6670a01284..c7d02486dd 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -1,7 +1,6 @@ /obj/machinery/rnd/production name = "technology fabricator" desc = "Makes researched and prototype items with materials and energy." - container_type = OPENCONTAINER layer = BELOW_OBJ_LAYER var/consoleless_interface = FALSE //Whether it can be used without a console. var/efficiency_coeff = 1 //Materials needed / coeff = actual. @@ -21,7 +20,7 @@ /obj/machinery/rnd/production/Initialize(mapload) . = ..() - create_reagents(0) + create_reagents(0, OPENCONTAINER) matching_designs = list() cached_designs = list() stored_research = new diff --git a/code/modules/research/machinery/circuit_imprinter.dm b/code/modules/research/machinery/circuit_imprinter.dm index 5a84f2f663..09cf9cda87 100644 --- a/code/modules/research/machinery/circuit_imprinter.dm +++ b/code/modules/research/machinery/circuit_imprinter.dm @@ -2,7 +2,6 @@ name = "circuit imprinter" desc = "Manufactures circuit boards for the construction of machines." icon_state = "circuit_imprinter" - container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/circuit_imprinter categories = list( "AI Modules", diff --git a/code/modules/research/machinery/departmental_circuit_imprinter.dm b/code/modules/research/machinery/departmental_circuit_imprinter.dm index e47bd97494..53d4a21a9d 100644 --- a/code/modules/research/machinery/departmental_circuit_imprinter.dm +++ b/code/modules/research/machinery/departmental_circuit_imprinter.dm @@ -2,7 +2,6 @@ name = "department circuit imprinter" desc = "A special circuit imprinter with a built in interface meant for departmental usage, with built in ExoSync receivers allowing it to print designs researched that match its ROM-encoded department type." icon_state = "circuit_imprinter" - container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/circuit_imprinter/department requires_console = FALSE consoleless_interface = TRUE diff --git a/code/modules/research/machinery/departmental_protolathe.dm b/code/modules/research/machinery/departmental_protolathe.dm index f91f3282d5..7fad6825fe 100644 --- a/code/modules/research/machinery/departmental_protolathe.dm +++ b/code/modules/research/machinery/departmental_protolathe.dm @@ -2,7 +2,6 @@ name = "department protolathe" desc = "A special protolathe with a built in interface meant for departmental usage, with built in ExoSync receivers allowing it to print designs researched that match its ROM-encoded department type." icon_state = "protolathe" - container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/protolathe/department requires_console = FALSE consoleless_interface = TRUE diff --git a/code/modules/research/machinery/departmental_techfab.dm b/code/modules/research/machinery/departmental_techfab.dm index cf0e30596f..8b82fd2b37 100644 --- a/code/modules/research/machinery/departmental_techfab.dm +++ b/code/modules/research/machinery/departmental_techfab.dm @@ -2,7 +2,6 @@ name = "department techfab" desc = "An advanced fabricator designed to print out the latest prototypes and circuits researched from Science. Contains hardware to sync to research networks. This one is department-locked and only possesses a limited set of decryption keys." icon_state = "protolathe" - container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/techfab/department /obj/machinery/rnd/production/techfab/department/engineering diff --git a/code/modules/research/machinery/protolathe.dm b/code/modules/research/machinery/protolathe.dm index ef74fec666..6acfc9ec42 100644 --- a/code/modules/research/machinery/protolathe.dm +++ b/code/modules/research/machinery/protolathe.dm @@ -2,7 +2,6 @@ name = "protolathe" desc = "Converts raw materials into useful objects." icon_state = "protolathe" - container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/protolathe categories = list( "Power Designs", diff --git a/code/modules/research/machinery/techfab.dm b/code/modules/research/machinery/techfab.dm index 40b407ac61..332a1ccf88 100644 --- a/code/modules/research/machinery/techfab.dm +++ b/code/modules/research/machinery/techfab.dm @@ -2,7 +2,6 @@ name = "technology fabricator" desc = "Produces researched prototypes with raw materials and energy." icon_state = "protolathe" - container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/techfab categories = list( "Power Designs", diff --git a/code/modules/research/nanites/nanite_programs/buffing.dm b/code/modules/research/nanites/nanite_programs/buffing.dm index 578e7731bb..c80c5c5d96 100644 --- a/code/modules/research/nanites/nanite_programs/buffing.dm +++ b/code/modules/research/nanites/nanite_programs/buffing.dm @@ -106,11 +106,11 @@ /datum/nanite_program/conductive/enable_passive_effect() . = ..() - host_mob.add_trait(TRAIT_SHOCKIMMUNE, "nanites") + ADD_TRAIT(host_mob, TRAIT_SHOCKIMMUNE, "nanites") /datum/nanite_program/conductive/disable_passive_effect() . = ..() - host_mob.remove_trait(TRAIT_SHOCKIMMUNE, "nanites") + REMOVE_TRAIT(host_mob, TRAIT_SHOCKIMMUNE, "nanites") /datum/nanite_program/mindshield name = "Mental Barrier" @@ -121,10 +121,10 @@ /datum/nanite_program/mindshield/enable_passive_effect() . = ..() if(!host_mob.mind.has_antag_datum(/datum/antagonist/rev)) //won't work if on a rev, to avoid having implanted revs - host_mob.add_trait(TRAIT_MINDSHIELD, "nanites") + ADD_TRAIT(host_mob, TRAIT_MINDSHIELD, "nanites") host_mob.sec_hud_set_implants() /datum/nanite_program/mindshield/disable_passive_effect() . = ..() - host_mob.remove_trait(TRAIT_MINDSHIELD, "nanites") + REMOVE_TRAIT(host_mob, TRAIT_MINDSHIELD, "nanites") host_mob.sec_hud_set_implants() \ No newline at end of file diff --git a/code/modules/research/nanites/nanite_programs/healing.dm b/code/modules/research/nanites/nanite_programs/healing.dm index df32a5d127..ab314cb33c 100644 --- a/code/modules/research/nanites/nanite_programs/healing.dm +++ b/code/modules/research/nanites/nanite_programs/healing.dm @@ -215,7 +215,7 @@ if(!iscarbon(host_mob)) //nonstandard biology return FALSE var/mob/living/carbon/C = host_mob - if(C.suiciding || C.has_trait(TRAIT_NOCLONE) || C.hellbound) //can't revive + if(C.suiciding || HAS_TRAIT(C, TRAIT_NOCLONE) || C.hellbound) //can't revive return FALSE if((world.time - C.timeofdeath) > 1800) //too late return FALSE diff --git a/code/modules/research/nanites/nanite_programs/suppression.dm b/code/modules/research/nanites/nanite_programs/suppression.dm index 3d89baba68..a6225fd337 100644 --- a/code/modules/research/nanites/nanite_programs/suppression.dm +++ b/code/modules/research/nanites/nanite_programs/suppression.dm @@ -65,11 +65,11 @@ /datum/nanite_program/pacifying/enable_passive_effect() . = ..() - host_mob.add_trait(TRAIT_PACIFISM, "nanites") + ADD_TRAIT(host_mob, TRAIT_PACIFISM, "nanites") /datum/nanite_program/pacifying/disable_passive_effect() . = ..() - host_mob.remove_trait(TRAIT_PACIFISM, "nanites") + REMOVE_TRAIT(host_mob, TRAIT_PACIFISM, "nanites") /datum/nanite_program/blinding name = "Blindness" @@ -93,11 +93,11 @@ /datum/nanite_program/mute/enable_passive_effect() . = ..() - host_mob.add_trait(TRAIT_MUTE, "nanites") + ADD_TRAIT(host_mob, TRAIT_MUTE, "nanites") /datum/nanite_program/mute/disable_passive_effect() . = ..() - host_mob.remove_trait(TRAIT_MUTE, "nanites") + REMOVE_TRAIT(host_mob, TRAIT_MUTE, "nanites") /datum/nanite_program/fake_death name = "Death Simulation" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 4d631691d0..e25dced31c 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -102,8 +102,8 @@ /datum/techweb_node/adv_defibrillator_tec id = "adv_defibrillator_tec" - display_name = "Adv Defibrillator tec" - description = "More ways to bring back the freshly dead." + display_name = "Defibrillator Upgrades" + description = "More ways to bring back the newly dead." prereq_ids = list("adv_biotech", "exp_surgery", "adv_engi", "adv_power") design_ids = list("defib_decay", "defib_shock", "defib_heal", "defib_speed") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) @@ -246,7 +246,7 @@ display_name = "Bluespace Pockets" description = "Studies into the mysterious alternate dimension known as bluespace and how to place items in the threads of reality." prereq_ids = list("adv_power", "adv_bluespace", "adv_biotech", "adv_plasma") - design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash") + design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5500) export_price = 5000 /////////////////////////plasma tech///////////////////////// @@ -428,7 +428,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) export_price = 5000 design_ids = list("s-receiver", "s-bus", "s-broadcaster", "s-processor", "s-hub", "s-server", "s-relay", "comm_monitor", "comm_server", - "s-ansible", "s-filter", "s-amplifier", "ntnet_relay", "s-treatment", "s-analyzer", "s-crystal", "s-transmitter") + "s-ansible", "s-filter", "s-amplifier", "ntnet_relay", "s-treatment", "s-analyzer", "s-crystal", "s-transmitter", "message_monitor") /datum/techweb_node/integrated_HUDs id = "integrated_HUDs" @@ -564,7 +564,7 @@ display_name = "Weapon Development Technology" description = "Our researchers have found new to weaponize just about everything now." prereq_ids = list("engineering") - design_ids = list("pin_testing", "tele_shield") + design_ids = list("pin_testing", "tele_shield", "lasercarbine") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) export_price = 5000 @@ -963,7 +963,7 @@ prereq_ids = list("biotech","engineering") boost_item_paths = list(/obj/item/gun/energy/alien, /obj/item/scalpel/alien, /obj/item/hemostat/alien, /obj/item/retractor/alien, /obj/item/circular_saw/alien, /obj/item/cautery/alien, /obj/item/surgicaldrill/alien, /obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, - /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor) + /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor, /obj/item/stack/sheet/mineral/abductor) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) export_price = 20000 hidden = TRUE diff --git a/code/modules/research/xenobiology/crossbreeding/__corecross.dm b/code/modules/research/xenobiology/crossbreeding/__corecross.dm index d9d58083cb..1146f01f0b 100644 --- a/code/modules/research/xenobiology/crossbreeding/__corecross.dm +++ b/code/modules/research/xenobiology/crossbreeding/__corecross.dm @@ -90,12 +90,11 @@ To add a crossbreed: icon = 'icons/obj/slimecrossing.dmi' icon_state = "base" var/del_on_empty = TRUE - container_type = INJECTABLE | DRAWABLE var/list/list_reagents /obj/item/slimecrossbeaker/Initialize() . = ..() - create_reagents(50) + create_reagents(50, INJECTABLE | DRAWABLE) if(list_reagents) for(var/reagent in list_reagents) reagents.add_reagent(reagent, list_reagents[reagent]) @@ -130,10 +129,13 @@ To add a crossbreed: list_reagents = list("omnizine" = 15) /obj/item/slimecrossbeaker/autoinjector //As with the above, but automatically injects whomever it is used on with contents. - container_type = DRAWABLE //Cannot be refilled, since it's basically an autoinjector! var/ignore_flags = FALSE var/self_use_only = FALSE +/obj/item/slimecrossbeaker/autoinjector/Initialize() + . = ..() + reagents.reagents_holder_flags = DRAWABLE // Cannot be refilled, since it's basically an autoinjector! + /obj/item/slimecrossbeaker/autoinjector/attack(mob/living/M, mob/user) if(!reagents.total_volume) to_chat(user, "[src] is empty!") @@ -169,12 +171,15 @@ To add a crossbreed: list_reagents = list("slimejelly" = 50) /obj/item/slimecrossbeaker/autoinjector/peaceandlove - container_type = null //It won't be *that* easy to get your hands on pax. name = "peaceful distillation" desc = "A light pink gooey sphere. Simply touching it makes you a little dizzy." color = "#DDAAAA" list_reagents = list("synthpax" = 10, "space_drugs" = 15) //Peace, dudes +/obj/item/slimecrossbeaker/autoinjector/peaceandlove/Initialize() + . = ..() + reagents.reagents_holder_flags = NONE // It won't be *that* easy to get your hands on pax. + /obj/item/slimecrossbeaker/autoinjector/slimestimulant name = "invigorating gel" desc = "A bubbling purple mixture, designed to heal and boost movement." diff --git a/code/modules/research/xenobiology/crossbreeding/_clothing.dm b/code/modules/research/xenobiology/crossbreeding/_clothing.dm index 016fd95899..b8bdffbabf 100644 --- a/code/modules/research/xenobiology/crossbreeding/_clothing.dm +++ b/code/modules/research/xenobiology/crossbreeding/_clothing.dm @@ -20,14 +20,14 @@ Slimecrossing Armor /obj/item/clothing/mask/nobreath/equipped(mob/living/carbon/human/user, slot) . = ..() if(slot == SLOT_WEAR_MASK) - user.add_trait(TRAIT_NOBREATH, "breathmask_[REF(src)]") + ADD_TRAIT(user, TRAIT_NOBREATH, "breathmask_[REF(src)]") user.failed_last_breath = FALSE user.clear_alert("not_enough_oxy") user.apply_status_effect(/datum/status_effect/rebreathing) /obj/item/clothing/mask/nobreath/dropped(mob/living/carbon/human/user) ..() - user.remove_trait(TRAIT_NOBREATH, "breathmask_[REF(src)]") + REMOVE_TRAIT(user, TRAIT_NOBREATH, "breathmask_[REF(src)]") user.remove_status_effect(/datum/status_effect/rebreathing) /obj/item/clothing/glasses/prism_glasses @@ -112,11 +112,11 @@ Slimecrossing Armor /obj/item/clothing/head/peaceflower/equipped(mob/living/carbon/human/user, slot) . = ..() if(slot == SLOT_HEAD) - user.add_trait(TRAIT_PACIFISM, "peaceflower_[REF(src)]") + ADD_TRAIT(user, TRAIT_PACIFISM, "peaceflower_[REF(src)]") /obj/item/clothing/head/peaceflower/dropped(mob/living/carbon/human/user) ..() - user.remove_trait(TRAIT_PACIFISM, "peaceflower_[REF(src)]") + REMOVE_TRAIT(user, TRAIT_PACIFISM, "peaceflower_[REF(src)]") /obj/item/clothing/head/peaceflower/attack_hand(mob/user) if(iscarbon(user)) diff --git a/code/modules/research/xenobiology/crossbreeding/_misc.dm b/code/modules/research/xenobiology/crossbreeding/_misc.dm index 0784946a37..b28f1676a1 100644 --- a/code/modules/research/xenobiology/crossbreeding/_misc.dm +++ b/code/modules/research/xenobiology/crossbreeding/_misc.dm @@ -56,7 +56,7 @@ if(last_check_time + 50 < world.time) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.mind && !H.has_trait(TRAIT_AGEUSIA)) + if(H.mind && !HAS_TRAIT(H, TRAIT_AGEUSIA)) to_chat(H,"That didn't taste very good...") //No disgust, though. It's just not good tasting. GET_COMPONENT_FROM(mood, /datum/component/mood, H) if(mood) diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index aba54cfdf3..ad5bfa27dc 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -11,7 +11,7 @@ /datum/status_effect/rainbow_protection/on_apply() owner.status_flags |= GODMODE - owner.add_trait(TRAIT_PACIFISM, "slimestatus") + ADD_TRAIT(owner, TRAIT_PACIFISM, "slimestatus") owner.visible_message("[owner] shines with a brilliant rainbow light.", "You feel protected by an unknown force!") originalcolor = owner.color @@ -24,7 +24,7 @@ /datum/status_effect/rainbow_protection/on_remove() owner.status_flags &= ~GODMODE owner.color = originalcolor - owner.remove_trait(TRAIT_PACIFISM, "slimestatus") + REMOVE_TRAIT(owner, TRAIT_PACIFISM, "slimestatus") owner.visible_message("[owner] stops glowing, the rainbow light fading away.", "You no longer feel protected...") @@ -246,12 +246,12 @@ datum/status_effect/rebreathing/tick() duration = 100 /datum/status_effect/firecookie/on_apply() - owner.add_trait(TRAIT_RESISTCOLD,"firecookie") + ADD_TRAIT(owner, TRAIT_RESISTCOLD,"firecookie") owner.adjust_bodytemperature(110) return ..() /datum/status_effect/firecookie/on_remove() - owner.remove_trait(TRAIT_RESISTCOLD,"firecookie") + REMOVE_TRAIT(owner, TRAIT_RESISTCOLD,"firecookie") /datum/status_effect/watercookie id = "watercookie" @@ -260,7 +260,7 @@ datum/status_effect/rebreathing/tick() duration = 100 /datum/status_effect/watercookie/on_apply() - owner.add_trait(TRAIT_NOSLIPWATER,"watercookie") + ADD_TRAIT(owner, TRAIT_NOSLIPWATER,"watercookie") return ..() /datum/status_effect/watercookie/tick() @@ -268,7 +268,7 @@ datum/status_effect/rebreathing/tick() T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10, wet_time_to_add = 5) /datum/status_effect/watercookie/on_remove() - owner.remove_trait(TRAIT_NOSLIPWATER,"watercookie") + REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER,"watercookie") /datum/status_effect/metalcookie id = "metalcookie" @@ -313,11 +313,11 @@ datum/status_effect/rebreathing/tick() duration = 600 /datum/status_effect/toxincookie/on_apply() - owner.add_trait(TRAIT_TOXINLOVER,"toxincookie") + ADD_TRAIT(owner, TRAIT_TOXINLOVER,"toxincookie") return ..() /datum/status_effect/toxincookie/on_remove() - owner.remove_trait(TRAIT_TOXINLOVER,"toxincookie") + REMOVE_TRAIT(owner, TRAIT_TOXINLOVER,"toxincookie") /datum/status_effect/timecookie id = "timecookie" @@ -417,11 +417,11 @@ datum/status_effect/rebreathing/tick() duration = 30 /datum/status_effect/plur/on_apply() - owner.add_trait(TRAIT_PACIFISM, "peacecookie") + ADD_TRAIT(owner, TRAIT_PACIFISM, "peacecookie") return ..() /datum/status_effect/plur/on_remove() - owner.remove_trait(TRAIT_PACIFISM, "peacecookie") + REMOVE_TRAIT(owner, TRAIT_PACIFISM, "peacecookie") /datum/status_effect/adamantinecookie id = "adamantinecookie" @@ -515,11 +515,11 @@ datum/status_effect/rebreathing/tick() colour = "blue" /datum/status_effect/stabilized/blue/on_apply() - owner.add_trait(TRAIT_NOSLIPWATER, "slimestatus") + ADD_TRAIT(owner, TRAIT_NOSLIPWATER, "slimestatus") return ..() datum/status_effect/stabilized/blue/on_remove() - owner.remove_trait(TRAIT_NOSLIPWATER, "slimestatus") + REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER, "slimestatus") /datum/status_effect/stabilized/metal id = "stabilizedmetal" @@ -580,7 +580,7 @@ datum/status_effect/stabilized/blue/on_remove() examine_text = "Their fingertips burn brightly!" /datum/status_effect/stabilized/darkpurple/on_apply() - owner.add_trait(TRAIT_RESISTHEATHANDS, "slimestatus") + ADD_TRAIT(owner, TRAIT_RESISTHEATHANDS, "slimestatus") fire = new(owner) return ..() @@ -596,7 +596,7 @@ datum/status_effect/stabilized/blue/on_remove() return ..() /datum/status_effect/stabilized/darkpurple/on_remove() - owner.remove_trait(TRAIT_RESISTHEATHANDS, "slimestatus") + REMOVE_TRAIT(owner, TRAIT_RESISTHEATHANDS, "slimestatus") qdel(fire) /datum/status_effect/stabilized/darkblue @@ -767,11 +767,11 @@ datum/status_effect/stabilized/blue/on_remove() colour = "red" /datum/status_effect/stabilized/red/on_apply() - owner.add_trait(TRAIT_IGNORESLOWDOWN,"slimestatus") + owner.ignore_slowdown("slimestatus") return ..() /datum/status_effect/stabilized/red/on_remove() - owner.remove_trait(TRAIT_IGNORESLOWDOWN,"slimestatus") + owner.unignore_slowdown("slimestatus") /datum/status_effect/stabilized/green id = "stabilizedgreen" @@ -916,7 +916,7 @@ datum/status_effect/stabilized/blue/on_remove() colour = "light pink" /datum/status_effect/stabilized/lightpink/on_apply() - owner.add_trait(TRAIT_GOTTAGOFAST,"slimestatus") + ADD_TRAIT(owner, TRAIT_GOTTAGOFAST,"slimestatus") return ..() /datum/status_effect/stabilized/lightpink/tick() @@ -927,7 +927,7 @@ datum/status_effect/stabilized/blue/on_remove() return ..() /datum/status_effect/stabilized/lightpink/on_remove() - owner.remove_trait(TRAIT_GOTTAGOFAST,"slimestatus") + REMOVE_TRAIT(owner, TRAIT_GOTTAGOFAST,"slimestatus") /datum/status_effect/stabilized/adamantine id = "stabilizedadamantine" diff --git a/code/modules/research/xenobiology/crossbreeding/burning.dm b/code/modules/research/xenobiology/crossbreeding/burning.dm index 3b2131dd81..38362e6d64 100644 --- a/code/modules/research/xenobiology/crossbreeding/burning.dm +++ b/code/modules/research/xenobiology/crossbreeding/burning.dm @@ -7,12 +7,11 @@ Burning extracts: name = "burning extract" desc = "It's boiling over with barely-contained energy." effect = "burning" - container_type = INJECTABLE | DRAWABLE icon_state = "burning" /obj/item/slimecross/burning/Initialize() . = ..() - create_reagents(10) + create_reagents(10, INJECTABLE | DRAWABLE) /obj/item/slimecross/burning/attack_self(mob/user) if(!reagents.has_reagent("plasma",10)) diff --git a/code/modules/research/xenobiology/crossbreeding/charged.dm b/code/modules/research/xenobiology/crossbreeding/charged.dm index b664380d9e..7b5fe9e8b8 100644 --- a/code/modules/research/xenobiology/crossbreeding/charged.dm +++ b/code/modules/research/xenobiology/crossbreeding/charged.dm @@ -8,12 +8,11 @@ Charged extracts: name = "charged extract" desc = "It sparks with electric power." effect = "charged" - container_type = INJECTABLE | DRAWABLE icon_state = "charged" /obj/item/slimecross/charged/Initialize() . = ..() - create_reagents(10) + create_reagents(10, INJECTABLE | DRAWABLE) /obj/item/slimecross/charged/attack_self(mob/user) if(!reagents.has_reagent("plasma",10)) @@ -427,7 +426,7 @@ Charged extracts: else to_chat(user, "You drink the pacification potion!") if(isanimal(M)) - M.add_trait(TRAIT_PACIFISM, MAGIC_TRAIT) + ADD_TRAIT(M, TRAIT_PACIFISM, MAGIC_TRAIT) else if(iscarbon(M)) var/mob/living/carbon/C = M C.gain_trauma(/datum/brain_trauma/severe/pacifism, TRAUMA_RESILIENCE_SURGERY) diff --git a/code/modules/research/xenobiology/crossbreeding/chilling.dm b/code/modules/research/xenobiology/crossbreeding/chilling.dm index 25dbaa461f..881c830e5e 100644 --- a/code/modules/research/xenobiology/crossbreeding/chilling.dm +++ b/code/modules/research/xenobiology/crossbreeding/chilling.dm @@ -7,12 +7,11 @@ Chilling extracts: name = "chilling extract" desc = "It's cold to the touch, as if frozen solid." effect = "chilling" - container_type = INJECTABLE | DRAWABLE icon_state = "chilling" /obj/item/slimecross/chilling/Initialize() . = ..() - create_reagents(10) + create_reagents(10, INJECTABLE | DRAWABLE) /obj/item/slimecross/chilling/attack_self(mob/user) if(!reagents.has_reagent("plasma",10)) @@ -101,10 +100,9 @@ Chilling extracts: for(var/turf/open/T in A) var/datum/gas_mixture/G = T.air if(istype(G)) - G.assert_gas(/datum/gas/plasma) - G.gases[/datum/gas/plasma][MOLES] = 0 + G.gases[/datum/gas/plasma] = 0 filtered = TRUE - G.garbage_collect() + GAS_GARBAGE_COLLECT(G.gases) T.air_update_turf() if(filtered) user.visible_message("Cracks spread throughout [src], and some air is sucked in!") diff --git a/code/modules/research/xenobiology/crossbreeding/industrial.dm b/code/modules/research/xenobiology/crossbreeding/industrial.dm index 2ab39eb06f..4d39d956e7 100644 --- a/code/modules/research/xenobiology/crossbreeding/industrial.dm +++ b/code/modules/research/xenobiology/crossbreeding/industrial.dm @@ -5,7 +5,6 @@ Industrial extracts: /obj/item/slimecross/industrial name = "industrial extract" desc = "A gel-like, sturdy extract, fond of plasma and industry." - container_type = INJECTABLE | DRAWABLE effect = "industrial" icon_state = "industrial_still" var/plasmarequired = 2 //Units of plasma required to be consumed to produce item. @@ -22,7 +21,7 @@ Industrial extracts: /obj/item/slimecross/industrial/Initialize() . = ..() - create_reagents(100) + create_reagents(100, INJECTABLE | DRAWABLE) START_PROCESSING(SSobj,src) /obj/item/slimecross/industrial/Destroy() diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index ca12accbed..76d444da18 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -10,7 +10,6 @@ throwforce = 0 throw_speed = 3 throw_range = 6 - container_type = INJECTABLE | DRAWABLE grind_results = list() var/Uses = 1 // uses before it goes inert var/qdel_timer = null // deletion timer, for delayed reactions @@ -39,7 +38,7 @@ /obj/item/slime_extract/Initialize() . = ..() - create_reagents(100) + create_reagents(100, INJECTABLE | DRAWABLE) /obj/item/slime_extract/on_grind() if(Uses) diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index b8d19a7018..28ea849782 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -16,6 +16,17 @@ /obj/item/seeds/sunflower/moonflower = 8 ) +/obj/item/disk/design_disk/plant_disk + name = "Plant Disk Blueprints" + desc = "A disk to be uploaded into the autolathen for more plant disks." + icon_state = "datadisk1" + max_blueprints = 1 + +/obj/item/disk/design_disk/golem_shell/Initialize() + . = ..() + var/datum/design/diskplantgene/P = new + blueprints[1] = P + //Free Golems /obj/item/disk/design_disk/golem_shell diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 9af4194049..d41fd6a79b 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -516,10 +516,10 @@ name = "emergency space suits" desc = "A wall mounted safe containing space suits. Will only open in emergencies." anchored = TRUE - density = FALSE icon = 'icons/obj/storage.dmi' icon_state = "safe" - var/unlocked = FALSE + integrity_failure = 100 + component_type = /datum/component/storage/concrete/emergency /obj/item/storage/pod/PopulateContents() new /obj/item/clothing/head/helmet/space/orange(src) @@ -535,26 +535,6 @@ new /obj/item/survivalcapsule(src) new /obj/item/storage/toolbox/emergency(src) -/obj/item/storage/pod/attackby(obj/item/W, mob/user, params) - if (can_interact(user)) - return ..() - -/obj/item/storage/pod/attack_hand(mob/user) - if (can_interact(user)) - SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SHOW, user) - return TRUE - -/obj/item/storage/pod/MouseDrop(over_object, src_location, over_location) - if(can_interact(usr)) - return ..() - -/obj/item/storage/pod/can_interact(mob/user) - if(!..()) - return FALSE - if(GLOB.security_level == SEC_LEVEL_RED || GLOB.security_level == SEC_LEVEL_DELTA || unlocked) - return TRUE - to_chat(user, "The storage unit will only unlock during a Red or Delta security alert.") - /obj/docking_port/mobile/emergency/backup name = "backup shuttle" id = "backup" diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 9942446868..a6904c28cc 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -290,7 +290,8 @@ All ShuttleMove procs go here // ignores the movement of the shuttle from the staging area on CentCom to // the station as it is loaded in. if (oldT && !is_centcom_level(oldT.z)) - unlocked = TRUE + GET_COMPONENT(STR, /datum/component/storage/concrete/emergency) + STR?.unlock_me() /************************************Mob move procs************************************/ diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm index 35f9a8f50a..73a428af71 100644 --- a/code/modules/spells/spell_types/aimed.dm +++ b/code/modules/spells/spell_types/aimed.dm @@ -74,6 +74,8 @@ /obj/effect/proc_holder/spell/aimed/proc/fire_projectile(mob/living/user, atom/target) current_amount-- + if(!projectile_type) + return for(var/i in 1 to projectiles_per_fire) var/obj/item/projectile/P = new projectile_type(user.loc) P.firer = user diff --git a/code/modules/spells/spell_types/genetic.dm b/code/modules/spells/spell_types/genetic.dm index 37fca86f46..02d3c087f6 100644 --- a/code/modules/spells/spell_types/genetic.dm +++ b/code/modules/spells/spell_types/genetic.dm @@ -26,7 +26,7 @@ for(var/A in mutations) target.dna.add_mutation(A) for(var/A in traits) - target.add_trait(A, GENETICS_SPELL) + ADD_TRAIT(target, A, GENETICS_SPELL) active_on += target addtimer(CALLBACK(src, .proc/remove, target), duration) @@ -41,4 +41,4 @@ for(var/A in mutations) target.dna.remove_mutation(A) for(var/A in traits) - target.remove_trait(A, GENETICS_SPELL) \ No newline at end of file + REMOVE_TRAIT(target, A, GENETICS_SPELL) \ No newline at end of file diff --git a/code/modules/spells/spell_types/godhand.dm b/code/modules/spells/spell_types/godhand.dm index 919d87b4c7..06d1fc3dc5 100644 --- a/code/modules/spells/spell_types/godhand.dm +++ b/code/modules/spells/spell_types/godhand.dm @@ -94,3 +94,87 @@ M.Stun(40) M.petrify() return ..() + + +/obj/item/melee/touch_attack/megahonk + name = "\improper honkmother's blessing" + desc = "You've got a feeling they won't be laughing after this one. Honk honk." + catchphrase = "HONKDOOOOUKEN!" + on_use_sound = 'sound/items/airhorn.ogg' + icon = 'icons/mecha/mecha_equipment.dmi' + icon_state = "mecha_honker" + +/obj/item/melee/touch_attack/megahonk/afterattack(atom/target, mob/living/carbon/user, proximity) + if(!proximity || !iscarbon(target) || !iscarbon(user) || user.handcuffed) + return + user.say(catchphrase, forced = "spell") + playsound(get_turf(target), on_use_sound,100,1) + for(var/mob/living/carbon/M in (hearers(1, target) - user)) //3x3 around the target, not affecting the user + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(istype(H.ears, /obj/item/clothing/ears/earmuffs)) + continue + var/mul = (M==target ? 1 : 0.5) + to_chat(M, "HONK") + M.SetSleeping(0) + M.stuttering += 20*mul + M.adjustEarDamage(0, 30*mul) + M.Knockdown(60*mul) + if(prob(40)) + M.Knockdown(200*mul) + else + M.Jitter(500*mul) + + charges-- + if(charges <= 0) + qdel(src) + +/obj/item/melee/touch_attack/megahonk/attack_self(mob/user) + . = ..() + to_chat(user, "\The [src] disappears, to honk another day.") + qdel(src) + +/obj/item/melee/touch_attack/bspie + name = "\improper bluespace pie" + desc = "A thing you can barely comprehend as you hold it in your hand. You're fairly sure you could fit an entire body inside." + on_use_sound = 'sound/magic/demon_consume.ogg' + icon = 'icons/obj/food/piecake.dmi' + icon_state = "frostypie" + color = "#000077" + +/obj/item/melee/touch_attack/bspie/attack_self(mob/user) + . = ..() + to_chat(user, "You smear \the [src] on your chest! ") + qdel(src) + +/obj/item/melee/touch_attack/bspie/afterattack(atom/target, mob/living/carbon/user, proximity) + if(!proximity || !iscarbon(target) || !iscarbon(user) || user.handcuffed) + return + if(target == user) + to_chat(user, "You smear \the [src] on your chest!") + qdel(src) + return + var/mob/living/carbon/M = target + + user.visible_message("[user] is trying to stuff [M]\s body into \the [src]!") + if(do_mob(user, M, 250)) + var/name = M.real_name + var/obj/item/reagent_containers/food/snacks/pie/cream/body/pie = new(get_turf(M)) + pie.name = "\improper [name] [pie.name]" + + playsound(get_turf(target), on_use_sound, 50, 1) + + /* + var/obj/item/bodypart/head = M.get_bodypart("head") + if(head) + head.drop_limb() + head.throw_at(get_turf(head), 1, 1) + qdel(M) + */ + M.forceMove(pie) + + + charges-- + + if(charges <= 0) + qdel(src) diff --git a/code/modules/spells/spell_types/taeclowndo.dm b/code/modules/spells/spell_types/taeclowndo.dm new file mode 100644 index 0000000000..d2b0782b07 --- /dev/null +++ b/code/modules/spells/spell_types/taeclowndo.dm @@ -0,0 +1,86 @@ +/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pie + name = "Summon Creampie" + desc = "A clown's weapon of choice. Use this to summon a fresh pie, just waiting to acquaintain itself with someone's face." + invocation_type = "none" + include_user = 1 + range = -1 + clothes_req = 0 + item_type = /obj/item/reagent_containers/food/snacks/pie/cream + + charge_max = 30 + cooldown_min = 30 + action_icon = 'icons/obj/food/piecake.dmi' + action_icon_state = "pie" + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/obj/effect/proc_holder/spell/aimed/banana_peel + name = "Conjure Banana Peel" + desc = "Make a banana peel appear out of thin air right under someone's feet!" + charge_type = "recharge" + charge_max = 100 + cooldown_min = 100 + clothes_req = 0 + invocation_type = "none" + range = 7 + selection_type = "view" + projectile_type = null + + active_msg = "You focus, your mind reaching to the clown dimension, ready to make a peel matrialize wherever you want!" + deactive_msg = "You relax, the peel remaining right in the \"thin air\" it would appear out of." + action_icon = 'icons/obj/hydroponics/harvest.dmi' + base_icon_state = "banana_peel" + action_icon_state = "banana" + + +/obj/effect/proc_holder/spell/aimed/banana_peel/cast(list/targets, mob/user = usr) + var/target = get_turf(targets[1]) + + if(get_dist(user,target)>range) + to_chat(user, "\The [target] is too far away!") + return + + . = ..() + new /obj/item/grown/bananapeel(target) + +/obj/effect/proc_holder/spell/aimed/banana_peel/update_icon() + if(!action) + return + if(active) + action.button_icon_state = base_icon_state + else + action.button_icon_state = action_icon_state + + action.UpdateButtonIcon() + return +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/obj/effect/proc_holder/spell/targeted/touch/megahonk + name = "Mega HoNk" + desc = "This spell channels your inner clown powers, concentrating them into one massive HONK." + hand_path = /obj/item/melee/touch_attack/megahonk + + charge_max = 100 + clothes_req = 0 + cooldown_min = 100 + + action_icon = 'icons/mecha/mecha_equipment.dmi' + action_icon_state = "mecha_honker" + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/obj/effect/proc_holder/spell/targeted/touch/bspie + name = "Bluespace Banana Pie" + desc = "An entire body would fit in there!" + hand_path = /obj/item/melee/touch_attack/bspie + + charge_max = 450 + clothes_req = 0 + cooldown_min = 450 + + action_icon = 'icons/obj/food/piecake.dmi' + action_icon_state = "frostypie" + + + + diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm index 7f291be674..3073a6fcc3 100644 --- a/code/modules/station_goals/dna_vault.dm +++ b/code/modules/station_goals/dna_vault.dm @@ -258,25 +258,25 @@ var/obj/item/organ/lungs/L = H.internal_organs_slot[ORGAN_SLOT_LUNGS] L.tox_breath_dam_min = 0 L.tox_breath_dam_max = 0 - H.add_trait(TRAIT_VIRUSIMMUNE, "dna_vault") + ADD_TRAIT(H, TRAIT_VIRUSIMMUNE, "dna_vault") if(VAULT_NOBREATH) to_chat(H, "Your lungs feel great.") - H.add_trait(TRAIT_NOBREATH, "dna_vault") + ADD_TRAIT(H, TRAIT_NOBREATH, "dna_vault") if(VAULT_FIREPROOF) to_chat(H, "You feel fireproof.") S.burnmod = 0.5 - H.add_trait(TRAIT_RESISTHEAT, "dna_vault") - H.add_trait(TRAIT_NOFIRE, "dna_vault") + ADD_TRAIT(H, TRAIT_RESISTHEAT, "dna_vault") + ADD_TRAIT(H, TRAIT_NOFIRE, "dna_vault") if(VAULT_STUNTIME) to_chat(H, "Nothing can keep you down for long.") S.stunmod = 0.5 if(VAULT_ARMOUR) to_chat(H, "You feel tough.") S.armor = 30 - H.add_trait(TRAIT_PIERCEIMMUNE, "dna_vault") + ADD_TRAIT(H, TRAIT_PIERCEIMMUNE, "dna_vault") if(VAULT_SPEED) to_chat(H, "Your legs feel faster.") - H.add_trait(TRAIT_GOTTAGOFAST, "dna_vault") + ADD_TRAIT(H, TRAIT_GOTTAGOFAST, "dna_vault") if(VAULT_QUICK) to_chat(H, "Your arms move as fast as lightning.") H.next_move_modifier = 0.5 diff --git a/code/modules/surgery/advanced/brainwashing.dm b/code/modules/surgery/advanced/brainwashing.dm index f4db9ddbee..23783f1bf2 100644 --- a/code/modules/surgery/advanced/brainwashing.dm +++ b/code/modules/surgery/advanced/brainwashing.dm @@ -41,7 +41,7 @@ if(!target.mind) user.visible_message("[target] doesn't respond to the brainwashing, as if [target.p_they()] lacked a mind...") return FALSE - if(target.has_trait(TRAIT_MINDSHIELD)) + if(HAS_TRAIT(target, TRAIT_MINDSHIELD)) user.visible_message("You hear a faint buzzing from a device inside [target]'s brain, and the brainwashing is erased.") return FALSE user.visible_message("[user] successfully brainwashes [target]!", "You succeed in brainwashing [target].") diff --git a/code/modules/surgery/advanced/revival.dm b/code/modules/surgery/advanced/revival.dm index 0cd7a64235..ebda8a04e2 100644 --- a/code/modules/surgery/advanced/revival.dm +++ b/code/modules/surgery/advanced/revival.dm @@ -18,7 +18,7 @@ return FALSE if(target.stat != DEAD) return FALSE - if(target.suiciding || target.has_trait(TRAIT_NOCLONE) || target.hellbound) + if(target.suiciding || HAS_TRAIT(target, TRAIT_NOCLONE) || target.hellbound) return FALSE var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) if(!B) diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index f394351285..9204de3d08 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -45,9 +45,10 @@ var/species_color = "" var/mutation_color = "" var/no_update = 0 - var/body_markings //for bodypart markings + var/body_markings = "" //for bodypart markings + var/body_markings_icon = 'modular_citadel/icons/mob/mam_markings.dmi' var/list/markings_color = list() - var/auxmarking + var/auxmarking = "" var/list/auxmarking_color = list() var/animal_origin = null //for nonhuman bodypart (e.g. monkey) @@ -87,7 +88,7 @@ /obj/item/bodypart/attack(mob/living/carbon/C, mob/user) if(ishuman(C)) var/mob/living/carbon/human/H = C - if(C.has_trait(TRAIT_LIMBATTACHMENT)) + if(HAS_TRAIT(C, TRAIT_LIMBATTACHMENT)) if(!H.get_bodypart(body_zone) && !animal_origin) if(H == user) H.visible_message("[H] jams [src] into [H.p_their()] empty socket!",\ @@ -220,7 +221,7 @@ //Checks disabled status thresholds /obj/item/bodypart/proc/check_disabled() - if(!can_dismember() || owner.has_trait(TRAIT_NODISMEMBER)) + if(!can_dismember() || HAS_TRAIT(owner, TRAIT_NODISMEMBER)) return if(!disabled && (get_damage(TRUE) >= max_damage)) set_disabled(TRUE) @@ -283,13 +284,14 @@ C = owner no_update = FALSE - if(C.has_trait(TRAIT_HUSK) && is_organic_limb()) + if(HAS_TRAIT(C, TRAIT_HUSK) && is_organic_limb()) species_id = "husk" //overrides species_id dmg_overlay_type = "" //no damage overlay shown when husked should_draw_gender = FALSE should_draw_greyscale = FALSE no_update = TRUE body_markings = "husk" // reeee + auxmarking = "husk" if(no_update) return @@ -332,15 +334,20 @@ species_color = "" if("mam_body_markings" in S.default_features) + var/datum/sprite_accessory/Smark + Smark = GLOB.mam_body_markings_list[H.dna.features["mam_body_markings"]] + body_markings_icon = Smark.icon if(H.dna.features.["mam_body_markings"] != "None") body_markings = lowertext(H.dna.features.["mam_body_markings"]) - if(MATRIXED) - markings_color = list(colorlist) + auxmarking = lowertext(H.dna.features.["mam_body_markings"]) else - markings_color = (H.dna.features.["mcolor"]) + body_markings = "plain" + auxmarking = "plain" + markings_color = list(colorlist) + else - body_markings = "None" - markings_color = "" + body_markings = null + auxmarking = null if(!dropping_limb && H.dna.check_mutation(HULK)) mutation_color = "00aa00" @@ -354,6 +361,8 @@ if(status == BODYPART_ROBOTIC) dmg_overlay_type = "robotic" + body_markings = null + auxmarking = null if(dropping_limb) no_update = TRUE //when attached, the limb won't be affected by the appearance changes of its mob owner. @@ -378,6 +387,8 @@ . = list() var/image_dir = 0 + var/icon_gender = (body_gender == FEMALE) ? "f" : "m" //gender of the icon, if applicable + if(dropped) image_dir = SOUTH if(dmg_overlay_type) @@ -385,11 +396,15 @@ . += image('icons/mob/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_[brutestate]0", -DAMAGE_LAYER, image_dir) if(burnstate) . += image('icons/mob/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_0[burnstate]", -DAMAGE_LAYER, image_dir) - if(body_markings) - if(use_digitigrade == NOT_DIGITIGRADE) - . += image('modular_citadel/icons/mob/mam_markings.dmi', "[body_markings]_[body_zone]", -MARKING_LAYER, image_dir) + + if(!isnull(body_markings) && status == BODYPART_ORGANIC) + if(!use_digitigrade) + if(BODY_ZONE_CHEST) + . += image(body_markings_icon, "[body_markings]_[body_zone]_[icon_gender]", -MARKING_LAYER, image_dir) + else + . += image(body_markings_icon, "[body_markings]_[body_zone]", -MARKING_LAYER, image_dir) else - . += image('modular_citadel/icons/mob/mam_markings.dmi', "[body_markings]_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) + . += image(body_markings_icon, "[body_markings]_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) var/image/limb = image(layer = -BODYPARTS_LAYER, dir = image_dir) var/image/aux @@ -410,8 +425,6 @@ limb.icon_state = "[animal_origin]_[body_zone]" return - var/icon_gender = (body_gender == FEMALE) ? "f" : "m" //gender of the icon, if applicable - if((body_zone != BODY_ZONE_HEAD && body_zone != BODY_ZONE_CHEST)) should_draw_gender = FALSE @@ -440,16 +453,19 @@ limb.icon_state = "[species_id]_[body_zone]" // Body markings - if(body_markings) + if(!isnull(body_markings)) if(species_id == "husk") - marking = image('modular_citadel/icons/mob/mam_markings.dmi', "husk_[body_zone]", -MARKING_LAYER, image_dir) + marking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[body_zone]", -MARKING_LAYER, image_dir) else if(species_id == "husk" && use_digitigrade) - marking = image('modular_citadel/icons/mob/mam_markings.dmi', "husk_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) + marking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) else if(!use_digitigrade) - marking = image('modular_citadel/icons/mob/mam_markings.dmi', "[body_markings]_[body_zone]", -MARKING_LAYER, image_dir) + if(body_zone == BODY_ZONE_CHEST) + marking = image(body_markings_icon, "[body_markings]_[body_zone]_[icon_gender]", -MARKING_LAYER, image_dir) + else + marking = image(body_markings_icon, "[body_markings]_[body_zone]", -MARKING_LAYER, image_dir) else - marking = image('modular_citadel/icons/mob/mam_markings.dmi', "[body_markings]_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) + marking = image(body_markings_icon, "[body_markings]_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) . += marking // Citadel End @@ -457,11 +473,11 @@ if(aux_zone) aux = image(limb.icon, "[species_id]_[aux_zone]", -aux_layer, image_dir) . += aux - if(body_markings) + if(!isnull(auxmarking)) if(species_id == "husk") - auxmarking = image('modular_citadel/icons/mob/mam_markings.dmi', "husk_[aux_zone]", -aux_layer, image_dir) + auxmarking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[aux_zone]", -aux_layer, image_dir) else - auxmarking = image('modular_citadel/icons/mob/mam_markings.dmi', "[body_markings]_[aux_zone]", -aux_layer, image_dir) + auxmarking = image(body_markings_icon, "[body_markings]_[aux_zone]", -aux_layer, image_dir) . += auxmarking else @@ -470,40 +486,43 @@ limb.icon_state = "[body_zone]_[icon_gender]" else limb.icon_state = "[body_zone]" + if(aux_zone) - aux = image(limb.icon, "[species_id]_[aux_zone]", -aux_layer, image_dir) + aux = image(limb.icon, "[aux_zone]", -aux_layer, image_dir) . += aux - if(body_markings) + if(!isnull(auxmarking)) if(species_id == "husk") - auxmarking = image('modular_citadel/icons/mob/mam_markings.dmi', "husk_[aux_zone]", -aux_layer, image_dir) + auxmarking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[aux_zone]", -aux_layer, image_dir) else - auxmarking = image('modular_citadel/icons/mob/mam_markings.dmi', "[body_markings]_[aux_zone]", -aux_layer, image_dir) + auxmarking = image(body_markings_icon, "[body_markings]_[aux_zone]", -aux_layer, image_dir) . += auxmarking - if(body_markings) + if(!isnull(body_markings)) if(species_id == "husk") - marking = image('modular_citadel/icons/mob/mam_markings.dmi', "husk_[body_zone]", -MARKING_LAYER, image_dir) + marking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[body_zone]", -MARKING_LAYER, image_dir) else if(species_id == "husk" && use_digitigrade) - marking = image('modular_citadel/icons/mob/mam_markings.dmi', "husk_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) + marking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) else if(!use_digitigrade) - marking = image('modular_citadel/icons/mob/mam_markings.dmi', "[body_markings]_[body_zone]", -MARKING_LAYER, image_dir) + if(body_zone == BODY_ZONE_CHEST) + marking = image(body_markings_icon, "[body_markings]_[body_zone]_[icon_gender]", -MARKING_LAYER, image_dir) + else + marking = image(body_markings_icon, "[body_markings]_[body_zone]", -MARKING_LAYER, image_dir) else - marking = image('modular_citadel/icons/mob/mam_markings.dmi', "[body_markings]_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) + marking = image(body_markings_icon, "[body_markings]_digitigrade_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir) . += marking return - if(should_draw_greyscale) var/draw_color = mutation_color || species_color || (skin_tone && skintone2hex(skin_tone)) if(draw_color) limb.color = "#[draw_color]" if(aux_zone) aux.color = "#[draw_color]" - if(body_markings) + if(!isnull(auxmarking)) auxmarking.color = list(markings_color) - if(body_markings) + if(!isnull(body_markings)) if(species_id == "husk") marking.color = "#141414" else diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 1a46a9dcb1..9341fb6c25 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -12,7 +12,7 @@ return FALSE if(C.status_flags & GODMODE) return FALSE - if(C.has_trait(TRAIT_NODISMEMBER)) + if(HAS_TRAIT(C, TRAIT_NODISMEMBER)) return FALSE var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST) @@ -47,7 +47,7 @@ var/mob/living/carbon/C = owner if(!dismemberable) return FALSE - if(C.has_trait(TRAIT_NODISMEMBER)) + if(HAS_TRAIT(C, TRAIT_NODISMEMBER)) return FALSE . = list() var/organ_spilled = 0 diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 1f0fa00632..46ee10a3fd 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -68,7 +68,7 @@ C = owner real_name = C.real_name - if(C.has_trait(TRAIT_HUSK)) + if(HAS_TRAIT(C, TRAIT_HUSK)) real_name = "Unknown" hair_style = "Bald" facial_hair_style = "Shaved" diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index 9cc56a6ca8..a2e8017956 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -178,6 +178,7 @@ L.update_limb(fixed_icon, src) if(robotic) L.change_bodypart_status(BODYPART_ROBOTIC) + L.body_markings = null . = L /mob/living/carbon/monkey/newBodyPart(zone, robotic, fixed_icon) diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm index 7bc7553023..9967eba663 100644 --- a/code/modules/surgery/lipoplasty.dm +++ b/code/modules/surgery/lipoplasty.dm @@ -4,7 +4,7 @@ possible_locs = list(BODY_ZONE_CHEST) /datum/surgery/lipoplasty/can_start(mob/user, mob/living/carbon/target) - if(target.has_trait(TRAIT_FAT)) + if(HAS_TRAIT(target, TRAIT_FAT)) return 1 return 0 diff --git a/code/modules/surgery/nutcracker.dm b/code/modules/surgery/nutcracker.dm new file mode 100644 index 0000000000..9722d8af87 --- /dev/null +++ b/code/modules/surgery/nutcracker.dm @@ -0,0 +1,69 @@ +/obj/item/nutcracker + name = "nutcracker" + desc = "It seems quite oversized. You could probably even crush a watermelon with it." + icon = 'icons/obj/surgery.dmi' + icon_state = "nutcracker" + force = 10 + flags_1 = CONDUCT_1 + w_class = WEIGHT_CLASS_NORMAL + attack_verb = list("smashed", "beaten", "crushed") + +/obj/item/nutcracker/proc/gib_head(mob/living/carbon/M) + var/obj/item/bodypart/head = M.get_bodypart("head") + if(!head) + return + + var/turf/T = get_turf(M) + var/list/organs = M.getorganszone("head") + M.getorganszone("eyes") + M.getorganszone("mouth") + for(var/internal_organ in organs) + var/obj/item/organ/I = internal_organ + I.Remove(M) + I.forceMove(T) + head.drop_limb() + qdel(head) + new M.gib_type(T,1,M.get_static_viruses()) + M.add_splatter_floor(T) + playsound(M, 'sound/effects/splat.ogg', 50, 1) + +//It's a bit of a clusterfuck, but if someone wants, it can be easily repurposed to work on other limbs too. +/obj/item/nutcracker/attack(mob/living/carbon/M, mob/living/carbon/user) + . = ..() + var/target_zone = "head" + var/obj/item/bodypart/target_limb = M.get_bodypart(target_zone) + + if(!get_turf(M)) + return + if(!istype(M)) + return + if(M == user) //just use the suicide verb instead + return + if(user.zone_selected != "head") + return + if(!target_limb) + to_chat(user, "[M] has no [parse_zone(target_zone)]!") + return + if(!get_location_accessible(M, target_zone)) + to_chat(user, "Expose [M]\s head before trying to crush it!") + return + + M.visible_message("[user] is trying to crush [M]\s head with \the [src]!") + + var/crush_time = max(0, 400 - target_limb.brute_dam*2) + if(do_mob(user, M, crush_time)) + if(get_location_accessible(M, target_zone)) //Yes, two checks, before and after the timer. What if someone puts a helmet on the guy while you're crushing his head? + if(target_limb)//If he still has the head. In case you queue up a lot of these up at once or the guy loses the head while you're removing it. + M.visible_message("[M]\s head cracks like a watermelon, spilling everything inside, as it becomes an unrecognizable mess!") + gib_head(M) + else + to_chat(user, "Expose [M]\s head before trying to crush it!") + + +/obj/item/nutcracker/suicide_act(mob/living/carbon/user) + var/obj/item/bodypart/target_limb = user.get_bodypart("head") + if(target_limb) //I mean like... for example lings can be still alive without heads. + user.visible_message("[user] is crushing [user.p_their()] own head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + if(do_after(user, 30)) + gib_head(user) + else + return + return (BRUTELOSS) diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm index c54d3bb532..b0a2f38c46 100644 --- a/code/modules/surgery/organs/ears.dm +++ b/code/modules/surgery/organs/ears.dm @@ -25,7 +25,7 @@ return var/mob/living/carbon/C = owner // genetic deafness prevents the body from using the ears, even if healthy - if(C.has_trait(TRAIT_DEAF)) + if(HAS_TRAIT(C, TRAIT_DEAF)) deaf = max(deaf, 1) else if(ear_damage < UNHEALING_EAR_DAMAGE) // if higher than UNHEALING_EAR_DAMAGE, no natural healing occurs. ear_damage = max(ear_damage - 0.05, 0) @@ -37,7 +37,7 @@ var/mob/living/carbon/C = owner - if(iscarbon(owner) && C.has_trait(TRAIT_DEAF)) + if(iscarbon(owner) && HAS_TRAIT(C, TRAIT_DEAF)) deaf = 1 /obj/item/organ/ears/proc/adjustEarDamage(ddmg, ddeaf) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 9f42cf0baa..98abb2528a 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -26,7 +26,7 @@ HMN.regenerate_icons() else eye_color = HMN.eye_color - if(HMN.has_trait(TRAIT_NIGHT_VISION) && !lighting_alpha) + if(HAS_TRAIT(HMN, TRAIT_NIGHT_VISION) && !lighting_alpha) lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT see_in_dark = 8 M.update_tint() diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 52904b8af1..5852cba0c9 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -113,6 +113,10 @@ if(owner) to_chat(owner, "Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!") +/obj/item/organ/heart/cursed/Remove(mob/living/carbon/M, special = 0) + ..() + M.remove_client_colour(/datum/client_colour/cursed_heart_blood) + /datum/action/item_action/organ_action/cursed_heart name = "Pump your blood" diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index ee767566e6..f666fc209b 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -25,7 +25,7 @@ //slowly heal liver damage damage = max(0, damage - 0.1) - if(filterToxins && !owner.has_trait(TRAIT_TOXINLOVER)) + if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER)) //handle liver toxin filtration for(var/I in C.reagents.reagent_list) var/datum/reagent/pickedreagent = I diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 1e22796b1b..64be29c339 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -58,7 +58,7 @@ /obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H) if((H.status_flags & GODMODE)) return - if(H.has_trait(TRAIT_NOBREATH)) + if(HAS_TRAIT(H, TRAIT_NOBREATH)) return if(!breath || (breath.total_moles() == 0)) @@ -66,7 +66,7 @@ return if(H.health >= H.crit_threshold) H.adjustOxyLoss(HUMAN_MAX_OXYLOSS) - else if(!H.has_trait(TRAIT_NOCRITDAMAGE)) + else if(!HAS_TRAIT(H, TRAIT_NOCRITDAMAGE)) H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS) H.failed_last_breath = TRUE @@ -84,13 +84,11 @@ var/list/breath_gases = breath.gases - breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitrogen, /datum/gas/tritium, /datum/gas/nitryl, /datum/gas/pluoxium, /datum/gas/stimulum) - //Partial pressures in our breath - var/O2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/oxygen][MOLES])+(8*breath.get_breath_partial_pressure(breath_gases[/datum/gas/pluoxium][MOLES])) - var/N2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrogen][MOLES]) - var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/plasma][MOLES]) - var/CO2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/carbon_dioxide][MOLES]) + var/O2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/oxygen])+(8*breath.get_breath_partial_pressure(breath_gases[/datum/gas/pluoxium])) + var/N2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrogen]) + var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/plasma]) + var/CO2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/carbon_dioxide]) //-- OXY --// @@ -98,7 +96,7 @@ //Too much oxygen! //Yes, some species may not like it. if(safe_oxygen_max) if((O2_pp > safe_oxygen_max) && safe_oxygen_max == 0) //I guess plasma men technically need to have a check. - var/ratio = (breath_gases[/datum/gas/oxygen][MOLES]/safe_oxygen_max) * 10 + var/ratio = (breath_gases[/datum/gas/oxygen]/safe_oxygen_max) * 10 H.apply_damage_type(CLAMP(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type) H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) @@ -121,18 +119,18 @@ //Too little oxygen! if(safe_oxygen_min) if(O2_pp < safe_oxygen_min) - gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath_gases[/datum/gas/oxygen][MOLES]) + gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath_gases[/datum/gas/oxygen]) H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) else H.failed_last_breath = FALSE if(H.health >= H.crit_threshold) H.adjustOxyLoss(-5) - gas_breathed = breath_gases[/datum/gas/oxygen][MOLES] + gas_breathed = breath_gases[/datum/gas/oxygen] H.clear_alert("not_enough_oxy") //Exhale - breath_gases[/datum/gas/oxygen][MOLES] -= gas_breathed - breath_gases[/datum/gas/carbon_dioxide][MOLES] += gas_breathed + breath_gases[/datum/gas/oxygen] -= gas_breathed + breath_gases[/datum/gas/carbon_dioxide] += gas_breathed gas_breathed = 0 //-- Nitrogen --// @@ -140,7 +138,7 @@ //Too much nitrogen! if(safe_nitro_max) if(N2_pp > safe_nitro_max) - var/ratio = (breath_gases[/datum/gas/nitrogen][MOLES]/safe_nitro_max) * 10 + var/ratio = (breath_gases[/datum/gas/nitrogen]/safe_nitro_max) * 10 H.apply_damage_type(CLAMP(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type) H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro) H.losebreath += 2 @@ -150,18 +148,18 @@ //Too little nitrogen! if(safe_nitro_min) if(N2_pp < safe_nitro_min) - gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath_gases[/datum/gas/nitrogen][MOLES]) + gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath_gases[/datum/gas/nitrogen]) H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro) else H.failed_last_breath = FALSE if(H.health >= H.crit_threshold) H.adjustOxyLoss(-5) - gas_breathed = breath_gases[/datum/gas/nitrogen][MOLES] + gas_breathed = breath_gases[/datum/gas/nitrogen] H.clear_alert("nitro") //Exhale - breath_gases[/datum/gas/nitrogen][MOLES] -= gas_breathed - breath_gases[/datum/gas/carbon_dioxide][MOLES] += gas_breathed + breath_gases[/datum/gas/nitrogen] -= gas_breathed + breath_gases[/datum/gas/carbon_dioxide] += gas_breathed gas_breathed = 0 //-- CO2 --// @@ -187,18 +185,18 @@ //Too little CO2! if(safe_co2_min) if(CO2_pp < safe_co2_min) - gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath_gases[/datum/gas/carbon_dioxide][MOLES]) + gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath_gases[/datum/gas/carbon_dioxide]) H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) else H.failed_last_breath = FALSE if(H.health >= H.crit_threshold) H.adjustOxyLoss(-5) - gas_breathed = breath_gases[/datum/gas/carbon_dioxide][MOLES] + gas_breathed = breath_gases[/datum/gas/carbon_dioxide] H.clear_alert("not_enough_co2") //Exhale - breath_gases[/datum/gas/carbon_dioxide][MOLES] -= gas_breathed - breath_gases[/datum/gas/oxygen][MOLES] += gas_breathed + breath_gases[/datum/gas/carbon_dioxide] -= gas_breathed + breath_gases[/datum/gas/oxygen] += gas_breathed gas_breathed = 0 @@ -207,7 +205,7 @@ //Too much toxins! if(safe_toxins_max) if(Toxins_pp > safe_toxins_max) - var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_toxins_max) * 10 + var/ratio = (breath_gases[/datum/gas/plasma]/safe_toxins_max) * 10 H.apply_damage_type(CLAMP(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type) H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) else @@ -217,18 +215,18 @@ //Too little toxins! if(safe_toxins_min) if(Toxins_pp < safe_toxins_min) - gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath_gases[/datum/gas/plasma][MOLES]) + gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath_gases[/datum/gas/plasma]) H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) else H.failed_last_breath = FALSE if(H.health >= H.crit_threshold) H.adjustOxyLoss(-5) - gas_breathed = breath_gases[/datum/gas/plasma][MOLES] + gas_breathed = breath_gases[/datum/gas/plasma] H.clear_alert("not_enough_tox") //Exhale - breath_gases[/datum/gas/plasma][MOLES] -= gas_breathed - breath_gases[/datum/gas/carbon_dioxide][MOLES] += gas_breathed + breath_gases[/datum/gas/plasma] -= gas_breathed + breath_gases[/datum/gas/carbon_dioxide] += gas_breathed gas_breathed = 0 @@ -238,7 +236,7 @@ // N2O - var/SA_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrous_oxide][MOLES]) + var/SA_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrous_oxide]) if(SA_pp > SA_para_min) // Enough to make us stunned for a bit H.Unconscious(60) // 60 gives them one second to wake up and run away a bit! if(SA_pp > SA_sleep_min) // Enough to make us sleep as well @@ -249,7 +247,7 @@ // BZ - var/bz_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/bz][MOLES]) + var/bz_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/bz]) if(bz_pp > BZ_trip_balls_min) H.hallucination += 10 H.reagents.add_reagent("bz_metabolites",5) @@ -262,14 +260,14 @@ // Tritium - var/trit_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/tritium][MOLES]) + var/trit_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/tritium]) if (trit_pp > 50) H.radiation += trit_pp/2 //If you're breathing in half an atmosphere of radioactive gas, you fucked up. else H.radiation += trit_pp/10 // Nitryl - var/nitryl_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitryl][MOLES]) + var/nitryl_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitryl]) if (prob(nitryl_pp)) to_chat(H, "Your mouth feels like it's burning!") if (nitryl_pp >40) @@ -280,22 +278,22 @@ H.silent = max(H.silent, 3) else H.adjustFireLoss(nitryl_pp/4) - gas_breathed = breath_gases[/datum/gas/nitryl][MOLES] + gas_breathed = breath_gases[/datum/gas/nitryl] if (gas_breathed > gas_stimulation_min) H.reagents.add_reagent("no2",1) - breath_gases[/datum/gas/nitryl][MOLES]-=gas_breathed + breath_gases[/datum/gas/nitryl]-=gas_breathed // Stimulum - gas_breathed = breath_gases[/datum/gas/stimulum][MOLES] + gas_breathed = breath_gases[/datum/gas/stimulum] if (gas_breathed > gas_stimulation_min) var/existing = H.reagents.get_reagent_amount("stimulum") H.reagents.add_reagent("stimulum",max(0, 1 - existing)) - breath_gases[/datum/gas/stimulum][MOLES]-=gas_breathed + breath_gases[/datum/gas/stimulum]-=gas_breathed // Miasma if (breath_gases[/datum/gas/miasma]) - var/miasma_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/miasma][MOLES]) + var/miasma_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/miasma]) //Miasma sickness if(prob(0.5 * miasma_pp)) @@ -334,14 +332,14 @@ // Then again, this is a purely hypothetical scenario and hardly reachable owner.adjust_disgust(0.1 * miasma_pp) - breath_gases[/datum/gas/miasma][MOLES]-=gas_breathed + breath_gases[/datum/gas/miasma]-=gas_breathed // Clear out moods when no miasma at all else SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell") handle_breath_temperature(breath, H) - breath.garbage_collect() + GAS_GARBAGE_COLLECT(breath.gases) return TRUE @@ -365,7 +363,7 @@ /obj/item/organ/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures var/breath_temperature = breath.temperature - if(!H.has_trait(TRAIT_RESISTCOLD)) // COLD DAMAGE + if(!HAS_TRAIT(H, TRAIT_RESISTCOLD)) // COLD DAMAGE var/cold_modifier = H.dna.species.coldmod if(breath_temperature < cold_level_3_threshold) H.apply_damage_type(cold_level_3_damage*cold_modifier, cold_damage_type) @@ -377,7 +375,7 @@ if(prob(20)) to_chat(H, "You feel [cold_message] in your [name]!") - if(!H.has_trait(TRAIT_RESISTHEAT)) // HEAT DAMAGE + if(!HAS_TRAIT(H, TRAIT_RESISTHEAT)) // HEAT DAMAGE var/heat_modifier = H.dna.species.heatmod if(breath_temperature > heat_level_1_threshold && breath_temperature < heat_level_2_threshold) H.apply_damage_type(heat_level_1_damage*heat_modifier, heat_damage_type) diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 1408bff60c..b16967b6b0 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -110,7 +110,7 @@ var/breathes = TRUE var/blooded = TRUE if(dna && dna.species) - if(has_trait(TRAIT_NOBREATH, SPECIES_TRAIT)) + if(HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT)) breathes = FALSE if(NOBLOOD in dna.species.species_traits) blooded = FALSE diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index d5b2d16e67..0e672de225 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -17,6 +17,7 @@ /datum/language/beachbum, /datum/language/ratvar, /datum/language/aphasia, + /datum/language/slime, )) /obj/item/organ/tongue/Initialize(mapload) diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm index 3a3dd6a1dd..54482ade73 100644 --- a/code/modules/surgery/plastic_surgery.dm +++ b/code/modules/surgery/plastic_surgery.dm @@ -13,8 +13,8 @@ user.visible_message("[user] begins to alter [target]'s appearance.", "You begin to alter [target]'s appearance...") /datum/surgery_step/reshape_face/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - if(target.has_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)) - target.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) + if(HAS_TRAIT_FROM(target, TRAIT_DISFIGURED, TRAIT_GENERIC)) + REMOVE_TRAIT(target, TRAIT_DISFIGURED, TRAIT_GENERIC) user.visible_message("[user] successfully restores [target]'s appearance!", "You successfully restore [target]'s appearance.") else var/list/names = list() diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index af2c625670..f2f919a717 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -303,6 +303,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/melee/powerfist cost = 8 +/datum/uplink_item/badass/combatglovesplus + name = "Combat Gloves Plus" + desc = "A pair of gloves that are fireproof and shock resistant, however unlike the regular Combat Gloves this one uses nanotechnology \ + to learn the abilities of krav maga to the wearer." + item = /obj/item/clothing/gloves/krav_maga/combatglovesplus + cost = 5 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + /datum/uplink_item/dangerous/emp name = "EMP Grenades and Implanter Kit" desc = "A box that contains two EMP grenades and an EMP implant. Useful to disrupt communication, \ @@ -388,7 +396,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) autoinjectors for rapid application on up to two targets each, a syringe, and a bottle containing \ the BVAK solution." item = /obj/item/storage/box/syndie_kit/tuberculosisgrenade - cost = 12 + cost = 8 surplus = 35 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) restricted = TRUE @@ -510,7 +518,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) name = "12g Scatter Laser shot Slugs" desc = "An alternative 8-round Scatter Laser Shot magazine for use in the Bulldog shotgun." item = /obj/item/ammo_box/magazine/m12g/scatter - cost = 5 // most armor has less laser protection then bullet + cost = 4 // most armor has less laser protection then bullet /datum/uplink_item/ammo/shotgun/bag name = "12g Ammo Duffel Bag" @@ -768,7 +776,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) The concussive effect from the explosion will knock the recipient out for a short period, and deafen \ them for longer. Beware, it has a chance to detonate your PDA." item = /obj/item/cartridge/virus/syndicate - cost = 6 + cost = 5 restricted = TRUE /datum/uplink_item/stealthy_weapons/suppressor @@ -776,7 +784,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) desc = "Fitted for use on any small caliber weapon with a threaded barrel, this suppressor will silence the \ shots of the weapon for increased stealth and superior ambushing capability." item = /obj/item/suppressor - cost = 3 + cost = 1 surplus = 10 exclude_modes = list(/datum/game_mode/nuclear/clown_ops) @@ -837,6 +845,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 0 include_modes = list(/datum/game_mode/nuclear/clown_ops) +datum/uplink_item/stealthy_tools/taeclowndo_shoes + name = "Tae-clown-do Shoes" + desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." + cost = 12 + item = /obj/item/clothing/shoes/clown_shoes/taeclowndo + include_modes = list(/datum/game_mode/nuclear/clown_ops) + /datum/uplink_item/stealthy_tools/frame name = "F.R.A.M.E. PDA Cartridge" desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \ @@ -844,7 +859,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) You will receive the unlock code upon activating the virus, and the new uplink may be charged with \ telecrystals normally." item = /obj/item/cartridge/virus/frame - cost = 4 + cost = 2 restricted = TRUE /datum/uplink_item/stealthy_tools/agent_card @@ -894,7 +909,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) desc = "Screwed up and have security on your tail? This handy syringe will give you a completely new identity \ and appearance." item = /obj/item/reagent_containers/syringe/mulligan - cost = 4 + cost = 3 surplus = 30 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) @@ -988,12 +1003,18 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/storage/backpack/duffelbag/syndie/surgery cost = 3 +/datum/uplink_item/device_tools/nutcracker + name = "Nutcracker" + desc = "An oversized version of what you'd initially expect here. Big enough to crush skulls." + item = /obj/item/nutcracker + cost = 1 + /datum/uplink_item/device_tools/surgerybag_adv - name = "Syndicate Surgery Duffel Bag" + name = "Advanced Syndicate Surgery Duffel Bag" desc = "The Syndicate surgery duffel bag is a toolkit containing all newest surgery tools, surgical drapes, \ a Syndicate brand MMI, a straitjacket, a muzzle, and a full Syndicate Combat Medic Kit." item = /obj/item/storage/backpack/duffelbag/syndie/surgery_adv - cost = 15 //Mite be to cheap + cost = 10 /datum/uplink_item/device_tools/military_belt name = "Chest Rig" @@ -1035,7 +1056,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) such as AI units and cyborgs, over their private binary channel. Caution should \ be taken while doing this, as unless they are allied with you, they are programmed to report such intrusions." item = /obj/item/encryptionkey/binary - cost = 5 + cost = 2 surplus = 75 restricted = TRUE @@ -1202,7 +1223,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) name = "Syndicate Sentience Potion" item = /obj/item/slimepotion/slime/sentience/nuclear desc = "A potion recovered at great risk by undercover syndicate operatives and then subsequently modified with syndicate technology. Using it will make any animal sentient, and bound to serve you, as well as implanting an internal radio for communication and an internal ID card for opening doors." - cost = 4 + cost = 2 include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) restricted = TRUE @@ -1376,6 +1397,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/dnainjector/clumsymut restricted_roles = list("Clown") +/datum/uplink_item/role_restricted/taeclowndo_shoes + name = "Tae-clown-do Shoes" + desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." + cost = 14 + item = /obj/item/clothing/shoes/clown_shoes/taeclowndo + restricted_roles = list("Clown") + /datum/uplink_item/role_restricted/mimery name = "Guide to Advanced Mimery Series" desc = "The classical two part series on how to further hone your mime skills. Upon studying the series, the user should be able to make 3x1 invisible walls, and shoot bullets out of their fingers. Obviously only works for Mimes." @@ -1438,13 +1466,20 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 20 restricted_roles = list("Assistant") +/datum/uplink_item/role_restricted/goldenbox + name = "Gold Toolbox" + desc = "A gold planted plastitanium toolbox loaded with tools. Comes with a set of AI detection multi-tool and a pare of combat gloves." + item = /obj/item/storage/toolbox/gold_real + cost = 3 // Has synda tools + gloves + a robust weapon + restricted_roles = list("Assistant", "Curator") //Curator do to being made of gold - It fits the theme + /datum/uplink_item/role_restricted/brainwash_disk name = "Brainwashing Surgery Program" desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \ Insert into an Operating Console to enable the procedure." item = /obj/item/disk/surgery/brainwashing restricted_roles = list("Medical Doctor") - cost = 5 + cost = 3 /datum/uplink_item/role_restricted/haunted_magic_eightball name = "Haunted Magic Eightball" @@ -1504,12 +1539,12 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 15 restricted_roles = list("Clown") -/datum/uplink_item/device_tools/honkpins //Idealy so they can place it into their own guns without needing cargo +/datum/uplink_item/device_tools/ultrahonkpins //Idealy so they can place it into their own guns without needing cargo name = "Hilarious firing pin" desc = "A single firing pin made for Clown agents, this firing pin makes any gun honk when fired if not a true clown! \ This firing pin also helps you fire the gun correctly. May the HonkMother HONK you agent." - item = /obj/item/firing_pin/clown - cost = 1 + item = /obj/item/firing_pin/clown/ultra + cost = 2 restricted_roles = list("Clown") /* diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 80e422c6a0..c31c9a12a2 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -6,114 +6,114 @@ icon_deny = "clothes-deny" product_slogans = "Dress for success!;Prepare to look swagalicious!;Look at all this free swag!;Why leave style up to fate? Use the ClothesMate!" vend_reply = "Thank you for using the ClothesMate!" - products = list(/obj/item/clothing/head/that = 2, - /obj/item/clothing/head/fedora = 1, - /obj/item/clothing/glasses/monocle = 1, - /obj/item/clothing/suit/jacket = 2, - /obj/item/clothing/suit/jacket/puffer/vest = 2, - /obj/item/clothing/suit/jacket/puffer = 2, - /obj/item/clothing/under/suit_jacket/navy = 1, - /obj/item/clothing/under/suit_jacket/really_black = 1, - /obj/item/clothing/under/suit_jacket/burgundy = 1, - /obj/item/clothing/under/suit_jacket/charcoal = 1, - /obj/item/clothing/under/suit_jacket/white = 1, - /obj/item/clothing/under/kilt = 1, - /obj/item/clothing/under/overalls = 1, - /obj/item/clothing/under/sl_suit = 1, - /obj/item/clothing/under/pants/jeans = 3, - /obj/item/clothing/under/pants/classicjeans = 2, - /obj/item/clothing/under/pants/camo = 1, - /obj/item/clothing/under/pants/blackjeans = 2, - /obj/item/clothing/under/pants/khaki = 2, - /obj/item/clothing/under/pants/white = 2, - /obj/item/clothing/under/pants/red = 1, - /obj/item/clothing/under/pants/black = 2, - /obj/item/clothing/under/pants/tan = 2, - /obj/item/clothing/under/pants/track = 1, - /obj/item/clothing/suit/jacket/miljacket = 1, - /obj/item/clothing/neck/tie/blue = 1, - /obj/item/clothing/neck/tie/red = 1, - /obj/item/clothing/neck/tie/black = 1, - /obj/item/clothing/neck/tie/horrible = 1, - /obj/item/clothing/neck/scarf/pink = 1, - /obj/item/clothing/neck/scarf/red = 1, - /obj/item/clothing/neck/scarf/green = 1, - /obj/item/clothing/neck/scarf/darkblue = 1, - /obj/item/clothing/neck/scarf/purple = 1, - /obj/item/clothing/neck/scarf/yellow = 1, - /obj/item/clothing/neck/scarf/orange = 1, - /obj/item/clothing/neck/scarf/cyan = 1, - /obj/item/clothing/neck/scarf = 1, - /obj/item/clothing/neck/scarf/black = 1, - /obj/item/clothing/neck/scarf/zebra = 1, - /obj/item/clothing/neck/scarf/christmas = 1, - /obj/item/clothing/neck/stripedredscarf = 1, - /obj/item/clothing/neck/stripedbluescarf = 1, - /obj/item/clothing/neck/stripedgreenscarf = 1, - /obj/item/clothing/accessory/waistcoat = 1, - /obj/item/clothing/under/skirt/black = 1, - /obj/item/clothing/under/skirt/blue = 1, - /obj/item/clothing/under/skirt/red = 1, - /obj/item/clothing/under/skirt/purple = 1, - /obj/item/clothing/under/sundress = 2, - /obj/item/clothing/under/stripeddress = 1, - /obj/item/clothing/under/sailordress = 1, - /obj/item/clothing/under/redeveninggown = 1, - /obj/item/clothing/under/blacktango = 1, - /obj/item/clothing/under/plaid_skirt = 1, - /obj/item/clothing/under/plaid_skirt/blue = 1, - /obj/item/clothing/under/plaid_skirt/purple = 1, - /obj/item/clothing/under/plaid_skirt/green = 1, - /obj/item/clothing/glasses/regular = 1, - /obj/item/clothing/glasses/regular/jamjar = 1, - /obj/item/clothing/head/sombrero = 1, - /obj/item/clothing/suit/poncho = 1, - /obj/item/clothing/suit/ianshirt = 1, - /obj/item/clothing/shoes/laceup = 2, - /obj/item/clothing/shoes/sneakers/black = 4, - /obj/item/clothing/shoes/sandal = 1, - /obj/item/clothing/gloves/fingerless = 2, - /obj/item/clothing/glasses/orange = 1, - /obj/item/clothing/glasses/red = 1, - /obj/item/storage/belt/fannypack = 1, - /obj/item/storage/belt/fannypack/blue = 1, - /obj/item/storage/belt/fannypack/red = 1, - /obj/item/clothing/suit/jacket/letterman = 2, - /obj/item/clothing/head/beanie = 1, - /obj/item/clothing/head/beanie/black = 1, - /obj/item/clothing/head/beanie/red = 1, - /obj/item/clothing/head/beanie/green = 1, - /obj/item/clothing/head/beanie/darkblue = 1, - /obj/item/clothing/head/beanie/purple = 1, - /obj/item/clothing/head/beanie/yellow = 1, - /obj/item/clothing/head/beanie/orange = 1, - /obj/item/clothing/head/beanie/cyan = 1, - /obj/item/clothing/head/beanie/christmas = 1, - /obj/item/clothing/head/beanie/striped = 1, - /obj/item/clothing/head/beanie/stripedred = 1, - /obj/item/clothing/head/beanie/stripedblue = 1, - /obj/item/clothing/head/beanie/stripedgreen = 1, - /obj/item/clothing/suit/jacket/letterman_red = 1, + products = list(/obj/item/clothing/head/that = 4, + /obj/item/clothing/head/fedora = 3, + /obj/item/clothing/glasses/monocle = 3, + /obj/item/clothing/suit/jacket = 4, + /obj/item/clothing/suit/jacket/puffer/vest = 4, + /obj/item/clothing/suit/jacket/puffer = 4, + /obj/item/clothing/under/suit_jacket/navy = 3, + /obj/item/clothing/under/suit_jacket/really_black = 3, + /obj/item/clothing/under/suit_jacket/burgundy = 3, + /obj/item/clothing/under/suit_jacket/charcoal = 3, + /obj/item/clothing/under/suit_jacket/white = 3, + /obj/item/clothing/under/kilt = 3, + /obj/item/clothing/under/overalls = 3, + /obj/item/clothing/under/sl_suit = 3, + /obj/item/clothing/under/pants/jeans = 5, + /obj/item/clothing/under/pants/classicjeans = 5, + /obj/item/clothing/under/pants/camo = 3, + /obj/item/clothing/under/pants/blackjeans = 5, + /obj/item/clothing/under/pants/khaki = 5, + /obj/item/clothing/under/pants/white = 5, + /obj/item/clothing/under/pants/red = 3, + /obj/item/clothing/under/pants/black = 4, + /obj/item/clothing/under/pants/tan = 4, + /obj/item/clothing/under/pants/track = 3, + /obj/item/clothing/suit/jacket/miljacket = 5, + /obj/item/clothing/neck/tie/blue = 3, + /obj/item/clothing/neck/tie/red = 3, + /obj/item/clothing/neck/tie/black = 3, + /obj/item/clothing/neck/tie/horrible = 5, + /obj/item/clothing/neck/scarf/pink = 3, + /obj/item/clothing/neck/scarf/red = 3, + /obj/item/clothing/neck/scarf/green = 3, + /obj/item/clothing/neck/scarf/darkblue = 3, + /obj/item/clothing/neck/scarf/purple = 3, + /obj/item/clothing/neck/scarf/yellow = 3, + /obj/item/clothing/neck/scarf/orange = 3, + /obj/item/clothing/neck/scarf/cyan = 3, + /obj/item/clothing/neck/scarf = 3, + /obj/item/clothing/neck/scarf/black = 3, + /obj/item/clothing/neck/scarf/zebra = 3, + /obj/item/clothing/neck/scarf/christmas = 3, + /obj/item/clothing/neck/stripedredscarf = 3, + /obj/item/clothing/neck/stripedbluescarf = 3, + /obj/item/clothing/neck/stripedgreenscarf = 3, + /obj/item/clothing/accessory/waistcoat = 2, + /obj/item/clothing/under/skirt/black = 3, + /obj/item/clothing/under/skirt/blue = 3, + /obj/item/clothing/under/skirt/red = 3, + /obj/item/clothing/under/skirt/purple = 3, + /obj/item/clothing/under/sundress = 4, + /obj/item/clothing/under/stripeddress = 3, + /obj/item/clothing/under/sailordress = 3, + /obj/item/clothing/under/redeveninggown = 3, + /obj/item/clothing/under/blacktango = 3, + /obj/item/clothing/under/plaid_skirt = 3, + /obj/item/clothing/under/plaid_skirt/blue = 3, + /obj/item/clothing/under/plaid_skirt/purple = 3, + /obj/item/clothing/under/plaid_skirt/green = 3, + /obj/item/clothing/glasses/regular = 2, + /obj/item/clothing/glasses/regular/jamjar = 2, + /obj/item/clothing/head/sombrero = 3, + /obj/item/clothing/suit/poncho = 3, + /obj/item/clothing/suit/ianshirt = 3, + /obj/item/clothing/shoes/laceup = 5, + /obj/item/clothing/shoes/sneakers/black = 6, + /obj/item/clothing/shoes/sandal = 3, + /obj/item/clothing/gloves/fingerless = 3, + /obj/item/clothing/glasses/orange = 5, + /obj/item/clothing/glasses/red = 5, + /obj/item/storage/belt/fannypack = 3, + /obj/item/storage/belt/fannypack/blue = 3, + /obj/item/storage/belt/fannypack/red = 3, + /obj/item/clothing/suit/jacket/letterman = 5, + /obj/item/clothing/head/beanie = 3, + /obj/item/clothing/head/beanie/black = 3, + /obj/item/clothing/head/beanie/red = 3, + /obj/item/clothing/head/beanie/green = 3, + /obj/item/clothing/head/beanie/darkblue = 3, + /obj/item/clothing/head/beanie/purple = 3, + /obj/item/clothing/head/beanie/yellow = 3, + /obj/item/clothing/head/beanie/orange = 3, + /obj/item/clothing/head/beanie/cyan = 3, + /obj/item/clothing/head/beanie/christmas = 3, + /obj/item/clothing/head/beanie/striped = 3, + /obj/item/clothing/head/beanie/stripedred = 3, + /obj/item/clothing/head/beanie/stripedblue = 3, + /obj/item/clothing/head/beanie/stripedgreen = 3, + /obj/item/clothing/suit/jacket/letterman_red = 3, /obj/item/clothing/ears/headphones = 10, - /obj/item/clothing/suit/apron/purple_bartender = 2, - /obj/item/clothing/under/rank/bartender/purple = 2) - contraband = list(/obj/item/clothing/under/syndicate/tacticool = 1, - /obj/item/clothing/mask/balaclava = 1, - /obj/item/clothing/head/ushanka = 1, - /obj/item/clothing/under/soviet = 1, - /obj/item/storage/belt/fannypack/black = 2, - /obj/item/clothing/suit/jacket/letterman_syndie = 1, - /obj/item/clothing/under/jabroni = 1, - /obj/item/clothing/suit/vapeshirt = 1, - /obj/item/clothing/under/geisha = 1) - premium = list(/obj/item/clothing/under/suit_jacket/checkered = 1, - /obj/item/clothing/head/mailman = 1, - /obj/item/clothing/under/rank/mailman = 1, - /obj/item/clothing/suit/jacket/leather = 1, - /obj/item/clothing/suit/jacket/leather/overcoat = 1, - /obj/item/clothing/under/pants/mustangjeans = 1, - /obj/item/clothing/neck/necklace/dope = 3, - /obj/item/clothing/suit/jacket/letterman_nanotrasen = 1) + /obj/item/clothing/suit/apron/purple_bartender = 4, + /obj/item/clothing/under/rank/bartender/purple = 4) + contraband = list(/obj/item/clothing/under/syndicate/tacticool = 3, + /obj/item/clothing/mask/balaclava = 3, + /obj/item/clothing/head/ushanka = 3, + /obj/item/clothing/under/soviet = 3, + /obj/item/storage/belt/fannypack/black = 3, + /obj/item/clothing/suit/jacket/letterman_syndie = 5, + /obj/item/clothing/under/jabroni = 2, + /obj/item/clothing/suit/vapeshirt = 2, + /obj/item/clothing/under/geisha = 4) + premium = list(/obj/item/clothing/under/suit_jacket/checkered = 4, + /obj/item/clothing/head/mailman = 2, + /obj/item/clothing/under/rank/mailman = 2, + /obj/item/clothing/suit/jacket/leather = 4, + /obj/item/clothing/suit/jacket/leather/overcoat = 4, + /obj/item/clothing/under/pants/mustangjeans = 3, + /obj/item/clothing/neck/necklace/dope = 5, + /obj/item/clothing/suit/jacket/letterman_nanotrasen = 5) refill_canister = /obj/item/vending_refill/clothing /obj/item/vending_refill/clothing diff --git a/code/modules/vending/drinnerware.dm b/code/modules/vending/drinnerware.dm index 151da9bc2f..33e839c039 100644 --- a/code/modules/vending/drinnerware.dm +++ b/code/modules/vending/drinnerware.dm @@ -13,7 +13,7 @@ /obj/item/reagent_containers/food/condiment/pack/hotsauce = 5, /obj/item/reagent_containers/food/condiment/saltshaker = 5, /obj/item/reagent_containers/food/condiment/peppermill = 5, - /obj/item/reagent_containers/glass/bowl = 20) + /obj/item/reagent_containers/glass/bowl = 30) contraband = list(/obj/item/kitchen/rollingpin = 2, /obj/item/kitchen/knife/butcher = 2) armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index 6db8d4a8b3..9481d4d086 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -7,21 +7,21 @@ icon_state = "secdrobe" product_ads = "Beat perps in style!;It's red so you can't see the blood!;You have the right to be fashionable!;Now you can be the fashion police you always wanted to be!" vend_reply = "Thank you for using the SecDrobe!" - products = list(/obj/item/clothing/suit/hooded/wintercoat/security = 1, - /obj/item/storage/backpack/security = 1, - /obj/item/storage/backpack/satchel/sec = 1, - /obj/item/storage/backpack/duffelbag/sec = 2, - /obj/item/clothing/under/rank/security = 3, - /obj/item/clothing/shoes/jackboots = 3, - /obj/item/clothing/head/beret/sec = 3, - /obj/item/clothing/head/soft/sec = 3, - /obj/item/clothing/mask/bandana/red = 3, - /obj/item/clothing/under/rank/security/skirt = 3, - /obj/item/clothing/under/rank/security/grey = 3, - /obj/item/clothing/under/pants/khaki = 3) - premium = list(/obj/item/clothing/under/rank/security/navyblue = 3, - /obj/item/clothing/suit/security/officer = 3, - /obj/item/clothing/head/beret/sec/navyofficer = 3) + products = list(/obj/item/clothing/suit/hooded/wintercoat/security = 2, + /obj/item/storage/backpack/security = 2, + /obj/item/storage/backpack/satchel/sec = 2, + /obj/item/storage/backpack/duffelbag/sec = 3, + /obj/item/clothing/under/rank/security = 5, + /obj/item/clothing/shoes/jackboots = 5, + /obj/item/clothing/head/beret/sec =5, + /obj/item/clothing/head/soft/sec = 5, + /obj/item/clothing/mask/bandana/red = 5, + /obj/item/clothing/under/rank/security/skirt = 5, + /obj/item/clothing/under/rank/security/grey = 5, + /obj/item/clothing/under/pants/khaki = 5) + premium = list(/obj/item/clothing/under/rank/security/navyblue = 5, + /obj/item/clothing/suit/security/officer = 5, + /obj/item/clothing/head/beret/sec/navyofficer = 5) refill_canister = /obj/item/vending_refill/wardrobe/sec_wardrobe /obj/item/vending_refill/wardrobe/sec_wardrobe @@ -33,23 +33,23 @@ icon_state = "medidrobe" product_ads = "Make those blood stains look fashionable!!" vend_reply = "Thank you for using the MediDrobe!" - products = list(/obj/item/clothing/accessory/pocketprotector = 1, - /obj/item/storage/backpack/duffelbag/med = 1, - /obj/item/storage/backpack/medic = 1, - /obj/item/storage/backpack/satchel/med = 1, - /obj/item/clothing/suit/hooded/wintercoat/medical = 1, - /obj/item/clothing/under/rank/nursesuit = 1, - /obj/item/clothing/head/nursehat = 1, - /obj/item/clothing/under/rank/medical/blue = 1, - /obj/item/clothing/under/rank/medical/green = 1, - /obj/item/clothing/under/rank/medical/purple = 1, - /obj/item/clothing/under/rank/medical = 3, - /obj/item/clothing/suit/toggle/labcoat = 3, - /obj/item/clothing/suit/toggle/labcoat/emt = 3, - /obj/item/clothing/shoes/sneakers/white = 3, - /obj/item/clothing/head/soft/emt = 3, - /obj/item/clothing/suit/apron/surgical = 1, - /obj/item/clothing/mask/surgical = 1) + products = list(/obj/item/clothing/accessory/pocketprotector = 3, + /obj/item/storage/backpack/duffelbag/med = 3, + /obj/item/storage/backpack/medic = 3, + /obj/item/storage/backpack/satchel/med = 3, + /obj/item/clothing/suit/hooded/wintercoat/medical = 3, + /obj/item/clothing/under/rank/nursesuit = 3, + /obj/item/clothing/head/nursehat = 3, + /obj/item/clothing/under/rank/medical/blue = 2, + /obj/item/clothing/under/rank/medical/green = 2, + /obj/item/clothing/under/rank/medical/purple = 2, + /obj/item/clothing/under/rank/medical = 5, + /obj/item/clothing/suit/toggle/labcoat = 5, + /obj/item/clothing/suit/toggle/labcoat/emt = 5, + /obj/item/clothing/shoes/sneakers/white = 5, + /obj/item/clothing/head/soft/emt = 5, + /obj/item/clothing/suit/apron/surgical = 3, + /obj/item/clothing/mask/surgical = 5) refill_canister = /obj/item/vending_refill/wardrobe/medi_wardrobe /obj/item/vending_refill/wardrobe/medi_wardrobe @@ -61,15 +61,15 @@ icon_state = "engidrobe" product_ads = "Guaranteed to protect your feet from industrial accidents!;Afraid of radiation? Then wear yellow!" vend_reply = "Thank you for using the EngiDrobe!" - products = list(/obj/item/clothing/accessory/pocketprotector = 1, - /obj/item/storage/backpack/duffelbag/engineering = 1, - /obj/item/storage/backpack/industrial = 1, - /obj/item/storage/backpack/satchel/eng = 1, - /obj/item/clothing/suit/hooded/wintercoat/engineering = 1, - /obj/item/clothing/under/rank/engineer = 3, - /obj/item/clothing/suit/hazardvest = 3, - /obj/item/clothing/shoes/workboots = 3, - /obj/item/clothing/head/hardhat = 3) + products = list(/obj/item/clothing/accessory/pocketprotector = 5, + /obj/item/storage/backpack/duffelbag/engineering = 2, + /obj/item/storage/backpack/industrial = 3, + /obj/item/storage/backpack/satchel/eng = 3, + /obj/item/clothing/suit/hooded/wintercoat/engineering = 3, + /obj/item/clothing/under/rank/engineer = 5, + /obj/item/clothing/suit/hazardvest = 5, + /obj/item/clothing/shoes/workboots = 5, + /obj/item/clothing/head/hardhat = 5) refill_canister = /obj/item/vending_refill/wardrobe/engi_wardrobe /obj/item/vending_refill/wardrobe/engi_wardrobe @@ -81,13 +81,13 @@ icon_state = "atmosdrobe" product_ads = "Get your inflammable clothing right here!!!" vend_reply = "Thank you for using the AtmosDrobe!" - products = list(/obj/item/clothing/accessory/pocketprotector = 1, - /obj/item/storage/backpack/duffelbag/engineering = 1, - /obj/item/storage/backpack/satchel/eng = 1, - /obj/item/storage/backpack/industrial = 1, - /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos = 3, - /obj/item/clothing/under/rank/atmospheric_technician = 3, - /obj/item/clothing/shoes/sneakers/black = 3) + products = list(/obj/item/clothing/accessory/pocketprotector = 3, + /obj/item/storage/backpack/duffelbag/engineering = 3, + /obj/item/storage/backpack/satchel/eng = 3, + /obj/item/storage/backpack/industrial = 3, + /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos = 5, + /obj/item/clothing/under/rank/atmospheric_technician = 5, + /obj/item/clothing/shoes/sneakers/black = 5) refill_canister = /obj/item/vending_refill/wardrobe/atmos_wardrobe /obj/item/vending_refill/wardrobe/atmos_wardrobe @@ -99,12 +99,12 @@ icon_state = "cargodrobe" product_ads = "Upgraded Assistant Style! Pick yours today!;These shorts are comfy and easy to wear, get yours now!" vend_reply = "Thank you for using the CargoDrobe!" - products = list(/obj/item/clothing/suit/hooded/wintercoat/cargo = 1, - /obj/item/clothing/under/rank/cargotech = 3, - /obj/item/clothing/shoes/sneakers/black = 3, - /obj/item/clothing/gloves/fingerless = 3, - /obj/item/clothing/head/soft = 3, - /obj/item/radio/headset/headset_cargo = 1) + products = list(/obj/item/clothing/suit/hooded/wintercoat/cargo = 3, + /obj/item/clothing/under/rank/cargotech = 5, + /obj/item/clothing/shoes/sneakers/black = 5, + /obj/item/clothing/gloves/fingerless = 5, + /obj/item/clothing/head/soft = 5, + /obj/item/radio/headset/headset_cargo = 3) refill_canister = /obj/item/vending_refill/wardrobe/cargo_wardrobe /obj/item/vending_refill/wardrobe/cargo_wardrobe @@ -116,13 +116,13 @@ icon_state = "robodrobe" product_ads = "You turn me TRUE, use defines!;0110001101101100011011110111010001101000011001010111001101101000011001010111001001100101" vend_reply = "Thank you for using the RoboDrobe!" - products = list(/obj/item/clothing/glasses/hud/diagnostic = 2, - /obj/item/clothing/under/rank/roboticist = 2, - /obj/item/clothing/suit/toggle/labcoat = 2, - /obj/item/clothing/shoes/sneakers/black = 2, - /obj/item/clothing/gloves/fingerless = 2, - /obj/item/clothing/head/soft/black = 2, - /obj/item/clothing/mask/bandana/skull = 1) + products = list(/obj/item/clothing/glasses/hud/diagnostic = 3, + /obj/item/clothing/under/rank/roboticist = 3, + /obj/item/clothing/suit/toggle/labcoat = 3, + /obj/item/clothing/shoes/sneakers/black = 3, + /obj/item/clothing/gloves/fingerless = 3, + /obj/item/clothing/head/soft/black = 3, + /obj/item/clothing/mask/bandana/skull = 2) premium = list(/obj/item/radio/headset/headset_rob = 2) //Cit change refill_canister = /obj/item/vending_refill/wardrobe/robo_wardrobe @@ -135,15 +135,15 @@ icon_state = "scidrobe" product_ads = "Longing for the smell of flesh plasma? Buy your science clothing now!;Made with 10% Auxetics, so you don't have to worry losing your arm!" vend_reply = "Thank you for using the SciDrobe!" - products = list(/obj/item/clothing/accessory/pocketprotector = 1, - /obj/item/storage/backpack/science = 2, - /obj/item/storage/backpack/satchel/tox = 2, - /obj/item/clothing/suit/hooded/wintercoat/science = 1, - /obj/item/clothing/under/rank/scientist = 3, - /obj/item/clothing/suit/toggle/labcoat/science = 3, - /obj/item/clothing/shoes/sneakers/white = 3, - /obj/item/radio/headset/headset_sci = 2, - /obj/item/clothing/mask/gas = 3) + products = list(/obj/item/clothing/accessory/pocketprotector = 5, + /obj/item/storage/backpack/science = 3, + /obj/item/storage/backpack/satchel/tox = 3, + /obj/item/clothing/suit/hooded/wintercoat/science = 3, + /obj/item/clothing/under/rank/scientist = 4, + /obj/item/clothing/suit/toggle/labcoat/science = 4, + /obj/item/clothing/shoes/sneakers/white = 4, + /obj/item/radio/headset/headset_sci = 4, + /obj/item/clothing/mask/gas = 5) refill_canister = /obj/item/vending_refill/wardrobe/science_wardrobe /obj/item/vending_refill/wardrobe/science_wardrobe @@ -155,13 +155,13 @@ icon_state = "hydrobe" product_ads = "Do you love soil? Then buy our clothes!;Get outfits to match your green thumb here!" vend_reply = "Thank you for using the Hydrobe!" - products = list(/obj/item/storage/backpack/botany = 2, - /obj/item/storage/backpack/satchel/hyd = 2, - /obj/item/clothing/suit/hooded/wintercoat/hydro = 1, - /obj/item/clothing/suit/apron = 2, - /obj/item/clothing/suit/apron/overalls = 3, - /obj/item/clothing/under/rank/hydroponics = 3, - /obj/item/clothing/mask/bandana = 3) + products = list(/obj/item/storage/backpack/botany = 3, + /obj/item/storage/backpack/satchel/hyd = 3, + /obj/item/clothing/suit/hooded/wintercoat/hydro = 2, + /obj/item/clothing/suit/apron = 3, + /obj/item/clothing/suit/apron/overalls = 5, + /obj/item/clothing/under/rank/hydroponics = 5, + /obj/item/clothing/mask/bandana = 4) refill_canister = /obj/item/vending_refill/wardrobe/hydro_wardrobe /obj/item/vending_refill/wardrobe/hydro_wardrobe @@ -173,12 +173,12 @@ icon_state = "curadrobe" product_ads = "Our clothes are endorsed by treasure hunters everywhere!" vend_reply = "Thank you for using the CuraDrobe!" - products = list(/obj/item/clothing/head/fedora/curator = 1, - /obj/item/clothing/suit/curator = 1, - /obj/item/clothing/under/rank/curator/treasure_hunter = 1, - /obj/item/clothing/shoes/workboots/mining = 1, - /obj/item/storage/backpack/satchel/explorer = 1, - /obj/item/storage/bag/books = 1) + products = list(/obj/item/clothing/head/fedora/curator = 2, + /obj/item/clothing/suit/curator = 2, + /obj/item/clothing/under/rank/curator/treasure_hunter = 2, + /obj/item/clothing/shoes/workboots/mining = 2, + /obj/item/storage/backpack/satchel/explorer = 2, + /obj/item/storage/bag/books = 2) refill_canister = /obj/item/vending_refill/wardrobe/curator_wardrobe /obj/item/vending_refill/wardrobe/curator_wardrobe @@ -190,21 +190,21 @@ icon_state = "bardrobe" product_ads = "Guaranteed to prevent stains from spilled drinks!" vend_reply = "Thank you for using the BarDrobe!" - products = list(/obj/item/clothing/head/that = 2, - /obj/item/radio/headset/headset_srv = 2, - /obj/item/clothing/under/sl_suit = 2, - /obj/item/clothing/under/rank/bartender = 2, - /obj/item/clothing/under/rank/bartender/purple = 1, - /obj/item/clothing/accessory/waistcoat = 2, - /obj/item/clothing/suit/apron/purple_bartender = 1, - /obj/item/clothing/head/soft/black = 2, - /obj/item/clothing/shoes/sneakers/black = 2, - /obj/item/reagent_containers/glass/rag = 2, + products = list(/obj/item/clothing/head/that = 3, + /obj/item/radio/headset/headset_srv = 3, + /obj/item/clothing/under/sl_suit = 3, + /obj/item/clothing/under/rank/bartender = 3, + /obj/item/clothing/under/rank/bartender/purple = 2, + /obj/item/clothing/accessory/waistcoat = 3, + /obj/item/clothing/suit/apron/purple_bartender = 2, + /obj/item/clothing/head/soft/black = 4, + /obj/item/clothing/shoes/sneakers/black = 4, + /obj/item/reagent_containers/glass/rag = 4, /obj/item/storage/box/beanbag = 1, /obj/item/clothing/suit/armor/vest/alt = 1, /obj/item/circuitboard/machine/dish_drive = 1, /obj/item/clothing/glasses/sunglasses/reagent = 1, - /obj/item/clothing/neck/petcollar = 1, + /obj/item/clothing/neck/petcollar = 3, /obj/item/storage/belt/bandolier = 1) refill_canister = /obj/item/vending_refill/wardrobe/bar_wardrobe @@ -217,17 +217,17 @@ icon_state = "chefdrobe" product_ads = "Our clothes are guaranteed to protect you from food splatters!" vend_reply = "Thank you for using the ChefDrobe!" - products = list(/obj/item/clothing/under/waiter = 2, - /obj/item/radio/headset/headset_srv = 2, - /obj/item/clothing/accessory/waistcoat = 2, + products = list(/obj/item/clothing/under/waiter = 3, + /obj/item/radio/headset/headset_srv = 4, + /obj/item/clothing/accessory/waistcoat = 3, /obj/item/clothing/suit/apron/chef = 3, /obj/item/clothing/head/soft/mime = 2, /obj/item/storage/box/mousetraps = 2, /obj/item/circuitboard/machine/dish_drive = 1, - /obj/item/clothing/suit/toggle/chef = 1, - /obj/item/clothing/under/rank/chef = 1, - /obj/item/clothing/head/chefhat = 1, - /obj/item/reagent_containers/glass/rag = 1) + /obj/item/clothing/suit/toggle/chef = 2, + /obj/item/clothing/under/rank/chef = 2, + /obj/item/clothing/head/chefhat = 2, + /obj/item/reagent_containers/glass/rag = 3) refill_canister = /obj/item/vending_refill/wardrobe/chef_wardrobe /obj/item/vending_refill/wardrobe/chef_wardrobe @@ -239,21 +239,21 @@ icon_state = "janidrobe" product_ads = "Come and get your janitorial clothing, now endorsed by lizard janitors everywhere!" vend_reply = "Thank you for using the JaniDrobe!" - products = list(/obj/item/clothing/under/rank/janitor = 1, - /obj/item/cartridge/janitor = 1, - /obj/item/clothing/gloves/color/black = 1, - /obj/item/clothing/head/soft/purple = 1, - /obj/item/paint/paint_remover = 1, + products = list(/obj/item/clothing/under/rank/janitor = 2, + /obj/item/cartridge/janitor = 3, + /obj/item/clothing/gloves/color/black = 2, + /obj/item/clothing/head/soft/purple = 2, + /obj/item/paint/paint_remover = 2, /obj/item/melee/flyswatter = 1, - /obj/item/flashlight = 1, - /obj/item/caution = 6, + /obj/item/flashlight = 2, + /obj/item/caution = 8, /obj/item/holosign_creator = 1, /obj/item/lightreplacer = 1, /obj/item/soap = 1, /obj/item/storage/bag/trash = 1, /obj/item/clothing/shoes/galoshes = 1, /obj/item/watertank/janitor = 1, - /obj/item/storage/belt/janitor = 1) + /obj/item/storage/belt/janitor = 2) refill_canister = /obj/item/vending_refill/wardrobe/jani_wardrobe /obj/item/vending_refill/wardrobe/jani_wardrobe @@ -265,17 +265,17 @@ icon_state = "lawdrobe" product_ads = "OBJECTION! Get the rule of law for yourself!" vend_reply = "Thank you for using the LawDrobe!" - products = list(/obj/item/clothing/under/lawyer/female = 1, - /obj/item/clothing/under/lawyer/black = 1, - /obj/item/clothing/under/lawyer/red = 1, - /obj/item/clothing/under/lawyer/bluesuit = 1, - /obj/item/clothing/suit/toggle/lawyer = 1, - /obj/item/clothing/under/lawyer/purpsuit = 1, - /obj/item/clothing/suit/toggle/lawyer/purple = 1, - /obj/item/clothing/under/lawyer/blacksuit = 1, - /obj/item/clothing/suit/toggle/lawyer/black = 1, - /obj/item/clothing/shoes/laceup = 2, - /obj/item/clothing/accessory/lawyers_badge = 2) + products = list(/obj/item/clothing/under/lawyer/female = 3, + /obj/item/clothing/under/lawyer/black = 3, + /obj/item/clothing/under/lawyer/red = 3, + /obj/item/clothing/under/lawyer/bluesuit = 3, + /obj/item/clothing/suit/toggle/lawyer = 3, + /obj/item/clothing/under/lawyer/purpsuit = 3, + /obj/item/clothing/suit/toggle/lawyer/purple = 3, + /obj/item/clothing/under/lawyer/blacksuit = 3, + /obj/item/clothing/suit/toggle/lawyer/black = 3, + /obj/item/clothing/shoes/laceup = 3, + /obj/item/clothing/accessory/lawyers_badge = 3) refill_canister = /obj/item/vending_refill/wardrobe/law_wardrobe /obj/item/vending_refill/wardrobe/law_wardrobe @@ -288,14 +288,14 @@ product_ads = "Are you being bothered by cultists or pesky revenants? Then come and dress like the holy man!;Clothes for men of the cloth!" vend_reply = "Thank you for using the ChapDrobe!" products = list(/obj/item/holybeacon = 1, - /obj/item/storage/backpack/cultpack = 1, - /obj/item/clothing/accessory/pocketprotector/cosmetology = 1, - /obj/item/clothing/under/rank/chaplain = 1, - /obj/item/clothing/shoes/sneakers/black = 1, - /obj/item/clothing/suit/nun = 1, - /obj/item/clothing/head/nun_hood = 1, - /obj/item/clothing/suit/holidaypriest = 1, - /obj/item/storage/fancy/candle_box = 2) + /obj/item/storage/backpack/cultpack = 2, + /obj/item/clothing/accessory/pocketprotector/cosmetology = 2, + /obj/item/clothing/under/rank/chaplain = 2, + /obj/item/clothing/shoes/sneakers/black = 2, + /obj/item/clothing/suit/nun = 2, + /obj/item/clothing/head/nun_hood = 2, + /obj/item/clothing/suit/holidaypriest = 2, + /obj/item/storage/fancy/candle_box = 3) refill_canister = /obj/item/vending_refill/wardrobe/chap_wardrobe /obj/item/vending_refill/wardrobe/chap_wardrobe @@ -307,12 +307,12 @@ icon_state = "chemdrobe" product_ads = "Our clothes are 0.5% more resistant to acid spills! Get yours now!" vend_reply = "Thank you for using the ChemDrobe!" - products = list(/obj/item/clothing/under/rank/chemist = 2, - /obj/item/clothing/shoes/sneakers/white = 2, - /obj/item/clothing/suit/toggle/labcoat/chemist = 2, - /obj/item/storage/backpack/chemistry = 2, - /obj/item/storage/backpack/satchel/chem = 2, - /obj/item/storage/bag/chemistry = 2) + products = list(/obj/item/clothing/under/rank/chemist = 3, + /obj/item/clothing/shoes/sneakers/white = 3, + /obj/item/clothing/suit/toggle/labcoat/chemist = 3, + /obj/item/storage/backpack/chemistry = 3, + /obj/item/storage/backpack/satchel/chem = 3, + /obj/item/storage/bag/chemistry = 3) refill_canister = /obj/item/vending_refill/wardrobe/chem_wardrobe /obj/item/vending_refill/wardrobe/chem_wardrobe @@ -324,11 +324,11 @@ icon_state = "genedrobe" product_ads = "Perfect for the mad scientist in you!" vend_reply = "Thank you for using the GeneDrobe!" - products = list(/obj/item/clothing/under/rank/geneticist = 2, - /obj/item/clothing/shoes/sneakers/white = 2, - /obj/item/clothing/suit/toggle/labcoat/genetics = 2, - /obj/item/storage/backpack/genetics = 2, - /obj/item/storage/backpack/satchel/gen = 2) + products = list(/obj/item/clothing/under/rank/geneticist = 3, + /obj/item/clothing/shoes/sneakers/white = 3, + /obj/item/clothing/suit/toggle/labcoat/genetics = 3, + /obj/item/storage/backpack/genetics = 3, + /obj/item/storage/backpack/satchel/gen = 3) refill_canister = /obj/item/vending_refill/wardrobe/gene_wardrobe /obj/item/vending_refill/wardrobe/gene_wardrobe @@ -340,12 +340,12 @@ icon_state = "virodrobe" product_ads = " Viruses getting you down? Then upgrade to sterilized clothing today!" vend_reply = "Thank you for using the ViroDrobe" - products = list(/obj/item/clothing/under/rank/virologist = 2, - /obj/item/clothing/shoes/sneakers/white = 2, - /obj/item/clothing/suit/toggle/labcoat/virologist = 2, - /obj/item/clothing/mask/surgical = 2, - /obj/item/storage/backpack/virology = 2, - /obj/item/storage/backpack/satchel/vir = 2) + products = list(/obj/item/clothing/under/rank/virologist = 3, + /obj/item/clothing/shoes/sneakers/white = 3, + /obj/item/clothing/suit/toggle/labcoat/virologist = 3, + /obj/item/clothing/mask/surgical = 3, + /obj/item/storage/backpack/virology = 3, + /obj/item/storage/backpack/satchel/vir = 3) refill_canister = /obj/item/vending_refill/wardrobe/viro_wardrobe /obj/item/vending_refill/wardrobe/viro_wardrobe diff --git a/html/changelogs/AutoChangeLog-pr-8182.yml b/html/changelogs/AutoChangeLog-pr-8182.yml new file mode 100644 index 0000000000..8247409f1b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8182.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - code_imp: "get_hearers_in_view() now actually caches the results of view() instead of calling view() twice" diff --git a/html/changelogs/AutoChangeLog-pr-8236.yml b/html/changelogs/AutoChangeLog-pr-8236.yml new file mode 100644 index 0000000000..3e266fb6fc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8236.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - refactor: "Added unomos, which is basically listmos except gas mixtures only use one single list for handling their gasses. This is a significant performance improvement that also offers a mild memory improvement under normal circumstances." diff --git a/html/changelogs/AutoChangeLog-pr-8247.yml b/html/changelogs/AutoChangeLog-pr-8247.yml new file mode 100644 index 0000000000..1ab08ece4d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8247.yml @@ -0,0 +1,5 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Added custom species names! Examining people will now display their species name unless they're an Unknown or have their face hidden. like flavor text. Set it in your character window!" + - code_imp: "changed how health scanners print messages, wrapping it in msg for one to_chat instead of printing every line to_chat." diff --git a/html/changelogs/AutoChangeLog-pr-8252.yml b/html/changelogs/AutoChangeLog-pr-8252.yml new file mode 100644 index 0000000000..c86d0b5aa0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8252.yml @@ -0,0 +1,6 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds the bonermeter; a device that measures arousal based statistics." + - refactor: "Added a new input to the electrostimulator that controls the strength of the shock. It accepts negative inputs which reduce arousal. Added a new output to the electrostimulator that displays the amount of arousal gained." + - balance: "Rebalanced the electro-stimulator to be less spammy by giving it a 2.5 second enforced cooldown per circuit contraption. Increased the complexity of electro stimulator from 10 to 15." diff --git a/html/changelogs/AutoChangeLog-pr-8255.yml b/html/changelogs/AutoChangeLog-pr-8255.yml new file mode 100644 index 0000000000..1b2e81f5bd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8255.yml @@ -0,0 +1,4 @@ +author: "BurgerB" +delete-after: True +changes: + - tweak: "Tweaked the UI of the loadout to be less cluttered due to an issue with formatting." diff --git a/html/changelogs/AutoChangeLog-pr-8258.yml b/html/changelogs/AutoChangeLog-pr-8258.yml new file mode 100644 index 0000000000..2d1f75603f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8258.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - refactor: "Reworked the Vent Clog event to spray smoke instead of foam, also made it shoot smoke over time instead through each vent instead of all at once." diff --git a/html/changelogs/AutoChangeLog-pr-8259.yml b/html/changelogs/AutoChangeLog-pr-8259.yml new file mode 100644 index 0000000000..54a1dd6a4b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8259.yml @@ -0,0 +1,5 @@ +author: "deathride58" +delete-after: True +changes: + - balance: "Locomotion circuits are now restricted to jogging speed" + - balance: "MMI circuits and pAI circuits both now have 60 complexity, up from their original 29." diff --git a/html/changelogs/AutoChangeLog-pr-8260.yml b/html/changelogs/AutoChangeLog-pr-8260.yml new file mode 100644 index 0000000000..e6ef697917 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8260.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "cakes!" + - imageadd: "Made some sprites! -Love them really came out well" diff --git a/html/changelogs/AutoChangeLog-pr-8261.yml b/html/changelogs/AutoChangeLog-pr-8261.yml new file mode 100644 index 0000000000..e7624aec73 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8261.yml @@ -0,0 +1,7 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "new economics" + - tweak: "cargo and robotics relationships" + - balance: "unbalanced something" + - bugfix: "fixed a maybe oversight" diff --git a/html/changelogs/AutoChangeLog-pr-8264.yml b/html/changelogs/AutoChangeLog-pr-8264.yml new file mode 100644 index 0000000000..15e525c581 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8264.yml @@ -0,0 +1,7 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscdel: "Fun" + - tweak: "costs of suit voucher" + - balance: "Unblances miner vender" + - bugfix: "spare cheaper brute kit" diff --git a/html/changelogs/AutoChangeLog-pr-8265.yml b/html/changelogs/AutoChangeLog-pr-8265.yml new file mode 100644 index 0000000000..e581a93315 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8265.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "harm from hentie" + - balance: "rebalanced goliaths stun to be less auto death" diff --git a/html/changelogs/AutoChangeLog-pr-8274.yml b/html/changelogs/AutoChangeLog-pr-8274.yml new file mode 100644 index 0000000000..41b2de1d9e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8274.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - tweak: "Increased the spawn area of the City of Cogs (Reebe). This does not affect the area in which builders can build." diff --git a/html/changelogs/AutoChangeLog-pr-8277.yml b/html/changelogs/AutoChangeLog-pr-8277.yml new file mode 100644 index 0000000000..2a663ea2a4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8277.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Significantly tweaks the Wizard race transformation event to be less unreasonably troublesome." diff --git a/html/changelogs/AutoChangeLog-pr-8278.yml b/html/changelogs/AutoChangeLog-pr-8278.yml new file mode 100644 index 0000000000..57655b8ace --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8278.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Armor to blob shields" + - tweak: "block weaken state to 70% from 75%" diff --git a/html/changelogs/AutoChangeLog-pr-8279.yml b/html/changelogs/AutoChangeLog-pr-8279.yml new file mode 100644 index 0000000000..7ed141640a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8279.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "restores the deathriplys missing armor" diff --git a/html/changelogs/AutoChangeLog-pr-8283.yml b/html/changelogs/AutoChangeLog-pr-8283.yml new file mode 100644 index 0000000000..7a614e2e82 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8283.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds a new 0 cost trait that makes you immune* to Crocin and Hexacrocin" diff --git a/html/changelogs/AutoChangeLog-pr-8286.yml b/html/changelogs/AutoChangeLog-pr-8286.yml new file mode 100644 index 0000000000..d59a8dad66 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8286.yml @@ -0,0 +1,5 @@ +author: "BurgerBB" +delete-after: True +changes: + - tweak: "Tweaks how slurring works so it's more of a gradual change into slurring instead of immediate." + - balance: "Slurring is now directly proportional to your drunkenness, with other sources of slur being added on top of it." diff --git a/html/changelogs/AutoChangeLog-pr-8287.yml b/html/changelogs/AutoChangeLog-pr-8287.yml new file mode 100644 index 0000000000..aafba03474 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8287.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "new lockable colalr" diff --git a/html/changelogs/AutoChangeLog-pr-8288.yml b/html/changelogs/AutoChangeLog-pr-8288.yml new file mode 100644 index 0000000000..6b3fbadbd8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8288.yml @@ -0,0 +1,7 @@ +author: "BurgerBB" +delete-after: True +changes: + - tweak: "Bras are now separate from underwear, meaning you can mix and match bras if you're into that." + - tweak: "Men can wear female accessory clothing, and females can wear men accessory clothing. It's not a fetish, mom, it's PROGRESSIVE." + - code_imp: "Reorganized accessories into their own files to prevent a massive 1000 line file." + - server: "i'm 10% sure that merging this PR will cause preference corruption sooooooooooo I just need to hear from @deathride58 or perhaps someone else on how much damage this could possibly do." diff --git a/html/changelogs/AutoChangeLog-pr-8289.yml b/html/changelogs/AutoChangeLog-pr-8289.yml new file mode 100644 index 0000000000..d389d95cd6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8289.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "armor" diff --git a/html/changelogs/AutoChangeLog-pr-8290.yml b/html/changelogs/AutoChangeLog-pr-8290.yml new file mode 100644 index 0000000000..553bfbf4f9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8290.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "missing hopes and dreams" + - code_imp: "orgized the weapon file to be more cat brain friendly" diff --git a/html/changelogs/AutoChangeLog-pr-8294.yml b/html/changelogs/AutoChangeLog-pr-8294.yml new file mode 100644 index 0000000000..bce0031c2b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8294.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - imageadd: "This means sprite right?" diff --git a/html/changelogs/AutoChangeLog-pr-8295.yml b/html/changelogs/AutoChangeLog-pr-8295.yml new file mode 100644 index 0000000000..833474e9af --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8295.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscdel: "Many engi flags on non-engi things" + - code_imp: "changed some code to be organized at a glance" diff --git a/html/changelogs/AutoChangeLog-pr-8296.yml b/html/changelogs/AutoChangeLog-pr-8296.yml new file mode 100644 index 0000000000..78db7ccb0d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8296.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "25% < --- 50% For NPC blocking bullshit +ided: Yes" diff --git a/html/changelogs/AutoChangeLog-pr-8301.yml b/html/changelogs/AutoChangeLog-pr-8301.yml new file mode 100644 index 0000000000..90e893bdf2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8301.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "mag gun uses cells" + - balance: "kev things their to op" diff --git a/html/changelogs/AutoChangeLog-pr-8302.yml b/html/changelogs/AutoChangeLog-pr-8302.yml new file mode 100644 index 0000000000..e2b535c40f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8302.yml @@ -0,0 +1,5 @@ +author: "BurgerBB" +delete-after: True +changes: + - tweak: "Tweaked penis." + - balance: "Rebalanced penis." diff --git a/html/changelogs/AutoChangeLog-pr-8303.yml b/html/changelogs/AutoChangeLog-pr-8303.yml new file mode 100644 index 0000000000..8c3742ca8a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8303.yml @@ -0,0 +1,5 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Added the following reagents to the common list of vent clog reagents: ~~Cooking Oil~~, ~~Frost Oil~~, Sodium Chloride, Corn Oil, Uranium, Carpet, Firefighting Foam, semen, femcum, tear juice, strange reagent, ~~spraytan~~." + - balance: "Vent Clog smoke emits the same transparent smoke as a smoke machine, including how much it transfers. Vent Clogs also do not trigger in areas deemed \"Safe\" in code, such as in the dorms or trusted areas where dangerous things shouldn't occur." diff --git a/html/changelogs/AutoChangeLog-pr-8305.yml b/html/changelogs/AutoChangeLog-pr-8305.yml new file mode 100644 index 0000000000..2293fa9163 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8305.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - server: "Discord bot will now report when a round ends and give the vague news ticker that a sister-station would have received for the game mode and result of the round." diff --git a/html/changelogs/AutoChangeLog-pr-8306.yml b/html/changelogs/AutoChangeLog-pr-8306.yml new file mode 100644 index 0000000000..95ceb32968 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8306.yml @@ -0,0 +1,6 @@ +author: "Poojawa" +delete-after: True +changes: + - bugfix: "fixed medical hardsuit overlay issue. I thought it was going to work well but fuck byond." + - bugfix: "None body markings shouldn't give rgb hell, but it also should reset properly anyway. ree." + - bugfix: "Sorted some sprites to better sooth my byond icon limit anxiety." diff --git a/html/changelogs/AutoChangeLog-pr-8311.yml b/html/changelogs/AutoChangeLog-pr-8311.yml new file mode 100644 index 0000000000..6ec7aae071 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8311.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "syndicate phobia" + - tweak: "other phobia's" diff --git a/html/changelogs/AutoChangeLog-pr-8315.yml b/html/changelogs/AutoChangeLog-pr-8315.yml new file mode 100644 index 0000000000..5d0b85e162 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8315.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "laser carbine" diff --git a/html/changelogs/AutoChangeLog-pr-8316.yml b/html/changelogs/AutoChangeLog-pr-8316.yml new file mode 100644 index 0000000000..b51a40c846 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8316.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "makes collars only locked via key" diff --git a/html/changelogs/AutoChangeLog-pr-8317.yml b/html/changelogs/AutoChangeLog-pr-8317.yml new file mode 100644 index 0000000000..0fd31c3c52 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8317.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - tweak: "Biogenerators now have a sane limit for production" diff --git a/html/changelogs/AutoChangeLog-pr-8318.yml b/html/changelogs/AutoChangeLog-pr-8318.yml new file mode 100644 index 0000000000..0c0a5c06c4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8318.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds additional random brain damage text" diff --git a/html/changelogs/AutoChangeLog-pr-8319.yml b/html/changelogs/AutoChangeLog-pr-8319.yml new file mode 100644 index 0000000000..e46b83c121 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8319.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds penis enlargement pills." diff --git a/html/changelogs/AutoChangeLog-pr-8322.yml b/html/changelogs/AutoChangeLog-pr-8322.yml new file mode 100644 index 0000000000..188c988021 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8322.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "charging" diff --git a/html/changelogs/AutoChangeLog-pr-8323.yml b/html/changelogs/AutoChangeLog-pr-8323.yml new file mode 100644 index 0000000000..0c4fc13b48 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8323.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Combat inducers for COMBAT!" diff --git a/html/changelogs/AutoChangeLog-pr-8325.yml b/html/changelogs/AutoChangeLog-pr-8325.yml new file mode 100644 index 0000000000..1e665e7917 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8325.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - code_imp: "made it look nice" diff --git a/html/changelogs/AutoChangeLog-pr-8334.yml b/html/changelogs/AutoChangeLog-pr-8334.yml new file mode 100644 index 0000000000..3c9152c257 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8334.yml @@ -0,0 +1,4 @@ +author: "dtfe3" +delete-after: True +changes: + - tweak: "Increased music maxlines from 300 to 600" diff --git a/html/changelogs/AutoChangeLog-pr-8336.yml b/html/changelogs/AutoChangeLog-pr-8336.yml new file mode 100644 index 0000000000..25a14e5d1f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8336.yml @@ -0,0 +1,5 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds Stun Circuit and Pneumatic Cannon Integrated Circuits" + - bugfix: "Fixed extinguisher and smoke circuits not accepting any reagents." diff --git a/html/changelogs/AutoChangeLog-pr-8341.yml b/html/changelogs/AutoChangeLog-pr-8341.yml new file mode 100644 index 0000000000..50dedb7374 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8341.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "golden swag boxes" diff --git a/html/changelogs/AutoChangeLog-pr-8342.yml b/html/changelogs/AutoChangeLog-pr-8342.yml new file mode 100644 index 0000000000..a159f3240f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8342.yml @@ -0,0 +1,7 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds a few important clockcult tips." + - rscadd: "Added Mech Sensors, a brass-created trap that activates when a mech not controlled by a cultist crosses it." + - rscadd: "Added power nullifiers, an emp trap that emps everything in a 3x3 area, with the center suffering a heavy EMP." + - tweak: "Brass Skewers now deal 50 damage to mechs." diff --git a/html/changelogs/AutoChangeLog-pr-8348.yml b/html/changelogs/AutoChangeLog-pr-8348.yml new file mode 100644 index 0000000000..b4272de0a5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8348.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Crafting suitcases" diff --git a/html/changelogs/AutoChangeLog-pr-8352.yml b/html/changelogs/AutoChangeLog-pr-8352.yml new file mode 100644 index 0000000000..ff9e9130db --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8352.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Fixed a fairly huge server crash exploit" diff --git a/html/changelogs/AutoChangeLog-pr-8362.yml b/html/changelogs/AutoChangeLog-pr-8362.yml new file mode 100644 index 0000000000..29a840e22f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8362.yml @@ -0,0 +1,4 @@ +author: "dtfe3" +delete-after: True +changes: + - tweak: "Made it so any oxygen tank can be used instead of only red ones." diff --git a/html/changelogs/AutoChangeLog-pr-8366.yml b/html/changelogs/AutoChangeLog-pr-8366.yml new file mode 100644 index 0000000000..c7c16a8e7d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8366.yml @@ -0,0 +1,10 @@ +author: "Poojawa" +delete-after: True +changes: + - bugfix: "Box Cryopods expanded to 6 public. Permabrig cryo fixed." + - bugfix: "Delta Cryopods expanded to 6 public. Permabrig cryo fixed." + - bugfix: "MetaStation Crypods expanded to 6 public, relocated above sparring ring. Permabrig cryo fixed" + - bugfix: "PubbyStation gained one more cryopod, Permabrig's cryo fixed." + - rscadd: "Omega given one more crypod as well." + - rscadd: "Gulag was given a cryopod." + - tweak: "Box and Meta's cryo rooms are now a new room entirely." diff --git a/html/changelogs/AutoChangeLog-pr-8367.yml b/html/changelogs/AutoChangeLog-pr-8367.yml new file mode 100644 index 0000000000..b5e3a87cc5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8367.yml @@ -0,0 +1,7 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Added erect states for all phallic bodyparts" + - bugfix: "YOUR DICK ACTUALLY STANDS UP NOW, YOU'RE WELCOME." + - bugfix: "skintone locked genitals match the new skintone colorations." + - rscadd: "added two new vaginal types and descriptions." diff --git a/html/changelogs/AutoChangeLog-pr-8368.yml b/html/changelogs/AutoChangeLog-pr-8368.yml new file mode 100644 index 0000000000..cffcd2208e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8368.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "better stocks" diff --git a/html/changelogs/AutoChangeLog-pr-8369.yml b/html/changelogs/AutoChangeLog-pr-8369.yml new file mode 100644 index 0000000000..ca13347288 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8369.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "more evil blood fluff text" diff --git a/html/changelogs/AutoChangeLog-pr-8370.yml b/html/changelogs/AutoChangeLog-pr-8370.yml new file mode 100644 index 0000000000..1ff275b762 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8370.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Added more mime names" diff --git a/html/changelogs/AutoChangeLog-pr-8372.yml b/html/changelogs/AutoChangeLog-pr-8372.yml new file mode 100644 index 0000000000..88ebc9854c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8372.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - bugfix: "fixed borg defib runtimes" diff --git a/html/changelogs/AutoChangeLog-pr-8374.yml b/html/changelogs/AutoChangeLog-pr-8374.yml new file mode 100644 index 0000000000..e86e591827 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8374.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - bugfix: "fixed heart attacks being nonlethal" diff --git a/html/changelogs/AutoChangeLog-pr-8376.yml b/html/changelogs/AutoChangeLog-pr-8376.yml new file mode 100644 index 0000000000..8ab3b8b8bc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8376.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Ported Oracle's cloning set up, you're now visible like cryo when being cloned, though it's a mystery until you have skin on your meat puppet existance" diff --git a/html/changelogs/AutoChangeLog-pr-8377.yml b/html/changelogs/AutoChangeLog-pr-8377.yml new file mode 100644 index 0000000000..b6265b3bff --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8377.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - balance: "Recyclers are unable to destroy the indestructible any longer." diff --git a/html/changelogs/AutoChangeLog-pr-8384.yml b/html/changelogs/AutoChangeLog-pr-8384.yml new file mode 100644 index 0000000000..f98b473e6c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8384.yml @@ -0,0 +1,6 @@ +author: "Nero1024" +delete-after: True +changes: + - soundadd: "Bare feet will now make the correct footstep sounds." + - soundadd: "Other mobs will make the correct footstep sounds." + - soundadd: "Crawling/dragging sounds for downed/incapacitated mobs" diff --git a/html/changelogs/AutoChangeLog-pr-8387.yml b/html/changelogs/AutoChangeLog-pr-8387.yml new file mode 100644 index 0000000000..4770fe08fc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8387.yml @@ -0,0 +1,4 @@ +author: "jtgsz" +delete-after: True +changes: + - rscadd: "ported gang mode" diff --git a/html/changelogs/AutoChangeLog-pr-8388.yml b/html/changelogs/AutoChangeLog-pr-8388.yml new file mode 100644 index 0000000000..570b30448a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8388.yml @@ -0,0 +1,4 @@ +author: "Useroth" +delete-after: True +changes: + - bugfix: "the collars are now aware of their proper overlay sprites" diff --git a/html/changelogs/AutoChangeLog-pr-8391.yml b/html/changelogs/AutoChangeLog-pr-8391.yml new file mode 100644 index 0000000000..32e837a0a6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8391.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "replaces a sink with a autolathen" diff --git a/html/changelogs/AutoChangeLog-pr-8392.yml b/html/changelogs/AutoChangeLog-pr-8392.yml new file mode 100644 index 0000000000..986bb0a6fa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8392.yml @@ -0,0 +1,5 @@ +author: "Poojawa" +delete-after: True +changes: + - bugfix: "Kiara's toy sabre now actually is the correct item + icon states" + - bugfix: "Generic armor for taurs fixed, there isn't actually any sprites for 'em, so. Full sprites overlay over bodies, but I really can't be bothered to do all the offset fixes otherwise." diff --git a/html/changelogs/AutoChangeLog-pr-8393.yml b/html/changelogs/AutoChangeLog-pr-8393.yml new file mode 100644 index 0000000000..4bc0472560 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8393.yml @@ -0,0 +1,4 @@ +author: "WhiteHusky" +delete-after: True +changes: + - rscadd: "Sleepers now show blood level and type." diff --git a/html/changelogs/AutoChangeLog-pr-8397.yml b/html/changelogs/AutoChangeLog-pr-8397.yml new file mode 100644 index 0000000000..28ed98666f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8397.yml @@ -0,0 +1,5 @@ +author: "WhiteHusky" +delete-after: True +changes: + - tweak: "Changed the styling of arousal messages to use pink-ish colors." + - bugfix: "The orgasm moodlet message new-lines properly." diff --git a/html/changelogs/AutoChangeLog-pr-8398.yml b/html/changelogs/AutoChangeLog-pr-8398.yml new file mode 100644 index 0000000000..a7ce2fbe2d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8398.yml @@ -0,0 +1,6 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Ass slapping only works if you're actually behind the target. Ass slapping now respects disarm blocking. You can no longer face/ass slap someone on an intent other than help, unless they are also face/ass slapping." + - bugfix: "Fixed ass and face slapping grammar." + - rscadd: "Adds meh effects for ass and face slapping." diff --git a/html/changelogs/AutoChangeLog-pr-8399.yml b/html/changelogs/AutoChangeLog-pr-8399.yml new file mode 100644 index 0000000000..5c71d19faa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8399.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Large maps have had a patient room transformed into micro chemistry stations with nothing else in them. They've been labelled 'Apothecary' rooms and are accessible by doctors." diff --git a/html/changelogs/AutoChangeLog-pr-8400.yml b/html/changelogs/AutoChangeLog-pr-8400.yml new file mode 100644 index 0000000000..485e4c4812 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8400.yml @@ -0,0 +1,4 @@ +author: "dtfe3" +delete-after: True +changes: + - tweak: "Watcher wing Trophy's effect lasts 1 second instead of 0.5" diff --git a/html/changelogs/AutoChangeLog-pr-8404.yml b/html/changelogs/AutoChangeLog-pr-8404.yml new file mode 100644 index 0000000000..c230977a44 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8404.yml @@ -0,0 +1,5 @@ +author: "WhiteHusky" +delete-after: True +changes: + - bugfix: "Flavor text with special characters will not get partially unescaped." + - bugfix: "Canceling when setting flavor text does not clear it anymore." diff --git a/html/changelogs/AutoChangeLog-pr-8407.yml b/html/changelogs/AutoChangeLog-pr-8407.yml new file mode 100644 index 0000000000..5f1d9d0729 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8407.yml @@ -0,0 +1,6 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "females now have female defined sprites" + - bugfix: "Slime legs have had their excess pixels adjusted" + - bugfix: "Mammal normal legs are more in line with human legs now" diff --git a/html/changelogs/AutoChangeLog-pr-8408.yml b/html/changelogs/AutoChangeLog-pr-8408.yml new file mode 100644 index 0000000000..548e4947be --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8408.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes cult potentially stalling if the target is erased from existence without being sacced." diff --git a/html/changelogs/AutoChangeLog-pr-8409.yml b/html/changelogs/AutoChangeLog-pr-8409.yml new file mode 100644 index 0000000000..01f69bf437 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8409.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - bugfix: "fixed species like abductors and golems getting the fat tiddy or pingas" diff --git a/html/changelogs/AutoChangeLog-pr-8411.yml b/html/changelogs/AutoChangeLog-pr-8411.yml new file mode 100644 index 0000000000..4d4a122cf2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8411.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "2 -> 3" diff --git a/html/changelogs/AutoChangeLog-pr-8413.yml b/html/changelogs/AutoChangeLog-pr-8413.yml new file mode 100644 index 0000000000..01de909a3b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8413.yml @@ -0,0 +1,5 @@ +author: "Useroth" +delete-after: True +changes: + - bugfix: "The space hotel dorms are now properly boltable with the buttons inside." + - bugfix: "Makes the booze-o-mat hacked by default. Alternative to https://github.com/Citadel-Station-13/Citadel-Station-13/pull/8350." diff --git a/html/changelogs/AutoChangeLog-pr-8414.yml b/html/changelogs/AutoChangeLog-pr-8414.yml new file mode 100644 index 0000000000..eaec60b3a9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8414.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "MASON SUIT!" diff --git a/html/changelogs/AutoChangeLog-pr-8417.yml b/html/changelogs/AutoChangeLog-pr-8417.yml new file mode 100644 index 0000000000..2a6eaa6237 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8417.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Added a few jet packs to the space queens men" + - tweak: "volume of jet packs" diff --git a/html/changelogs/AutoChangeLog-pr-8419.yml b/html/changelogs/AutoChangeLog-pr-8419.yml new file mode 100644 index 0000000000..037dba41ad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8419.yml @@ -0,0 +1,4 @@ +author: "UntoldTactics" +delete-after: True +changes: + - tweak: "Rewords the click here prompt given when an attempted conversion is done on an offer rune (for blood cult)" diff --git a/html/changelogs/AutoChangeLog-pr-8420.yml b/html/changelogs/AutoChangeLog-pr-8420.yml new file mode 100644 index 0000000000..60c8543647 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8420.yml @@ -0,0 +1,5 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Shield blobs no longer become completely invulnerable to all forms of damage after reaching a \"\"\"weakened\"\"\" state" + - tweak: "Taken care of what appeared to have been an oversight where shield blobs don't recover their armor after becoming weakened." diff --git a/html/changelogs/AutoChangeLog-pr-8424.yml b/html/changelogs/AutoChangeLog-pr-8424.yml new file mode 100644 index 0000000000..12295e8a82 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8424.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - rscadd: "You can now use CTRL and ALT click on pumps and filters to toggle them on and off and max their output respectively" diff --git a/html/changelogs/AutoChangeLog-pr-8429.yml b/html/changelogs/AutoChangeLog-pr-8429.yml new file mode 100644 index 0000000000..0769af85aa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8429.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Nerfed concatenators by limiting the amount of characters they're able to output" diff --git a/html/changelogs/AutoChangeLog-pr-8430.yml b/html/changelogs/AutoChangeLog-pr-8430.yml new file mode 100644 index 0000000000..e59f61821a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8430.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Bad Idea" diff --git a/html/changelogs/AutoChangeLog-pr-8432.yml b/html/changelogs/AutoChangeLog-pr-8432.yml new file mode 100644 index 0000000000..e65bfd68d3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8432.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "Nukes the stunprod's 3 seconds delay." + - bugfix: "Fixes teleprods." diff --git a/html/changelogs/AutoChangeLog-pr-8434.yml b/html/changelogs/AutoChangeLog-pr-8434.yml new file mode 100644 index 0000000000..d01858d2b4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8434.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Stops pulls of resting mobs breaking off whenever you swap turfs with someone else because of crawling delays." diff --git a/html/changelogs/AutoChangeLog-pr-8435.yml b/html/changelogs/AutoChangeLog-pr-8435.yml new file mode 100644 index 0000000000..3c2caeb994 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8435.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "fixes IAA." diff --git a/html/changelogs/AutoChangeLog-pr-8436.yml b/html/changelogs/AutoChangeLog-pr-8436.yml new file mode 100644 index 0000000000..6d626bf357 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8436.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "bio mass meat" diff --git a/html/changelogs/AutoChangeLog-pr-8437.yml b/html/changelogs/AutoChangeLog-pr-8437.yml new file mode 100644 index 0000000000..4257a801c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8437.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "more box options" + - bugfix: "a lack of replaceable boxes" diff --git a/html/changelogs/AutoChangeLog-pr-8439.yml b/html/changelogs/AutoChangeLog-pr-8439.yml new file mode 100644 index 0000000000..1e4bd2efae --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8439.yml @@ -0,0 +1,6 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "EMPs now flick off stunbatons, they can be turned back on immediately by the user anyway." + - balance: "Stunbatons now very slowly consume charge whilst kept on, at a rate of 4/1000th of a standard batoning charge cost per tick." + - balance: "Softened up the charge cost checks to stop the above update from practically reducing the maximum uses of a stun baton by one. Now, should the remaining charge be lower than the hit cost, the resulting stun will be be proportional to the remaining charge divided by the hitcost, within a limit under which the stun batoning just won't happen." diff --git a/html/changelogs/AutoChangeLog-pr-8442.yml b/html/changelogs/AutoChangeLog-pr-8442.yml new file mode 100644 index 0000000000..e73c67c6dc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8442.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "clothing needing a emag" diff --git a/html/changelogs/AutoChangeLog-pr-8443.yml b/html/changelogs/AutoChangeLog-pr-8443.yml new file mode 100644 index 0000000000..1b1f82977b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8443.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - tweak: "The timer for stripping an item off of a spaceman is no longer interrupted by your active held item changing. This means you no longer have to worry about filling both of your hands when you're stripping items off of someone." diff --git a/html/changelogs/AutoChangeLog-pr-8448.yml b/html/changelogs/AutoChangeLog-pr-8448.yml new file mode 100644 index 0000000000..e670ffc0f4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8448.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "4 - > 5" diff --git a/html/changelogs/AutoChangeLog-pr-8449.yml b/html/changelogs/AutoChangeLog-pr-8449.yml new file mode 100644 index 0000000000..c2c397cdd0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8449.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "5->6" diff --git a/html/changelogs/AutoChangeLog-pr-8450.yml b/html/changelogs/AutoChangeLog-pr-8450.yml new file mode 100644 index 0000000000..8afa74c68c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8450.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "4tc - > 2tc" diff --git a/html/changelogs/AutoChangeLog-pr-8452.yml b/html/changelogs/AutoChangeLog-pr-8452.yml new file mode 100644 index 0000000000..2b4e430757 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8452.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "mulligan costs 4 - > 3" diff --git a/html/changelogs/AutoChangeLog-pr-8453.yml b/html/changelogs/AutoChangeLog-pr-8453.yml new file mode 100644 index 0000000000..cda1843779 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8453.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "Tuberculosis 12tc - > 8tc" diff --git a/html/changelogs/AutoChangeLog-pr-8454.yml b/html/changelogs/AutoChangeLog-pr-8454.yml new file mode 100644 index 0000000000..4cc6d98df1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8454.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "15 - >10" + - bugfix: "both bags have the same name" diff --git a/html/changelogs/AutoChangeLog-pr-8455.yml b/html/changelogs/AutoChangeLog-pr-8455.yml new file mode 100644 index 0000000000..e7944f5869 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8455.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "5 - > 2" diff --git a/html/changelogs/AutoChangeLog-pr-8456.yml b/html/changelogs/AutoChangeLog-pr-8456.yml new file mode 100644 index 0000000000..3ff35b1c09 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8456.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "3 -> 1" diff --git a/html/changelogs/AutoChangeLog-pr-8459.yml b/html/changelogs/AutoChangeLog-pr-8459.yml new file mode 100644 index 0000000000..ebce2f0db1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8459.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "2 < - 4" diff --git a/html/changelogs/AutoChangeLog-pr-8460.yml b/html/changelogs/AutoChangeLog-pr-8460.yml new file mode 100644 index 0000000000..39af97ef12 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8460.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "1->2 and ultra" diff --git a/html/changelogs/AutoChangeLog-pr-8463.yml b/html/changelogs/AutoChangeLog-pr-8463.yml new file mode 100644 index 0000000000..a6c8d05522 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8463.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "shield + crafting" diff --git a/html/changelogs/AutoChangeLog-pr-8465.yml b/html/changelogs/AutoChangeLog-pr-8465.yml new file mode 100644 index 0000000000..91556b4afc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8465.yml @@ -0,0 +1,4 @@ +author: "Useroth" +delete-after: True +changes: + - bugfix: "After the PR which raised the ammo capacity of said magazines, due to the code, they ended up with an invalid icon state. Fixed through changing the icon state name in the icon file." diff --git a/html/changelogs/AutoChangeLog-pr-8466.yml b/html/changelogs/AutoChangeLog-pr-8466.yml new file mode 100644 index 0000000000..a3cffc8f59 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8466.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - bugfix: "Atmos and Station alerts should be more alerting." diff --git a/html/changelogs/AutoChangeLog-pr-8470.yml b/html/changelogs/AutoChangeLog-pr-8470.yml new file mode 100644 index 0000000000..39399c0724 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8470.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "Buffs condensed capsaicin, a yet another feature previously dunked by stam combat." + - balance: "speeds up pepper spray puffs." diff --git a/html/changelogs/AutoChangeLog-pr-8473.yml b/html/changelogs/AutoChangeLog-pr-8473.yml new file mode 100644 index 0000000000..a4743c9a39 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8473.yml @@ -0,0 +1,10 @@ +author: "Useroth" +delete-after: True +changes: + - rscadd: "Taeclowndo shoes which grant the four following abilities: +- Conjuring a cream pie right into their hand. Every three seconds. +- Making a banana peel appear out of thin air at the tile of the clown's choice. Every ten seconds. +- Mega HoNk. A touch-ranged, very small AOE ability, with effect equal to being honked by a Honkerblast on a clown mech, with the effects halved for anyone who isn't its direct target. Every ten seconds. +- Bluespace Banana Pie. You don't throw this one... not right away at least. This baby can fit an entire body inside. Good for disposal of evidence. 25 second-long action, 45 second cooldown. Also produces a \"[victim's name] cream pie\". The body drops out of the pie if you splat it somewhere or destroy the pie. If you eat it, it will chestburst out of you a'la monkey cube. + +It's a 14 TC item for traitor clowns and a 12 TC item for clown-ops." diff --git a/html/changelogs/AutoChangeLog-pr-8476.yml b/html/changelogs/AutoChangeLog-pr-8476.yml new file mode 100644 index 0000000000..551a443f94 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8476.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "hierophant movment and melee attack" diff --git a/html/changelogs/AutoChangeLog-pr-8477.yml b/html/changelogs/AutoChangeLog-pr-8477.yml new file mode 100644 index 0000000000..f5478ed178 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8477.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - rscadd: "Ported the zulie cloak and blackredgold coat donor items from RP." diff --git a/html/changelogs/AutoChangeLog-pr-8482.yml b/html/changelogs/AutoChangeLog-pr-8482.yml new file mode 100644 index 0000000000..095f93a7a3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8482.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "fixes eyestabbing people with cutlery while being a pacifist." diff --git a/html/changelogs/AutoChangeLog-pr-8483.yml b/html/changelogs/AutoChangeLog-pr-8483.yml new file mode 100644 index 0000000000..2e3b35ca92 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8483.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by mrhugo13 on tgstation13)" +delete-after: True +changes: + - rscadd: "The Syndicate has decided to equip their Syndicate leaders operative (Aswell as their clown counterparts) with the new Combat Glove Plus! The new Combat Glove Plus does everything the old boring Combat Gloves does but with the added extra of learning Krav Maga upon wearing them, any other Syndicate operative who wants to get in on the action will have to pay 5tc." diff --git a/html/changelogs/AutoChangeLog-pr-8485.yml b/html/changelogs/AutoChangeLog-pr-8485.yml new file mode 100644 index 0000000000..abc79f1f30 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8485.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "More plushies" + - tweak: "attack verbs and descs" diff --git a/html/changelogs/AutoChangeLog-pr-8489.yml b/html/changelogs/AutoChangeLog-pr-8489.yml new file mode 100644 index 0000000000..5e90c56d67 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8489.yml @@ -0,0 +1,5 @@ +author: "Coolgat3" +delete-after: True +changes: + - rscadd: "Added combat gloves sprite" + - imageadd: "Added said sprite" diff --git a/html/changelogs/AutoChangeLog-pr-8491.yml b/html/changelogs/AutoChangeLog-pr-8491.yml new file mode 100644 index 0000000000..0e82e809f7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8491.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Reduces goonchat lag from being blasted by pellets and bullets repeatedly whilst wearing armor by properly removing the armor protection texts this times." + - spellcheck: "also reduced the size of armor protection messages in general. they clog up the chat box." diff --git a/html/changelogs/AutoChangeLog-pr-8494.yml b/html/changelogs/AutoChangeLog-pr-8494.yml new file mode 100644 index 0000000000..2e4d7ac65e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8494.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "bone satchles" diff --git a/html/changelogs/AutoChangeLog-pr-8495.yml b/html/changelogs/AutoChangeLog-pr-8495.yml new file mode 100644 index 0000000000..92777ef8b0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8495.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - tweak: "\"Unwillingly\" eating food now sends a warning message instead of a notice. Unable to stuff food down your throat sends a danger message instead of a warning message." diff --git a/html/changelogs/AutoChangeLog-pr-8500.yml b/html/changelogs/AutoChangeLog-pr-8500.yml new file mode 100644 index 0000000000..09bfbd9748 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8500.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - balance: "rebalanced stunslugs" diff --git a/html/changelogs/AutoChangeLog-pr-8501.yml b/html/changelogs/AutoChangeLog-pr-8501.yml new file mode 100644 index 0000000000..fba27c4d52 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8501.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "colored boxes, and more types" diff --git a/html/changelogs/AutoChangeLog-pr-8503.yml b/html/changelogs/AutoChangeLog-pr-8503.yml new file mode 100644 index 0000000000..f6c4a7dc75 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8503.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "harm and such" + - balance: "item classes" diff --git a/html/changelogs/AutoChangeLog-pr-8504.yml b/html/changelogs/AutoChangeLog-pr-8504.yml new file mode 100644 index 0000000000..4e80d02845 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8504.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "resonators being so shitty" diff --git a/html/changelogs/AutoChangeLog-pr-8506.yml b/html/changelogs/AutoChangeLog-pr-8506.yml new file mode 100644 index 0000000000..6711217fb5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8506.yml @@ -0,0 +1,5 @@ +author: "CalamaBanana" +delete-after: True +changes: + - rscadd: "Added Deer taur" + - rscadd: "Added Elf ears to mammals" diff --git a/html/changelogs/AutoChangeLog-pr-8514.yml b/html/changelogs/AutoChangeLog-pr-8514.yml new file mode 100644 index 0000000000..f1d01a97e4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8514.yml @@ -0,0 +1,6 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds several new toy loot to the arcade machine." + - balance: "Rebalanced the arcade machine loot. Battlemachines now have a 0.5 second delay instead of a second delay between actions." + - bugfix: "Fixed a bug that would not allow the one in a million pulse rifle to spawn." diff --git a/html/changelogs/AutoChangeLog-pr-8515.yml b/html/changelogs/AutoChangeLog-pr-8515.yml new file mode 100644 index 0000000000..99e414f5e1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8515.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixes stunbatons icon not properly updating on cell removal and insertion." + - tweak: "Allows lower charge cells to be used with stun batons, and thus single use crapshots batons." diff --git a/html/changelogs/AutoChangeLog-pr-8516.yml b/html/changelogs/AutoChangeLog-pr-8516.yml new file mode 100644 index 0000000000..f7419f1add --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8516.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "Adds in a 7 seconds delay to the jackhammer dismantling a superheated clockwork wall." diff --git a/html/changelogs/AutoChangeLog-pr-8517.yml b/html/changelogs/AutoChangeLog-pr-8517.yml new file mode 100644 index 0000000000..5e14c1c696 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8517.yml @@ -0,0 +1,6 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Added visible and hidden testicles" + - rscadd: "Added multi-boob support. Now you can have two or three pairs of breasts." + - bugfix: "fixed missing vagina and breast sprites" diff --git a/html/changelogs/AutoChangeLog-pr-8518.yml b/html/changelogs/AutoChangeLog-pr-8518.yml new file mode 100644 index 0000000000..cbc34893b6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8518.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "escape pods emergency suits storage can now be busted open by emags or excessive damage." + - bugfix: "Fixes alt click bypassing the escape pods' suits storage lock." diff --git a/html/changelogs/AutoChangeLog-pr-8522.yml b/html/changelogs/AutoChangeLog-pr-8522.yml new file mode 100644 index 0000000000..eb646034fd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8522.yml @@ -0,0 +1,4 @@ +author: "Useroth" +delete-after: True +changes: + - tweak: "The tentacle now directly puts the item in your hands, instead of toggling your throwing and tossing it at you. Tentacles suffer from ranged inaccuracies as if they were guns, I think it's enough of an inconvenience." diff --git a/html/changelogs/AutoChangeLog-pr-8524.yml b/html/changelogs/AutoChangeLog-pr-8524.yml new file mode 100644 index 0000000000..66a7b6d456 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8524.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - rscadd: "Adds a new trait \"Buns of Steel\" that makes you immune to the effects of ass slapping, and temporarily makes the user's arm useless like a stun baton hit. It costs 0 points." diff --git a/html/changelogs/AutoChangeLog-pr-8525.yml b/html/changelogs/AutoChangeLog-pr-8525.yml new file mode 100644 index 0000000000..ef26cf1a4b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8525.yml @@ -0,0 +1,5 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - bugfix: "Game braking bug +critical: bug fix" diff --git a/html/changelogs/AutoChangeLog-pr-8528.yml b/html/changelogs/AutoChangeLog-pr-8528.yml new file mode 100644 index 0000000000..0dece1e63d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8528.yml @@ -0,0 +1,7 @@ +author: "Poojawa" +delete-after: True +changes: + - bugfix: "fixed prosthetic hands being invisible" + - bugfix: "male foxes exist again" + - bugfix: "female chest markings improved from being too dark in comparison to their other colors, blending better" + - bugfix: "Markings behave better on non-organic limbs." diff --git a/html/changelogs/AutoChangeLog-pr-8534.yml b/html/changelogs/AutoChangeLog-pr-8534.yml new file mode 100644 index 0000000000..5c76fbdf36 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8534.yml @@ -0,0 +1,4 @@ +author: "dtfe3" +delete-after: True +changes: + - rscadd: "Pink Panties" diff --git a/html/changelogs/AutoChangeLog-pr-8538.yml b/html/changelogs/AutoChangeLog-pr-8538.yml new file mode 100644 index 0000000000..7349a31683 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8538.yml @@ -0,0 +1,4 @@ +author: "dtfe3" +delete-after: True +changes: + - rscadd: "Twintails" diff --git a/html/changelogs/AutoChangeLog-pr-8540.yml b/html/changelogs/AutoChangeLog-pr-8540.yml new file mode 100644 index 0000000000..895b80bfa6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8540.yml @@ -0,0 +1,4 @@ +author: "BurgerBB" +delete-after: True +changes: + - balance: "Ass slapping blowback from the Buns of Steel perk now deals 20 stamina damage instead of 50, and no brute damage." diff --git a/html/changelogs/AutoChangeLog-pr-8541.yml b/html/changelogs/AutoChangeLog-pr-8541.yml new file mode 100644 index 0000000000..82e76fe74b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8541.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "items to syndie surgery bags" diff --git a/html/changelogs/AutoChangeLog-pr-8543.yml b/html/changelogs/AutoChangeLog-pr-8543.yml new file mode 100644 index 0000000000..1e1ce8922b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8543.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "SNOW CONES" diff --git a/html/changelogs/AutoChangeLog-pr-8544.yml b/html/changelogs/AutoChangeLog-pr-8544.yml new file mode 100644 index 0000000000..1641eed42e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8544.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "carts buy-able cargo" diff --git a/html/changelogs/AutoChangeLog-pr-8547.yml b/html/changelogs/AutoChangeLog-pr-8547.yml new file mode 100644 index 0000000000..51c2252138 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8547.yml @@ -0,0 +1,6 @@ +author: "Ghommie (original PRs by Naksu and XDTM)" +delete-after: True +changes: + - bugfix: "Transferring quirks now properly removes the roundstart trait from the person losing the quirk." + - bugfix: "Roundstart traits no longer block the removal of other sources of that trait." + - code_imp: "status traits are now a datum var, the accessors are now defines rather than functions." diff --git a/html/changelogs/AutoChangeLog-pr-8548.yml b/html/changelogs/AutoChangeLog-pr-8548.yml new file mode 100644 index 0000000000..cd49f38686 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8548.yml @@ -0,0 +1,4 @@ +author: "dtfe3" +delete-after: True +changes: + - rscadd: "Schoolgirl outfits for the loadout menu!" diff --git a/html/changelogs/AutoChangeLog-pr-8549.yml b/html/changelogs/AutoChangeLog-pr-8549.yml new file mode 100644 index 0000000000..32b99d1d49 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8549.yml @@ -0,0 +1,6 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - tweak: "selling/time to craft" + - bugfix: "crafting problems, and red stamp exsplote" + - rscadd: "gives paper work sprites that are nicer" diff --git a/html/changelogs/AutoChangeLog-pr-8551.yml b/html/changelogs/AutoChangeLog-pr-8551.yml new file mode 100644 index 0000000000..738b410e26 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8551.yml @@ -0,0 +1,4 @@ +author: "tigercat2000@Paradise" +delete-after: True +changes: + - bugfix: "fixed invalid characters breaking chat output for that message" diff --git a/html/changelogs/AutoChangeLog-pr-8552.yml b/html/changelogs/AutoChangeLog-pr-8552.yml new file mode 100644 index 0000000000..2b63c79756 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8552.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by LaKiller8)" +delete-after: True +changes: + - bugfix: "Goonchat options should now save properly." diff --git a/html/changelogs/AutoChangeLog-pr-8553.yml b/html/changelogs/AutoChangeLog-pr-8553.yml new file mode 100644 index 0000000000..e89e04537b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8553.yml @@ -0,0 +1,5 @@ +author: "Poojawa" +delete-after: True +changes: + - tweak: "tweaked the name of Sublter to distinguish its use" + - tweak: "Gave a hint for vore posting." diff --git a/html/changelogs/AutoChangeLog-pr-8554.yml b/html/changelogs/AutoChangeLog-pr-8554.yml new file mode 100644 index 0000000000..8bf00955b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8554.yml @@ -0,0 +1,10 @@ +author: "Ghommie (original PRs by Nichlas0010 and ShizCalev)" +delete-after: True +changes: + - tweak: "AI core display screen can now be set in character preferences." + - bugfix: "AI core display screen will now be restore when revived." + - spellcheck: "Corrected some inconsistent capitalization in the player preferences screen." + - imageadd: "Readded some forgotten AI sprites." + - bugfix: "Fixed Hades AI death animation not playing." + - tweak: "the AI icon-selection menu now uses a radial." + - imageadd: "Added in the death icon_states for the \"TechDemon\" AI screen." diff --git a/html/changelogs/AutoChangeLog-pr-8555.yml b/html/changelogs/AutoChangeLog-pr-8555.yml new file mode 100644 index 0000000000..bb2c116dfa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8555.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - code_imp: "Ported some radials code updates." + - rscadd: "Ported the RCL wiring menu and a comfier RCD interface." diff --git a/html/changelogs/AutoChangeLog-pr-8556.yml b/html/changelogs/AutoChangeLog-pr-8556.yml new file mode 100644 index 0000000000..e84af4f774 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8556.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - rscadd: "Readded Ninja speech modifications with their mask" diff --git a/html/changelogs/AutoChangeLog-pr-8557.yml b/html/changelogs/AutoChangeLog-pr-8557.yml new file mode 100644 index 0000000000..601f70f2cb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8557.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original pr by Dennok on tgstation)" +delete-after: True +changes: + - bugfix: "Now you don't lose your pulled thing on the z level edge." diff --git a/html/changelogs/AutoChangeLog-pr-8558.yml b/html/changelogs/AutoChangeLog-pr-8558.yml new file mode 100644 index 0000000000..6bb951f8a2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8558.yml @@ -0,0 +1,4 @@ +author: "Ghommie (Original PR by coiax)" +delete-after: True +changes: + - refactor: "atom/var/container_type has been moved into datum/reagents/var/reagents_holder_flags. There should be no visible changes to effects." diff --git a/html/changelogs/AutoChangeLog-pr-8559.yml b/html/changelogs/AutoChangeLog-pr-8559.yml new file mode 100644 index 0000000000..aee1727348 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8559.yml @@ -0,0 +1,4 @@ +author: "Ghommie (original PR by Naksu)" +delete-after: True +changes: + - code_imp: "get_area() is now a define rather than a proc." diff --git a/html/changelogs/AutoChangeLog-pr-8560.yml b/html/changelogs/AutoChangeLog-pr-8560.yml new file mode 100644 index 0000000000..aa1be89e09 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8560.yml @@ -0,0 +1,5 @@ +author: "Ghommie (original PR by 4dplanner)" +delete-after: True +changes: + - bugfix: "thrown objects (but not mobs) no longer hit the thrower" + - bugfix: "mirror shield rebound no longer depends on the original thrower's momentum" diff --git a/html/changelogs/AutoChangeLog-pr-8562.yml b/html/changelogs/AutoChangeLog-pr-8562.yml new file mode 100644 index 0000000000..a93babfdae --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8562.yml @@ -0,0 +1,5 @@ +author: "AnalWerewolf" +delete-after: True +changes: + - rscadd: "Fritz plushie" + - rscadd: "Donor item" diff --git a/html/changelogs/AutoChangeLog-pr-8566.yml b/html/changelogs/AutoChangeLog-pr-8566.yml new file mode 100644 index 0000000000..085b74e87a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8566.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "A milder combat stance message will show up if the user switch combat mode on while on help intent." diff --git a/html/changelogs/AutoChangeLog-pr-8567.yml b/html/changelogs/AutoChangeLog-pr-8567.yml new file mode 100644 index 0000000000..3814607aaa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8567.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - rscadd: "You can now use RPDs on windows and grilles." diff --git a/html/changelogs/AutoChangeLog-pr-8569.yml b/html/changelogs/AutoChangeLog-pr-8569.yml new file mode 100644 index 0000000000..9a51ab1099 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8569.yml @@ -0,0 +1,4 @@ +author: "dtfe3" +delete-after: True +changes: + - tweak: "Now the fox ears are located in front of hair meaning they now behave much like cat ears, that being they are on-top of the hair layer." diff --git a/icons/effects/crayondecal.dmi b/icons/effects/crayondecal.dmi index bb48832025..fcd27698e7 100644 Binary files a/icons/effects/crayondecal.dmi and b/icons/effects/crayondecal.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 70a5a71652..29086033c8 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/mob/AI.dmi b/icons/mob/AI.dmi index dac88d62fc..7de8152118 100644 Binary files a/icons/mob/AI.dmi and b/icons/mob/AI.dmi differ diff --git a/icons/mob/actions/actions_items.dmi b/icons/mob/actions/actions_items.dmi index ca380a5376..39e2ea0584 100644 Binary files a/icons/mob/actions/actions_items.dmi and b/icons/mob/actions/actions_items.dmi differ diff --git a/icons/mob/aibots.dmi b/icons/mob/aibots.dmi index 913a0dff02..f4049abc41 100644 Binary files a/icons/mob/aibots.dmi and b/icons/mob/aibots.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 90c7e42c8e..e3c80708c3 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/custom_w.dmi b/icons/mob/custom_w.dmi index 1101f22d2e..dcb36e7b47 100644 Binary files a/icons/mob/custom_w.dmi and b/icons/mob/custom_w.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 3da5fc08e2..09d6fe5374 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 047f080946..10474f94da 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index b479fa0764..9540599364 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/human_parts_greyscale.dmi b/icons/mob/human_parts_greyscale.dmi index a8d2a2aef3..f49a27fda4 100644 Binary files a/icons/mob/human_parts_greyscale.dmi and b/icons/mob/human_parts_greyscale.dmi differ diff --git a/icons/mob/inhands/equipment/backpack_lefthand.dmi b/icons/mob/inhands/equipment/backpack_lefthand.dmi index c37d12e2c0..0e466486c5 100644 Binary files a/icons/mob/inhands/equipment/backpack_lefthand.dmi and b/icons/mob/inhands/equipment/backpack_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/backpack_righthand.dmi b/icons/mob/inhands/equipment/backpack_righthand.dmi index 08e05e055e..1c265a4137 100644 Binary files a/icons/mob/inhands/equipment/backpack_righthand.dmi and b/icons/mob/inhands/equipment/backpack_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/hammers_lefthand.dmi b/icons/mob/inhands/weapons/hammers_lefthand.dmi index acdb551174..0ea340f1f3 100644 Binary files a/icons/mob/inhands/weapons/hammers_lefthand.dmi and b/icons/mob/inhands/weapons/hammers_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/hammers_righthand.dmi b/icons/mob/inhands/weapons/hammers_righthand.dmi index b20dce8d0a..dbe34513ea 100644 Binary files a/icons/mob/inhands/weapons/hammers_righthand.dmi and b/icons/mob/inhands/weapons/hammers_righthand.dmi differ diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi index b91c29e03f..3c126daba6 100644 Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ diff --git a/icons/mob/radial.dmi b/icons/mob/radial.dmi index ba3179a421..cfdd0e549a 100644 Binary files a/icons/mob/radial.dmi and b/icons/mob/radial.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index b518157bb5..0f3438dfc4 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/underwear.dmi b/icons/mob/underwear.dmi index 385cd21516..0b63685668 100644 Binary files a/icons/mob/underwear.dmi and b/icons/mob/underwear.dmi differ diff --git a/icons/mob/underwear_old.dmi b/icons/mob/underwear_old.dmi new file mode 100644 index 0000000000..5e16a473ba Binary files /dev/null and b/icons/mob/underwear_old.dmi differ diff --git a/icons/obj/Cryogenic2.dmi b/icons/obj/Cryogenic2.dmi index 764e67ebf0..58d3ac631d 100644 Binary files a/icons/obj/Cryogenic2.dmi and b/icons/obj/Cryogenic2.dmi differ diff --git a/icons/obj/assemblies/electronic_setups.dmi b/icons/obj/assemblies/electronic_setups.dmi index 58ef0903be..5804c3f8ab 100644 Binary files a/icons/obj/assemblies/electronic_setups.dmi and b/icons/obj/assemblies/electronic_setups.dmi differ diff --git a/icons/obj/atmospherics/components/unary_devices.dmi b/icons/obj/atmospherics/components/unary_devices.dmi index e54f6034e4..e18ee92849 100644 Binary files a/icons/obj/atmospherics/components/unary_devices.dmi and b/icons/obj/atmospherics/components/unary_devices.dmi differ diff --git a/icons/obj/atmospherics/pipes/pipe_item.dmi b/icons/obj/atmospherics/pipes/pipe_item.dmi index e89db9f02b..b17ecb1a15 100644 Binary files a/icons/obj/atmospherics/pipes/pipe_item.dmi and b/icons/obj/atmospherics/pipes/pipe_item.dmi differ diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi index 5b8fc246cb..56cfdf468b 100644 Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index a90efcdfea..619db9290d 100644 Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index d905979c9c..8256c1fc07 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi index 0f3668ce10..0bdaa36e62 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 8e0359e6b3..2cb473fb00 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/cryo_mobs.dmi b/icons/obj/cryo_mobs.dmi index 0707110de4..9b5bd6d289 100644 Binary files a/icons/obj/cryo_mobs.dmi and b/icons/obj/cryo_mobs.dmi differ diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi index a05fbb72ab..9faaf8f81a 100644 Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index becb58568f..55c33e5e83 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/food/snowcones.dmi b/icons/obj/food/snowcones.dmi new file mode 100644 index 0000000000..bdaa89fdf7 Binary files /dev/null and b/icons/obj/food/snowcones.dmi differ diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi index e3ec4171ad..4dec451008 100644 Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index 0ee0e3d2d1..e4a39903b3 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 543d57ff56..655d37d4a6 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/machines/cloning.dmi b/icons/obj/machines/cloning.dmi index de68060740..0deb59aff8 100644 Binary files a/icons/obj/machines/cloning.dmi and b/icons/obj/machines/cloning.dmi differ diff --git a/icons/obj/plushes.dmi b/icons/obj/plushes.dmi index 7ca7b068b0..8e845d9710 100644 Binary files a/icons/obj/plushes.dmi and b/icons/obj/plushes.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 0c9155827b..9467e8f818 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 4ab614cf83..1a3b344566 100755 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index 1454d17a16..8f6b844a23 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ diff --git a/modular_citadel/code/datums/mood_events/generic_positive_events.dm b/modular_citadel/code/datums/mood_events/generic_positive_events.dm index 4c581d8184..7b989d7700 100644 --- a/modular_citadel/code/datums/mood_events/generic_positive_events.dm +++ b/modular_citadel/code/datums/mood_events/generic_positive_events.dm @@ -21,14 +21,14 @@ timeout = 3000 /datum/mood_event/orgasm - description = "I came!" //funny meme haha + description = "I came!\n" //funny meme haha mood_change = 3 timeout = 1000 - + /datum/mood_event/fedpred description = "I've devoured someone!\n" mood_change = 3 /datum/mood_event/fedprey description = "It feels quite cozy in here.\n" - mood_change = 3 \ No newline at end of file + mood_change = 3 diff --git a/modular_citadel/code/datums/mood_events/moodular.dm b/modular_citadel/code/datums/mood_events/moodular.dm index b764c0027e..b53ce417e8 100644 --- a/modular_citadel/code/datums/mood_events/moodular.dm +++ b/modular_citadel/code/datums/mood_events/moodular.dm @@ -7,12 +7,7 @@ if(mood) mood.add_event("hugbox", /datum/mood_event/hugbox) -// headpats (IMPORTANT) -/mob/living/carbon/help_shake_act(mob/living/carbon/M) - . = ..() - GET_COMPONENT_FROM(mood, /datum/component/mood, src) - if(mood) - mood.add_event("headpat", /datum/mood_event/headpat) +//Removed headpats here, duplicate code? // plush petting /obj/item/toy/plush/attack_self(mob/user) diff --git a/modular_citadel/code/datums/traits/neutral.dm b/modular_citadel/code/datums/traits/neutral.dm index 264dbfef0a..05aeb27361 100644 --- a/modular_citadel/code/datums/traits/neutral.dm +++ b/modular_citadel/code/datums/traits/neutral.dm @@ -4,6 +4,7 @@ name = "Nymphomania" desc = "You're always feeling a bit in heat. Also, you get aroused faster than usual." value = 0 + mob_trait = TRAIT_NYMPHO gain_text = "You are feeling extra wild." lose_text = "You don't feel that burning sensation anymore." @@ -22,3 +23,11 @@ if(M.canbearoused == FALSE) to_chat(quirk_holder, "Having high libido is useless when you can't feel arousal at all!") qdel(src) + +/datum/quirk/maso + name = "Masochism" + desc = "You are aroused by pain." + value = 0 + mob_trait = TRAIT_MASO + gain_text = "You desire to be hurt." + lose_text = "Pain has become less exciting for you." diff --git a/modular_citadel/code/game/gamemodes/gangs/dominator.dm b/modular_citadel/code/game/gamemodes/gangs/dominator.dm new file mode 100644 index 0000000000..0d89c78010 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/dominator.dm @@ -0,0 +1,243 @@ +#define DOM_BLOCKED_SPAM_CAP 6 +//32 instead of 40 for safety reasons. How many turfs aren't walls around dominator for it to work +#define DOM_REQUIRED_TURFS 32 +#define DOM_HULK_HITS_REQUIRED 10 + +/obj/machinery/dominator + name = "dominator" + desc = "A visibly sinister device. Looks like you can break it if you hit it enough." + icon = 'icons/obj/machines/dominator.dmi' + icon_state = "dominator" + density = TRUE + anchored = TRUE + layer = HIGH_OBJ_LAYER + max_integrity = 300 + integrity_failure = 100 + armor = list("melee" = 20, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 10, "acid" = 70) + var/datum/team/gang/gang + var/operating = FALSE //false=standby or broken, true=takeover + var/warned = FALSE //if this device has set off the warning at <3 minutes yet + var/spam_prevention = DOM_BLOCKED_SPAM_CAP //first message is immediate + var/datum/effect_system/spark_spread/spark_system + var/obj/effect/countdown/dominator/countdown + +/obj/machinery/dominator/Initialize() + . = ..() + set_light(l_range = 2, l_power = 0.75) + GLOB.poi_list |= src + spark_system = new + spark_system.set_up(5, TRUE, src) + countdown = new(src) + update_icon() + +/obj/machinery/dominator/Destroy() + if(!(stat & BROKEN)) + set_broken() + GLOB.poi_list.Remove(src) + gang = null + QDEL_NULL(spark_system) + QDEL_NULL(countdown) + STOP_PROCESSING(SSmachines, src) + return ..() + +/obj/machinery/dominator/emp_act(severity) + take_damage(100, BURN, "energy", 0) + ..() + +/obj/machinery/dominator/hulk_damage() + return (max_integrity - integrity_failure) / DOM_HULK_HITS_REQUIRED + +/obj/machinery/dominator/tesla_act() + qdel(src) + +/obj/machinery/dominator/update_icon() + cut_overlays() + if(!(stat & BROKEN)) + icon_state = "dominator-active" + if(operating) + var/mutable_appearance/dominator_overlay = mutable_appearance('icons/obj/machines/dominator.dmi', "dominator-overlay") + if(gang) + dominator_overlay.color = gang.color + add_overlay(dominator_overlay) + else + icon_state = "dominator" + if(obj_integrity/max_integrity < 0.66) + add_overlay("damage") + else + icon_state = "dominator-broken" + +/obj/machinery/dominator/examine(mob/user) + ..() + if(stat & BROKEN) + return + + if(gang && gang.domination_time != NOT_DOMINATING) + if(gang.domination_time > world.time) + to_chat(user, "Hostile Takeover in progress. Estimated [gang.domination_time_remaining()] seconds remain.") + else + to_chat(user, "Hostile Takeover of [station_name()] successful. Have a great day.") + else + to_chat(user, "System on standby.") + to_chat(user, "System Integrity: [round((obj_integrity/max_integrity)*100,1)]%") + +/obj/machinery/dominator/process() + ..() + if(gang && gang.domination_time != NOT_DOMINATING) + var/time_remaining = gang.domination_time_remaining() + if(time_remaining > 0) + if(excessive_walls_check()) + gang.domination_time += 20 + if(spam_prevention < DOM_BLOCKED_SPAM_CAP) + spam_prevention++ + else + playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0) // Play sound buzz-two.ogg, not before cause its annoying. + gang.message_gangtools("Warning: There are too many walls around your gang's dominator, its signal is being blocked!") + say("Error: Takeover signal is currently blocked! There are too many walls within 3 standard units of this device.") + spam_prevention = 0 + return + . = TRUE + playsound(loc, 'sound/items/timer.ogg', 10, 0) + if(!warned && (time_remaining < 180)) + warned = TRUE + var/area/domloc = get_area(loc) + gang.message_gangtools("Less than 3 minutes remains in hostile takeover. Defend your dominator at [domloc.map_name]!") + for(var/G in GLOB.gangs) + var/datum/team/gang/tempgang = G + if(tempgang != gang) + tempgang.message_gangtools("WARNING: [gang.name] Gang takeover imminent. Their dominator at [domloc.map_name] must be destroyed!",1,1) + else + Cinematic(CINEMATIC_MALF,world) //Here is the gang victory trigger on the dominator ending. + gang.winner = TRUE + SSticker.force_ending = TRUE + + if(!.) + STOP_PROCESSING(SSmachines, src) + +/obj/machinery/dominator/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(src, 'sound/effects/bang.ogg', 50, 1) + else + playsound(loc, 'sound/weapons/tap.ogg', 50, 1) + if(BURN) + playsound(src.loc, 'sound/items/welder.ogg', 100, 1) + +/obj/machinery/dominator/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) + . = ..() + if(.) + if(obj_integrity/max_integrity > 0.66) + if(prob(damage_amount*2)) + spark_system.start() + else if(!(stat & BROKEN)) + spark_system.start() + update_icon() + + +/obj/machinery/dominator/obj_break(damage_flag) + if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1)) + set_broken() + +/obj/machinery/dominator/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + if(!(stat & BROKEN)) + set_broken() + new /obj/item/stack/sheet/plasteel(src.loc) + qdel(src) + +/obj/machinery/dominator/attacked_by(obj/item/I, mob/living/user) + add_fingerprint(user) + ..() + +/obj/machinery/dominator/attack_hand(mob/user) + if(operating || (stat & BROKEN)) + examine(user) + return + + var/datum/team/gang/tempgang + + var/datum/antagonist/gang/GA = user.mind.has_antag_datum(/datum/antagonist/gang) + if(GA) + tempgang = GA.gang + if(!tempgang) + examine(user) + return + + if(tempgang.domination_time != NOT_DOMINATING) + to_chat(user, "Error: Hostile Takeover is already in progress.") + return + + if(!tempgang.dom_attempts) + to_chat(user, "Error: Unable to breach station network. Firewall has logged our signature and is blocking all further attempts.") + return + + var/time = round(tempgang.determine_domination_time()/60,0.1) + if(alert(user,"A takeover will require [time] minutes.\nYour gang will be unable to gain influence while it is active.\nThe entire station will likely be alerted to it once it starts.\nYou have [tempgang.dom_attempts] attempt(s) remaining. Are you ready?","Confirm","Ready","Later") == "Ready") + if((tempgang.domination_time != NOT_DOMINATING) || !tempgang.dom_attempts || !in_range(src, user) || !isturf(loc)) + return 0 + + var/area/A = get_area(loc) + var/locname = A.map_name + + gang = tempgang + gang.dom_attempts -- + priority_announce("Network breach detected in [locname]. The [gang.name] Gang is attempting to seize control of the station!","Network Alert") + gang.domination() + SSshuttle.registerHostileEnvironment(src) + name = "[gang.name] Gang [name]" + operating = TRUE + update_icon() + + countdown.start() + countdown.color = gang.color + + set_light(l_range = 3, l_power = 0.9) + light_color = gang.color + START_PROCESSING(SSmachines, src) + + gang.message_gangtools("Hostile takeover in progress: Estimated [time] minutes until victory.[gang.dom_attempts ? "" : " This is your final attempt."]") + for(var/G in GLOB.gangs) + var/datum/team/gang/vagos = G + if(vagos != gang) + vagos.message_gangtools("Enemy takeover attempt detected in [locname]: Estimated [time] minutes until our defeat.",1,1) + +/obj/machinery/dominator/proc/excessive_walls_check() // why the fuck was this even a global proc... + var/open = 0 + for(var/turf/T in view(3, src)) + if(!iswallturf(T)) //Check for /closed/wall, isclosedturf() moves it back to just checking for /closed/ which makes it very finicky. + open++ + //to_chat(world, "THE DOMINATOR SEES [open] OPEN TURFS") uncomment to see what this shitty fucking wallcheck sees + if(open < DOM_REQUIRED_TURFS) + return TRUE + else + return FALSE +/obj/machinery/dominator/proc/set_broken() + if(gang) + gang.domination_time = NOT_DOMINATING + + var/takeover_in_progress = FALSE + for(var/G in GLOB.gangs) + var/datum/team/gang/ballas = G + if(ballas.domination_time != NOT_DOMINATING) + takeover_in_progress = TRUE + break + if(!takeover_in_progress) + var/was_stranded = SSshuttle.emergency.mode == SHUTTLE_STRANDED + if(!was_stranded) + priority_announce("All hostile activity within station systems has ceased.","Network Alert") + + if(get_security_level() == "delta") + set_security_level("red") + + SSshuttle.clearHostileEnvironment(src) + gang.message_gangtools("Hostile takeover cancelled: Dominator is no longer operational.[gang.dom_attempts ? " You have [gang.dom_attempts] attempt remaining." : " The station network will have likely blocked any more attempts by us."]",1,1) + + set_light(0) + operating = FALSE + stat |= BROKEN + update_icon() + STOP_PROCESSING(SSmachines, src) + +#undef DOM_BLOCKED_SPAM_CAP +#undef DOM_REQUIRED_TURFS +#undef DOM_HULK_HITS_REQUIRED \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/dominator_countdown.dm b/modular_citadel/code/game/gamemodes/gangs/dominator_countdown.dm new file mode 100644 index 0000000000..c6ae610e37 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/dominator_countdown.dm @@ -0,0 +1,13 @@ +/obj/effect/countdown/dominator + name = "dominator countdown" + text_size = 1 + color = "#e5e5e5" // Overwritten when the dominator starts + +/obj/effect/countdown/dominator/get_value() + var/obj/machinery/dominator/D = attached_to + if(!istype(D)) + return + else if(D.gang && D.gang.domination_time != NOT_DOMINATING) + return D.gang.domination_time_remaining() + else + return "OFFLINE" \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang.dm b/modular_citadel/code/game/gamemodes/gangs/gang.dm new file mode 100644 index 0000000000..00ce3f81a9 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang.dm @@ -0,0 +1,476 @@ +/datum/antagonist/gang + name = "Gangster" + roundend_category = "gangsters" + can_coexist_with_others = FALSE + job_rank = ROLE_GANG + antagpanel_category = "Gang" + var/hud_type = "gangster" + var/message_name = "Gangster" + var/datum/team/gang/gang + +/datum/antagonist/gang/can_be_owned(datum/mind/new_owner) + . = ..() + if(.) + if(new_owner.unconvertable) + return FALSE + +/datum/antagonist/gang/apply_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_gang_icons_added(M) + +/datum/antagonist/gang/remove_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_gang_icons_removed(M) + +/datum/antagonist/gang/get_team() + return gang + +/datum/antagonist/gang/greet() + gang.greet_gangster(owner) + +/datum/antagonist/gang/farewell() + if(ishuman(owner.current)) + owner.current.visible_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!", null, null, null, owner.current) + to_chat(owner, "You are no longer a gangster!") + +/datum/antagonist/gang/on_gain() + if(!gang) + create_team() + ..() + var/mob/living/carbon/human/H = owner.current + if(istype(H)) + if(owner.assigned_role == "Clown") + to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") + H.dna.remove_mutation(CLOWNMUT) + add_to_gang() + +/datum/antagonist/gang/on_removal() + remove_from_gang() + ..() + +/datum/antagonist/gang/create_team(team) + if(!gang) // add_antag_datum calls create_team, so we need to avoid generating two gangs in that case + if(team) + gang = team + return + var/datum/team/gang/gangteam = pick_n_take(GLOB.possible_gangs) + if(gangteam) + gang = new gangteam + +/datum/antagonist/gang/proc/equip_gang() // Bosses get equipped with their tools + return + +/datum/antagonist/gang/proc/update_gang_icons_added(mob/living/M) + var/datum/atom_hud/antag/gang/ganghud = GLOB.huds[gang.hud_entry_num] + if(!ganghud) + ganghud = new/datum/atom_hud/antag/gang() + gang.hud_entry_num = GLOB.huds.len+1 // this is the index the gang hud will be added at + GLOB.huds += ganghud + ganghud.color = gang.color + ganghud.join_hud(M) + set_antag_hud(M,hud_type) + +/datum/antagonist/gang/proc/update_gang_icons_removed(mob/living/M) + var/datum/atom_hud/antag/gang/ganghud = GLOB.huds[gang.hud_entry_num] + if(ganghud) + ganghud.leave_hud(M) + set_antag_hud(M, null) + +/datum/antagonist/gang/proc/can_be_converted(mob/living/candidate) + if(!candidate.mind) + return FALSE + if(!can_be_owned(candidate.mind)) + return FALSE + var/mob/living/carbon/human/H = candidate + if(!istype(H)) //Can't nonhumans + return FALSE + return TRUE + +/datum/antagonist/gang/proc/promote() // Bump up to boss + var/datum/team/gang/old_gang = gang + var/datum/mind/old_owner = owner + owner.remove_antag_datum(/datum/antagonist/gang) + var/datum/antagonist/gang/boss/lieutenant/new_boss = new + new_boss.silent = TRUE + old_owner.add_antag_datum(new_boss,old_gang) + new_boss.silent = FALSE + log_game("[key_name(old_owner)] has been promoted to Lieutenant in the [old_gang.name] Gang") + to_chat(old_owner, "You have been promoted to Lieutenant!") + + +// Admin commands +/datum/antagonist/gang/get_admin_commands() + . = ..() + .["Promote"] = CALLBACK(src,.proc/admin_promote) + .["Set Influence"] = CALLBACK(src, .proc/admin_adjust_influence) + if(gang.domination_time != NOT_DOMINATING) + .["Set domination time left"] = CALLBACK(src, .proc/set_dom_time_left) + +/datum/antagonist/gang/admin_add(datum/mind/new_owner,mob/admin) + var/new_or_existing = input(admin, "Which gang do you want to be assigned to the user?", "Gangs") as null|anything in list("New","Existing") + if(isnull(new_or_existing)) + return + else if(new_or_existing == "New") + var/newgang = input(admin, "Select a gang, or select random to pick a random one.", "New gang") as null|anything in GLOB.possible_gangs + "Random" + if(isnull(newgang)) + return + else if(newgang == "Random") + var/datum/team/gang/G = pick_n_take(GLOB.possible_gangs) + gang = new G + else + GLOB.possible_gangs -= newgang + gang = new newgang + else + if(!GLOB.gangs.len) // no gangs exist + to_chat(admin, "No gangs exist, please create a new one instead.") + return + var/existinggang = input(admin, "Select a gang, or select random to pick a random one.", "Existing gang") as null|anything in GLOB.gangs + "Random" + if(isnull(existinggang)) + return + else if(existinggang == "Random") + gang = pick(GLOB.gangs) + else + gang = existinggang + ..() + return TRUE + +/datum/antagonist/gang/proc/admin_promote(mob/admin) + message_admins("[key_name_admin(admin)] has promoted [owner] to gang boss.") + log_admin("[key_name(admin)] has promoted [owner] to boss.") + promote() + +/datum/antagonist/gang/proc/admin_adjust_influence() + var/inf = input("Influence for [gang.name]","Gang influence", gang.influence) as null | num + if(!isnull(inf)) + gang.influence = inf + message_admins("[key_name_admin(usr)] changed [gang.name]'s influence to [inf].") + log_admin("[key_name(usr)] changed [gang.name]'s influence to [inf].") + +/datum/antagonist/gang/proc/add_to_gang() + gang.add_member(owner) + owner.current.log_message("Has been converted to the [gang.name] gang!", INDIVIDUAL_ATTACK_LOG) + +/datum/antagonist/gang/proc/remove_from_gang() + gang.remove_member(owner) + owner.current.log_message("Has been deconverted from the [gang.name] gang!", INDIVIDUAL_ATTACK_LOG) + +/datum/antagonist/gang/proc/set_dom_time_left(mob/admin) + if(gang.domination_time == NOT_DOMINATING) + return // an admin shouldn't need this + var/seconds = input(admin, "Set the time left for the gang to win, in seconds", "Domination time left") as null|num + if(seconds && seconds > 0) + gang.domination_time = world.time + seconds*10 + gang.message_gangtools("Takeover shortened to [gang.domination_time_remaining()] seconds by your Syndicate benefactors.") + +// Boss type. Those can use gang tools to buy items for their gang, in particular the Dominator, used to win the gamemode, along with more gang tools to promote fellow gangsters to boss status. +/datum/antagonist/gang/boss + name = "Gang boss" + hud_type = "gang_boss" + message_name = "Leader" + +/datum/antagonist/gang/boss/on_gain() + ..() + if(gang) + gang.leaders += owner + +/datum/antagonist/gang/boss/on_removal() + if(gang) + gang.leaders -= owner + ..() + +/datum/antagonist/gang/boss/antag_listing_name() + return ..() + "(Boss)" + +/datum/antagonist/gang/boss/equip_gang(gangtool = TRUE, pen = TRUE, spraycan = TRUE, hud = TRUE) // usually has to be called separately + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + return + + var/list/slots = list ( + "backpack" = SLOT_IN_BACKPACK, + "left pocket" = SLOT_L_STORE, + "right pocket" = SLOT_R_STORE, + "hands" = SLOT_HANDS + ) + + if(gangtool)//Here is where all of the text occurs when a gang boss first spawns in. + var/obj/item/device/gangtool/G = new() + var/where = H.equip_in_one_of_slots(G, slots) + if (!where) + to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a Gangtool.") + else + G.register_device(H) + to_chat(H, "The Gangtool in your [where] will allow you to purchase weapons and equipment, send messages to your gang, and recall the emergency shuttle from anywhere on the station.") + to_chat(H, "As the gang boss, you can also promote your gang members to lieutenant. Unlike regular gangsters, Lieutenants cannot be deconverted and are able to use gangtools too.") + + if(pen) + var/obj/item/pen/gang/T = new() + var/where2 = H.equip_in_one_of_slots(T, slots) + if (!where2) + to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a recruitment pen to start.") + else + to_chat(H, "The recruitment pen in your [where2] will help you get your gang started. Stab unsuspecting crew members with it to recruit them. All gangsters can use these, distribute them to see your gang grow.") + + if(spraycan) + var/obj/item/toy/crayon/spraycan/gang/SC = new(null,gang) + var/where3 = H.equip_in_one_of_slots(SC, slots) + if (!where3) + to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a territory spraycan to start.") + else + to_chat(H, "The territory spraycan in your [where3] can be used to claim areas of the station for your gang. The more territory your gang controls, the more influence you get. All gangsters can use these, so distribute them to grow your influence faster.") + + if(hud) + var/obj/item/clothing/glasses/hud/security/chameleon/C = new(null,gang) + var/where4 = H.equip_in_one_of_slots(C, slots) + if (!where4) + to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a chameleon security HUD.") + else + to_chat(H, "The chameleon security HUD in your [where4] will help you keep track of who is mindshield-implanted, and unable to be recruited.") + +// Admin commands for bosses +/datum/antagonist/gang/boss/admin_add(datum/mind/new_owner,mob/admin) + if(!new_owner.has_antag_datum(parent_type)) + ..() + to_chat(new_owner.current, "You are a member of the [gang.name] Gang leadership now!") + return + promote() + message_admins("[key_name_admin(admin)] has made [new_owner.current] a boss of the [gang.name] gang.") + log_admin("[key_name(admin)] has made [new_owner.current] a boss of the [gang.name] gang.") + to_chat(new_owner.current, "You are a member of the [gang.name] Gang leadership now!") + +/datum/antagonist/gang/boss/get_admin_commands() + . = ..() + . -= "Promote" + .["Take gangtool"] = CALLBACK(src,.proc/admin_take_gangtool) + .["Give gangtool"] = CALLBACK(src,.proc/admin_give_gangtool) + .["Demote"] = CALLBACK(src,.proc/admin_demote) + +/datum/antagonist/gang/boss/proc/demote() + var/old_gang = gang + var/datum/mind/old_owner = owner + silent = TRUE + owner.remove_antag_datum(/datum/antagonist/gang/boss) + var/datum/antagonist/gang/new_gangster = new /datum/antagonist/gang() + new_gangster.silent = TRUE + old_owner.add_antag_datum(new_gangster,old_gang) + new_gangster.silent = FALSE + log_game("[key_name(old_owner)] has been demoted to Gangster in the [gang.name] Gang") + to_chat(old_owner, "The gang has been disappointed of your leader traits! You are a regular gangster now!") + +/datum/antagonist/gang/boss/proc/admin_take_gangtool(mob/admin) + var/list/L = owner.current.get_contents() + var/obj/item/device/gangtool/gangtool = locate() in L + if (!gangtool) + to_chat(admin, "Deleting gangtool failed!") + return + qdel(gangtool) + +/datum/antagonist/gang/boss/proc/admin_give_gangtool(mob/admin) + equip_gang(TRUE, FALSE, FALSE, FALSE) + +/datum/antagonist/gang/boss/proc/admin_demote(datum/mind/target,mob/user) + message_admins("[key_name_admin(user)] has demoted [owner.current] from gang boss.") + log_admin("[key_name(user)] has demoted [owner.current] from gang boss.") + admin_take_gangtool(user) + demote() + +/datum/antagonist/gang/boss/lieutenant + name = "Gang Lieutenant" + message_name = "Lieutenant" + hud_type = "gang_lt" + +#define MAXIMUM_RECALLS 3 +#define INFLUENCE_INTERVAL 1200 //This handles the interval between each count of influence. +// Gang team datum. This handles the gang itself. +/datum/team/gang + name = "Gang" + member_name = "gangster" + var/hud_entry_num // because if you put something other than a number in GLOB.huds, god have mercy on your fucking soul friend + var/list/leaders = list() // bosses + var/max_leaders = MAX_LEADERS_GANG + var/list/territories = list() // territories owned by the gang. + var/list/lost_territories = list() // territories lost by the gang. + var/list/new_territories = list() // territories captured by the gang. + var/list/gangtools = list() + var/domination_time = NOT_DOMINATING + var/dom_attempts = INITIAL_DOM_ATTEMPTS + var/color + var/influence = 0 // influence of the gang, based on how many territories they own. Can be used to buy weapons and tools from a gang uplink. + var/winner // Once the gang wins with a dominator, this becomes true. For roundend credits purposes. + var/list/inner_outfits = list() + var/list/outer_outfits = list() + var/next_point_time + var/recalls = MAXIMUM_RECALLS // Once this reaches 0, this gang cannot force recall the shuttle with their gangtool anymore + +/datum/team/gang/New(starting_members) + . = ..() + GLOB.gangs += src + if(starting_members) + if(islist(starting_members)) + for(var/datum/mind/groveboss in starting_members) + leaders += groveboss + var/datum/antagonist/gang/boss/gb = new + groveboss.add_antag_datum(gb, src) + gb.equip_gang() + + else + var/datum/mind/CJ = starting_members + if(istype(CJ)) + leaders += CJ + var/datum/antagonist/gang/boss/bossdatum = new + CJ.add_antag_datum(bossdatum, src) + bossdatum.equip_gang() + next_point_time = world.time + INFLUENCE_INTERVAL + addtimer(CALLBACK(src, .proc/handle_territories), INFLUENCE_INTERVAL) + +/datum/team/gang/Destroy() + GLOB.gangs -= src + ..() + +/datum/team/gang/roundend_report() //roundend report. + var/list/report = list() + report += "[name]:" + if(winner) + report += "The [name] gang successfully activated the mind dominator!" + else + report += "The [name] gang has failed!" + + report += "The [name] gang bosses were:" + report += printplayerlist(leaders) + report += "The [name] [member_name]s were:" + report += printplayerlist(members-leaders) + + return "
[report.Join("
")]
" + +/datum/team/gang/proc/greet_gangster(datum/mind/gangster) //The text a person receives when recruited. + to_chat(gangster, "You are now a member of the [name] Gang!") + to_chat(gangster, "Help your bosses take over the station by claiming territory with spraycans. Simply spray on any unclaimed area of the station.") + to_chat(gangster, "You can also use recruitment pens to recruit more to your cause, If your boss provides you one.") + to_chat(gangster, "Their ultimate objective is to take over the station with a Dominator machine.") + to_chat(gangster, "You can identify your mates by their large, \[G\] icon.") + gangster.store_memory("You are a member of the [name] Gang!") + +/datum/team/gang/proc/handle_territories() + next_point_time = world.time + INFLUENCE_INTERVAL + if(!leaders.len) + return + var/added_names = "" + var/lost_names = "" + + //Re-add territories that were reclaimed, so if they got tagged over, they can still earn income if they tag it back before the next status report + var/list/reclaimed_territories = new_territories & lost_territories + territories |= reclaimed_territories + new_territories -= reclaimed_territories + lost_territories -= reclaimed_territories + + //Process lost territories + for(var/area in lost_territories) + if(lost_names != "") + lost_names += ", " + lost_names += "[lost_territories[area]]" + territories -= area + + //Calculate and report influence growth + + //Process new territories + for(var/area in new_territories) + if(added_names != "") + added_names += ", " + added_names += "[new_territories[area]]" + territories += area + + //Report territory changes + var/message = "[src] Gang Status Report:.
*---------*
" + message += "[new_territories.len] new territories:
[added_names]
" + message += "[lost_territories.len] territories lost:
[lost_names]
" + //Clear the lists + new_territories = list() + lost_territories = list() + var/total_territories = total_claimable_territories() + var/control = round((territories.len/total_territories)*100, 1) + var/uniformed = check_clothing() + message += "Your gang now has [control]% control of the station.
*---------*
" + if(domination_time != NOT_DOMINATING) + var/new_time = max(world.time, domination_time - (uniformed * 4) - (territories.len * 2)) + if(new_time < domination_time) + message += "Takeover shortened by [(domination_time - new_time)*0.1] seconds for defending [territories.len] territories.
" + domination_time = new_time + message += "[domination_time_remaining()] seconds remain in hostile takeover.
" + else + var/new_influence = check_territory_income() + if(new_influence != influence) + message += "Gang influence has increased by [new_influence - influence] for defending [territories.len] territories and [uniformed] uniformed gangsters.
" + influence = new_influence + message += "Your gang now has [influence] influence.
" + message_gangtools(message) + addtimer(CALLBACK(src, .proc/handle_territories), INFLUENCE_INTERVAL) + +/datum/team/gang/proc/total_claimable_territories() + var/list/valid_territories = list() + for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION)) //First, collect all area types on the station zlevel + for(var/ar in SSmapping.areas_in_z["[z]"]) + var/area/A = ar + if(!(A.type in valid_territories) && A.valid_territory) + valid_territories |= A.type + return valid_territories.len + +/datum/team/gang/proc/check_territory_income() + var/new_influence = min(999,influence + 15 + (check_clothing() * 2) + territories.len) + return new_influence + +/datum/team/gang/proc/check_clothing() + //Count uniformed gangsters + var/uniformed = 0 + for(var/datum/mind/gangmind in members) + if(ishuman(gangmind.current)) + var/mob/living/carbon/human/gangster = gangmind.current + //Gangster must be alive and should return 0 not continue if conditions are met. + if(!istype(gangster) || gangster.stat == DEAD) + return 0 + + var/obj/item/clothing/outfit + var/obj/item/clothing/gang_outfit + if(gangster.w_uniform) + outfit = gangster.w_uniform + if(outfit.type in inner_outfits) + gang_outfit = outfit + if(gangster.wear_suit) + outfit = gangster.wear_suit + if(outfit.type in outer_outfits) + gang_outfit = outfit + + if(gang_outfit) + uniformed++ + return uniformed + +/datum/team/gang/proc/adjust_influence(value) + influence = max(0, influence + value) + +/datum/team/gang/proc/message_gangtools(message) + if(!gangtools.len || !message) + return + for(var/i in gangtools) + var/obj/item/device/gangtool/tool = i + var/mob/living/mob = get(tool.loc, /mob/living) + if(mob && mob.mind && mob.stat == CONSCIOUS) + var/datum/antagonist/gang/gangster = mob.mind.has_antag_datum(/datum/antagonist/gang) + if(gangster.gang == src) + to_chat(mob, "[icon2html(tool, mob)] [message]") + playsound(mob.loc, 'sound/machines/twobeep.ogg', 50, 1) + return + +/datum/team/gang/proc/domination() + domination_time = world.time + determine_domination_time()*10 + set_security_level("delta") + +/datum/team/gang/proc/determine_domination_time() // calculates the value in seconds (this is the initial domination time!) + var/total_territories = total_claimable_territories() + return max(180,480 - (round((territories.len/total_territories)*100, 1) * 9)) + +/datum/team/gang/proc/domination_time_remaining() // retrieves the value from world.time based deciseconds to seconds + var/diff = domination_time - world.time + return round(diff * 0.1) + + +#undef MAXIMUM_RECALLS +#undef INFLUENCE_INTERVAL \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm b/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm new file mode 100644 index 0000000000..334d6bf423 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm @@ -0,0 +1,139 @@ +// Gang datums go here. If you want to create a new gang, you must be sure to edit: +// name +// color (must be a hex, "blue" isn't acceptable due to how spraycans are handled) +// inner_outfits (must be a list() with typepaths of the clothes in it. One is fine, but there is support for multiple: one will be picked at random when bought) +// outer_outfits (same as above) +// You also need to make a gang graffiti, that will go in crayondecal.dmi inside our icons, with the same name of the gang it's assigned to. Nothing else,just the icon. +// Those are all required. If one is missed, stuff could break. + +/datum/team/gang/clandestine + name = "Clandestine" + color = "#FF0000" + inner_outfits = list(/obj/item/clothing/under/syndicate/combat) + outer_outfits = list(/obj/item/clothing/suit/jacket) + +/datum/team/gang/prima + name = "Prima" + color = "#FFFF00" + inner_outfits = list(/obj/item/clothing/under/color/yellow) + outer_outfits = list(/obj/item/clothing/suit/hastur) + +/datum/team/gang/zerog + name = "Zero-G" + color = "#C0C0C0" + inner_outfits = list(/obj/item/clothing/under/suit_jacket/white) + outer_outfits = list(/obj/item/clothing/suit/hooded/wintercoat) + +/datum/team/gang/max + name = "Max" + color = "#800000" + inner_outfits = list(/obj/item/clothing/under/color/maroon) + outer_outfits = list(/obj/item/clothing/suit/poncho/red) + +/datum/team/gang/blasto + name = "Blasto" + color = "#000080" + inner_outfits = list(/obj/item/clothing/under/suit_jacket/navy) + outer_outfits = list(/obj/item/clothing/suit/jacket/miljacket) + +/datum/team/gang/waffle + name = "Waffle" + color = "#808000" //shared color with cyber, but they can keep brown cause waffles. + inner_outfits = list(/obj/item/clothing/under/suit_jacket/green) + outer_outfits = list(/obj/item/clothing/suit/poncho) + +/datum/team/gang/north + name = "North" + color = "#00FF00" + inner_outfits = list(/obj/item/clothing/under/color/green) + outer_outfits = list(/obj/item/clothing/suit/poncho/green) + +/datum/team/gang/omni + name = "Omni" + color = "#008080" + inner_outfits = list(/obj/item/clothing/under/color/teal) + outer_outfits = list(/obj/item/clothing/suit/studentuni) + +/datum/team/gang/newton + name = "Newton" + color = "#A52A2A" + inner_outfits = list(/obj/item/clothing/under/color/brown) + outer_outfits = list(/obj/item/clothing/suit/toggle/owlwings) + +/datum/team/gang/cyber + name = "Cyber" + color = "#00f904" //Cyber and waffle shared colors, I made these guys green and made weed darker green. + inner_outfits = list(/obj/item/clothing/under/color/lightbrown) + outer_outfits = list(/obj/item/clothing/suit/nemes) + +/datum/team/gang/donk + name = "Donk" + color = "#0000FF" + inner_outfits = list(/obj/item/clothing/under/color/darkblue) + outer_outfits = list(/obj/item/clothing/suit/apron/overalls) + +/datum/team/gang/gene + name = "Gene" + color = "#00FFFF" + inner_outfits = list(/obj/item/clothing/under/color/blue) + outer_outfits = list(/obj/item/clothing/suit/apron) + +/datum/team/gang/gib + name = "Gib" + color = "#636060" //Applying black to grayscale... Zero-G is already grey too. oh well. + inner_outfits = list(/obj/item/clothing/under/color/black) + outer_outfits = list(/obj/item/clothing/suit/jacket/leather/overcoat) + +/datum/team/gang/tunnel + name = "Tunnel" + color = "#FF00FF" //Gave the leather jacket to the tunnel gang over diablo. + inner_outfits = list(/obj/item/clothing/under/villain) + outer_outfits = list(/obj/item/clothing/suit/jacket/leather) + +/datum/team/gang/diablo + name = "Diablo" + color = "#FF0000" //literal early 90s skinhead regalia. + inner_outfits = list(/obj/item/clothing/under/pants/classicjeans) + outer_outfits = list(/obj/item/clothing/suit/suspenders) + +/datum/team/gang/psyke + name = "Psyke" + color = "#808080" + inner_outfits = list(/obj/item/clothing/under/color/grey) + outer_outfits = list(/obj/item/clothing/suit/toggle/owlwings/griffinwings) + +/datum/team/gang/osiron + name = "Osiron" + color = "#FFFFFF" + inner_outfits = list(/obj/item/clothing/under/color/white) + outer_outfits = list(/obj/item/clothing/suit/toggle/labcoat) + +/datum/team/gang/sirius + name = "Sirius" + color = "#FFC0CB" + inner_outfits = list(/obj/item/clothing/under/color/pink) + outer_outfits = list(/obj/item/clothing/suit/jacket/puffer/vest) + +/datum/team/gang/sleepingcarp + name = "Sleeping Carp" + color = "#800080" + inner_outfits = list(/obj/item/clothing/under/color/lightpurple) + outer_outfits = list(/obj/item/clothing/suit/hooded/carp_costume) + +/datum/team/gang/h + name = "H" + color = "#993333" + inner_outfits = list(/obj/item/clothing/under/jabroni) //Why not? + outer_outfits = list(/obj/item/clothing/suit/toggle/owlwings) + +/datum/team/gang/rigatonifamily + name = "Rigatoni family" + color = "#cc9900" // p a s t a colored + inner_outfits = list(/obj/item/clothing/under/rank/chef) + outer_outfits = list(/obj/item/clothing/suit/apron/chef) + +/datum/team/gang/weed + name = "Weed" + color = "#6cd648" + inner_outfits = list(/obj/item/clothing/under/color/darkgreen) + outer_outfits = list(/obj/item/clothing/suit/vapeshirt) \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_decals.dm b/modular_citadel/code/game/gamemodes/gangs/gang_decals.dm new file mode 100644 index 0000000000..6e5cb58891 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_decals.dm @@ -0,0 +1,38 @@ +/obj/effect/decal/cleanable/crayon/Initialize(mapload, main, type, e_name, graf_rot, alt_icon = null) + . = ..() + if(type == "poseur tag") + var/datum/team/gang/gang = pick(subtypesof(/datum/team/gang)) + var/gangname = initial(gang.name) + icon = 'icons/effects/crayondecal.dmi' + icon_state = "[gangname]" + type = null + +/obj/effect/decal/cleanable/crayon/gang + icon = 'icons/effects/crayondecal.dmi' + layer = ABOVE_NORMAL_TURF_LAYER //Harder to hide + plane = GAME_PLANE + do_icon_rotate = FALSE //These are designed to always face south, so no rotation please. + var/datum/team/gang/gang + +/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, datum/team/gang/G, e_name = "gang tag", rotation = 0, mob/user) + if(!G) + return INITIALIZE_HINT_QDEL + gang = G + var/newcolor = G.color + var/area/territory = get_area(src) + icon_state = G.name + G.new_territories |= list(territory.type = territory.name) + //If this isn't tagged by a specific gangster there's no bonus income. + .=..(mapload, newcolor, icon_state, e_name, rotation) + +/obj/effect/decal/cleanable/crayon/gang/Destroy() + if(gang) + var/area/territory = get_area(src) + gang.territories -= territory.type + gang.new_territories -= territory.type + gang.lost_territories |= list(territory.type = territory.name) + gang = null + return ..() + +/obj/effect/decal/cleanable/crayon/NeverShouldHaveComeHere(turf/T) + return isspaceturf(T) || islava(T) || istype(T, /turf/open/water) || ischasm(T) \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_hud.dm b/modular_citadel/code/game/gamemodes/gangs/gang_hud.dm new file mode 100644 index 0000000000..3fde6d4123 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_hud.dm @@ -0,0 +1,34 @@ +/datum/atom_hud/antag/gang + var/color = null + +/datum/atom_hud/antag/gang/add_to_hud(atom/A) + if(!A) + return + var/image/holder = A.hud_list[ANTAG_HUD] + if(holder) + holder.color = color + ..() + +/datum/atom_hud/antag/gang/remove_from_hud(atom/A) + if(!A) + return + var/image/holder = A.hud_list[ANTAG_HUD] + if(holder) + holder.color = null + ..() + +/datum/atom_hud/antag/gang/join_hud(mob/M) + if(!istype(M)) + CRASH("join_hud(): [M] ([M.type]) is not a mob!") + var/image/holder = M.hud_list[ANTAG_HUD] + if(holder) + holder.color = color + ..() + +/datum/atom_hud/antag/gang/leave_hud(mob/M) + if(!istype(M)) + CRASH("leave_hud(): [M] ([M.type]) is not a mob!") + var/image/holder = M.hud_list[ANTAG_HUD] + if(holder) + holder.color = null + ..() \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_items.dm b/modular_citadel/code/game/gamemodes/gangs/gang_items.dm new file mode 100644 index 0000000000..0f16b6462b --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_items.dm @@ -0,0 +1,416 @@ +/datum/gang_item + var/name + var/item_path + var/cost + var/spawn_msg + var/category + var/list/gang_whitelist = list() + var/list/gang_blacklist = list() + var/id + +/datum/gang_item/proc/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool, check_canbuy = TRUE) + if(check_canbuy && !can_buy(user, gang, gangtool)) + return FALSE + var/real_cost = get_cost(user, gang, gangtool) + if(!spawn_item(user, gang, gangtool)) + gang.adjust_influence(-real_cost) + to_chat(user, "You bought \the [name].") + return TRUE + +/datum/gang_item/proc/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) // If this returns anything other than null, something fucked up and influence won't lower. + if(item_path) + var/obj/item/O = new item_path(user.loc) + user.put_in_hands(O) + else + return TRUE + if(spawn_msg) + to_chat(user, "[spawn_msg]") + +/datum/gang_item/proc/can_buy(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return gang && (gang.influence >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool) + +/datum/gang_item/proc/can_see(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return TRUE + +/datum/gang_item/proc/get_cost(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return cost + +/datum/gang_item/proc/get_cost_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return "([get_cost(user, gang, gangtool)] Influence)" + +/datum/gang_item/proc/get_name_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return name + +/datum/gang_item/proc/get_extra_info(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return + +/////////////////// +//CLOTHING +/////////////////// + +/datum/gang_item/clothing + category = "Purchase Gang Clothes (Only the jumpsuit and suit give you added influence):" + +/datum/gang_item/clothing/under + name = "Gang Uniform" + id = "under" + cost = 1 + +/datum/gang_item/clothing/under/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gang.inner_outfits.len) + var/outfit = pick(gang.inner_outfits) + if(outfit) + var/obj/item/O = new outfit(user.loc) + user.put_in_hands(O) + to_chat(user, " This is your gang's official uniform, wearing it will increase your influence") + return + return TRUE + +/datum/gang_item/clothing/suit + name = "Gang Armored Outerwear" + id = "suit" + cost = 1 + +/datum/gang_item/clothing/suit/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gang.outer_outfits.len) + var/outfit = pick(gang.outer_outfits) + if(outfit) + var/obj/item/O = new outfit(user.loc) + O.armor = O.armor.setRating(melee = 25, bullet = 35, laser = 15, energy = 10, bomb = 30, bio = 0, rad = 0, fire = 30, acid = 30) + O.desc += " Tailored for the [gang.name] Gang to offer the wearer moderate protection against ballistics and physical trauma." + user.put_in_hands(O) + to_chat(user, " This is your gang's official outerwear, wearing it will increase your influence") + return + return TRUE + + +/datum/gang_item/clothing/hat + name = "Pimp Hat" + id = "hat" + cost = 16 + item_path = /obj/item/clothing/head/collectable/petehat/gang + + +/obj/item/clothing/head/collectable/petehat/gang + name = "pimpin' hat" + desc = "The undisputed king of style." + +/datum/gang_item/clothing/mask + name = "Golden Death Mask" + id = "mask" + cost = 18 + item_path = /obj/item/clothing/mask/gskull + +/obj/item/clothing/mask/gskull + name = "golden death mask" + icon_state = "gskull" + desc = "Strike terror, and envy, into the hearts of your enemies." + +/datum/gang_item/clothing/shoes + name = "Bling Boots" + id = "boots" + cost = 22 + item_path = /obj/item/clothing/shoes/gang + +/obj/item/clothing/shoes/gang + name = "blinged-out boots" + desc = "Stand aside peasants." + icon_state = "bling" + +/datum/gang_item/clothing/neck + name = "Gold Necklace" + id = "necklace" + cost = 9 + item_path = /obj/item/clothing/neck/necklace/dope + +/datum/gang_item/clothing/hands + name = "Decorative Brass Knuckles" + id = "hand" + cost = 11 + item_path = /obj/item/clothing/gloves/gang + +/obj/item/clothing/gloves/gang + name = "braggadocio's brass knuckles" + desc = "Purely decorative, don't find out the hard way." + icon_state = "knuckles" + w_class = 3 + +datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang member anyways? + name = "Cool Sunglasses" + id = "glasses" + cost = 5 + item_path = /obj/item/clothing/glasses/sunglasses + +/datum/gang_item/clothing/belt + name = "Badass Belt" + id = "belt" + cost = 13 + item_path = /obj/item/storage/belt/military/gang + +/obj/item/storage/belt/military/gang + name = "badass belt" + icon_state = "gangbelt" + item_state = "gang" + desc = "The belt buckle simply reads 'BAMF'." + +/////////////////// +//WEAPONS +/////////////////// + +/datum/gang_item/weapon + category = "Purchase Weapons:" + +/datum/gang_item/weapon/ammo + +/datum/gang_item/weapon/shuriken + name = "Shuriken" + id = "shuriken" + cost = 2 + item_path = /obj/item/throwing_star + +/datum/gang_item/weapon/switchblade + name = "Switchblade" + id = "switchblade" + cost = 5 + item_path = /obj/item/switchblade + +/datum/gang_item/weapon/surplus //For when a gang boss is extra broke or cheap. + name = "Surplus Rifle" + id = "surplus" + cost = 6 + item_path = /obj/item/gun/ballistic/automatic/surplus + +/datum/gang_item/weapon/ammo/surplus_ammo + name = "Surplus Rifle Ammo" + id = "surplus_ammo" + cost = 3 + item_path = /obj/item/ammo_box/magazine/m10mm/rifle + +/datum/gang_item/weapon/improvised + name = "Sawn-Off Improvised Shotgun" + id = "sawn" + cost = 5 + item_path = /obj/item/gun/ballistic/revolver/doublebarrel/improvised/sawn + +/datum/gang_item/weapon/ammo/improvised_ammo + name = "Box of Buckshot" + id = "buckshot" + cost = 5 + item_path = /obj/item/storage/box/lethalshot + +/datum/gang_item/weapon/pistol + name = "10mm Pistol" + id = "pistol" + cost = 25 + item_path = /obj/item/gun/ballistic/automatic/pistol + +/datum/gang_item/weapon/ammo/pistol_ammo + name = "10mm Ammo" + id = "pistol_ammo" + cost = 10 + item_path = /obj/item/ammo_box/magazine/m10mm + +/datum/gang_item/weapon/sniper + name = "Black Market .50cal Sniper Rifle" + id = "sniper" + cost = 35 + item_path = /obj/item/gun/ballistic/automatic/sniper_rifle + +/datum/gang_item/weapon/ammo/sniper_ammo + name = "Smuggled .50cal Sniper Rounds" + id = "sniper_ammo" + cost = 15 + item_path = /obj/item/ammo_box/magazine/sniper_rounds + +/datum/gang_item/weapon/ammo/sleeper_ammo + name = "Illicit Soporific Cartridges" + id = "sniper_ammo" + cost = 15 + item_path = /obj/item/ammo_box/magazine/sniper_rounds/soporific + +/datum/gang_item/weapon/machinegun + name = "Mounted Machine Gun" + id = "MG" + cost = 45 + item_path = /obj/machinery/manned_turret + spawn_msg = "The mounted machine gun features enhanced responsiveness. Hold down on the trigger while firing to control where you're shooting." + +/datum/gang_item/weapon/machinegun/spawn_item(mob/living/carbon/user, obj/item/device/gangtool/gangtool) + new item_path(user.loc) + to_chat(user, spawn_msg) + +/datum/gang_item/weapon/uzi + name = "Uzi SMG" + id = "uzi" + cost = 50 + item_path = /obj/item/gun/ballistic/automatic/mini_uzi + +/datum/gang_item/weapon/ammo/uzi_ammo + name = "Uzi Ammo" + id = "uzi_ammo" + cost = 20 + item_path = /obj/item/ammo_box/magazine/uzim9mm + +/////////////////// +//EQUIPMENT +/////////////////// + +/datum/gang_item/equipment + category = "Purchase Equipment:" + + +/datum/gang_item/equipment/spraycan + name = "Territory Spraycan" + id = "spraycan" + cost = 1 + item_path = /obj/item/toy/crayon/spraycan/gang + +/datum/gang_item/equipment/spraycan/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + var/obj/item/O = new item_path(user.loc, gang) + user.put_in_hands(O) + +/datum/gang_item/equipment/sharpener + name = "Sharpener" + id = "whetstone" + cost = 3 + item_path = /obj/item/sharpener + + +/datum/gang_item/equipment/emp + name = "EMP Grenade" + id = "EMP" + cost = 7 + item_path = /obj/item/grenade/empgrenade + +/datum/gang_item/equipment/c4 + name = "C4 Explosive" + id = "c4" + cost = 7 + item_path = /obj/item/grenade/plastic/c4 + +/datum/gang_item/equipment/frag + name = "Fragmentation Grenade" + id = "frag nade" + cost = 5 + item_path = /obj/item/grenade/syndieminibomb/concussion/frag + +/datum/gang_item/equipment/stimpack + name = "Black Market Stimulants" + id = "stimpack" + cost = 12 + item_path = /obj/item/reagent_containers/syringe/stimulants + +/datum/gang_item/equipment/implant_breaker + name = "Implant Breaker" + id = "implant_breaker" + cost = 10 + item_path = /obj/item/implanter/gang + +/datum/gang_item/equipment/implant_breaker/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + var/obj/item/O = new item_path(user.loc, gang) + user.put_in_hands(O) + to_chat(user, "The implant breaker is a single-use device that destroys all implants within the target before trying to recruit them to your gang. Also works on enemy gangsters.") + +/datum/gang_item/equipment/wetwork_boots + name = "Wetwork boots" + id = "wetwork" + cost = 8 + item_path = /obj/item/clothing/shoes/combat/gang + +/obj/item/clothing/shoes/combat/gang + name = "Wetwork boots" + desc = "A gang's best hitmen are prepared for anything." + permeability_coefficient = 0.01 + clothing_flags = NOSLIP + +datum/gang_item/equipment/shield + name = "Riot Shield" + id = "riot_shield" + cost = 25 + item_path = /obj/item/shield/riot + +/datum/gang_item/equipment/pen + name = "Recruitment Pen" + id = "pen" + cost = 20 + item_path = /obj/item/pen/gang + spawn_msg = "More recruitment pens will allow you to recruit gangsters faster. Only gang leaders can recruit with pens." + +/datum/gang_item/equipment/pen/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(..()) + gangtool.free_pen = FALSE + return TRUE + return FALSE + +/datum/gang_item/equipment/pen/get_cost(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gangtool && gangtool.free_pen) + return 0 + return ..() + +/datum/gang_item/equipment/pen/get_cost_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gangtool && gangtool.free_pen) + return "(GET ONE FREE)" + return ..() + + +/datum/gang_item/equipment/gangtool + id = "gangtool" + cost = 5 + +/datum/gang_item/equipment/gangtool/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + var/item_type + if(gang) + item_type = /obj/item/device/gangtool/spare/lt + if(gang.leaders.len < MAX_LEADERS_GANG) + to_chat(user, "Gangtools allow you to promote a gangster to be your Lieutenant, enabling them to recruit and purchase items like you. Simply have them register the gangtool. You may promote up to [MAX_LEADERS_GANG-gang.leaders.len] more Lieutenants") + else + item_type = /obj/item/device/gangtool/spare + var/obj/item/device/gangtool/spare/tool = new item_type(user.loc) + user.put_in_hands(tool) + +/datum/gang_item/equipment/gangtool/get_name_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gang && (gang.leaders.len < gang.max_leaders)) + return "Promote a Gangster" + return "Spare Gangtool" + +/datum/gang_item/equipment/dominator + name = "Station Dominator" + id = "dominator" + cost = 30 + item_path = /obj/machinery/dominator + spawn_msg = "The dominator will secure your gang's dominance over the station. Turn it on when you are ready to defend it." + +/datum/gang_item/equipment/dominator/can_buy(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(!gang || !gang.dom_attempts) + return FALSE + return ..() + +/datum/gang_item/equipment/dominator/get_name_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(!gang || !gang.dom_attempts) + return ..() + return "[..()]" + +/datum/gang_item/equipment/dominator/get_cost_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(!gang || !gang.dom_attempts) + return "(Out of stock)" + return ..() + +/datum/gang_item/equipment/dominator/get_extra_info(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gang) + return "This device requires a 5x5 area clear of walls to FUNCTION. (Estimated Takeover Time: [round(gang.determine_domination_time()/60,0.1)] minutes)" + +/datum/gang_item/equipment/dominator/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + var/area/userarea = get_area(user) + if(!(userarea.type in gang.territories|gang.new_territories)) + to_chat(user,"The dominator can be spawned only on territory controlled by your gang!") + return FALSE + for(var/obj/obj in get_turf(user)) + if(obj.density) + to_chat(user, "There's not enough room here!") + return FALSE + + return ..() + +/datum/gang_item/equipment/dominator/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + new item_path(user.loc) + to_chat(user, spawn_msg) \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_pen.dm b/modular_citadel/code/game/gamemodes/gangs/gang_pen.dm new file mode 100644 index 0000000000..0851f3b596 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_pen.dm @@ -0,0 +1,59 @@ +/* + * Gang Boss Pens + */ +/obj/item/pen/gang + var/cooldown + var/last_used + +/obj/item/pen/gang/Initialize() + . = ..() + last_used = world.time + +/obj/item/pen/gang/attack(mob/living/M, mob/user, stealth = TRUE) //ha + if(!istype(M)) + return + if(!ishuman(M) || !ishuman(user) || M.stat == DEAD) + return ..() + //var/datum/antagonist/gang/boss/L = user.mind.has_antag_datum(/datum/antagonist/gang/boss) //Pen works with bosses only. + var/datum/antagonist/gang/L = user.mind.has_antag_datum(/datum/antagonist/gang) //Pen works with anyone in gang. + if(!L) + return ..() + if(!..()) + return + if(cooldown) + to_chat(user, "[src] needs more time to recharge before it can be used.") + return + if(!M.client || !M.mind) + to_chat(user, "A braindead gangster is an useless gangster!") + return + var/datum/team/gang/gang = L.gang + if(!add_gangster(user, gang, M.mind)) + return + cooldown = TRUE + icon_state = "pen_blink" + var/cooldown_time = 600/gang.leaders.len + addtimer(CALLBACK(src, .proc/cooldown), cooldown_time) + +/obj/item/pen/gang/proc/cooldown() + cooldown = FALSE + icon_state = "pen" + var/mob/M = loc + if(istype(M)) + to_chat(M, "[icon2html(src, M)] [src][(loc == M)?(""):(" in your [loc]")] vibrates softly. It is ready to be used again.") + +/obj/item/pen/gang/proc/add_gangster(mob/user, datum/team/gang/gang, datum/mind/gangster_mind, check = TRUE) // Basically a wrapper to add_antag_datum. + var/datum/antagonist/dudegang = gangster_mind.has_antag_datum(/datum/antagonist/gang) + if(dudegang) + if(dudegang == gang) + to_chat(user, "This mind is already controlled by your gang!") + return + to_chat(user, "This mind is already controlled by someone else!") + return + if(check && HAS_TRAIT(gangster_mind.current, TRAIT_MINDSHIELD)) //Check to see if the potential gangster is implanted + to_chat(user, "This mind is too strong to control!") + return + var/mob/living/carbon/human/H = gangster_mind.current // we are sure the dude's human cause it's checked in attack() + H.silent = max(H.silent, 5) + H.Knockdown(100) + gangster_mind.add_antag_datum(/datum/antagonist/gang, gang) + return TRUE \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gangs.dm b/modular_citadel/code/game/gamemodes/gangs/gangs.dm new file mode 100644 index 0000000000..9151107d6f --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gangs.dm @@ -0,0 +1,65 @@ +//gang.dm +//Gang War Game Mode +GLOBAL_LIST_INIT(possible_gangs, subtypesof(/datum/team/gang)) +GLOBAL_LIST_EMPTY(gangs) +/datum/game_mode/gang + name = "gang war" + config_tag = "gang" + antag_flag = ROLE_GANG + restricted_jobs = list("Security Officer", "Warden", "Detective", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security") + required_players = 15 + required_enemies = 0 + recommended_enemies = 2 + enemy_minimum_age = 14 + + announce_span = "danger" + announce_text = "A violent turf war has erupted on the station!\n\ + Gangsters: Take over the station with a dominator.\n\ + Crew: Prevent the gangs from expanding and initiating takeover." + + var/list/datum/mind/gangboss_candidates = list() + +/datum/game_mode/gang/generate_report() + return "Cybersun Industries representatives claimed that they, in joint research with the Tiger Cooperative, have made a major breakthrough in brainwashing technology, and have \ + made the nanobots that apply the \"conversion\" very small and capable of fitting into usually innocent objects - namely, pens. While they refused to outsource this technology for \ + months to come due to its flaws, they reported some as missing but passed it off to carelessness. At Central Command, we don't like mysteries, and we have reason to believe that this \ + technology was stolen for anti-Nanotrasen use. Be on the lookout for territory claims and unusually violent crew behavior, applying mindshield implants as necessary." + +/datum/game_mode/gang/pre_setup() + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_jobs += protected_jobs + + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + restricted_jobs += "Assistant" + + //Spawn more bosses depending on server population + var/gangs_to_create = 2 + if(prob(num_players()) && num_players() > 1.5*required_players) + gangs_to_create++ + if(prob(num_players()) && num_players() > 2*required_players) + gangs_to_create++ + gangs_to_create = min(gangs_to_create, GLOB.possible_gangs.len) + + for(var/i in 1 to gangs_to_create) + if(!antag_candidates.len) + break + + //Now assign a boss for the gang + var/datum/mind/boss = pick_n_take(antag_candidates) + antag_candidates -= boss + gangboss_candidates += boss + boss.restricted_roles = restricted_jobs + + if(gangboss_candidates.len < 1) //Need at least one gangs + return + + return TRUE + +/datum/game_mode/gang/post_setup() + set waitfor = FALSE + ..() + for(var/i in gangboss_candidates) + var/datum/mind/M = i + var/datum/antagonist/gang/boss/B = new() + M.add_antag_datum(B) + B.equip_gang() diff --git a/modular_citadel/code/game/gamemodes/gangs/gangtool.dm b/modular_citadel/code/game/gamemodes/gangs/gangtool.dm new file mode 100644 index 0000000000..9e828a7042 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gangtool.dm @@ -0,0 +1,259 @@ +//gangtool device +/obj/item/device/gangtool + name = "suspicious device" + desc = "A strange device of sorts. Hard to really make out what it actually does if you don't know how to operate it." + icon = 'icons/obj/device.dmi' + icon_state = "gangtool" + item_state = "radio" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + throwforce = 0 + w_class = WEIGHT_CLASS_TINY + throw_speed = 3 + throw_range = 7 + flags_1 = CONDUCT_1 + var/datum/team/gang/gang //Which gang uses this? + var/recalling = 0 + var/outfits = 2 + var/free_pen = 0 + var/promotable = FALSE + var/static/list/buyable_items = list() + var/list/tags = list() + +/obj/item/device/gangtool/Initialize() + . = ..() + update_icon() + for(var/i in subtypesof(/datum/gang_item)) + var/datum/gang_item/G = i + var/id = initial(G.id) + var/cat = initial(G.category) + if(id) + if(!islist(buyable_items[cat])) + buyable_items[cat] = list() + buyable_items[cat][id] = new G +/obj/item/device/gangtool/Destroy() + if(gang) + gang.gangtools -= src + return ..() + +/obj/item/device/gangtool/attack_self(mob/user) + ..() + if (!can_use(user)) + return + var/datum/antagonist/gang/boss/L = user.mind.has_antag_datum(/datum/antagonist/gang/boss) + var/dat + if(!gang) + dat += "This device is not registered.

" + if(L) + if(promotable && L.gang.leaders.len < L.gang.max_leaders) + dat += "Give this device to another member of your organization to use to promote them to Lieutenant.

" + dat += "If this is meant as a spare device for yourself:
" + dat += "Register Device as Spare
" + else if(promotable) + var/datum/antagonist/gang/sweet = user.mind.has_antag_datum(/datum/antagonist/gang) + if(sweet.gang.leaders.len < sweet.gang.max_leaders) + dat += "You have been selected for a promotion!
" + dat += "Accept Promotion
" + else + dat += "No promotions available: All positions filled.
" + else + dat += "This device is not authorized to promote.
" + else + if(gang.domination_time != NOT_DOMINATING) + dat += "
Takeover In Progress:
[DisplayTimeText(gang.domination_time_remaining() * 10)] remain
" + + dat += "Registration: [gang.name] Gang Boss
" + dat += "Organization Size: [gang.members.len] | Station Control: [gang.territories.len] territories under control. | Influence: [gang.influence]
" + dat += "Time until Influence grows: [time2text(gang.next_point_time - world.time, "mm:ss")]
" + dat += "Send message to Gang
" + dat += "Recall shuttle
" + dat += "
" + for(var/cat in buyable_items) + dat += "[cat]
" + for(var/id in buyable_items[cat]) + var/datum/gang_item/G = buyable_items[cat][id] + if(!G.can_see(user, gang, src)) + continue + + var/cost = G.get_cost_display(user, gang, src) + if(cost) + dat += cost + " " + + var/toAdd = G.get_name_display(user, gang, src) + if(G.can_buy(user, gang, src)) + toAdd = "[toAdd]" + dat += toAdd + var/extra = G.get_extra_info(user, gang, src) + if(extra) + dat += "
[extra]" + dat += "
" + dat += "
" + + dat += "Refresh
" + + var/datum/browser/popup = new(user, "gangtool", "Welcome to GangTool v4.0", 340, 625) + popup.set_content(dat) + popup.open() + +/obj/item/device/gangtool/Topic(href, href_list) + if(!can_use(usr)) + return + + add_fingerprint(usr) + + if(href_list["register"]) + register_device(usr) + + else if(!gang) //Gangtool must be registered before you can use the functions below + return + + if(href_list["purchase"]) + if(islist(buyable_items[href_list["cat"]])) + var/list/L = buyable_items[href_list["cat"]] + var/datum/gang_item/G = L[href_list["id"]] + if(G && G.can_buy(usr, gang, src)) + G.purchase(usr, gang, src, FALSE) + + if(href_list["commute"]) + ping_gang(usr) + if(href_list["recall"]) + recall(usr) + attack_self(usr) + +/obj/item/device/gangtool/update_icon() + overlays.Cut() + var/image/I = new(icon, "[icon_state]-overlay") + if(gang) + I.color = gang.color + overlays.Add(I) + +/obj/item/device/gangtool/proc/ping_gang(mob/user) + if(!can_use(user)) + return + var/message = stripped_input(user,"Discreetly send a gang-wide message.","Send Message") as null|text + if(!message || !can_use(user)) + return + if(!is_station_level(user.z)) + to_chat(user, "[icon2html(src, user)]Error: Station out of range.") + return + if(gang.members.len) + var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) + if(!G) + return + var/ping = "[gang.name] [G.message_name] [user.real_name]: [message]" + for(var/datum/mind/ganger in gang.members) + if(ganger.current && is_station_level(ganger.current.z) && (ganger.current.stat == CONSCIOUS)) + to_chat(ganger.current, ping) + for(var/mob/M in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(M, user) + to_chat(M, "[link] [ping]") + user.log_talk(message,LOG_SAY, tag="[gang.name] gangster") + +/obj/item/device/gangtool/proc/register_device(mob/user) + if(gang) //It's already been registered! + return + var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) + if(G) + gang = G.gang + gang.gangtools += src + update_icon() + if(!(user.mind in gang.leaders) && promotable) + G.promote() + free_pen = TRUE + gang.message_gangtools("[user] has been promoted to Lieutenant.") + to_chat(user, "The Gangtool you registered will allow you to purchase weapons and equipment, and send messages to your gang.") + to_chat(user, "Unlike regular gangsters, you may use recruitment pens to add recruits to your gang. Use them on unsuspecting crew members to recruit them. Don't forget to get your one free pen from the gangtool.") + else + to_chat(user, "ACCESS DENIED: Unauthorized user.") + +/obj/item/device/gangtool/proc/recall(mob/user) + if(!recallchecks(user)) + return + if(recalling) + to_chat(user, "Error: Recall already in progress.") + return + gang.message_gangtools("[user] is attempting to recall the emergency shuttle.") + recalling = TRUE + to_chat(user, "[icon2html(src, loc)]Generating shuttle recall order with codes retrieved from last call signal...") + addtimer(CALLBACK(src, .proc/recall2, user), rand(100,300)) + +/obj/item/device/gangtool/proc/recall2(mob/user) + if(!recallchecks(user)) + return + to_chat(user, "[icon2html(src, loc)]Shuttle recall order generated. Accessing station long-range communication arrays...") + addtimer(CALLBACK(src, .proc/recall3, user), rand(100,300)) + +/obj/item/device/gangtool/proc/recall3(mob/user) + if(!recallchecks(user)) + return + var/list/living_crew = list()//shamelessly copied from mulligan code, there should be a helper for this + for(var/mob/Player in GLOB.mob_list) + if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) && !isbrain(Player) && Player.client) + living_crew += Player + var/malc = CONFIG_GET(number/midround_antag_life_check) + if(living_crew.len / GLOB.joined_player_list.len <= malc) //Shuttle cannot be recalled if too many people died + to_chat(user, "[icon2html(src, user)]Error: Station communication systems compromised. Unable to establish connection.") + recalling = FALSE + return + to_chat(user, "[icon2html(src, loc)]Comm arrays accessed. Broadcasting recall signal...") + addtimer(CALLBACK(src, .proc/recallfinal, user), rand(100,300)) + +/obj/item/device/gangtool/proc/recallfinal(mob/user) + if(!recallchecks(user)) + return + recalling = FALSE + log_game("[key_name(user)] has tried to recall the shuttle with a gangtool.") + message_admins("[key_name_admin(user)] has tried to recall the shuttle with a gangtool.", 1) + if(SSshuttle.cancelEvac(user)) + gang.recalls-- + return TRUE + + to_chat(user, "[icon2html(src, loc)]No response recieved. Emergency shuttle cannot be recalled at this time.") + return + +/obj/item/device/gangtool/proc/recallchecks(mob/user) + if(!can_use(user)) + return + if(SSshuttle.emergencyNoRecall) + return + if(!gang.recalls) + to_chat(user, "Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.") + return + if(SSshuttle.emergency.mode != SHUTTLE_CALL) //Shuttle can only be recalled when it's moving to the station + to_chat(user, "[icon2html(src, user)]Emergency shuttle cannot be recalled at this time.") + recalling = FALSE + return + if(!gang.dom_attempts) + to_chat(user, "[icon2html(src, user)]Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.") + recalling = FALSE + return + if(!is_station_level(user.z)) //Shuttle can only be recalled while on station + to_chat(user, "[icon2html(src, user)]Error: Device out of range of station communication arrays.") + recalling = FALSE + return + return TRUE + +/obj/item/device/gangtool/proc/can_use(mob/living/carbon/human/user) + if(!istype(user)) + return + if(user.incapacitated()) + return + if(!(src in user.contents)) + return + if(!user.mind) + return + var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) + if(!G) + to_chat(user, "Huh, what's this?") + return + if(!isnull(gang) && G.gang != gang) + to_chat(user, "You cannot use gang tools owned by enemy gangs!") + return + return TRUE + + +/obj/item/device/gangtool/spare + outfits = TRUE + +/obj/item/device/gangtool/spare/lt + promotable = TRUE \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/implant_gang.dm b/modular_citadel/code/game/gamemodes/gangs/implant_gang.dm new file mode 100644 index 0000000000..ee91928845 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/implant_gang.dm @@ -0,0 +1,61 @@ +/obj/item/implant/gang + name = "gang implant" + desc = "Makes you a gangster or such." + activated = 0 + var/datum/team/gang/gang + +/obj/item/implant/gang/Initialize(loc, setgang) + .=..() + gang = setgang + +/obj/item/implant/gang/Destroy() + gang = null + return ..() + +/obj/item/implant/gang/get_data() + var/dat = {"Implant Specifications:
+ Name: Criminal brainwash implant
+ Life: A few seconds after injection.
+ Important Notes: Illegal
+
+ Implant Details:
+ Function: Contains a small pod of nanobots that change the host's brain to be loyal to a certain organization.
+ Special Features: This device will also emit a small EMP pulse, destroying any other implants within the host's brain.
+ Integrity: Implant's EMP function will destroy itself in the process."} + return dat + +/obj/item/implant/gang/implant(mob/living/target, mob/user, silent = 0) + if(!target || !target.mind || target.stat == DEAD) + return 0 + var/datum/antagonist/gang/G = target.mind.has_antag_datum(/datum/antagonist/gang) + if(G && G.gang == G) + return 0 // it's pointless + if(..()) + for(var/obj/item/implant/I in target.implants) + if(I != src) + qdel(I) + + if(ishuman(target)) + var/success + if(G) + if(!istype(G, /datum/antagonist/gang/boss)) + success = TRUE //Was not a gang boss, convert as usual + target.mind.remove_antag_datum(/datum/antagonist/gang) + else + success = TRUE + if(!success) + target.visible_message("[target] seems to resist the implant!", "You feel the influence of your enemies try to invade your mind!") + return FALSE + target.mind.add_antag_datum(/datum/antagonist/gang, gang) + qdel(src) + return TRUE + +/obj/item/implanter/gang + name = "implanter (gang)" + +/obj/item/implanter/gang/Initialize(loc, gang) + if(!gang) + qdel(src) + return + imp = new /obj/item/implant/gang(src,gang) + .=..() \ No newline at end of file diff --git a/modular_citadel/code/game/machinery/cryopod.dm b/modular_citadel/code/game/machinery/cryopod.dm index 1ff628bfbd..15e7d34c65 100644 --- a/modular_citadel/code/game/machinery/cryopod.dm +++ b/modular_citadel/code/game/machinery/cryopod.dm @@ -245,43 +245,6 @@ // This function can not be undone; do not call this unless you are sure /obj/machinery/cryopod/proc/despawn_occupant() var/mob/living/mob_occupant = occupant - var/list/target_candidates = list() - - if(istype(SSticker.mode, /datum/antagonist/cult))//thank - if("sacrifice" in SSticker.mode.cult) - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && !is_convertable_to_cult(player) && player.stat != DEAD) - target_candidates += player.mind - - target_candidates -= mob_occupant.mind - - if(target_candidates.len == 0) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && player.stat != DEAD) - target_candidates += player.mind - - listclearnulls(target_candidates) - if(LAZYLEN(target_candidates)) - var/datum/objective/sacrifice/sac_objective = locate() in GLOB.objectives - sac_objective.target = pick(target_candidates) - sac_objective.update_explanation_text() - - var/datum/job/sacjob = SSjob.GetJob(sac_objective.target.assigned_role) - var/datum/preferences/sacface = sac_objective.target.current.client.prefs - var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) - reshape.Shift(SOUTH, 4) - reshape.Shift(EAST, 1) - reshape.Crop(7,4,26,31) - reshape.Crop(-5,-3,26,30) - sac_objective.sac_image = reshape - - for(var/datum/mind/H in SSticker.mode.cult) - if(H.current) - to_chat(H.current, "Nar'Sie murmurs, [occupant] is beyond your reach. Sacrifice [sac_objective.target.current] instead...
") - - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target after cryopod. WELP!") //Update any existing objectives involving this mob. for(var/datum/objective/O in GLOB.objectives) diff --git a/modular_citadel/code/game/machinery/vending.dm b/modular_citadel/code/game/machinery/vending.dm index 213dd8a17a..bdca91b0e6 100755 --- a/modular_citadel/code/game/machinery/vending.dm +++ b/modular_citadel/code/game/machinery/vending.dm @@ -54,8 +54,11 @@ /obj/item/clothing/neck/petcollar = 5, /obj/item/clothing/under/mankini = 1, /obj/item/dildo/flared/huge = 1 - ) - premium = list(/obj/item/electropack/shockcollar = 3) + ) + premium = list( + /obj/item/electropack/shockcollar = 3, + /obj/item/clothing/neck/petcollar/locked = 1 + ) refill_canister = /obj/item/vending_refill/kink /* /obj/machinery/vending/nazivend diff --git a/modular_citadel/code/game/objects/items/honk.dm b/modular_citadel/code/game/objects/items/honk.dm index 9deb8aec30..47b9df7f10 100644 --- a/modular_citadel/code/game/objects/items/honk.dm +++ b/modular_citadel/code/game/objects/items/honk.dm @@ -3,4 +3,15 @@ desc = "A shiny bike horn handcrafted in the artisan workshops of Mars, with superior kevlar-reinforced rubber bulb attached to a polished plasteel reed horn." attack_verb = list("elegantly HONKED") icon = 'modular_citadel/icons/obj/honk.dmi' - icon_state = "silverhorn" \ No newline at end of file + icon_state = "silverhorn" + +/obj/item/bikehorn/bluespacehonker + name = "bluespace bike horn" + desc = "A normal bike horn colored blue and has bluespace dust held in to reed horn allowing for silly honks through space and time, into your in childhood." + attack_verb = list("HONKED in bluespace", "HONKED", "quantumly HONKED") + icon = 'modular_citadel/icons/obj/honk.dmi' + icon_state = "bluespacehonker" + +/obj/item/bikehorn/bluespacehonker/attack(mob/living/carbon/M, mob/living/carbon/user) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "bshonk", /datum/mood_event/bshonk) + return ..() diff --git a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm index bdd193c477..ce6aada0fc 100644 --- a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm +++ b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm @@ -117,6 +117,28 @@ desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. This one seems to have a damaged handle and misaligned components, causing the blade to be unstable at best" force_on = 15 //As strong a survival knife/bone dagger +/obj/item/melee/transforming/energy/sword/cx/attackby(obj/item/W, mob/living/user, params) + if(istype(W, /obj/item/melee/transforming/energy/sword/cx)) + if((W.item_flags & NODROP) || (item_flags & NODROP)) + to_chat(user, "\the [item_flags & NODROP ? src : W] is stuck to your hand, you can't attach it to \the [item_flags & NODROP ? W : src]!") + return + else + to_chat(user, "You combine the two light swords, making a single supermassive blade! You're cool.") + new /obj/item/twohanded/hypereutactic(user.drop_location()) + qdel(W) + qdel(src) + else + return ..() + +/obj/item/melee/transforming/energy/sword/cx/chaplain + name = "divine lightblade" + force_on = 20 //haha i'll regret this + block_chance = 50 + +/obj/item/melee/transforming/energy/sword/cx/chaplain/Initialize() + . = ..() + AddComponent(/datum/component/anti_magic, TRUE, TRUE) + //OBLIGATORY TOY MEMES ///////////////////////////////////// /obj/item/toy/sword/cx @@ -235,21 +257,21 @@ inhand_y_dimension = 64 name = "hypereutactic blade" desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter." - force = 3 + force = 7 throwforce = 5 throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_SMALL var/w_class_on = WEIGHT_CLASS_BULKY - force_unwielded = 3 - force_wielded = 30 + force_unwielded = 7 + force_wielded = 40 wieldsound = 'sound/weapons/nebon.ogg' unwieldsound = 'sound/weapons/neboff.ogg' hitsound = "swing_hit" - armour_penetration = 10 + armour_penetration = 60 light_color = "#37FFF7" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded") - block_chance = 25 + block_chance = 75 max_integrity = 200 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) resistance_flags = FIRE_PROOF @@ -265,7 +287,6 @@ user.visible_message("[user] points the tip of [src] at [target].", "You point the tip of [src] at [target].") return TRUE - /obj/item/twohanded/hypereutactic/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflection chance for balance issues and switches hitsounds. if(M.has_dna()) if(M.dna.check_mutation(HULK)) @@ -278,7 +299,6 @@ hitsound = 'sound/weapons/nebhit.ogg' START_PROCESSING(SSobj, src) set_light(brightness_on) - slowdown = 1 /obj/item/twohanded/hypereutactic/unwield() //Specific unwield () to switch hitsounds. sharpness = initial(sharpness) @@ -338,12 +358,8 @@ ..() to_chat(user, "Alt-click to recolor it.") - - ////////// stuff beneath this is all taken from the desword //////////// wow very professional such OOP wow - - /obj/item/twohanded/hypereutactic/attack(mob/target, mob/living/carbon/human/user) if(user.has_dna()) if(user.dna.check_mutation(HULK)) @@ -351,7 +367,7 @@ unwield() return ..() - if(user.has_trait(TRAIT_CLUMSY) && (wielded) && prob(40)) + if(HAS_TRAIT(user, TRAIT_CLUMSY) && (wielded) && prob(40)) impale(user) return @@ -426,7 +442,7 @@ It appears to have a wooden grip and a shaved down guard." icon_state = "cxsword_hilt_traitor" force_on = 30 - armour_penetration = 35 + armour_penetration = 50 embedding = list("embedded_pain_multiplier" = 10, "embed_chance" = 75, "embedded_fall_chance" = 0, "embedded_impact_pain_multiplier" = 10) block_chance = 50 hitsound_on = 'sound/weapons/blade1.ogg' diff --git a/modular_citadel/code/game/objects/items/melee/misc.dm b/modular_citadel/code/game/objects/items/melee/misc.dm index 82ede048a8..6a53adcc1f 100644 --- a/modular_citadel/code/game/objects/items/melee/misc.dm +++ b/modular_citadel/code/game/objects/items/melee/misc.dm @@ -16,7 +16,7 @@ return //CIT CHANGE - ditto add_fingerprint(user) - if((user.has_trait(TRAIT_CLUMSY)) && prob(50)) + if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) to_chat(user, "You club yourself over the head.") user.Knockdown(60 * force) if(ishuman(user)) diff --git a/modular_citadel/code/modules/admin/chat_commands.dm b/modular_citadel/code/modules/admin/chat_commands.dm index d5d66a1888..deb3de589e 100644 --- a/modular_citadel/code/modules/admin/chat_commands.dm +++ b/modular_citadel/code/modules/admin/chat_commands.dm @@ -6,7 +6,12 @@ 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","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","Jecca Qua","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/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")]" - saltresult += "[saltprimarysubject] [saltsecondarysubject]" + if(prob(10)) + saltresult += "@here for your salt, all day every day" + if(prob(1)) + saltresult += " @everyone gets some salt this time too" + else + saltresult += "[saltprimarysubject] [saltsecondarysubject]" return "[saltresult]!" /datum/tgs_chat_command/despacito diff --git a/modular_citadel/code/modules/arousal/arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm index a625829577..846a8cff62 100644 --- a/modular_citadel/code/modules/arousal/arousal.dm +++ b/modular_citadel/code/modules/arousal/arousal.dm @@ -1,13 +1,13 @@ //Mob vars /mob/living - var/arousalloss = 0 //How aroused the mob is. - var/min_arousal = 0 //The lowest this mobs arousal will get. default = 0 - var/max_arousal = 100 //The highest this mobs arousal will get. default = 100 - var/arousal_rate = 1 //The base rate that arousal will increase in this mob. - var/arousal_loss_rate = 1 //How easily arousal can be relieved for this mob. - var/canbearoused = FALSE //Mob-level disabler for arousal. Starts off and can be enabled as features are added for different mob types. - var/mb_cd_length = 100 //5 second cooldown for masturbating because fuck spam. - var/mb_cd_timer = 0 //The timer itself + var/arousalloss = 0 //How aroused the mob is. + var/min_arousal = AROUSAL_MINIMUM_DEFAULT //The lowest this mobs arousal will get. default = 0 + var/max_arousal = AROUSAL_MAXIMUM_DEFAULT //The highest this mobs arousal will get. default = 100 + var/arousal_rate = AROUSAL_START_VALUE //The base rate that arousal will increase in this mob. + var/arousal_loss_rate = AROUSAL_START_VALUE //How easily arousal can be relieved for this mob. + var/canbearoused = FALSE //Mob-level disabler for arousal. Starts off and can be enabled as features are added for different mob types. + var/mb_cd_length = 5 SECONDS //5 second cooldown for masturbating because fuck spam. + var/mb_cd_timer = 0 //The timer itself /mob/living/carbon/human canbearoused = TRUE @@ -22,8 +22,8 @@ //Species vars /datum/species - var/arousal_gain_rate = 1 //Rate at which this species becomes aroused - var/arousal_lose_rate = 1 //Multiplier for how easily arousal can be relieved + var/arousal_gain_rate = AROUSAL_START_VALUE //Rate at which this species becomes aroused + var/arousal_lose_rate = AROUSAL_START_VALUE //Multiplier for how easily arousal can be relieved var/list/cum_fluids = list("semen") var/list/milk_fluids = list("milk") var/list/femcum_fluids = list("femcum") @@ -40,7 +40,7 @@ adjustArousalLoss(arousal_rate * S.arousal_gain_rate) if(dna.features["exhibitionist"] && client) var/amt_nude = 0 - if(is_chest_exposed() && (gender == FEMALE || getorganslot("breasts"))) + if(is_chest_exposed() && (getorganslot("breasts"))) amt_nude++ if(is_groin_exposed()) if(getorganslot("penis")) @@ -64,20 +64,21 @@ /mob/living/proc/adjustArousalLoss(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) - return 0 + return FALSE arousalloss = CLAMP(arousalloss + amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() /mob/living/proc/setArousalLoss(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) - return 0 + return FALSE arousalloss = CLAMP(amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() /mob/living/proc/getPercentAroused() - return ((100 / max_arousal) * arousalloss) + var/percentage = ((100 / max_arousal) * arousalloss) + return percentage /mob/living/proc/isPercentAroused(percentage)//returns true if the mob's arousal (measured in a percent of 100) is greater than the arg percentage. if(!isnum(percentage) || percentage > 100 || percentage < 0) @@ -98,65 +99,69 @@ switch(G.type) if(/obj/item/organ/genital/penis) S = GLOB.cock_shapes_list[G.shape] + if(/obj/item/organ/genital/testicles) + S = GLOB.balls_shapes_list[G.shape] if(/obj/item/organ/genital/vagina) S = GLOB.vagina_shapes_list[G.shape] if(/obj/item/organ/genital/breasts) S = GLOB.breasts_shapes_list[G.shape] if(S?.alt_aroused) G.aroused_state = isPercentAroused(G.aroused_amount) + if(getArousalLoss() >= ((max_arousal / 100) * 33)) + G.aroused_state = TRUE else G.aroused_state = FALSE G.update_appearance() /mob/living/proc/update_arousal_hud() - return 0 + return FALSE /datum/species/proc/update_arousal_hud(mob/living/carbon/human/H) - return 0 + return FALSE /mob/living/carbon/human/update_arousal_hud() if(!client || !hud_used) - return 0 + return FALSE if(dna.species.update_arousal_hud()) - return 0 + return FALSE if(!canbearoused) hud_used.arousal.icon_state = "" - return 0 + return FALSE else if(hud_used.arousal) if(stat == DEAD) hud_used.arousal.icon_state = "arousal0" - return 1 + return TRUE if(getArousalLoss() == max_arousal) hud_used.arousal.icon_state = "arousal100" - return 1 + return TRUE if(getArousalLoss() >= (max_arousal / 100) * 90)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal90" - return 1 + return TRUE if(getArousalLoss() >= (max_arousal / 100) * 80)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal80" - return 1 + return TRUE if(getArousalLoss() >= (max_arousal / 100) * 70)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal70" - return 1 + return TRUE if(getArousalLoss() >= (max_arousal / 100) * 60)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal60" - return 1 + return TRUE if(getArousalLoss() >= (max_arousal / 100) * 50)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal50" - return 1 + return TRUE if(getArousalLoss() >= (max_arousal / 100) * 40)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal40" - return 1 + return TRUE if(getArousalLoss() >= (max_arousal / 100) * 30)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal30" - return 1 + return TRUE if(getArousalLoss() >= (max_arousal / 100) * 20)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal10" - return 1 + return TRUE if(getArousalLoss() >= (max_arousal / 100) * 10)//M O D U L A R , W O W hud_used.arousal.icon_state = "arousal10" - return 1 + return TRUE else hud_used.arousal.icon_state = "arousal0" @@ -168,11 +173,11 @@ /obj/screen/arousal/Click() if(!isliving(usr)) - return 0 + return FALSE var/mob/living/M = usr if(M.canbearoused) M.mob_climax() - return 1 + return TRUE else to_chat(M, "Arousal is disabled. Feature is unavailable.") @@ -193,13 +198,6 @@ "You have relieved yourself.") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) setArousalLoss(min_arousal) - /* - switch(gender) - if(MALE) - PoolOrNew(/obj/effect/decal/cleanable/semen, loc) - if(FEMALE) - PoolOrNew(/obj/effect/decal/cleanable/femcum, loc) - */ else to_chat(src, "You aren't aroused enough for that.") @@ -219,17 +217,17 @@ fluid_source = G.linked_organ.reagents total_fluids = fluid_source.total_volume if(mb_time) - src.visible_message("[src] starts to [G.masturbation_verb] [p_their()] [G.name].", \ - "You start to [G.masturbation_verb] your [G.name].", \ - "You start to [G.masturbation_verb] your [G.name].") + src.visible_message("[src] starts to [G.masturbation_verb] [p_their()] [G.name].", \ + "You start to [G.masturbation_verb] your [G.name].", \ + "You start to [G.masturbation_verb] your [G.name].") if(do_after(src, mb_time, target = src)) if(total_fluids > 5) fluid_source.reaction(src.loc, TOUCH, 1, 0) fluid_source.clear_reagents() - src.visible_message("[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!", \ - "You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].", \ - "You have relieved yourself.") + src.visible_message("[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!", \ + "You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].", \ + "You have relieved yourself.") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) setArousalLoss(min_arousal) @@ -257,16 +255,16 @@ else total_fluids = fluid_source.total_volume if(mb_time) //as long as it's not instant, give a warning - src.visible_message("[src] looks like they're about to cum.", \ - "You feel yourself about to orgasm.", \ - "You feel yourself about to orgasm.") + src.visible_message("[src] looks like they're about to cum.", \ + "You feel yourself about to orgasm.", \ + "You feel yourself about to orgasm.") if(do_after(src, mb_time, target = src)) if(total_fluids > 5) fluid_source.reaction(src.loc, TOUCH, 1, 0) fluid_source.clear_reagents() - src.visible_message("[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], using [p_their()] [G.name]!", \ - "You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name].", \ - "You climax using your [G.name].") + src.visible_message("[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], using [p_their()] [G.name]!", \ + "You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name].", \ + "You climax using your [G.name].") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) setArousalLoss(min_arousal) @@ -285,9 +283,9 @@ fluid_source = G.linked_organ.reagents total_fluids = fluid_source.total_volume if(mb_time) //Skip warning if this is an instant climax. - src.visible_message("[src] is about to climax with [L]!", \ - "You're about to climax with [L]!", \ - "You're preparing to climax with someone!") + src.visible_message("[src] is about to climax with [L]!", \ + "You're about to climax with [L]!", \ + "You're preparing to climax with someone!") if(spillage) if(do_after(src, mb_time, target = src) && in_range(src, L)) fluid_source.trans_to(L, total_fluids*G.fluid_transfer_factor) @@ -295,9 +293,9 @@ if(total_fluids > 5) fluid_source.reaction(L.loc, TOUCH, 1, 0) fluid_source.clear_reagents() - src.visible_message("[src] climaxes with [L][spillage ? ", overflowing and spilling":""], using [p_their()] [G.name]!", \ - "You orgasm with [L][spillage ? ", spilling out of them":""], using your [G.name].", \ - "You have climaxed with someone[spillage ? ", spilling out of them":""], using your [G.name].") + src.visible_message("[src] climaxes with [L][spillage ? ", overflowing and spilling":""], using [p_their()] [G.name]!", \ + "You orgasm with [L][spillage ? ", spilling out of them":""], using your [G.name].", \ + "You have climaxed with someone[spillage ? ", spilling out of them":""], using your [G.name].") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) @@ -306,9 +304,9 @@ if(do_after(src, mb_time, target = src) && in_range(src, L)) fluid_source.trans_to(L, total_fluids) total_fluids = 0 - src.visible_message("[src] climaxes with [L], [p_their()] [G.name] spilling nothing!", \ - "You ejaculate with [L], your [G.name] spilling nothing.", \ - "You have climaxed inside someone, your [G.name] spilling nothing.") + src.visible_message("[src] climaxes with [L], [p_their()] [G.name] spilling nothing!", \ + "You ejaculate with [L], your [G.name] spilling nothing.", \ + "You have climaxed inside someone, your [G.name] spilling nothing.") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) @@ -332,14 +330,14 @@ // to_chat(src, "You need a container to do this!") // return - src.visible_message("[src] starts to [G.masturbation_verb] their [G.name] over [container].", \ - "You start to [G.masturbation_verb] your [G.name] over [container].", \ - "You start to [G.masturbation_verb] your [G.name] over something.") + src.visible_message("[src] starts to [G.masturbation_verb] their [G.name] over [container].", \ + "You start to [G.masturbation_verb] your [G.name] over [container].", \ + "You start to [G.masturbation_verb] your [G.name] over something.") if(do_after(src, mb_time, target = src) && in_range(src, container)) fluid_source.trans_to(container, total_fluids) - src.visible_message("[src] uses [p_their()] [G.name] to fill [container]!", \ - "You used your [G.name] to fill [container].", \ - "You have relieved some pressure.") + src.visible_message("[src] uses [p_their()] [G.name] to fill [container]!", \ + "You used your [G.name] to fill [container].", \ + "You have relieved some pressure.") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) setArousalLoss(min_arousal) diff --git a/modular_citadel/code/modules/arousal/organs/breasts.dm b/modular_citadel/code/modules/arousal/organs/breasts.dm index a9e8744975..1223f0b616 100644 --- a/modular_citadel/code/modules/arousal/organs/breasts.dm +++ b/modular_citadel/code/modules/arousal/organs/breasts.dm @@ -5,7 +5,6 @@ icon = 'modular_citadel/icons/obj/genitals/breasts.dmi' zone = "chest" slot = "breasts" - w_class = 3 size = BREASTS_SIZE_DEF fluid_id = "milk" var/amount = 2 @@ -14,7 +13,7 @@ can_masturbate_with = TRUE masturbation_verb = "massage" can_climax = TRUE - fluid_transfer_factor =0.5 + fluid_transfer_factor = 0.5 /obj/item/organ/genital/breasts/Initialize() . = ..() @@ -36,12 +35,14 @@ reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate)) /obj/item/organ/genital/breasts/update_appearance() - var/string = "breasts_[lowertext(shape)]_[size]" - icon_state = sanitize_text(string) var/lowershape = lowertext(shape) switch(lowershape) if("pair") desc = "You see a pair of breasts." + if("quad") + desc = "You see two pairs of breast, one just under the other." + if("sextuple") + desc = "You see three sets of breasts, running from their chest to their belly." else desc = "You see some breasts, they seem to be quite exotic." if (size) @@ -50,10 +51,17 @@ desc += " You wouldn't measure them in cup sizes." if(producing && aroused_state) desc += " They're leaking [fluid_id]." + var/string if(owner) if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"]) if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow... var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need. color = "#[skintone2hex(H.skin_tone)]" + string = "breasts_[GLOB.breasts_shapes_icons[shape]]_[size]-s" else color = "#[owner.dna.features["breasts_color"]]" + string = "breasts_[GLOB.breasts_shapes_icons[shape]]_[size]" + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + icon_state = sanitize_text(string) + H.update_genitals() diff --git a/modular_citadel/code/modules/arousal/organs/eggsack.dm b/modular_citadel/code/modules/arousal/organs/eggsack.dm index 27104cd36a..402d246e40 100644 --- a/modular_citadel/code/modules/arousal/organs/eggsack.dm +++ b/modular_citadel/code/modules/arousal/organs/eggsack.dm @@ -6,7 +6,6 @@ zone = "groin" slot = "testicles" color = null //don't use the /genital color since it already is colored - w_class = 3 internal = TRUE var/egg_girth = EGG_GIRTH_DEF var/cum_mult = CUM_RATE_MULT diff --git a/modular_citadel/code/modules/arousal/organs/genitals.dm b/modular_citadel/code/modules/arousal/organs/genitals.dm index c10d444f07..52508d7803 100644 --- a/modular_citadel/code/modules/arousal/organs/genitals.dm +++ b/modular_citadel/code/modules/arousal/organs/genitals.dm @@ -1,25 +1,26 @@ /obj/item/organ/genital color = "#fcccb3" - var/shape = "human" - var/sensitivity = 1 - var/list/genital_flags = list() - var/can_masturbate_with = FALSE - var/masturbation_verb = "masturbate" - var/can_climax = FALSE - var/fluid_transfer_factor = 0.0 //How much would a partner get in them if they climax using this? - var/size = 2 //can vary between num or text, just used in icon_state strings - var/fluid_id = null - var/fluid_max_volume = 50 - var/fluid_efficiency = 1 - var/fluid_rate = 1 - var/fluid_mult = 1 - var/producing = FALSE - var/aroused_state = FALSE //Boolean used in icon_state strings - var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons. + w_class = WEIGHT_CLASS_NORMAL + var/shape = "human" + var/sensitivity = AROUSAL_START_VALUE + var/list/genital_flags = list() + var/can_masturbate_with = FALSE + var/masturbation_verb = "masturbate" + var/can_climax = FALSE + var/fluid_transfer_factor = 0.0 //How much would a partner get in them if they climax using this? + var/size = 2 //can vary between num or text, just used in icon_state strings + var/fluid_id = null + var/fluid_max_volume = 50 + var/fluid_efficiency = 1 + var/fluid_rate = 1 + var/fluid_mult = 1 + var/producing = FALSE + var/aroused_state = FALSE //Boolean used in icon_state strings + var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons. var/obj/item/organ/genital/linked_organ - var/through_clothes = FALSE - var/internal = FALSE - var/hidden = FALSE + var/through_clothes = FALSE + var/internal = FALSE + var/hidden = FALSE /obj/item/organ/genital/Initialize() . = ..() @@ -92,7 +93,7 @@ var/list/genital_list = list() for(var/obj/item/organ/O in internal_organs) - if(istype(O, /obj/item/organ/genital)) + if(isgenital(O)) var/obj/item/organ/genital/G = O if(!G.internal) genital_list += G @@ -110,10 +111,13 @@ /obj/item/organ/genital/proc/update_size() + return /obj/item/organ/genital/proc/update_appearance() + return /obj/item/organ/genital/proc/update_link() + return /obj/item/organ/genital/proc/remove_ref() if(linked_organ) @@ -130,21 +134,21 @@ //proc to give a player their genitals and stuff when they log in /mob/living/carbon/human/proc/give_genitals(clean=0)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA - if (NOGENITALS in dna.species.species_traits) - return if(clean) var/obj/item/organ/genital/GtoClean for(GtoClean in internal_organs) qdel(GtoClean) + if (NOGENITALS in dna.species.species_traits) + return //Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in. - if(dna.features["has_breasts"]) - give_breasts() if(dna.features["has_vag"]) give_vagina() if(dna.features["has_womb"]) give_womb() if(dna.features["has_balls"]) give_balls() + if(dna.features["has_breasts"]) // since we have multi-boobs as a thing, we'll want to at least draw over these. but not over the pingas. + give_breasts() if(dna.features["has_cock"]) give_penis() if(dna.features["has_ovi"]) @@ -162,7 +166,7 @@ P.Insert(src) if(P) if(dna.species.use_skintones && dna.features["genitals_use_skintone"]) - P.color = skintone2hex(skin_tone) + P.color = "#[skintone2hex(skin_tone)]" else P.color = "#[dna.features["cock_color"]]" P.length = dna.features["cock_length"] @@ -178,13 +182,18 @@ if(!getorganslot("testicles")) var/obj/item/organ/genital/testicles/T = new T.Insert(src) -// if(dna.species.use_skintones && dna.features["genitals_use_skintone"]) -// T.color = skintone2hex(skin_tone) -// else -// T.color = "#[dna.features["balls_color"]]" if(T) + if(dna.species.use_skintones && dna.features["genitals_use_skintone"]) + T.color = "#[skintone2hex(skin_tone)]" + else + T.color = "#[dna.features["balls_color"]]" T.size = dna.features["balls_size"] T.sack_size = dna.features["balls_sack_size"] + T.shape = dna.features["balls_shape"] + if(dna.features["balls_shape"] == "Hidden") + T.internal = TRUE + else + T.internal = FALSE T.fluid_id = dna.features["balls_fluid"] T.fluid_rate = dna.features["balls_cum_rate"] T.fluid_mult = dna.features["balls_cum_mult"] @@ -201,7 +210,7 @@ B.Insert(src) if(B) if(dna.species.use_skintones && dna.features["genitals_use_skintone"]) - B.color = skintone2hex(skin_tone) + B.color = "#[skintone2hex(skin_tone)]" else B.color = "#[dna.features["breasts_color"]]" B.size = dna.features["breasts_size"] @@ -211,7 +220,10 @@ /mob/living/carbon/human/proc/give_ovipositor() + return /mob/living/carbon/human/proc/give_eggsack() + return + /mob/living/carbon/human/proc/give_vagina() if(!dna) return FALSE @@ -222,7 +234,7 @@ V.Insert(src) if(V) if(dna.species.use_skintones && dna.features["genitals_use_skintone"]) - V.color = skintone2hex(skin_tone) + V.color = "#[skintone2hex(skin_tone)]" else V.color = "[dna.features["vag_color"]]" V.shape = "[dna.features["vag_shape"]]" @@ -274,13 +286,14 @@ return if(NOGENITALS in species_traits)//golems and such return - if(H.has_trait(TRAIT_HUSK)) + if(HAS_TRAIT(H, TRAIT_HUSK)) return var/list/genitals_to_add = list() var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_ADJ_LAYER, GENITALS_FRONT_LAYER) var/list/standing = list() - var/size = null + var/size + var/aroused_state for(var/L in relevant_layers) //Less hardcode H.remove_overlay(L) @@ -288,7 +301,7 @@ //start scanning for genitals //var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again for(var/obj/item/organ/O in H.internal_organs) - if(istype(O, /obj/item/organ/genital)) + if(isgenital(O)) var/obj/item/organ/genital/G = O if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes genitals_to_add += H.getorganslot(G.slot) @@ -300,9 +313,12 @@ for(var/obj/item/organ/genital/G in genitals_to_add) var/datum/sprite_accessory/S size = G.size + aroused_state = G.aroused_state switch(G.type) if(/obj/item/organ/genital/penis) S = GLOB.cock_shapes_list[G.shape] + if(/obj/item/organ/genital/testicles) + S = GLOB.balls_shapes_list[G.shape] if(/obj/item/organ/genital/vagina) S = GLOB.vagina_shapes_list[G.shape] if(/obj/item/organ/genital/breasts) @@ -310,38 +326,29 @@ if(!S || S.icon_state == "none") continue + var/mutable_appearance/genital_overlay = mutable_appearance(S.icon, layer = -layer) - genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]_[G.aroused_state]_[layertext]" + genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]_[aroused_state]_[layertext]" if(S.center) genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y) if(use_skintones && H.dna.features["genitals_use_skintone"]) genital_overlay.color = "#[skintone2hex(H.skin_tone)]" + genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]" else switch(S.color_src) if("cock_color") genital_overlay.color = "#[H.dna.features["cock_color"]]" + if("balls_color") + genital_overlay.color = "#[H.dna.features["balls_color"]]" if("breasts_color") genital_overlay.color = "#[H.dna.features["breasts_color"]]" if("vag_color") genital_overlay.color = "#[H.dna.features["vag_color"]]" - if(MUTCOLORS) - if(fixed_mut_color) - genital_overlay.color = "#[fixed_mut_color]" - else - genital_overlay.color = "#[H.dna.features["mcolor"]]" - if(MUTCOLORS2) - if(fixed_mut_color2) - genital_overlay.color = "#[fixed_mut_color2]" - else - genital_overlay.color = "#[H.dna.features["mcolor2"]]" - if(MUTCOLORS3) - if(fixed_mut_color3) - genital_overlay.color = "#[fixed_mut_color3]" - else - genital_overlay.color = "#[H.dna.features["mcolor3"]]" + standing += genital_overlay + if(LAZYLEN(standing)) H.overlays_standing[layer] = standing.Copy() standing = list() diff --git a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm index bcfa462789..b913a90fb6 100644 --- a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm +++ b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm @@ -55,8 +55,24 @@ center = TRUE //Center the image 'cause 2-tile wide. dimension_x = 64 +//Testicles +//These ones aren't inert +/datum/sprite_accessory/testicles + icon = 'modular_citadel/icons/obj/genitals/testicles_onmob.dmi' + icon_state = "testicle" + name = "testicle" //the preview name of the accessory + color_src = "balls_color" + locked = 0 +/datum/sprite_accessory/testicles/hidden + icon_state = "hidden" + name = "Hidden" + alt_aroused = TRUE +/datum/sprite_accessory/testicles/single + icon_state = "single" + name = "Single" + alt_aroused = TRUE //Vaginas /datum/sprite_accessory/vagina @@ -87,6 +103,13 @@ icon_state = "hairy" name = "Hairy" +/datum/sprite_accessory/vagina/spade + icon_state = "spade" + name = "Spade" + +/datum/sprite_accessory/vagina/furred + icon_state = "furred" + name = "Furred" //BREASTS BE HERE /datum/sprite_accessory/breasts @@ -102,6 +125,15 @@ name = "Pair" alt_aroused = TRUE +/datum/sprite_accessory/breasts/quad + icon_state = "quad" + name = "Quad" + alt_aroused = TRUE + +/datum/sprite_accessory/breasts/sextuple + icon_state = "sextuple" + name = "Sextuple" + alt_aroused = TRUE //OVIPOSITORS BE HERE /datum/sprite_accessory/ovipositor diff --git a/modular_citadel/code/modules/arousal/organs/penis.dm b/modular_citadel/code/modules/arousal/organs/penis.dm index 38e8e44f39..b6cb8fa4b2 100644 --- a/modular_citadel/code/modules/arousal/organs/penis.dm +++ b/modular_citadel/code/modules/arousal/organs/penis.dm @@ -4,15 +4,14 @@ icon_state = "penis" icon = 'modular_citadel/icons/obj/genitals/penis.dmi' zone = "groin" - slot = "penis" - w_class = 3 + slot = ORGAN_SLOT_PENIS can_masturbate_with = TRUE masturbation_verb = "stroke" can_climax = TRUE - fluid_transfer_factor = 0.5 + fluid_transfer_factor = 0.5 size = 2 //arbitrary value derived from length and girth for sprites. var/length = 6 //inches - var/cached_length //used to detect a change in length + var/cached_length //used to detect a change in length var/girth = 0 var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF @@ -27,7 +26,7 @@ size = 1 if(5 to 9) size = 2 - if(9 to INFINITY) + if(15 to INFINITY) size = 3//no new sprites for anything larger yet /* if(9 to 15) size = 3 @@ -37,23 +36,30 @@ cached_length = length /obj/item/organ/genital/penis/update_appearance() - var/string = "penis_[GLOB.cock_shapes_icons[shape]]_[size]" - icon_state = sanitize_text(string) + var/string var/lowershape = lowertext(shape) - desc = "You see a [lowershape] penis. You estimate it's about [round(length, 0.25)] inch[length > 1 ? "es" : ""] long." + desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] penis. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth." + if(owner) if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"]) if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow... var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need. color = "#[skintone2hex(H.skin_tone)]" + string = "penis_[GLOB.cock_shapes_icons[shape]]_[size]-s" else color = "#[owner.dna.features["cock_color"]]" + string = "penis_[GLOB.cock_shapes_icons[shape]]_[size]" + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + icon_state = sanitize_text(string) + H.update_genitals() /obj/item/organ/genital/penis/update_link() if(owner) linked_organ = (owner.getorganslot("testicles")) if(linked_organ) linked_organ.linked_organ = src + linked_organ.size = size else if(linked_organ) linked_organ.linked_organ = null diff --git a/modular_citadel/code/modules/arousal/organs/testicles.dm b/modular_citadel/code/modules/arousal/organs/testicles.dm index 815d8034e7..0cf698392c 100644 --- a/modular_citadel/code/modules/arousal/organs/testicles.dm +++ b/modular_citadel/code/modules/arousal/organs/testicles.dm @@ -1,17 +1,20 @@ /obj/item/organ/genital/testicles - name = "testicles" - desc = "A male reproductive organ." - icon_state = "testicles" - icon = 'modular_citadel/icons/obj/genitals/penis.dmi' - zone = "groin" - slot = "testicles" - w_class = 3 - internal = TRUE - size = BALLS_SIZE_DEF - var/sack_size = BALLS_SACK_SIZE_DEF - fluid_id = "semen" - producing = TRUE - var/sent_full_message = 1 //defaults to 1 since they're full to start + name = "testicles" + desc = "A male reproductive organ." + icon_state = "testicles" + icon = 'modular_citadel/icons/obj/genitals/testicles.dmi' + zone = "groin" + slot = "testicles" + size = BALLS_SIZE_MIN + var/size_name = "average" + shape = "single" + var/sack_size = BALLS_SACK_SIZE_DEF + fluid_id = "semen" + producing = TRUE + can_masturbate_with = TRUE + masturbation_verb = "massage" + can_climax = TRUE + var/sent_full_message = TRUE //defaults to 1 since they're full to start /obj/item/organ/genital/testicles/Initialize() . = ..() @@ -28,9 +31,9 @@ if(reagents.total_volume >= reagents.maximum_volume) if(!sent_full_message) send_full_message() - sent_full_message = 1 + sent_full_message = TRUE return FALSE - sent_full_message = 0 + sent_full_message = FALSE update_link() if(!linked_organ) return FALSE @@ -42,6 +45,7 @@ linked_organ = (owner.getorganslot("penis")) if(linked_organ) linked_organ.linked_organ = src + else if(linked_organ) linked_organ.linked_organ = null @@ -49,6 +53,34 @@ /obj/item/organ/genital/testicles/proc/send_full_message(msg = "Your balls finally feel full, again.") if(owner && istext(msg)) - owner << msg + to_chat(owner, msg) return TRUE +/obj/item/organ/genital/testicles/update_appearance() + if(owner) + if(size == 0) + size_name = "nonexistant" + if(size == 1) + size_name = "average" + if(size == 2) + size_name = "enlarged" + if(size >= 3) + size_name = "engorged" + + if(!internal) + desc = "You see an [size_name] pair of testicles dangling." + else + desc = "They don't have any testicles you can see." + var/string + if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"]) + if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow... + var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need. + color = "#[skintone2hex(H.skin_tone)]" + string = "testicles_[GLOB.balls_shapes_icons[shape]]_[size]-s" + else + color = "#[owner.dna.features["balls_color"]]" + string = "testicles_[GLOB.balls_shapes_icons[shape]]_[size]" + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + icon_state = sanitize_text(string) + H.update_genitals() diff --git a/modular_citadel/code/modules/arousal/organs/vagina.dm b/modular_citadel/code/modules/arousal/organs/vagina.dm index 228c3141e3..8c15aa5437 100644 --- a/modular_citadel/code/modules/arousal/organs/vagina.dm +++ b/modular_citadel/code/modules/arousal/organs/vagina.dm @@ -17,12 +17,11 @@ var/clits = 1 var/clit_diam = 0.25 var/clit_len = 0.25 - var/list/vag_types = list("tentacle", "dentata", "hairy") + var/list/vag_types = list("tentacle", "dentata", "hairy", "spade", "furred") /obj/item/organ/genital/vagina/update_appearance() - var/string = "vagina" //Keeping this code here, so making multiple sprites for the different kinds is easier. - icon_state = sanitize_text(string) + var/string //Keeping this code here, so making multiple sprites for the different kinds is easier. var/lowershape = lowertext(shape) var/details @@ -37,6 +36,10 @@ details = "It is taut with smooth skin, though without much hair and " if("gaping") details = "It is gaping slightly open, though without much hair and " + if("spade") + details = "It is a plush canine spade, it " + if("furred") + details = "It has neatly groomed fur around the outer folds, it " else details = "It has an exotic shape and " if(aroused_state) @@ -51,9 +54,14 @@ if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow... var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need. color = "#[skintone2hex(H.skin_tone)]" + string = "vagina-s" else color = "#[owner.dna.features["vag_color"]]" - + string = "vagina" + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + icon_state = sanitize_text(string) + H.update_genitals() /obj/item/organ/genital/vagina/update_link() if(owner) diff --git a/modular_citadel/code/modules/arousal/organs/womb.dm b/modular_citadel/code/modules/arousal/organs/womb.dm index c59d74e629..686d9059a0 100644 --- a/modular_citadel/code/modules/arousal/organs/womb.dm +++ b/modular_citadel/code/modules/arousal/organs/womb.dm @@ -5,12 +5,10 @@ icon_state = "womb" zone = "groin" slot = "womb" - w_class = 3 internal = TRUE fluid_id = "femcum" producing = TRUE - /obj/item/organ/genital/womb/Initialize() . = ..() reagents.add_reagent(fluid_id, fluid_max_volume) diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index c0a4df2243..7dfaa4a386 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -373,4 +373,22 @@ datum/gear/darksabresheath name = "French Beret" category = SLOT_HEAD path = /obj/item/clothing/head/frenchberet - ckeywhitelist = list("notazoltan") \ No newline at end of file + ckeywhitelist = list("notazoltan") + +/datum/gear/zuliecloak + name = "Project: Zul-E" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/hooded/cloak/zuliecloak + ckeywhitelist = list("asky") + +/datum/gear/blackredgold + name = "Black, Red, and Gold Coat" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/blackredgold + ckeywhitelist = list("ttbnc") + +/datum/gear/fritzplush + name = "Fritz Plushie" + category = SLOT_IN_BACKPACK + path = /obj/item/toy/plush/mammal/dog/fritz + ckeywhitelist = list("analwerewolf") \ No newline at end of file diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm index 1ef203d538..bd26f44482 100644 --- a/modular_citadel/code/modules/client/loadout/head.dm +++ b/modular_citadel/code/modules/client/loadout/head.dm @@ -56,25 +56,34 @@ //trek fancy Hats! /datum/gear/trekcap - name = "Federation Officer's Cap" + name = "Federation Officer's Cap (White)" category = SLOT_HEAD path = /obj/item/clothing/head/caphat/formal/fedcover restricted_roles = list("Captain","Head of Personnel") +/datum/gear/trekcapcap + name = "Federation Officer's Cap (Black)" + category = SLOT_HEAD + path = /obj/item/clothing/head/caphat/formal/fedcover/black + restricted_roles = list("Captain","Head of Personnel") + /datum/gear/trekcapmedisci - name = "Federation Officer's Cap" + name = "Federation Officer's Cap (Blue)" category = SLOT_HEAD path = /obj/item/clothing/head/caphat/formal/fedcover/medsci + restricted_desc = "Medical and Science" restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist","Research Director","Scientist", "Roboticist") /datum/gear/trekcapeng - name = "Federation Officer's Cap" + name = "Federation Officer's Cap (Yellow)" category = SLOT_HEAD path = /obj/item/clothing/head/caphat/formal/fedcover/eng + restricted_desc = "Engineering, Security, and Cargo" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") /datum/gear/trekcapsec - name = "Federation Officer's Cap" + name = "Federation Officer's Cap (Red)" category = SLOT_HEAD path = /obj/item/clothing/head/caphat/formal/fedcover/sec + restricted_desc = "Engineering, Security, and Cargo" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") \ No newline at end of file diff --git a/modular_citadel/code/modules/client/loadout/loadout.dm b/modular_citadel/code/modules/client/loadout/loadout.dm index 52e4f86dbe..2e11519d0b 100644 --- a/modular_citadel/code/modules/client/loadout/loadout.dm +++ b/modular_citadel/code/modules/client/loadout/loadout.dm @@ -52,6 +52,7 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids) var/geargroupID //defines the ID that the gear inherits from the config var/list/restricted_roles var/list/ckeywhitelist + var/restricted_desc /datum/gear/New() ..() diff --git a/modular_citadel/code/modules/client/loadout/neck.dm b/modular_citadel/code/modules/client/loadout/neck.dm index f7346ec135..320a83b87d 100644 --- a/modular_citadel/code/modules/client/loadout/neck.dm +++ b/modular_citadel/code/modules/client/loadout/neck.dm @@ -18,6 +18,16 @@ category = SLOT_NECK path = /obj/item/clothing/neck/petcollar +/datum/gear/leathercollar + name = "Leather collar" + category = SLOT_NECK + path = /obj/item/clothing/neck/petcollar/leather + +/datum/gear/choker + name = "Choker" + category = SLOT_NECK + path = /obj/item/clothing/neck/petcollar/choker + /datum/gear/scarf name = "White scarf" category = SLOT_NECK diff --git a/modular_citadel/code/modules/client/loadout/suit.dm b/modular_citadel/code/modules/client/loadout/suit.dm index 9d3a6b9a02..5a12a6bf0b 100644 --- a/modular_citadel/code/modules/client/loadout/suit.dm +++ b/modular_citadel/code/modules/client/loadout/suit.dm @@ -84,31 +84,62 @@ name = "DS9 Overcoat (use uniform)" category = SLOT_WEAR_SUIT path = /obj/item/clothing/suit/storage/trek/ds9 + restricted_desc = "All, barring Service and Civilian" restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster", "Medical Doctor","Chemist","Virologist","Geneticist","Scientist", "Roboticist", "Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer", "Cargo Technician", "Shaft Miner") //everyone who actually deserves a job. //Federation jackets from movies /datum/gear/trekcmdcap - name = "fed (movie) uniform, Captain" + name = "Fed (movie) uniform, Black" category = SLOT_WEAR_SUIT path = /obj/item/clothing/suit/storage/fluff/fedcoat/capt restricted_roles = list("Captain","Head of Personnel") /datum/gear/trekcmdmov - name = "fed (movie) uniform, sec" + name = "Fed (movie) uniform, Red" category = SLOT_WEAR_SUIT path = /obj/item/clothing/suit/storage/fluff/fedcoat + restricted_desc = "Heads of Staff and Security" restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster","Warden","Detective","Security Officer") /datum/gear/trekmedscimov - name = "fed (movie) uniform, med/sci" + name = "Fed (movie) uniform, Blue" category = SLOT_WEAR_SUIT path = /obj/item/clothing/suit/storage/fluff/fedcoat/medsci + restricted_desc = "Medical and Science" restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist","Research Director","Scientist", "Roboticist") /datum/gear/trekengmov - name = "fed (movie) uniform, ops/eng" + name = "Fed (movie) uniform, Yellow" category = SLOT_WEAR_SUIT path = /obj/item/clothing/suit/storage/fluff/fedcoat/eng + restricted_desc = "Engineering and Cargo" + restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Cargo Technician", "Shaft Miner", "Quartermaster") + +/datum/gear/trekcmdcapmod + name = "Fed (Modern) uniform, White" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/storage/fluff/modernfedcoat + restricted_roles = list("Captain","Head of Personnel") + +/datum/gear/trekcmdmod + name = "Fed (Modern) uniform, Red" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/storage/fluff/modernfedcoat/sec + restricted_desc = "Heads of Staff and Security" + restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster","Warden","Detective","Security Officer") + +/datum/gear/trekmedscimod + name = "Fed (Modern) uniform, Blue" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/storage/fluff/modernfedcoat/medsci + restricted_desc = "Medical and Science" + restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist","Research Director","Scientist", "Roboticist") + +/datum/gear/trekengmod + name = "Fed (Modern) uniform, Yellow" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/storage/fluff/modernfedcoat/eng + restricted_desc = "Engineering and Cargo" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Cargo Technician", "Shaft Miner", "Quartermaster") diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index e4e2f063d3..07309ffd0d 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -73,6 +73,26 @@ category = SLOT_W_UNIFORM path = /obj/item/clothing/under/skirt/purple +/datum/gear/schoolgirlblue + name = "Blue Schoolgirl Uniform" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/schoolgirl + +/datum/gear/schoolgirlred + name = "Red Schoolgirl Uniform" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/schoolgirl/red + +/datum/gear/schoolgirlgreen + name = "Green Schoolgirl Uniform" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/schoolgirl/green + +/datum/gear/schoolgirlorange + name = "Orange Schoolgirl Uniform" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/schoolgirl/orange + /datum/gear/kilt name = "Kilt" category = SLOT_W_UNIFORM @@ -179,18 +199,21 @@ name = "TOS uniform, cmd" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/command + restricted_desc = "Heads of Staff" restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster") /datum/gear/trekmedscitos name = "TOS uniform, med/sci" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/medsci + restricted_desc = "Medical and Science" restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist","Research Director","Scientist", "Roboticist") /datum/gear/trekengtos name = "TOS uniform, ops/sec" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/engsec + restricted_desc = "Engineering and Security" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") //TNG @@ -198,18 +221,21 @@ name = "TNG uniform, cmd" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/command/next + restricted_desc = "Heads of Staff" restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster") /datum/gear/trekmedscitng name = "TNG uniform, med/sci" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/medsci/next + restricted_desc = "Medical and Science" restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist","Research Director","Scientist", "Roboticist") /datum/gear/trekengtng name = "TNG uniform, ops/sec" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/engsec/next + restricted_desc = "Engineering and Security" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") //VOY @@ -217,18 +243,21 @@ name = "VOY uniform, cmd" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/command/voy + restricted_desc = "Heads of Staff" restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster") /datum/gear/trekmedscivoy name = "VOY uniform, med/sci" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/medsci/voy + restricted_desc = "Medical and Science" restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist","Research Director","Scientist", "Roboticist") /datum/gear/trekengvoy name = "VOY uniform, ops/sec" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/engsec/voy + restricted_desc = "Engineering and Security" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") //DS9 @@ -236,18 +265,21 @@ name = "DS9 uniform, cmd" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/command/ds9 + restricted_desc = "Heads of Staff" restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster") /datum/gear/trekmedscids9 name = "DS9 uniform, med/sci" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/medsci/ds9 + restricted_desc = "Medical and Science" restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist","Research Director","Scientist", "Roboticist") /datum/gear/trekengds9 name = "DS9 uniform, ops/sec" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/engsec/ds9 + restricted_desc = "Engineering and Security" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") //ENT @@ -255,16 +287,19 @@ name = "ENT uniform, cmd" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/command/ent + restricted_desc = "Heads of Staff" restricted_roles = list("Head of Security","Captain","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Quartermaster") /datum/gear/trekmedscient name = "ENT uniform, med/sci" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/medsci/ent + restricted_desc = "Medical and Science" restricted_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist","Research Director","Scientist", "Roboticist") /datum/gear/trekengent name = "ENT uniform, ops/sec" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/rank/trek/engsec/ent + restricted_desc = "Engineering and Security" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") diff --git a/modular_citadel/code/modules/client/preferences.dm b/modular_citadel/code/modules/client/preferences.dm index 358208c1d7..dfe419964e 100644 --- a/modular_citadel/code/modules/client/preferences.dm +++ b/modular_citadel/code/modules/client/preferences.dm @@ -24,77 +24,7 @@ // stuff that was in base max_save_slots = 10 - features = list("mcolor" = "FFF", - "tail_lizard" = "Smooth", - "tail_human" = "None", - "snout" = "Round", - "horns" = "None", - "ears" = "None", - "wings" = "None", - "frills" = "None", - "spines" = "None", - "body_markings" = "None", - "legs" = "Normal Legs", - "moth_wings" = "Plain", - "mcolor2" = "FFF", - "mcolor3" = "FFF", - "mam_body_markings" = "None", - "mam_ears" = "None", - "mam_snouts" = "None", - "mam_tail" = "None", - "mam_tail_animated" = "None", - "xenodorsal" = "Standard", - "xenohead" = "Standard", - "xenotail" = "Xenomorph Tail", - "taur" = "None", - "exhibitionist" = FALSE, - "genitals_use_skintone" = FALSE, - "has_cock" = FALSE, - "cock_shape" = "Human", - "cock_length" = 6, - "cock_girth_ratio" = COCK_GIRTH_RATIO_DEF, - "cock_color" = "fff", - "has_sheath" = FALSE, - "sheath_color" = "fff", - "has_balls" = FALSE, - "balls_internal" = FALSE, - "balls_color" = "fff", - "balls_amount" = 2, - "balls_sack_size" = BALLS_SACK_SIZE_DEF, - "balls_size" = BALLS_SIZE_DEF, - "balls_cum_rate" = CUM_RATE, - "balls_cum_mult" = CUM_RATE_MULT, - "balls_efficiency" = CUM_EFFICIENCY, - "balls_fluid" = "semen", - "has_ovi" = FALSE, - "ovi_shape" = "knotted", - "ovi_length" = 6, - "ovi_color" = "fff", - "has_eggsack" = FALSE, - "eggsack_internal" = TRUE, - "eggsack_color" = "fff", - "eggsack_size" = BALLS_SACK_SIZE_DEF, - "eggsack_egg_color" = "fff", - "eggsack_egg_size" = EGG_GIRTH_DEF, - "has_breasts" = FALSE, - "breasts_color" = "fff", - "breasts_size" = "C", - "breasts_shape" = "Pair", - "breasts_fluid" = "milk", - "has_vag" = FALSE, - "vag_shape" = "Human", - "vag_color" = "fff", - "vag_clits" = 1, - "vag_clit_diam" = 0.25, - "has_womb" = FALSE, - "womb_cum_rate" = CUM_RATE, - "womb_cum_mult" = CUM_RATE_MULT, - "womb_efficiency" = CUM_EFFICIENCY, - "womb_fluid" = "femcum", - "ipc_screen" = "Sunburst", - "ipc_antenna" = "None", - "flavor_text" = "" - ) + /datum/preferences/New(client/C) ..() diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm index 209d46db61..2921f70684 100644 --- a/modular_citadel/code/modules/client/preferences_savefile.dm +++ b/modular_citadel/code/modules/client/preferences_savefile.dm @@ -56,6 +56,7 @@ WRITE_FILE(S["feature_has_balls"], features["has_balls"]) WRITE_FILE(S["feature_balls_color"], features["balls_color"]) WRITE_FILE(S["feature_balls_size"], features["balls_size"]) + WRITE_FILE(S["feature_balls_shape"], features["balls_shape"]) WRITE_FILE(S["feature_balls_sack_size"], features["balls_sack_size"]) WRITE_FILE(S["feature_balls_fluid"], features["balls_fluid"]) //breasts features diff --git a/modular_citadel/code/modules/clothing/under/trek_under.dm b/modular_citadel/code/modules/clothing/under/trek_under.dm index ddcf0e6344..8e2b94372d 100644 --- a/modular_citadel/code/modules/clothing/under/trek_under.dm +++ b/modular_citadel/code/modules/clothing/under/trek_under.dm @@ -15,7 +15,6 @@ alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi' item_state = "" can_adjust = FALSE //to prevent you from "wearing it casually" - mutantrace_variation = NO_MUTANTRACE_VARIATION //TOS /obj/item/clothing/under/rank/trek/command @@ -117,25 +116,25 @@ /obj/item/clothing/under/rank/trek/command/ds9 desc = "The uniform worn by command officers of the 2380s." - icon_state = "trek_command" + icon_state = "trek_ds9_command" item_state = "trek_ds9_command" /obj/item/clothing/under/rank/trek/engsec/ds9 desc = "The uniform worn by operations officers of the 2380s." - icon_state = "trek_engsec" + icon_state = "trek_ds9_engsec" item_state = "trek_ds9_engsec" /obj/item/clothing/under/rank/trek/medsci/ds9 desc = "The uniform undershirt worn by medsci officers of the 2380s." - icon_state = "trek_medsci" + icon_state = "trek_ds9_medsci" item_state = "trek_ds9_medsci" //MODERN ish Joan sqrl sprites. I think //For general use /obj/item/clothing/suit/storage/fluff/fedcoat - name = "Federation Uniform Jacket (Red)" - desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it. Set phasers to awesome." + name = "Federation Uniform Jacket" + desc = "A uniform jacket from the United Federation. Set phasers to awesome." icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi' alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi' @@ -177,27 +176,24 @@ icon_state = "[initial(icon_state)]_open" item_state = "[initial(item_state)]_open" unbuttoned = 1 - usr << "You unbutton the coat." + to_chat(usr,"You unbutton the coat.") if(1) icon_state = "[initial(icon_state)]" item_state = "[initial(item_state)]" unbuttoned = 0 - usr << "You button up the coat." + to_chat(usr,"You button up the coat.") usr.update_inv_wear_suit() //Variants /obj/item/clothing/suit/storage/fluff/fedcoat/medsci - desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it. Wearing this may make you feel all scientific." icon_state = "fedblue" item_state = "fedblue" /obj/item/clothing/suit/storage/fluff/fedcoat/eng - desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it.Wearing it may make you feel like checking a warp core, whatever that is." icon_state = "fedeng" item_state = "fedeng" /obj/item/clothing/suit/storage/fluff/fedcoat/capt - desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it. You feel like a commanding officer of Starfleet." icon_state = "fedcapt" item_state = "fedcapt" @@ -205,34 +201,31 @@ /obj/item/clothing/suit/storage/fluff/modernfedcoat name = "Modern Federation Uniform Jacket" - desc = "A modern uniform jacket from the United Federation. Their Starfleet had recently started using these uniforms. Wearing this makes you feel like a competant commander." + desc = "A modern uniform jacket from the United Federation." icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi' alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi' icon_state = "fedmodern" item_state = "fedmodern" body_parts_covered = CHEST|GROIN|ARMS allowed = list( - /obj/item/tank/internals/emergency_oxygen, - /obj/item/flashlight, - /obj/item/gun, - /obj/item/melee/baton, - /obj/item/restraints/handcuffs, - /obj/item/taperecorder) - armor = list("melee" = 45, "bullet" = 25, "laser" = 25,"energy" = 25, "bomb" = 25, "bio" = 25, "rad" = 50, "fire" = 50, "acid" = 50) + /obj/item/flashlight, /obj/item/analyzer, + /obj/item/radio, /obj/item/tank/internals/emergency_oxygen, + /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer,/obj/item/reagent_containers/syringe, + /obj/item/reagent_containers/glass/bottle/vial,/obj/item/reagent_containers/glass/beaker, + /obj/item/reagent_containers/pill,/obj/item/storage/pill_bottle, /obj/item/restraints/handcuffs,/obj/item/hypospray + ) + armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 5, "rad" = 10, "fire" = 10, "acid" = 0) //Variants /obj/item/clothing/suit/storage/fluff/modernfedcoat/medsci - desc = "A modern uniform jacket from the United Federation. Their Starfleet had recently started using these uniforms. Wearing this makes you feel like a scientist or a pilot." icon_state = "fedmodernblue" item_state = "fedmodernblue" /obj/item/clothing/suit/storage/fluff/modernfedcoat/eng - desc = "A modern uniform jacket from the United Federation. Their Starfleet had recently started using these uniforms. You feel like you can handle any type of technical engineering problems." icon_state = "fedmoderneng" item_state = "fedmoderneng" /obj/item/clothing/suit/storage/fluff/modernfedcoat/sec - desc = "A modern uniform jacket from the United Federation. Their Starfleet had recently started using these uniforms. This uniform makes you want to protect and serve as an officer." icon_state = "fedmodernsec" item_state = "fedmodernsec" @@ -256,3 +249,7 @@ /obj/item/clothing/head/caphat/formal/fedcover/sec icon_state = "fedcapsec" item_state = "fedcapsec" + +/obj/item/clothing/head/caphat/formal/fedcover/black + icon_state = "fedcapblack" + item_state = "fedcapblack" diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index 5f0d8cfc00..e1b1110cf8 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -49,6 +49,66 @@ item_color = "steele" medaltype = "medal-silver" +/obj/item/toy/sword/darksabre + name = "Kiara's Sabre" + desc = "This blade looks as dangerous as its owner." + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + icon_state = "darksabre" + item_state = "darksabre" + lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi' + righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi' + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("attacked", "struck", "hit") + + +/obj/item/storage/belt/sabre/darksabre + name = "Ornate Sheathe" + desc = "An ornate and rather sinister looking sabre sheathe." + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + icon_state = "darksheath" + item_state = "darksheath" + w_class = WEIGHT_CLASS_BULKY + +/obj/item/storage/belt/sabre/darksabre/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_items = 1 + STR.rustle_sound = FALSE + STR.max_w_class = WEIGHT_CLASS_BULKY + STR.can_hold = typecacheof(list( + /obj/item/toy/sword/darksabre + )) + +/obj/item/storage/belt/sabre/darksabre/update_icon() + icon_state = "darksheath" + item_state = "darksheath" + if(contents.len) + icon_state += "-darksabre" + item_state += "-darksabre" + if(loc && isliving(loc)) + var/mob/living/L = loc + L.regenerate_icons() + ..() + +/obj/item/storage/belt/sabre/darksabre/PopulateContents() + new /obj/item/toy/sword/darksabre(src) + update_icon() + +/obj/item/clothing/suit/armor/vest/darkcarapace + name = "Dark Armor" + desc = "A dark, non-functional piece of armor sporting a red and black finish." + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + icon_state = "darkcarapace" + item_state = "darkcarapace" + blood_overlay_type = "armor" + dog_fashion = /datum/dog_fashion/back + mutantrace_variation = NO_MUTANTRACE_VARIATION + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + + /obj/item/lighter/gold name = "\improper Engraved Zippo" desc = "A shiny and relatively expensive zippo lighter. There's a small etched in verse on the bottom that reads, 'No Gods, No Masters, Only Man.'" @@ -307,51 +367,6 @@ if(prob(5) && H.hallucination < 15) H.hallucination += 10 -/obj/item/toy/sword/darksabre - name = "Kiara's Sabre" - desc = "This blade looks as dangerous as its owner." - icon = 'icons/obj/custom.dmi' - alternate_worn_icon = 'icons/mob/custom_w.dmi' - icon_state = "darksabre" - item_state = "darksabre" - lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi' - righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi' - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("attacked", "struck", "hit") - - -/obj/item/storage/belt/sabre/darksabre - name = "Ornate Sheathe" - desc = "An ornate and rather sinister looking sabre sheathe." - icon = 'icons/obj/custom.dmi' - alternate_worn_icon = 'icons/mob/custom_w.dmi' - icon_state = "darksheath" - item_state = "darksheath" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/belt/sabre/darksabre/ComponentInitialize() - . = ..() - GET_COMPONENT(STR, /datum/component/storage) - STR.max_items = 1 - STR.rustle_sound = FALSE - STR.max_w_class = WEIGHT_CLASS_BULKY - STR.can_hold = typecacheof(list( - /obj/item/toy/sword/darksabre - )) - -/obj/item/clothing/suit/armor/vest/darkcarapace - name = "Dark Armor" - desc = "A dark, non-functional piece of armor sporting a red and black finish." - icon = 'icons/obj/custom.dmi' - alternate_worn_icon = 'icons/mob/custom_w.dmi' - icon_state = "darkcarapace" - item_state = "darkcarapace" - blood_overlay_type = "armor" - dog_fashion = /datum/dog_fashion/back - mutantrace_variation = NO_MUTANTRACE_VARIATION - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) - - /obj/item/clothing/neck/cloak/green name = "Generic Green Cloak" desc = "This cloak doesn't seem too special." @@ -439,3 +454,34 @@ icon_state = "moveralls" mutantrace_variation = NO_MUTANTRACE_VARIATION +/obj/item/clothing/suit/hooded/cloak/zuliecloak + name = "Project: Zul-E" + desc = "A standard version of a prototype cloak given out by Nanotrasen higher ups. It's surprisingly thick and heavy for a cloak despite having most of it's tech stripped. It also comes with a bluespace trinket which calls it's accompanying hat onto the user. A worn inscription on the inside of the cloak reads 'Fleuret' ...the rest is faded away." + icon_state = "zuliecloak" + item_state = "zuliecloak" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + hoodtype = /obj/item/clothing/head/hooded/cloakhood/zuliecloak + body_parts_covered = CHEST|GROIN|ARMS + slot_flags = SLOT_WEAR_SUIT | ITEM_SLOT_NECK //it's a cloak. it's cosmetic. so why the hell not? what could possibly go wrong? + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/head/hooded/cloakhood/zuliecloak + name = "NT Special Issue" + desc = "This hat is unquestionably the best one, bluespaced to and from CentComm. It smells of Fish and Tea with a hint of antagonism" + icon_state = "zuliecap" + item_state = "zuliecap" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + flags_inv = HIDEEARS|HIDEHAIR + mutantrace_variation = NO_MUTANTRACE_VARIATION + +/obj/item/clothing/suit/blackredgold + name = "Multicolor Coat" + desc = "An oddly special looking coat with black, red, and gold" + icon = 'icons/obj/custom.dmi' + alternate_worn_icon = 'icons/mob/custom_w.dmi' + icon_state = "redgoldjacket" + item_state = "redgoldjacket" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = NO_MUTANTRACE_VARIATION \ No newline at end of file diff --git a/modular_citadel/code/modules/integrated_electronics/subtypes/manipulation.dm b/modular_citadel/code/modules/integrated_electronics/subtypes/manipulation.dm index 79d229c757..547c1a5768 100644 --- a/modular_citadel/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/modular_citadel/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -1,33 +1,53 @@ /obj/item/integrated_circuit/manipulation/electric_stimulator name = "electronic stimulation module" - desc = "Used to induce sexual stimulation with electricity." + desc = "Used to induce sexual stimulation in a target via electricity." icon_state = "power_relay" - extended_desc = "The circuit accepts a reference to a person and upon activation, attempts to stimulate them to orgasm." - complexity = 10 - size = 3 - inputs = list("target" = IC_PINTYPE_REF) - outputs = list() - activators = list("fire" = IC_PINTYPE_PULSE_IN) + extended_desc = "The circuit accepts a reference to a person, as well as a number representing the strength of the shock, and upon activation, attempts to stimulate them to orgasm. The number ranges from -35 to 35, with negative numbers reducing arousal and positive numbers increasing it by that amount." + complexity = 15 + size = 2 + inputs = list("target" = IC_PINTYPE_REF, "strength" = IC_PINTYPE_NUMBER) + outputs = list("arousal gain"=IC_PINTYPE_NUMBER) + activators = list("fire" = IC_PINTYPE_PULSE_IN, "on success" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT, "on orgasm" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 500 cooldown_per_use = 50 + ext_cooldown = 25 /obj/item/integrated_circuit/manipulation/electric_stimulator/do_work() - ..() + set_pin_data(IC_OUTPUT, 1, 0) var/mob/living/M = get_pin_data_as_type(IC_INPUT, 1, /mob/living) if(!check_target(M)) return - if(ismob(M) && M.canbearoused) - if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna()) - var/mob/living/carbon/human/H = M - var/orgasm_message = pick("A sharp pulse of electricity pushes you to orgasm!", "You feel a jolt of electricity force you into orgasm!") - H.visible_message("\The [assembly] electrodes shock [H]!", "[orgasm_message]") - playsound(src, "sound/effects/light_flicker.ogg", 30, 1) - H.mob_climax(forced_climax=TRUE) + + var/arousal_gain = CLAMP(get_pin_data(IC_INPUT, 2),-35,35) + set_pin_data(IC_OUTPUT, 1, arousal_gain) + + if(ismob(M) && M.canbearoused && arousal_gain != 0) + var/orgasm = FALSE + if(arousal_gain > 0) + if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna()) + var/mob/living/carbon/human/H = M + var/orgasm_message = pick("A sharp pulse of electricity pushes you to orgasm!", "You feel a jolt of electricity force you into orgasm!") + H.visible_message("\The [assembly] electrodes shock [H]!", "[orgasm_message]") + playsound(src, "sound/effects/light_flicker.ogg", 30, 1) + H.mob_climax(forced_climax=TRUE) + orgasm = TRUE + else + M.adjustArousalLoss(arousal_gain) + var/stimulate_message = pick("You feel a sharp warming tingle of electricity through your body!", "A burst of arousing electricity flows through your body!") + M.visible_message("\The [assembly] electrodes shock [M]!", "[stimulate_message]") + else - M.adjustArousalLoss(35) - var/stimulate_message = pick("You feel a sharp warming tingle of electricity through your body!", "A burst of arousing electricity flows through your body!") + var/stimulate_message = pick("You feel a dull prickle of electricity through your body!", "A burst of dull electricity flows through your body!") M.visible_message("\The [assembly] electrodes shock [M]!", "[stimulate_message]") - playsound(src, "sound/effects/light_flicker.ogg", 30, 1) + M.adjustArousalLoss(arousal_gain) + + playsound(src, "sound/effects/light_flicker.ogg", 30, 1) + push_data() + activate_pin(2) + if(orgasm) activate_pin(4) + else visible_message("\The [assembly] electrodes fail to shock [M]!") + push_data() + activate_pin(3) diff --git a/modular_citadel/code/modules/mentor/mentorpm.dm b/modular_citadel/code/modules/mentor/mentorpm.dm index 4184a4abef..34ace6f002 100644 --- a/modular_citadel/code/modules/mentor/mentorpm.dm +++ b/modular_citadel/code/modules/mentor/mentorpm.dm @@ -70,16 +70,16 @@ else //recipient is an mentor but sender is not to_chat(C, "Reply PM from-[key_name_mentor(src, C, 1, 0, show_char)]: [msg]") - to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, 0)]: [msg]") + to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, 0)]: [msg]") else if(is_mentor()) //sender is an mentor but recipient is not. to_chat(C, "Mentor PM from-[key_name_mentor(src, C, 1, 0, 0)]: [msg]") - to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, show_char)]: [msg]") + to_chat(src, "Mentor PM to-[key_name_mentor(C, C, 1, 0, show_char)]: [msg]") //we don't use message_Mentors here because the sender/receiver might get it too var/show_char_sender = !is_mentor() && CONFIG_GET(flag/mentors_mobname_only) var/show_char_recip = !C.is_mentor() && CONFIG_GET(flag/mentors_mobname_only) for(var/client/X in GLOB.mentors | GLOB.admins) if(X.key!=key && X.key!=C.key) //check client/X is an Mentor and isn't the sender or recipient - to_chat(X, "Mentor PM: [key_name_mentor(src, X, 0, 0, show_char_sender)]->[key_name_mentor(C, X, 0, 0, show_char_recip)]: [msg]") //inform X \ No newline at end of file + to_chat(X, "Mentor PM: [key_name_mentor(src, X, 0, 0, show_char_sender)]->[key_name_mentor(C, X, 0, 0, show_char_recip)]: [msg]") //inform X diff --git a/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm b/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm index 1a82040dbc..e552c2cbdd 100644 --- a/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm +++ b/modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm @@ -36,6 +36,24 @@ color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' +/datum/sprite_accessory/body_markings/guilmon + name = "Guilmon" + icon_state = "guilmon" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' + +/datum/sprite_accessory/tails/lizard/guilmon + name = "Guilmon" + icon_state = "guilmon" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/lizard/guilmon + name = "Guilmon" + icon_state = "guilmon" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + //christ this was a mistake, but it's here just in case someone wants to selectively fix /************* Lizard compatable snoots *********** /datum/sprite_accessory/snouts/bird @@ -197,6 +215,12 @@ icon = 'modular_citadel/icons/mob/mam_ears.dmi' color_src = MATRIXED +/datum/sprite_accessory/ears/human/elf + name = "Elf" + icon_state = "elf" + icon = 'modular_citadel/icons/mob/mam_ears.dmi' + color_src = SKINTONE + /datum/sprite_accessory/ears/fennec name = "Fennec" icon_state = "fennec" @@ -291,7 +315,7 @@ icon_state = "wah" icon = 'modular_citadel/icons/mob/mam_tails.dmi' color_src = MATRIXED - + /datum/sprite_accessory/tails/human/axolotl name = "Axolotl" icon_state = "axolotl" @@ -315,7 +339,7 @@ icon_state = "bee" icon = 'modular_citadel/icons/mob/mam_tails.dmi' color_src = MATRIXED - + /datum/sprite_accessory/tails/human/cat name = "Cat" icon_state = "cat" @@ -327,7 +351,7 @@ icon_state = "cat" icon = 'modular_citadel/icons/mob/mam_tails.dmi' color_src = HAIR - + /datum/sprite_accessory/tails/human/catbig name = "Cat, Big" icon_state = "catbig" @@ -339,7 +363,7 @@ icon_state = "catbig" icon = 'modular_citadel/icons/mob/mam_tails.dmi' color_src = MATRIXED - + /datum/sprite_accessory/tails/human/cow name = "Cow" icon_state = "cow" @@ -359,7 +383,7 @@ /datum/sprite_accessory/tails_animated/human/corvid name = "Corvid" icon_state = "crow" - + /datum/sprite_accessory/tails/human/eevee name = "Eevee" icon_state = "eevee" @@ -371,7 +395,7 @@ icon_state = "eevee" icon = 'modular_citadel/icons/mob/mam_tails.dmi' color_src = MATRIXED - + /datum/sprite_accessory/tails/human/fennec name = "Fennec" icon_state = "fennec" @@ -383,7 +407,7 @@ icon_state = "fennec" icon = 'modular_citadel/icons/mob/mam_tails.dmi' color_src = MATRIXED - + /datum/sprite_accessory/tails/human/fish name = "Fish" icon_state = "fish" @@ -395,7 +419,7 @@ icon_state = "fish" icon = 'modular_citadel/icons/mob/mam_tails.dmi' color_src = MATRIXED - + /datum/sprite_accessory/tails/human/fox name = "Fox" icon_state = "fox" @@ -443,7 +467,7 @@ icon_state = "insect" icon = 'modular_citadel/icons/mob/mam_tails.dmi' color_src = MATRIXED - + /datum/sprite_accessory/tails/human/kitsune name = "Kitsune" icon_state = "kitsune" @@ -455,7 +479,7 @@ icon_state = "kitsune" color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' - + /datum/sprite_accessory/tails/human/murid name = "Murid" icon_state = "murid" @@ -467,7 +491,7 @@ icon_state = "murid" color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' - + /datum/sprite_accessory/tails/human/otie name = "Otusian" icon_state = "otie" @@ -491,7 +515,7 @@ icon_state = "orca" color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' - + /datum/sprite_accessory/tails/human/pede name = "Scolipede" icon_state = "pede" @@ -503,7 +527,7 @@ icon_state = "pede" color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' - + /datum/sprite_accessory/tails/human/rabbit name = "Rabbit" icon_state = "rabbit" @@ -515,7 +539,7 @@ icon_state = "rabbit" color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' - + /datum/sprite_accessory/tails/human/sergal name = "Sergal" icon_state = "sergal" @@ -527,7 +551,7 @@ icon_state = "sergal" color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' - + /datum/sprite_accessory/tails/human/skunk name = "skunk" icon_state = "skunk" @@ -571,7 +595,7 @@ /datum/sprite_accessory/tails_animated/human/straighttail name = "Straight Tail" icon_state = "straighttail" - + /datum/sprite_accessory/tails/human/squirrel name = "Squirrel" icon_state = "squirrel" @@ -595,7 +619,7 @@ icon_state = "tentacle" color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' - + /datum/sprite_accessory/tails/human/tiger name = "Tiger" icon_state = "tiger" @@ -607,7 +631,7 @@ icon_state = "tiger" color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' - + /datum/sprite_accessory/tails/human/wolf name = "Wolf" icon_state = "wolf" @@ -619,7 +643,7 @@ icon_state = "wolf" color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' - + /****************************************** *********** Mammal Body Parts ************* *******************************************/ @@ -935,6 +959,13 @@ name = "Eevee" icon_state = "eevee" + +/datum/sprite_accessory/mam_ears/elf + name = "Elf" + icon_state = "elf" + color_src = MUTCOLORS3 + + /datum/sprite_accessory/mam_ears/elephant name = "Elephant" icon_state = "elephant" @@ -1281,26 +1312,31 @@ datum/sprite_accessory/mam_tails/insect name = "None" icon_state = "none" ckeys_allowed = list("yousshouldnteverbeseeingthisyoumeme") + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /datum/sprite_accessory/mam_body_markings/plain name = "Plain" icon_state = "plain" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' -/datum/sprite_accessory/mam_body_markings/ailurus +/datum/sprite_accessory/mam_body_markings/redpanda name = "Redpanda" - icon_state = "wah" + icon_state = "redpanda" /datum/sprite_accessory/mam_body_markings/bee name = "Bee" icon_state = "bee" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /datum/sprite_accessory/mam_body_markings/belly name = "Belly" icon_state = "belly" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /datum/sprite_accessory/mam_body_markings/bellyslim name = "Bellyslim" icon_state = "bellyslim" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /datum/sprite_accessory/mam_body_markings/corgi name = "Corgi" @@ -1345,6 +1381,7 @@ datum/sprite_accessory/mam_tails/insect /datum/sprite_accessory/mam_body_markings/frog name = "Frog" icon_state = "frog" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /datum/sprite_accessory/mam_body_markings/goat name = "Goat" @@ -1353,6 +1390,7 @@ datum/sprite_accessory/mam_tails/insect /datum/sprite_accessory/mam_body_markings/handsfeet name = "Handsfeet" icon_state = "handsfeet" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /datum/sprite_accessory/mam_body_markings/hawk name = "Hawk" @@ -1373,6 +1411,7 @@ datum/sprite_accessory/mam_tails/insect /datum/sprite_accessory/mam_body_markings/moth name = "Moth" icon_state = "moth" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /datum/sprite_accessory/mam_body_markings/otie name = "Otie" @@ -1401,6 +1440,7 @@ datum/sprite_accessory/mam_tails/insect /datum/sprite_accessory/mam_body_markings/pede name = "Scolipede" icon_state = "scolipede" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /datum/sprite_accessory/mam_body_markings/shark name = "Shark" @@ -1429,6 +1469,7 @@ datum/sprite_accessory/mam_tails/insect /datum/sprite_accessory/mam_body_markings/turian name = "Turian" icon_state = "turian" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /datum/sprite_accessory/mam_body_markings/wolf name = "Wolf" @@ -1437,6 +1478,7 @@ datum/sprite_accessory/mam_tails/insect /datum/sprite_accessory/mam_body_markings/xeno name = "Xeno" icon_state = "xeno" + icon = 'modular_citadel/icons/mob/markings_notmammals.dmi' /****************************************** @@ -1462,6 +1504,12 @@ datum/sprite_accessory/mam_tails/insect icon_state = "cow" taur_mode = HOOF_TAURIC +/datum/sprite_accessory/taur/deer + name = "Deer" + icon_state = "deer" + taur_mode = HOOF_TAURIC + color_src = MUTCOLORS + /datum/sprite_accessory/taur/drake name = "Drake" icon_state = "drake" @@ -1746,19 +1794,6 @@ datum/sprite_accessory/mam_tails/insect // *** Snooooow flaaaaake *** -/datum/sprite_accessory/body_markings/guilmon - name = "Guilmon" - icon_state = "guilmon" - color_src = MATRIXED - -/datum/sprite_accessory/tails/lizard/guilmon - name = "Guilmon" - icon_state = "guilmon" - -/datum/sprite_accessory/tails_animated/lizard/guilmon - name = "Guilmon" - icon_state = "guilmon" - /datum/sprite_accessory/horns/guilmon name = "Guilmon" icon_state = "guilmon" @@ -1788,6 +1823,7 @@ datum/sprite_accessory/mam_tails/insect name = "sabresune" icon_state = "sabresune" ckeys_allowed = list("poojawa") + extra = TRUE /datum/sprite_accessory/mam_tails/sabresune name = "sabresune" diff --git a/modular_citadel/code/modules/mob/living/carbon/carbon.dm b/modular_citadel/code/modules/mob/living/carbon/carbon.dm index cd24bfc8a2..43931db689 100644 --- a/modular_citadel/code/modules/mob/living/carbon/carbon.dm +++ b/modular_citadel/code/modules/mob/living/carbon/carbon.dm @@ -34,7 +34,10 @@ for(var/obj/screen/combattoggle/selector in hud_used.static_inventory) selector.rebasetointerbay(src) if(world.time >= combatmessagecooldown && combatmode) - visible_message("[src] [resting ? "tenses up" : (prob(95)? "drops into a combative stance" : (prob(95)? "poses aggressively" : "asserts dominance with their pose"))].") + if(a_intent != INTENT_HELP) + visible_message("[src] [resting ? "tenses up" : (prob(95)? "drops into a combative stance" : (prob(95)? "poses aggressively" : "asserts dominance with their pose"))].") + else + visible_message("[src] [pick("looks","seems","goes")] [pick("alert","attentive","vigilant")].") combatmessagecooldown = 10 SECONDS + world.time //This is set 100% of the time to make sure squeezing regen out of process cycles doesn't result in the combat mode message getting spammed SEND_SIGNAL(src, COMSIG_COMBAT_TOGGLED, src, combatmode) return TRUE diff --git a/modular_citadel/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/modular_citadel/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 64898f0121..b4eec5786a 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -14,7 +14,7 @@ default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None") say_mod = "says" hair_color = "mutcolor" - hair_alpha = 180 + hair_alpha = 160 //a notch brighter so it blends better. liked_food = MEAT coldmod = 3 heatmod = 1 diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm index f0e5c35a8b..5e10e71433 100644 --- a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm +++ b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm @@ -1,390 +1,389 @@ -/* -DOG BORG EQUIPMENT HERE -SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! -*/ - -/obj/item/dogborg/jaws - name = "Dogborg jaws" - desc = "The jaws of the debug errors oh god." - icon = 'icons/mob/dogborg.dmi' - flags_1 = CONDUCT_1 - force = 1 - throwforce = 0 - w_class = 3 - hitsound = 'sound/weapons/bite.ogg' - sharpness = IS_SHARP - -/obj/item/dogborg/jaws/big - name = "combat jaws" - desc = "The jaws of the law. Very sharp." - icon_state = "jaws" - force = 12 - attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") - -/obj/item/dogborg/jaws/small - name = "puppy jaws" - desc = "Rubberized teeth designed to protect accidental harm. Sharp enough for specialized tasks however." - icon_state = "smalljaws" - force = 6 - attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") - var/status = 0 - -/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user) - ..() - user.do_attack_animation(A, ATTACK_EFFECT_BITE) - log_combat(user, A, "bit") - -/obj/item/dogborg/jaws/small/attack_self(mob/user) - var/mob/living/silicon/robot.R = user - if(R.cell && R.cell.charge > 100) - if(R.emagged && status == 0) - name = "combat jaws" - icon_state = "jaws" - desc = "The jaws of the law." - force = 12 - attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") - status = 1 - to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"].") - else - name = "puppy jaws" - icon_state = "smalljaws" - desc = "The jaws of a small dog." - force = 5 - attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") - status = 0 - if(R.emagged) - to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"].") - update_icon() - -//Boop - -/obj/item/analyzer/nose - name = "boop module" - icon = 'icons/mob/dogborg.dmi' - icon_state = "nose" - desc = "The BOOP module" - flags_1 = CONDUCT_1 - force = 0 - throwforce = 0 - attack_verb = list("nuzzles", "pushes", "boops") - w_class = 1 - -/obj/item/analyzer/nose/attack_self(mob/user) - user.visible_message("[user] sniffs around the air.", "You sniff the air for gas traces.") - - var/turf/location = user.loc - if(!istype(location)) - return - - var/datum/gas_mixture/environment = location.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - to_chat(user, "Results:") - if(abs(pressure - ONE_ATMOSPHERE) < 10) - to_chat(user, "Pressure: [round(pressure,0.1)] kPa") - else - to_chat(user, "Pressure: [round(pressure,0.1)] kPa") - if(total_moles) - var/list/env_gases = environment.gases - - environment.assert_gases(arglist(GLOB.hardcoded_gases)) - var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles - var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles - var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles - var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles - environment.garbage_collect() - - if(abs(n2_concentration - N2STANDARD) < 20) - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") - else - to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") - - if(abs(o2_concentration - O2STANDARD) < 2) - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") - else - to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") - - if(co2_concentration > 0.01) - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") - else - to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") - - if(plasma_concentration > 0.005) - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") - else - to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") - - - for(var/id in env_gases) - if(id in GLOB.hardcoded_gases) - continue - var/gas_concentration = env_gases[id][MOLES]/total_moles - to_chat(user, "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %") - to_chat(user, "Temperature: [round(environment.temperature-T0C)] °C") - -/obj/item/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens - . = ..() - -/obj/item/analyzer/nose/afterattack(atom/target, mob/user, proximity) - . = ..() - if(!proximity) - return - do_attack_animation(target, null, src) - user.visible_message("[user] [pick(attack_verb)] \the [target.name] with their nose!") - -//Delivery -/obj/item/storage/bag/borgdelivery - name = "fetching storage" - desc = "Fetch the thing!" - icon = 'icons/mob/dogborg.dmi' - icon_state = "dbag" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/storage/bag/borgdelivery/ComponentInitialize() - . = ..() - GET_COMPONENT(STR, /datum/component/storage) - STR.max_w_class = WEIGHT_CLASS_BULKY - STR.max_combined_w_class = 5 - STR.max_items = 1 - STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/radio/intercom)) - -//Tongue stuff -/obj/item/soap/tongue - name = "synthetic tongue" - desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." - icon = 'icons/mob/dogborg.dmi' - icon_state = "synthtongue" - hitsound = 'sound/effects/attackblob.ogg' - cleanspeed = 80 - var/status = 0 - -/obj/item/soap/tongue/scrubpup - cleanspeed = 25 //slightly faster than a mop. - -/obj/item/soap/tongue/New() - ..() - item_flags |= NOBLUDGEON //No more attack messages - -/obj/item/soap/tongue/attack_self(mob/user) - var/mob/living/silicon/robot.R = user - if(R.cell && R.cell.charge > 100) - if(R.emagged && status == 0) - status = !status - name = "energized tongue" - desc = "Your tongue is energized for dangerously maximum efficency." - icon_state = "syndietongue" - to_chat(user, "Your tongue is now [status ? "Energized" : "Normal"].") - cleanspeed = 10 //(nerf'd)tator soap stat - else - status = 0 - name = "synthetic tongue" - desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." - icon_state = "synthtongue" - cleanspeed = initial(cleanspeed) - if(R.emagged) - to_chat(user, "Your tongue is now [status ? "Energized" : "Normal"].") - update_icon() - -/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity) - var/mob/living/silicon/robot.R = user - if(!proximity || !check_allowed_items(target)) - return - if(R.client && (target in R.client.screen)) - to_chat(R, "You need to take that [target.name] off before cleaning it!") - else if(is_cleanable(target)) - R.visible_message("[R] begins to lick off \the [target.name].", "You begin to lick off \the [target.name]...") - if(do_after(R, src.cleanspeed, target = target)) - if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. - return //If they moved away, you can't eat them. - to_chat(R, "You finish licking off \the [target.name].") - qdel(target) - R.cell.give(50) - else if(isobj(target)) //hoo boy. danger zone man - if(istype(target,/obj/item/trash)) - R.visible_message("[R] nibbles away at \the [target.name].", "You begin to nibble away at \the [target.name]...") - if(!do_after(R, src.cleanspeed, target = target)) - return //If they moved away, you can't eat them. - to_chat(R, "You finish off \the [target.name].") - qdel(target) - R.cell.give(250) - return - if(istype(target,/obj/item/stock_parts/cell)) - R.visible_message("[R] begins cramming \the [target.name] down its throat.", "You begin cramming \the [target.name] down your throat...") - if(!do_after(R, 50, target = target)) - return //If they moved away, you can't eat them. - to_chat(R, "You finish off \the [target.name].") - var/obj/item/stock_parts/cell.C = target - R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf - qdel(target) - return - var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT - if(!I.anchored && R.emagged) - R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "You begin chewing up \the [target.name]...") - if(!do_after(R, 100, target = I)) //Nerf dat time yo - return //If they moved away, you can't eat them. - visible_message("[R] chews up \the [target.name] and cleans off the debris!") - to_chat(R, "You finish off \the [target.name].") - qdel(I) - R.cell.give(500) - return - R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") - else if(ishuman(target)) - var/mob/living/L = target - if(status == 0 && check_zone(R.zone_selected) == "head") - R.visible_message("\the [R] affectionally licks \the [L]'s face!", "You affectionally lick \the [L]'s face!") - playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) - if(istype(L) && L.fire_stacks > 0) - L.adjust_fire_stacks(-10) - return - else if(status == 0) - R.visible_message("\the [R] affectionally licks \the [L]!", "You affectionally lick \the [L]!") - playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) - if(istype(L) && L.fire_stacks > 0) - L.adjust_fire_stacks(-10) - return - else - if(R.cell.charge <= 800) - to_chat(R, "Insufficent Power!") - return - L.Stun(4) // normal stunbaton is force 7 gimme a break good sir! - L.Knockdown(80) - L.apply_effect(EFFECT_STUTTER, 4) - L.visible_message("[R] has shocked [L] with its tongue!", \ - "[R] has shocked you with its tongue!") - playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) - R.cell.use(666) - log_combat(R, L, "tongue stunned") - - else if(istype(target, /obj/structure/window)) - R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") - if(do_after(user, src.cleanspeed, target = target)) - to_chat(user, "You clean \the [target.name].") - target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - target.set_opacity(initial(target.opacity)) - else - R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") - if(do_after(user, src.cleanspeed, target = target)) - to_chat(user, "You clean \the [target.name].") - var/obj/effect/decal/cleanable/C = locate() in target - qdel(C) - target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM) - target.wash_cream() - return - -//Dogfood - -/obj/item/trash/rkibble - name = "robo kibble" - desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge." - icon = 'icons/mob/dogborg.dmi' - icon_state= "kibble" - -//Defibs - -/obj/item/twohanded/shockpaddles/cyborg/hound - name = "Paws of Life" - desc = "MediHound specific shock paws." - icon = 'icons/mob/dogborg.dmi' - icon_state = "defibpaddles0" - item_state = "defibpaddles0" - -// Pounce stuff for K-9 - -/obj/item/dogborg/pounce - name = "pounce" - icon = 'icons/mob/dogborg.dmi' - icon_state = "pounce" - desc = "Leap at your target to momentarily stun them." - force = 0 - throwforce = 0 - -/obj/item/dogborg/pounce/New() - ..() - item_flags |= NOBLUDGEON - -/mob/living/silicon/robot - var/leaping = 0 - var/pounce_cooldown = 0 - var/pounce_cooldown_time = 50 //Nearly doubled, u happy? - var/pounce_spoolup = 3 - var/leap_at - var/disabler - var/laser - var/sleeper_g - var/sleeper_r - var/sleeper_nv - -#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance. - -/obj/item/dogborg/pounce/afterattack(atom/A, mob/user) - var/mob/living/silicon/robot/R = user - if(R && !R.pounce_cooldown) - R.pounce_cooldown = !R.pounce_cooldown - to_chat(R, "Your targeting systems lock on to [A]...") - addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup) - spawn(R.pounce_cooldown_time) - R.pounce_cooldown = !R.pounce_cooldown - else if(R && R.pounce_cooldown) - to_chat(R, "Your leg actuators are still recharging!") - -/mob/living/silicon/robot/proc/leap_at(atom/A) - if(leaping || stat || buckled || lying) - return - - if(!has_gravity(src) || !has_gravity(A)) - to_chat(src,"It is unsafe to leap without gravity!") - //It's also extremely buggy visually, so it's balance+bugfix - return - - if(cell.charge <= 500) - to_chat(src,"Insufficent reserves for jump actuators!") - return - - else - leaping = 1 - weather_immunities += "lava" - pixel_y = 10 - update_icons() - throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1) - cell.use(500) //Doubled the energy consumption - weather_immunities -= "lava" - -/mob/living/silicon/robot/throw_impact(atom/A) - - if(!leaping) - return ..() - - if(A) - if(isliving(A)) - var/mob/living/L = A - var/blocked = 0 - if(ishuman(A)) - var/mob/living/carbon/human/H = A - if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK)) - blocked = 1 - if(!blocked) - L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") - L.Knockdown(iscarbon(L) ? 450 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice. - playsound(src, 'sound/weapons/Egloves.ogg', 50, 1) - sleep(2)//Runtime prevention (infinite bump() calls on hulks) - step_towards(src,L) - log_combat(src, L, "borg pounced") - else - Knockdown(45, 1, 1) - - pounce_cooldown = !pounce_cooldown - spawn(pounce_cooldown_time) //3s by default - pounce_cooldown = !pounce_cooldown - else if(A.density && !A.CanPass(src)) - visible_message("[src] smashes into [A]!", "You smash into [A]!") - playsound(src, 'sound/items/trayhit1.ogg', 50, 1) - Knockdown(45, 1, 1) - - if(leaping) - leaping = 0 - pixel_y = initial(pixel_y) - update_icons() - update_canmove() +/* +DOG BORG EQUIPMENT HERE +SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! +*/ + +/obj/item/dogborg/jaws + name = "Dogborg jaws" + desc = "The jaws of the debug errors oh god." + icon = 'icons/mob/dogborg.dmi' + flags_1 = CONDUCT_1 + force = 1 + throwforce = 0 + w_class = 3 + hitsound = 'sound/weapons/bite.ogg' + sharpness = IS_SHARP + +/obj/item/dogborg/jaws/big + name = "combat jaws" + desc = "The jaws of the law. Very sharp." + icon_state = "jaws" + force = 12 + attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") + +/obj/item/dogborg/jaws/small + name = "puppy jaws" + desc = "Rubberized teeth designed to protect accidental harm. Sharp enough for specialized tasks however." + icon_state = "smalljaws" + force = 6 + attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") + var/status = 0 + +/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user) + ..() + user.do_attack_animation(A, ATTACK_EFFECT_BITE) + log_combat(user, A, "bit") + +/obj/item/dogborg/jaws/small/attack_self(mob/user) + var/mob/living/silicon/robot.R = user + if(R.cell && R.cell.charge > 100) + if(R.emagged && status == 0) + name = "combat jaws" + icon_state = "jaws" + desc = "The jaws of the law." + force = 12 + attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") + status = 1 + to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"].") + else + name = "puppy jaws" + icon_state = "smalljaws" + desc = "The jaws of a small dog." + force = 5 + attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") + status = 0 + if(R.emagged) + to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"].") + update_icon() + +//Boop + +/obj/item/analyzer/nose + name = "boop module" + icon = 'icons/mob/dogborg.dmi' + icon_state = "nose" + desc = "The BOOP module" + flags_1 = CONDUCT_1 + force = 0 + throwforce = 0 + attack_verb = list("nuzzles", "pushes", "boops") + w_class = 1 + +/obj/item/analyzer/nose/attack_self(mob/user) + user.visible_message("[user] sniffs around the air.", "You sniff the air for gas traces.") + + var/turf/location = user.loc + if(!istype(location)) + return + + var/datum/gas_mixture/environment = location.return_air() + + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() + + to_chat(user, "Results:") + if(abs(pressure - ONE_ATMOSPHERE) < 10) + to_chat(user, "Pressure: [round(pressure,0.1)] kPa") + else + to_chat(user, "Pressure: [round(pressure,0.1)] kPa") + if(total_moles) + var/list/env_gases = environment.gases + + var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles + var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles + var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles + var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles + GAS_GARBAGE_COLLECT(environment.gases) + + if(abs(n2_concentration - N2STANDARD) < 20) + to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") + else + to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %") + + if(abs(o2_concentration - O2STANDARD) < 2) + to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") + else + to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %") + + if(co2_concentration > 0.01) + to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") + else + to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %") + + if(plasma_concentration > 0.005) + to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") + else + to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %") + + + for(var/id in env_gases) + if(id in GLOB.hardcoded_gases) + continue + var/gas_concentration = env_gases[id]/total_moles + to_chat(user, "[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] %") + to_chat(user, "Temperature: [round(environment.temperature-T0C)] °C") + +/obj/item/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens + . = ..() + +/obj/item/analyzer/nose/afterattack(atom/target, mob/user, proximity) + . = ..() + if(!proximity) + return + do_attack_animation(target, null, src) + user.visible_message("[user] [pick(attack_verb)] \the [target.name] with their nose!") + +//Delivery +/obj/item/storage/bag/borgdelivery + name = "fetching storage" + desc = "Fetch the thing!" + icon = 'icons/mob/dogborg.dmi' + icon_state = "dbag" + w_class = WEIGHT_CLASS_BULKY + +/obj/item/storage/bag/borgdelivery/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_w_class = WEIGHT_CLASS_BULKY + STR.max_combined_w_class = 5 + STR.max_items = 1 + STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/radio/intercom)) + +//Tongue stuff +/obj/item/soap/tongue + name = "synthetic tongue" + desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." + icon = 'icons/mob/dogborg.dmi' + icon_state = "synthtongue" + hitsound = 'sound/effects/attackblob.ogg' + cleanspeed = 80 + var/status = 0 + +/obj/item/soap/tongue/scrubpup + cleanspeed = 25 //slightly faster than a mop. + +/obj/item/soap/tongue/New() + ..() + item_flags |= NOBLUDGEON //No more attack messages + +/obj/item/soap/tongue/attack_self(mob/user) + var/mob/living/silicon/robot.R = user + if(R.cell && R.cell.charge > 100) + if(R.emagged && status == 0) + status = !status + name = "energized tongue" + desc = "Your tongue is energized for dangerously maximum efficency." + icon_state = "syndietongue" + to_chat(user, "Your tongue is now [status ? "Energized" : "Normal"].") + cleanspeed = 10 //(nerf'd)tator soap stat + else + status = 0 + name = "synthetic tongue" + desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." + icon_state = "synthtongue" + cleanspeed = initial(cleanspeed) + if(R.emagged) + to_chat(user, "Your tongue is now [status ? "Energized" : "Normal"].") + update_icon() + +/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity) + var/mob/living/silicon/robot.R = user + if(!proximity || !check_allowed_items(target)) + return + if(R.client && (target in R.client.screen)) + to_chat(R, "You need to take that [target.name] off before cleaning it!") + else if(is_cleanable(target)) + R.visible_message("[R] begins to lick off \the [target.name].", "You begin to lick off \the [target.name]...") + if(do_after(R, src.cleanspeed, target = target)) + if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. + return //If they moved away, you can't eat them. + to_chat(R, "You finish licking off \the [target.name].") + qdel(target) + R.cell.give(50) + else if(isobj(target)) //hoo boy. danger zone man + if(istype(target,/obj/item/trash)) + R.visible_message("[R] nibbles away at \the [target.name].", "You begin to nibble away at \the [target.name]...") + if(!do_after(R, src.cleanspeed, target = target)) + return //If they moved away, you can't eat them. + to_chat(R, "You finish off \the [target.name].") + qdel(target) + R.cell.give(250) + return + if(istype(target,/obj/item/stock_parts/cell)) + R.visible_message("[R] begins cramming \the [target.name] down its throat.", "You begin cramming \the [target.name] down your throat...") + if(!do_after(R, 50, target = target)) + return //If they moved away, you can't eat them. + to_chat(R, "You finish off \the [target.name].") + var/obj/item/stock_parts/cell.C = target + R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf + qdel(target) + return + var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT + if(!I.anchored && R.emagged) + R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "You begin chewing up \the [target.name]...") + if(!do_after(R, 100, target = I)) //Nerf dat time yo + return //If they moved away, you can't eat them. + visible_message("[R] chews up \the [target.name] and cleans off the debris!") + to_chat(R, "You finish off \the [target.name].") + qdel(I) + R.cell.give(500) + return + R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") + else if(ishuman(target)) + var/mob/living/L = target + if(status == 0 && check_zone(R.zone_selected) == "head") + R.visible_message("\the [R] affectionally licks \the [L]'s face!", "You affectionally lick \the [L]'s face!") + playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) + if(istype(L) && L.fire_stacks > 0) + L.adjust_fire_stacks(-10) + return + else if(status == 0) + R.visible_message("\the [R] affectionally licks \the [L]!", "You affectionally lick \the [L]!") + playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) + if(istype(L) && L.fire_stacks > 0) + L.adjust_fire_stacks(-10) + return + else + if(R.cell.charge <= 800) + to_chat(R, "Insufficent Power!") + return + L.Stun(4) // normal stunbaton is force 7 gimme a break good sir! + L.Knockdown(80) + L.apply_effect(EFFECT_STUTTER, 4) + L.visible_message("[R] has shocked [L] with its tongue!", \ + "[R] has shocked you with its tongue!") + playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) + R.cell.use(666) + log_combat(R, L, "tongue stunned") + + else if(istype(target, /obj/structure/window)) + R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") + if(do_after(user, src.cleanspeed, target = target)) + to_chat(user, "You clean \the [target.name].") + target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) + target.set_opacity(initial(target.opacity)) + else + R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") + if(do_after(user, src.cleanspeed, target = target)) + to_chat(user, "You clean \the [target.name].") + var/obj/effect/decal/cleanable/C = locate() in target + qdel(C) + target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) + SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM) + target.wash_cream() + return + +//Dogfood + +/obj/item/trash/rkibble + name = "robo kibble" + desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge." + icon = 'icons/mob/dogborg.dmi' + icon_state= "kibble" + +//Defibs + +/obj/item/twohanded/shockpaddles/cyborg/hound + name = "Paws of Life" + desc = "MediHound specific shock paws." + icon = 'icons/mob/dogborg.dmi' + icon_state = "defibpaddles0" + item_state = "defibpaddles0" + +// Pounce stuff for K-9 + +/obj/item/dogborg/pounce + name = "pounce" + icon = 'icons/mob/dogborg.dmi' + icon_state = "pounce" + desc = "Leap at your target to momentarily stun them." + force = 0 + throwforce = 0 + +/obj/item/dogborg/pounce/New() + ..() + item_flags |= NOBLUDGEON + +/mob/living/silicon/robot + var/leaping = 0 + var/pounce_cooldown = 0 + var/pounce_cooldown_time = 50 //Nearly doubled, u happy? + var/pounce_spoolup = 3 + var/leap_at + var/disabler + var/laser + var/sleeper_g + var/sleeper_r + var/sleeper_nv + +#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance. + +/obj/item/dogborg/pounce/afterattack(atom/A, mob/user) + var/mob/living/silicon/robot/R = user + if(R && !R.pounce_cooldown) + R.pounce_cooldown = !R.pounce_cooldown + to_chat(R, "Your targeting systems lock on to [A]...") + addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup) + spawn(R.pounce_cooldown_time) + R.pounce_cooldown = !R.pounce_cooldown + else if(R && R.pounce_cooldown) + to_chat(R, "Your leg actuators are still recharging!") + +/mob/living/silicon/robot/proc/leap_at(atom/A) + if(leaping || stat || buckled || lying) + return + + if(!has_gravity(src) || !has_gravity(A)) + to_chat(src,"It is unsafe to leap without gravity!") + //It's also extremely buggy visually, so it's balance+bugfix + return + + if(cell.charge <= 500) + to_chat(src,"Insufficent reserves for jump actuators!") + return + + else + leaping = 1 + weather_immunities += "lava" + pixel_y = 10 + update_icons() + throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1) + cell.use(500) //Doubled the energy consumption + weather_immunities -= "lava" + +/mob/living/silicon/robot/throw_impact(atom/A) + + if(!leaping) + return ..() + + if(A) + if(isliving(A)) + var/mob/living/L = A + var/blocked = 0 + if(ishuman(A)) + var/mob/living/carbon/human/H = A + if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK)) + blocked = 1 + if(!blocked) + L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") + L.Knockdown(iscarbon(L) ? 450 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice. + playsound(src, 'sound/weapons/Egloves.ogg', 50, 1) + sleep(2)//Runtime prevention (infinite bump() calls on hulks) + step_towards(src,L) + log_combat(src, L, "borg pounced") + else + Knockdown(45, 1, 1) + + pounce_cooldown = !pounce_cooldown + spawn(pounce_cooldown_time) //3s by default + pounce_cooldown = !pounce_cooldown + else if(A.density && !A.CanPass(src)) + visible_message("[src] smashes into [A]!", "You smash into [A]!") + playsound(src, 'sound/items/trayhit1.ogg', 50, 1) + Knockdown(45, 1, 1) + + if(leaping) + leaping = 0 + pixel_y = initial(pixel_y) + update_icons() + update_canmove() diff --git a/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm b/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm index 0daf68f6c1..2bfd63a25d 100644 --- a/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm +++ b/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm @@ -91,7 +91,7 @@ feeding = TRUE vore_active = TRUE isPredator = TRUE - vore_default_mode = DM_HOLD + vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/bear devourable = TRUE @@ -99,14 +99,14 @@ feeding = TRUE vore_active = TRUE isPredator = TRUE - vore_default_mode = DM_HOLD + vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/poison/giant_spider devourable = TRUE digestable = TRUE feeding = TRUE vore_active = TRUE - vore_default_mode = DM_HOLD + vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/retaliate/poison/snake devourable = TRUE @@ -114,7 +114,7 @@ feeding = TRUE vore_active = TRUE isPredator = TRUE - vore_default_mode = DM_HOLD + vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/gorilla devourable = TRUE @@ -122,7 +122,7 @@ feeding = TRUE vore_active = TRUE isPredator = TRUE - vore_default_mode = DM_HOLD + vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/asteroid/goliath devourable = TRUE @@ -130,7 +130,7 @@ feeding = TRUE vore_active = TRUE isPredator = TRUE - vore_default_mode = DM_HOLD + vore_default_mode = DM_DIGEST /mob/living/simple_animal/hostile/carp devourable = TRUE @@ -138,4 +138,4 @@ feeding = TRUE vore_active = TRUE isPredator = TRUE - vore_default_mode = DM_HOLD + vore_default_mode = DM_DIGEST diff --git a/modular_citadel/code/modules/mob/living/status_procs.dm b/modular_citadel/code/modules/mob/living/status_procs.dm index f646af3286..851c7438a7 100644 --- a/modular_citadel/code/modules/mob/living/status_procs.dm +++ b/modular_citadel/code/modules/mob/living/status_procs.dm @@ -1,5 +1,5 @@ /mob/living/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg) //Can't go below remaining duration - if(((status_flags & CANKNOCKDOWN) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canknockdown) + if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canknockdown) if(absorb_stun(isnull(override_hardstun)? amount : override_hardstun, ignore_canknockdown)) return var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown() diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm index 017a9dd52d..b3af722332 100644 --- a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm @@ -55,7 +55,7 @@ /obj/item/projectile/bullet/nlmags //non-lethal boolets icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' icon_state = "magjectile-nl" - damage = 0 + damage = 2 knockdown = 0 stamina = 25 armour_penetration = -10 @@ -123,7 +123,7 @@ icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" ///research memes/// - +/* /obj/item/gun/ballistic/automatic/pistol/mag/nopin pin = null spawnwithmagazine = FALSE @@ -155,7 +155,7 @@ materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250) build_path = /obj/item/ammo_box/magazine/mmag/small departmental_flags = DEPARTMENTAL_FLAG_SECURITY - +*/ //////toy memes///// /obj/item/projectile/bullet/reusable/foam_dart/mag @@ -210,7 +210,7 @@ /obj/item/projectile/bullet/nlmagrifle //non-lethal boolets icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' icon_state = "magjectile-large-nl" - damage = 0 + damage = 2 knockdown = 0 stamina = 25 armour_penetration = -10 @@ -271,7 +271,8 @@ recoil = 0.15 casing_ejector = 0 -///research/// +/* +//research/// /obj/item/gun/ballistic/automatic/magrifle/nopin pin = null @@ -304,7 +305,7 @@ materials = list(MAT_METAL = 6000, MAT_SILVER = 500, MAT_TITANIUM = 500) build_path = /obj/item/ammo_box/magazine/mmag departmental_flags = DEPARTMENTAL_FLAG_SECURITY - +*/ ///foamagrifle/// /obj/item/ammo_box/magazine/toy/foamag @@ -326,10 +327,9 @@ spread = 60 w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_HEAVY - /* // TECHWEBS IMPLEMENTATION -*/ +// /datum/techweb_node/magnetic_weapons id = "magnetic_weapons" @@ -339,7 +339,7 @@ design_ids = list("magrifle", "magpisol", "mag_magrifle", "mag_magrifle_nl", "mag_magpistol", "mag_magpistol_nl") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 - +*/ //////Hyper-Burst Rifle////// diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm new file mode 100644 index 0000000000..8d08937f55 --- /dev/null +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm @@ -0,0 +1,291 @@ +///ammo/// + +/obj/item/ammo_casing/caseless/mag_e + var/energy_cost = 0 + +/obj/item/ammo_casing/caseless/mag_e/amagm_e + desc = "A large ferromagnetic slug intended to be launched out of a compatible weapon." + caliber = "mag_e" + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/magrifle + energy_cost = 200 + +/obj/item/ammo_casing/caseless/mag_e/anlmagm_e + desc = "A large, specialized ferromagnetic slug designed with a less-than-lethal payload." + caliber = "mag_e" + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/nlmagrifle + energy_cost = 200 + +/obj/item/ammo_casing/caseless/mag_e/amags + desc = "A ferromagnetic slug intended to be launched out of a compatible weapon." + caliber = "mag_e" + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/mags + energy_cost = 125 + +/obj/item/ammo_casing/caseless/mag_e/anlmags + desc = "A specialized ferromagnetic slug designed with a less-than-lethal payload." + caliber = "mag_e" + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/nlmags + energy_cost = 125 + +///magazines/// + +/obj/item/ammo_box/magazine/mmag_e/ + name = "magrifle magazine (non-lethal disabler)" + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "mediummagmag" + ammo_type = /obj/item/ammo_casing/caseless/mag_e/anlmagm_e + caliber = "mag_e" + max_ammo = 24 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/mmag_e/lethal + name = "magrifle magazine (lethal)" + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "mediummagmag" + ammo_type = /obj/item/ammo_casing/caseless/mag_e/amagm_e + max_ammo = 24 + +/obj/item/ammo_box/magazine/mmag_e/small + name = "magpistol magazine (non-lethal disabler)" + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "nlmagmag" + ammo_type = /obj/item/ammo_casing/caseless/mag_e/anlmags + caliber = "mag_e" + max_ammo = 16 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/mmag_e/small/lethal + name = "magpistol magazine (lethal)" + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "smallmagmag" + ammo_type = /obj/item/ammo_casing/caseless/mag_e/amags + max_ammo = 16 + +///cells/// + +/obj/item/stock_parts/cell/magrifle_e + name = "magrifle power supply" + maxcharge = 14400 + chargerate = 3520 + +/obj/item/stock_parts/cell/magpistol_e + name = "magpistol power supply" + maxcharge = 6000 + chargerate = 1000 + +///sci designs/// + +/datum/design/magrifle_e + name = "Magrifle" + desc = "An upscaled Magpistol in rifle form." + id = "magrifle_e" + build_type = PROTOLATHE + materials = list(MAT_METAL = 10000, MAT_GLASS = 2000, MAT_URANIUM = 2000, MAT_TITANIUM = 10000, MAT_SILVER = 4000, MAT_GOLD = 2000) + build_path = /obj/item/gun/ballistic/automatic/magrifle_e/nopin + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_magrifle_e + name = "Magrifle Magazine (Lethal)" + desc = "A 24-round magazine for the Magrifle." + id = "mag_magrifle_e" + build_type = PROTOLATHE + materials = list(MAT_METAL = 8000, MAT_SILVER = 1000) + build_path = /obj/item/ammo_box/magazine/mmag_e/lethal + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_magrifle_e/nl + name = "Magrifle Magazine (Non-Lethal)" + desc = "A 24- round non-lethal magazine for the Magrifle." + id = "mag_magrifle_e_nl" + materials = list(MAT_METAL = 6000, MAT_SILVER = 500, MAT_TITANIUM = 500) + build_path = /obj/item/ammo_box/magazine/mmag_e + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/magpistol_e + name = "Magpistol" + desc = "A weapon which fires ferromagnetic slugs." + id = "magpistol_e" + build_type = PROTOLATHE + materials = list(MAT_METAL = 7500, MAT_GLASS = 1000, MAT_URANIUM = 1000, MAT_TITANIUM = 5000, MAT_SILVER = 2000) + build_path = /obj/item/gun/ballistic/automatic/pistol/mag_e/nopin + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_magpistol_e + name = "Magpistol Magazine" + desc = "A 14 round magazine for the Magpistol." + id = "mag_magpistol_e" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_SILVER = 500) + build_path = /obj/item/ammo_box/magazine/mmag_e/small/lethal + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/mag_magpistol_e/nl + name = "Magpistol Magazine (Non-Lethal)" + desc = "A 14 round non-lethal magazine for the Magpistol." + id = "mag_magpistol_e_nl" + materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250) + build_path = /obj/item/ammo_box/magazine/mmag_e/small + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/* +// TECHWEBS IMPLEMENTATION +*/ + +/datum/techweb_node/magnetic_weapons + id = "magnetic_weapons" + display_name = "Magnetic Weapons" + description = "Weapons using magnetic technology" + prereq_ids = list("weaponry", "adv_weaponry", "emp_adv") + design_ids = list("magrifle_e", "magpistol_e", "mag_magrifle_e", "mag_magrifle_e_nl", "mag_magpistol_e", "mag_magpistol_e_nl") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 5000 + +///magrifle/// + +/obj/item/gun/ballistic/automatic/magrifle_e + name = "\improper Magnetic Rifle" + desc = "A simple upscalling of the technologies used in the magpistol, the magrifle is capable of firing slightly larger slugs in bursts. Compatible with the magpistol's slugs." + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "magrifle" + item_state = "arg" + slot_flags = 0 + mag_type = /obj/item/ammo_box/magazine/mmag_e + fire_sound = 'sound/weapons/magrifle.ogg' + can_suppress = 0 + burst_size = 3 + fire_delay = 2 + spread = 5 + recoil = 0.15 + casing_ejector = 0 + var/obj/item/stock_parts/cell/cell + var/cell_type = /obj/item/stock_parts/cell/magrifle_e + var/dead_cell = FALSE + +/obj/item/gun/ballistic/automatic/magrifle_e/examine(mob/user) + . = ..() + if(cell) + to_chat(user, "[src]'s cell is [round(cell.charge / cell.maxcharge, 0.1) * 100]% full.") + else + to_chat(user, "[src] doesn't seem to have a cell!") + +/obj/item/gun/ballistic/automatic/magrifle_e/can_shoot() + if(QDELETED(cell)) + return 0 + + var/obj/item/ammo_casing/caseless/mag_e/shot = chambered + if(!shot) + return 0 + if(cell.charge < shot.energy_cost*burst_size) + return 0 + . = ..() + +/obj/item/gun/ballistic/automatic/magrifle_e/shoot_live_shot() + var/obj/item/ammo_casing/caseless/mag_e/shot = chambered + cell.use(shot.energy_cost) + . = ..() + +/obj/item/gun/ballistic/automatic/magrifle_e/emp_act(severity) + . = ..() + if(!(. & EMP_PROTECT_CONTENTS)) + cell.use(round(cell.charge / severity)) + +/obj/item/gun/ballistic/automatic/magrifle_e/get_cell() + return cell + +/obj/item/gun/ballistic/automatic/magrifle_e/Initialize() + . = ..() + if(cell_type) + cell = new cell_type(src) + else + cell = new(src) + + if(!dead_cell) + cell.give(cell.maxcharge) + +/obj/item/gun/ballistic/automatic/magrifle_e/nopin + pin = null + spawnwithmagazine = FALSE + +///magpistol/// + +/obj/item/gun/ballistic/automatic/pistol/mag_e + name = "magpistol" + desc = "A handgun utilizing maglev technologies to propel a ferromagnetic slug to extreme velocities." + icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' + icon_state = "magpistol" + force = 10 + fire_sound = 'sound/weapons/magpistol.ogg' + mag_type = /obj/item/ammo_box/magazine/mmag_e/small + can_suppress = 0 + casing_ejector = 0 + fire_delay = 2 + recoil = 0.2 + var/obj/item/stock_parts/cell/cell + var/cell_type = /obj/item/stock_parts/cell/magpistol_e + var/dead_cell = FALSE + +/obj/item/gun/ballistic/automatic/pistol/mag_e/examine(mob/user) + . = ..() + if(cell) + to_chat(user, "[src]'s cell is [round(cell.charge / cell.maxcharge, 0.1) * 100]% full.") + else + to_chat(user, "[src] doesn't seem to have a cell!") + +/obj/item/gun/ballistic/automatic/pistol/mag_e/can_shoot() + if(QDELETED(cell)) + return 0 + + var/obj/item/ammo_casing/caseless/mag_e/shot = chambered + if(!shot) + return 0 + if(cell.charge < shot.energy_cost) + return 0 + . = ..() + +/obj/item/gun/ballistic/automatic/pistol/mag_e/shoot_live_shot() + var/obj/item/ammo_casing/caseless/mag_e/shot = chambered + cell.use(shot.energy_cost) + . = ..() + +/obj/item/gun/ballistic/automatic/pistol/mag_e/emp_act(severity) + . = ..() + if(!(. & EMP_PROTECT_CONTENTS)) + cell.use(round(cell.charge / severity)) + +/obj/item/gun/ballistic/automatic/pistol/mag_e/get_cell() + return cell + +/obj/item/gun/ballistic/automatic/pistol/mag_e/Initialize() + . = ..() + if(cell_type) + cell = new cell_type(src) + else + cell = new(src) + + if(!dead_cell) + cell.give(cell.maxcharge) + +/obj/item/gun/ballistic/automatic/pistol/mag_e/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("magpistol-magazine") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +/obj/item/gun/ballistic/automatic/pistol/mag_e/nopin + pin = null + spawnwithmagazine = FALSE diff --git a/modular_citadel/code/modules/projectiles/guns/energy/laser.dm b/modular_citadel/code/modules/projectiles/guns/energy/laser.dm index 61996a777a..c82a3e9ed9 100644 --- a/modular_citadel/code/modules/projectiles/guns/energy/laser.dm +++ b/modular_citadel/code/modules/projectiles/guns/energy/laser.dm @@ -17,30 +17,3 @@ /obj/item/gun/energy/laser/redtag lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' - -/obj/item/gun/energy/laser/carbine - name = "VGS blaster carbine" - desc = "A ruggedized laser carbine featuring much higher capacity and improved handling when compared to a normal blaster carbine." - icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi' - icon_state = "lasernew" - item_state = "laser" - force = 10 - throwforce = 10 - ammo_type = list(/obj/item/ammo_casing/energy/lasergun) - cell_type = /obj/item/stock_parts/cell/lascarbine - -/obj/item/gun/energy/laser/carbine/nopin - pin = null - -/obj/item/stock_parts/cell/lascarbine - name = "laser carbine power supply" - maxcharge = 2500 - -/datum/design/lasercarbine - name = "VGS Blaster Carbine" - desc = "Beefed up version of a normal blaster carbine." - id = "lasercarbine" - build_type = PROTOLATHE - materials = list(MAT_GOLD = 2500, MAT_METAL = 5000, MAT_GLASS = 5000) - build_path = /obj/item/gun/energy/laser/carbine/nopin - category = list("Weapons") \ No newline at end of file diff --git a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm index e46174b5a9..2a6f03fae3 100644 --- a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm +++ b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm @@ -97,14 +97,14 @@ color = "#FFADFF"//PINK, rgb(255, 173, 255) /datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M) - if(M && M.canbearoused) + if(M && M.canbearoused && !HAS_TRAIT(M, TRAIT_CROCRIN_IMMUNE)) if(prob(33)) M.adjustArousalLoss(2) if(prob(5)) M.emote(pick("moan","blush")) if(prob(5)) var/aroused_message = pick("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.") - to_chat(M, "[aroused_message]") + to_chat(M, "[aroused_message]") ..() /datum/reagent/drug/aphrodisiacplus @@ -119,7 +119,7 @@ overdose_threshold = 20 /datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M) - if(M && M.canbearoused) + if(M && M.canbearoused && !HAS_TRAIT(M, TRAIT_CROCRIN_IMMUNE)) if(prob(33)) M.adjustArousalLoss(6)//not quite six times as powerful, but still considerably more powerful. if(prob(5)) @@ -133,7 +133,7 @@ aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!") else aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.") - to_chat(M, "[aroused_message]") + to_chat(M, "[aroused_message]") ..() /datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M) @@ -151,7 +151,7 @@ ..() /datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M) - if(M && M.canbearoused && prob(33)) + if(M && M.canbearoused && !HAS_TRAIT(M, TRAIT_CROCRIN_IMMUNE) && prob(33)) if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna()) var/mob/living/carbon/human/H = M if(prob(50)) //Less spam diff --git a/modular_citadel/code/modules/research/designs/autolathe_designs.dm b/modular_citadel/code/modules/research/designs/autolathe_designs.dm deleted file mode 100755 index 55b83a2262..0000000000 --- a/modular_citadel/code/modules/research/designs/autolathe_designs.dm +++ /dev/null @@ -1,15 +0,0 @@ -/datum/design/hypovialsmall - name = "Hypovial" - id = "hypovial" - build_type = AUTOLATHE - materials = list(MAT_METAL = 500) - build_path = /obj/item/reagent_containers/glass/bottle/vial/small - category = list("initial","Medical") - -/datum/design/hypoviallarge - name = "Large Hypovial" - id = "large_hypovial" - build_type = AUTOLATHE - materials = list(MAT_METAL = 2500) - build_path = /obj/item/reagent_containers/glass/bottle/vial/large - category = list("initial","Medical") diff --git a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm index e931f37520..22085d520c 100644 --- a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm +++ b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm @@ -232,10 +232,11 @@ M.forceMove(drop_location()) // Move the belly contents into the same location as belly's owner. items_preserved -= M - for(var/mob/H in get_hearers_in_view(2, get_turf(owner))) - if(H.client && (H.client.prefs.cit_toggles & EATING_NOISES)) - var/sound/releasement = GLOB.release_sounds[release_sound] - playsound(get_turf(owner),releasement,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) + if(!silent) + for(var/mob/H in get_hearers_in_view(2, get_turf(owner))) + if(H.client && (H.client.prefs.cit_toggles & EATING_NOISES)) + var/sound/releasement = GLOB.release_sounds[release_sound] + playsound(get_turf(owner),releasement,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) if(istype(M,/mob/living)) var/mob/living/ML = M diff --git a/modular_citadel/code/modules/vore/eating/living_vr.dm b/modular_citadel/code/modules/vore/eating/living_vr.dm index b1d2a46ff2..a8a77895c8 100644 --- a/modular_citadel/code/modules/vore/eating/living_vr.dm +++ b/modular_citadel/code/modules/vore/eating/living_vr.dm @@ -289,8 +289,7 @@ if(!confirm == "Okay" || loc != B) return //Actual escaping - forceMove(get_turf(src)) //Just move me up to the turf, let's not cascade through bellies, there's been a problem, let's just leave. - src.cure_blind("belly_[REF(src)]") + B.release_specific_contents(src,TRUE) //we might as well take advantage of that specific belly's handling. Else we stay blinded forever. src.stop_sound_channel(CHANNEL_PREYLOOP) SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey) for(var/mob/living/simple_animal/SA in range(10)) diff --git a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm b/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm index 2ac2628d1f..6f484e7a51 100644 --- a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm +++ b/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm @@ -57,6 +57,7 @@ /datum/vore_look/proc/gen_vui(var/mob/living/user) var/dat dat += "Remember to toggle the vore mode, it's to the left of your combat toggle. Open mouth means you're voracious!
" + dat += "Remember that your prey is blind, use audible mode subtle messages to communicate to them with posts!
" dat += "
" var/atom/userloc = user.loc if (isbelly(userloc)) diff --git a/modular_citadel/icons/mob/clothing/trek_item_icon.dmi b/modular_citadel/icons/mob/clothing/trek_item_icon.dmi index 86afe16b03..ed3286615b 100644 Binary files a/modular_citadel/icons/mob/clothing/trek_item_icon.dmi and b/modular_citadel/icons/mob/clothing/trek_item_icon.dmi differ diff --git a/modular_citadel/icons/mob/clothing/trek_mob_icon.dmi b/modular_citadel/icons/mob/clothing/trek_mob_icon.dmi index 51daa8179f..d3ebc31b6a 100644 Binary files a/modular_citadel/icons/mob/clothing/trek_mob_icon.dmi and b/modular_citadel/icons/mob/clothing/trek_mob_icon.dmi differ diff --git a/modular_citadel/icons/mob/mam_ears.dmi b/modular_citadel/icons/mob/mam_ears.dmi index b3946b546c..569667a82d 100644 Binary files a/modular_citadel/icons/mob/mam_ears.dmi and b/modular_citadel/icons/mob/mam_ears.dmi differ diff --git a/modular_citadel/icons/mob/mam_markings.dmi b/modular_citadel/icons/mob/mam_markings.dmi index c391674190..8327be6eaf 100644 Binary files a/modular_citadel/icons/mob/mam_markings.dmi and b/modular_citadel/icons/mob/mam_markings.dmi differ diff --git a/modular_citadel/icons/mob/mam_tails.dmi b/modular_citadel/icons/mob/mam_tails.dmi index 74eccae2f8..b16de1c0de 100644 Binary files a/modular_citadel/icons/mob/mam_tails.dmi and b/modular_citadel/icons/mob/mam_tails.dmi differ diff --git a/modular_citadel/icons/mob/mam_taur.dmi b/modular_citadel/icons/mob/mam_taur.dmi index ebaa0123ae..84367ebf0a 100644 Binary files a/modular_citadel/icons/mob/mam_taur.dmi and b/modular_citadel/icons/mob/mam_taur.dmi differ diff --git a/modular_citadel/icons/mob/markings_notmammals.dmi b/modular_citadel/icons/mob/markings_notmammals.dmi index 4161ea2cea..59b10e93aa 100644 Binary files a/modular_citadel/icons/mob/markings_notmammals.dmi and b/modular_citadel/icons/mob/markings_notmammals.dmi differ diff --git a/modular_citadel/icons/mob/mutant_bodyparts.dmi b/modular_citadel/icons/mob/mutant_bodyparts.dmi index 6a0bf77cd3..5f72d1013b 100644 Binary files a/modular_citadel/icons/mob/mutant_bodyparts.dmi and b/modular_citadel/icons/mob/mutant_bodyparts.dmi differ diff --git a/modular_citadel/icons/mob/muzzled_helmet.dmi b/modular_citadel/icons/mob/muzzled_helmet.dmi index 3c0a229d58..a96f18c3ce 100644 Binary files a/modular_citadel/icons/mob/muzzled_helmet.dmi and b/modular_citadel/icons/mob/muzzled_helmet.dmi differ diff --git a/modular_citadel/icons/mob/suit_digi.dmi b/modular_citadel/icons/mob/suit_digi.dmi index 22fddbe59d..1f1f506d9f 100644 Binary files a/modular_citadel/icons/mob/suit_digi.dmi and b/modular_citadel/icons/mob/suit_digi.dmi differ diff --git a/modular_citadel/icons/mob/taur_naga.dmi b/modular_citadel/icons/mob/taur_naga.dmi index f4d6a6139f..1ca4509db7 100644 Binary files a/modular_citadel/icons/mob/taur_naga.dmi and b/modular_citadel/icons/mob/taur_naga.dmi differ diff --git a/modular_citadel/icons/mob/uniform_digi.dmi b/modular_citadel/icons/mob/uniform_digi.dmi index c5ee6b1780..9513f82c9c 100644 Binary files a/modular_citadel/icons/mob/uniform_digi.dmi and b/modular_citadel/icons/mob/uniform_digi.dmi differ diff --git a/modular_citadel/icons/obj/food/cake.dmi b/modular_citadel/icons/obj/food/cake.dmi new file mode 100644 index 0000000000..840bfe714d Binary files /dev/null and b/modular_citadel/icons/obj/food/cake.dmi differ diff --git a/modular_citadel/icons/obj/food/food.dmi b/modular_citadel/icons/obj/food/food.dmi index ea66b3d48a..da9a6c365f 100644 Binary files a/modular_citadel/icons/obj/food/food.dmi and b/modular_citadel/icons/obj/food/food.dmi differ diff --git a/modular_citadel/icons/obj/genitals/breasts.dmi b/modular_citadel/icons/obj/genitals/breasts.dmi index 7e4a631876..8c76891396 100644 Binary files a/modular_citadel/icons/obj/genitals/breasts.dmi and b/modular_citadel/icons/obj/genitals/breasts.dmi differ diff --git a/modular_citadel/icons/obj/genitals/breasts_onmob.dmi b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi index 2a7342553b..69a531bd11 100644 Binary files a/modular_citadel/icons/obj/genitals/breasts_onmob.dmi and b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/penis.dmi b/modular_citadel/icons/obj/genitals/penis.dmi index 9ac7d82cbd..397fa335e5 100644 Binary files a/modular_citadel/icons/obj/genitals/penis.dmi and b/modular_citadel/icons/obj/genitals/penis.dmi differ diff --git a/modular_citadel/icons/obj/genitals/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi index 733e0a08da..2457759b73 100644 Binary files a/modular_citadel/icons/obj/genitals/penis_onmob.dmi and b/modular_citadel/icons/obj/genitals/penis_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/testicles.dmi b/modular_citadel/icons/obj/genitals/testicles.dmi new file mode 100644 index 0000000000..3d7a5f4f48 Binary files /dev/null and b/modular_citadel/icons/obj/genitals/testicles.dmi differ diff --git a/modular_citadel/icons/obj/genitals/testicles_onmob.dmi b/modular_citadel/icons/obj/genitals/testicles_onmob.dmi new file mode 100644 index 0000000000..581bcb0583 Binary files /dev/null and b/modular_citadel/icons/obj/genitals/testicles_onmob.dmi differ diff --git a/modular_citadel/icons/obj/genitals/vagina.dmi b/modular_citadel/icons/obj/genitals/vagina.dmi index a57392868f..39bdd48e89 100644 Binary files a/modular_citadel/icons/obj/genitals/vagina.dmi and b/modular_citadel/icons/obj/genitals/vagina.dmi differ diff --git a/modular_citadel/icons/obj/genitals/vagina_onmob.dmi b/modular_citadel/icons/obj/genitals/vagina_onmob.dmi index 41bc818719..f5daa3fea1 100644 Binary files a/modular_citadel/icons/obj/genitals/vagina_onmob.dmi and b/modular_citadel/icons/obj/genitals/vagina_onmob.dmi differ diff --git a/modular_citadel/icons/obj/guns/cit_guns.dmi b/modular_citadel/icons/obj/guns/cit_guns.dmi index e02025f436..8154a753e0 100644 Binary files a/modular_citadel/icons/obj/guns/cit_guns.dmi and b/modular_citadel/icons/obj/guns/cit_guns.dmi differ diff --git a/modular_citadel/icons/obj/honk.dmi b/modular_citadel/icons/obj/honk.dmi index 950a0c784b..e605c646f8 100644 Binary files a/modular_citadel/icons/obj/honk.dmi and b/modular_citadel/icons/obj/honk.dmi differ diff --git a/sound/effects/footstep/carpetbarefoot1.ogg b/sound/effects/footstep/carpetbarefoot1.ogg new file mode 100644 index 0000000000..81615d2970 Binary files /dev/null and b/sound/effects/footstep/carpetbarefoot1.ogg differ diff --git a/sound/effects/footstep/carpetbarefoot2.ogg b/sound/effects/footstep/carpetbarefoot2.ogg new file mode 100644 index 0000000000..d1c7e1627e Binary files /dev/null and b/sound/effects/footstep/carpetbarefoot2.ogg differ diff --git a/sound/effects/footstep/carpetbarefoot3.ogg b/sound/effects/footstep/carpetbarefoot3.ogg new file mode 100644 index 0000000000..13ecb3398b Binary files /dev/null and b/sound/effects/footstep/carpetbarefoot3.ogg differ diff --git a/sound/effects/footstep/carpetbarefoot4.ogg b/sound/effects/footstep/carpetbarefoot4.ogg new file mode 100644 index 0000000000..31850250be Binary files /dev/null and b/sound/effects/footstep/carpetbarefoot4.ogg differ diff --git a/sound/effects/footstep/carpetbarefoot5.ogg b/sound/effects/footstep/carpetbarefoot5.ogg new file mode 100644 index 0000000000..e9a44765b1 Binary files /dev/null and b/sound/effects/footstep/carpetbarefoot5.ogg differ diff --git a/sound/effects/footstep/crawl1.ogg b/sound/effects/footstep/crawl1.ogg new file mode 100644 index 0000000000..61a73a58d0 Binary files /dev/null and b/sound/effects/footstep/crawl1.ogg differ diff --git a/sound/effects/footstep/hardbarefoot1.ogg b/sound/effects/footstep/hardbarefoot1.ogg new file mode 100644 index 0000000000..2614872191 Binary files /dev/null and b/sound/effects/footstep/hardbarefoot1.ogg differ diff --git a/sound/effects/footstep/hardbarefoot2.ogg b/sound/effects/footstep/hardbarefoot2.ogg new file mode 100644 index 0000000000..7d89d96105 Binary files /dev/null and b/sound/effects/footstep/hardbarefoot2.ogg differ diff --git a/sound/effects/footstep/hardbarefoot3.ogg b/sound/effects/footstep/hardbarefoot3.ogg new file mode 100644 index 0000000000..639751fab0 Binary files /dev/null and b/sound/effects/footstep/hardbarefoot3.ogg differ diff --git a/sound/effects/footstep/hardbarefoot4.ogg b/sound/effects/footstep/hardbarefoot4.ogg new file mode 100644 index 0000000000..9cf363a18c Binary files /dev/null and b/sound/effects/footstep/hardbarefoot4.ogg differ diff --git a/sound/effects/footstep/hardbarefoot5.ogg b/sound/effects/footstep/hardbarefoot5.ogg new file mode 100644 index 0000000000..72ebeca84d Binary files /dev/null and b/sound/effects/footstep/hardbarefoot5.ogg differ diff --git a/sound/effects/footstep/hardclaw1.ogg b/sound/effects/footstep/hardclaw1.ogg new file mode 100644 index 0000000000..1d66eb4d49 Binary files /dev/null and b/sound/effects/footstep/hardclaw1.ogg differ diff --git a/sound/effects/footstep/hardclaw2.ogg b/sound/effects/footstep/hardclaw2.ogg new file mode 100644 index 0000000000..a6a7951d77 Binary files /dev/null and b/sound/effects/footstep/hardclaw2.ogg differ diff --git a/sound/effects/footstep/hardclaw3.ogg b/sound/effects/footstep/hardclaw3.ogg new file mode 100644 index 0000000000..a2e5462199 Binary files /dev/null and b/sound/effects/footstep/hardclaw3.ogg differ diff --git a/sound/effects/footstep/hardclaw4.ogg b/sound/effects/footstep/hardclaw4.ogg new file mode 100644 index 0000000000..bd845a8782 Binary files /dev/null and b/sound/effects/footstep/hardclaw4.ogg differ diff --git a/sound/effects/footstep/heavy1.ogg b/sound/effects/footstep/heavy1.ogg new file mode 100644 index 0000000000..bfc80a4270 Binary files /dev/null and b/sound/effects/footstep/heavy1.ogg differ diff --git a/sound/effects/footstep/heavy2.ogg b/sound/effects/footstep/heavy2.ogg new file mode 100644 index 0000000000..514e3ac3e2 Binary files /dev/null and b/sound/effects/footstep/heavy2.ogg differ diff --git a/sound/effects/footstep/slime1.ogg b/sound/effects/footstep/slime1.ogg new file mode 100644 index 0000000000..a83b7646f1 Binary files /dev/null and b/sound/effects/footstep/slime1.ogg differ diff --git a/sound/effects/footstep/woodbarefoot1.ogg b/sound/effects/footstep/woodbarefoot1.ogg new file mode 100644 index 0000000000..bb66da770e Binary files /dev/null and b/sound/effects/footstep/woodbarefoot1.ogg differ diff --git a/sound/effects/footstep/woodbarefoot2.ogg b/sound/effects/footstep/woodbarefoot2.ogg new file mode 100644 index 0000000000..67397d868e Binary files /dev/null and b/sound/effects/footstep/woodbarefoot2.ogg differ diff --git a/sound/effects/footstep/woodbarefoot3.ogg b/sound/effects/footstep/woodbarefoot3.ogg new file mode 100644 index 0000000000..113a89003a Binary files /dev/null and b/sound/effects/footstep/woodbarefoot3.ogg differ diff --git a/sound/effects/footstep/woodbarefoot4.ogg b/sound/effects/footstep/woodbarefoot4.ogg new file mode 100644 index 0000000000..ccc2e82075 Binary files /dev/null and b/sound/effects/footstep/woodbarefoot4.ogg differ diff --git a/sound/effects/footstep/woodbarefoot5.ogg b/sound/effects/footstep/woodbarefoot5.ogg new file mode 100644 index 0000000000..6fbce27109 Binary files /dev/null and b/sound/effects/footstep/woodbarefoot5.ogg differ diff --git a/sound/effects/footstep/woodclaw1.ogg b/sound/effects/footstep/woodclaw1.ogg new file mode 100644 index 0000000000..181403b93f Binary files /dev/null and b/sound/effects/footstep/woodclaw1.ogg differ diff --git a/sound/effects/footstep/woodclaw2.ogg b/sound/effects/footstep/woodclaw2.ogg new file mode 100644 index 0000000000..29b04a9554 Binary files /dev/null and b/sound/effects/footstep/woodclaw2.ogg differ diff --git a/sound/effects/footstep/woodclaw3.ogg b/sound/effects/footstep/woodclaw3.ogg new file mode 100644 index 0000000000..9f4ac6d334 Binary files /dev/null and b/sound/effects/footstep/woodclaw3.ogg differ diff --git a/sound/voice/firebot/detected.ogg b/sound/voice/firebot/detected.ogg new file mode 100644 index 0000000000..e5acfa10c7 Binary files /dev/null and b/sound/voice/firebot/detected.ogg differ diff --git a/sound/voice/firebot/extinguishing.ogg b/sound/voice/firebot/extinguishing.ogg new file mode 100644 index 0000000000..d7b44b7fce Binary files /dev/null and b/sound/voice/firebot/extinguishing.ogg differ diff --git a/sound/voice/firebot/keepitcool.ogg b/sound/voice/firebot/keepitcool.ogg new file mode 100644 index 0000000000..e04c94337a Binary files /dev/null and b/sound/voice/firebot/keepitcool.ogg differ diff --git a/sound/voice/firebot/nofires.ogg b/sound/voice/firebot/nofires.ogg new file mode 100644 index 0000000000..962f18d135 Binary files /dev/null and b/sound/voice/firebot/nofires.ogg differ diff --git a/sound/voice/firebot/onlyyou.ogg b/sound/voice/firebot/onlyyou.ogg new file mode 100644 index 0000000000..e8eb3cdf2e Binary files /dev/null and b/sound/voice/firebot/onlyyou.ogg differ diff --git a/sound/voice/firebot/stopdropnroll.ogg b/sound/voice/firebot/stopdropnroll.ogg new file mode 100644 index 0000000000..9e6b1c1bb6 Binary files /dev/null and b/sound/voice/firebot/stopdropnroll.ogg differ diff --git a/sound/voice/firebot/tempnominal.ogg b/sound/voice/firebot/tempnominal.ogg new file mode 100644 index 0000000000..9eaa984cd6 Binary files /dev/null and b/sound/voice/firebot/tempnominal.ogg differ diff --git a/strings/clockwork_cult_changelog.txt b/strings/clockwork_cult_changelog.txt index c963ca91d1..3c5e5f5ef6 100644 --- a/strings/clockwork_cult_changelog.txt +++ b/strings/clockwork_cult_changelog.txt @@ -1 +1,4 @@ -Stargazers have been removed. Integration cogs are now the primary way of creating power. \ No newline at end of file +Stargazers have been removed. Integration cogs are now the primary way of creating power. +Brass Skewers now deal damage to mechs. +Mech Sensors are now available. They're similar to pressure sensors, but trigger if a mech steps on them, and can be built the same way. +Power nullifiers are now available. Upon triggering, they send out a small 3x3 EMP, affecting cultists and enemies alike. diff --git a/strings/names/mime.txt b/strings/names/mime.txt index cc65af67fd..094987da9d 100644 --- a/strings/names/mime.txt +++ b/strings/names/mime.txt @@ -1,7 +1,10 @@ +Church Mouse +Hush Foot Invisible Man Lemon Mime Marcel Marcel Mime +Master-Mime Mime Mr Beret Mr Mime @@ -12,13 +15,18 @@ Oui Oui Pantomime Quiet Quiet Riot +See Through Silence Silencio Silent Knight Silent Majority Silent Night Silent Sorrow +Silent Step +Silent Mouse +The Unspeakable Transparency Unspeakable Untouchable -Wall Runner \ No newline at end of file +Wall Runner +White Face diff --git a/strings/phobia.json b/strings/phobia.json index e1ae1f4e13..17f480bd99 100644 --- a/strings/phobia.json +++ b/strings/phobia.json @@ -14,6 +14,19 @@ "spess" ], + "eye": [ + "eye", + "blink", + "look", + "see", + "laser", + "iris", + "cornea", + "pupil", + "lens", + "optic" + ], + "security": [ "sec", "security", @@ -283,6 +296,25 @@ "slip" ], + "syndicate": [ + "syndicate", + "changeling", + "rev", + "nuke ops", + "syndicats", + "nukies", + "ops", + "traitor", + "second shooter", + "revolution", + "fuck nt", + "rigged from the start", + "debt to pay", + "brainwashing", + "enemy corporation", + "agent" + ], + "anime": [ "anime", "manga", diff --git a/strings/tips.txt b/strings/tips.txt index 9571527853..e9c1350469 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -229,6 +229,8 @@ As a Servant, wraith spectacles let you see everything through walls at virtuall As a Servant, declaring war empowers a huge amount of your tools and constructs, and makes you into a spaceproof, armored clockwork automaton. As a Servant, converting or sabotaging Science and Genetics can make defending the Ark much easier. As a Servant, the Clockwork Armaments scripture allows you to summon armor and/or a weapon at will. Use it whenever you unlock it! +As a Servant, Brass created from your replica fabricators can be ground down in reagent grinders for teslium and iron. +You can bypass Servant created pressure sensors if you walk instead of jog on them. Alternatively, you can also become a Servant of Ratvar. You can deconvert Cultists of Nar-Sie and Servants of Ratvar by feeding them large amounts of holy water. Unlike revolutionaries, implanting them with mindshield implants won't do it! Tiles sprayed with holy water will permanently block Servants of Ratvar from teleporting onto them. As a Wizard, you can turn people to stone, then animate the resulting statue with a staff of animation to create an extremely powerful minion, for all of 5 minutes at least. diff --git a/strings/traumas.json b/strings/traumas.json index 9394f11f3a..f83a023491 100644 --- a/strings/traumas.json +++ b/strings/traumas.json @@ -108,7 +108,31 @@ "@pick(semicolon)i ran into the supermattre ten i dsappeard @pick(bug)", "DON'T EVER TUCH ME", "@pick(semicolon)GIVE ME FREE ROBUX PLEASE JUST ENOUGH FOR SHIRT AND PANTS", - "@pick(semicolon) DOOR STUCK!!" + "@pick(semicolon) DOOR STUCK!!", + "HOW DO i VORE", + "HOW DO i HAV SEX", + "@pick(semicolon)how do u cum", + "@pick(semicolon)ahelp how do u use dildo", + ";AI LAW 3 OPEN THIS.", + "ahelp hos pwrgamre they have 24 inch dick", + ";KERPTAN IS A KERNDUM", + "@pick(semicolon)RESEARCH NANITES FIRST", + "@pick(semicolon)how use comms?????????", + "@pick(semicolon)im SICK of ths fuckign humans runin g my furry server", + "@pick(semicolon)ai ROUGE", + "ahelp want a big titty @pick(create_nouns) gf to deepthroat my pp", + "@pick(semicolon)CHEMISST MAKE HEXACROCON OR REPORT", + "@pick(semicolon)drone 765 law 2 state LAWS NOW", + "@pick(semicolon)SM ROGUE", + "@pick(semicolon)IPCS STATE LAWS NOW", + "@pick(semicolon)lING DORMS i hear Suking noises!!!", + "@pick(semicolon)@pick(roles) tator they have @pick(mutations)!!", + "@pick(semicolon)aooc how do i steel @pick(cargo)?", + "@pick(semicolon)how do i play", + "ahelp help security powergaming with mindshields???", + ";,g absorbing @pick(roles)", + ";chemist can u @pick(create_verbs) holy @pick(mellens) for @pick(s_roles)???!!", + "@pick(semicolon) LIZZARRD SPEAKIGN IN EVIL BULL LANGUAGE SCI!!" ], "mutations": [ diff --git a/tgstation.dme b/tgstation.dme index 5b4c4eabe5..e33566290c 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -199,6 +199,7 @@ #include "code\_onclick\hud\picture_in_picture.dm" #include "code\_onclick\hud\plane_master.dm" #include "code\_onclick\hud\radial.dm" +#include "code\_onclick\hud\radial_persistent.dm" #include "code\_onclick\hud\revenanthud.dm" #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" @@ -380,6 +381,7 @@ #include "code\datums\components\storage\concrete\_concrete.dm" #include "code\datums\components\storage\concrete\bag_of_holding.dm" #include "code\datums\components\storage\concrete\bluespace.dm" +#include "code\datums\components\storage\concrete\emergency.dm" #include "code\datums\components\storage\concrete\implant.dm" #include "code\datums\components\storage\concrete\pockets.dm" #include "code\datums\components\storage\concrete\rped.dm" @@ -1232,12 +1234,15 @@ #include "code\modules\antagonists\clockcult\clock_structures\mania_motor.dm" #include "code\modules\antagonists\clockcult\clock_structures\ocular_warden.dm" #include "code\modules\antagonists\clockcult\clock_structures\ratvar_the_clockwork_justicar.dm" +#include "code\modules\antagonists\clockcult\clock_structures\stargazer.dm" #include "code\modules\antagonists\clockcult\clock_structures\taunting_trail.dm" #include "code\modules\antagonists\clockcult\clock_structures\wall_gear.dm" #include "code\modules\antagonists\clockcult\clock_structures\trap_triggers\lever.dm" #include "code\modules\antagonists\clockcult\clock_structures\trap_triggers\pressure_sensor.dm" +#include "code\modules\antagonists\clockcult\clock_structures\trap_triggers\pressure_sensor_mech.dm" #include "code\modules\antagonists\clockcult\clock_structures\trap_triggers\repeater.dm" #include "code\modules\antagonists\clockcult\clock_structures\traps\brass_skewer.dm" +#include "code\modules\antagonists\clockcult\clock_structures\traps\power_null.dm" #include "code\modules\antagonists\clockcult\clock_structures\traps\steam_vent.dm" #include "code\modules\antagonists\cult\blood_magic.dm" #include "code\modules\antagonists\cult\cult.dm" @@ -1492,6 +1497,7 @@ #include "code\modules\clothing\shoes\colour.dm" #include "code\modules\clothing\shoes\magboots.dm" #include "code\modules\clothing\shoes\miscellaneous.dm" +#include "code\modules\clothing\shoes\taeclowndo.dm" #include "code\modules\clothing\shoes\vg_shoes.dm" #include "code\modules\clothing\spacesuits\_spacesuits.dm" #include "code\modules\clothing\spacesuits\chronosuit.dm" @@ -1619,6 +1625,7 @@ #include "code\modules\food_and_drinks\food\snacks_burgers.dm" #include "code\modules\food_and_drinks\food\snacks_cake.dm" #include "code\modules\food_and_drinks\food\snacks_egg.dm" +#include "code\modules\food_and_drinks\food\snacks_frozen.dm" #include "code\modules\food_and_drinks\food\snacks_meat.dm" #include "code\modules\food_and_drinks\food\snacks_other.dm" #include "code\modules\food_and_drinks\food\snacks_pastry.dm" @@ -1628,6 +1635,7 @@ #include "code\modules\food_and_drinks\food\snacks_sandwichtoast.dm" #include "code\modules\food_and_drinks\food\snacks_soup.dm" #include "code\modules\food_and_drinks\food\snacks_spaghetti.dm" +#include "code\modules\food_and_drinks\food\snacks_sushi.dm" #include "code\modules\food_and_drinks\food\snacks_vend.dm" #include "code\modules\food_and_drinks\food\snacks\dough.dm" #include "code\modules\food_and_drinks\food\snacks\meat.dm" @@ -1646,6 +1654,7 @@ #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_burger.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_cake.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_egg.dm" +#include "code\modules\food_and_drinks\recipes\tablecraft\recipes_frozen.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_meat.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_misc.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_pastry.dm" @@ -1655,6 +1664,7 @@ #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_sandwich.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_soup.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_spaghetti.dm" +#include "code\modules\food_and_drinks\recipes\tablecraft\recipes_sushi.dm" #include "code\modules\games\cas.dm" #include "code\modules\goonchat\browserOutput.dm" #include "code\modules\goonchat\jsErrorHandler.dm" @@ -1751,6 +1761,7 @@ #include "code\modules\integrated_electronics\subtypes\text.dm" #include "code\modules\integrated_electronics\subtypes\time.dm" #include "code\modules\integrated_electronics\subtypes\trig.dm" +#include "code\modules\integrated_electronics\subtypes\weaponized.dm" #include "code\modules\jobs\access.dm" #include "code\modules\jobs\job_exp.dm" #include "code\modules\jobs\jobs.dm" @@ -1874,7 +1885,23 @@ #include "code\modules\mob\dead\new_player\new_player.dm" #include "code\modules\mob\dead\new_player\poll.dm" #include "code\modules\mob\dead\new_player\preferences_setup.dm" -#include "code\modules\mob\dead\new_player\sprite_accessories.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\_sprite_accessories.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\body_markings.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\caps.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\ears.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\frills.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\hair_face.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\hair_head.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\horns.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\legs.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\moth_wings.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\pines.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\snouts.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\socks.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\tails.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\undershirt.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\underwear.dm" +#include "code\modules\mob\dead\new_player\sprite_accessories\wings.dm" #include "code\modules\mob\dead\observer\login.dm" #include "code\modules\mob\dead\observer\logout.dm" #include "code\modules\mob\dead\observer\notificationprefs.dm" @@ -2056,6 +2083,7 @@ #include "code\modules\mob\living\simple_animal\bot\cleanbot.dm" #include "code\modules\mob\living\simple_animal\bot\construction.dm" #include "code\modules\mob\living\simple_animal\bot\ed209bot.dm" +#include "code\modules\mob\living\simple_animal\bot\firebot.dm" #include "code\modules\mob\living\simple_animal\bot\floorbot.dm" #include "code\modules\mob\living\simple_animal\bot\honkbot.dm" #include "code\modules\mob\living\simple_animal\bot\medbot.dm" @@ -2479,15 +2507,12 @@ #include "code\modules\research\server.dm" #include "code\modules\research\stock_parts.dm" #include "code\modules\research\designs\AI_module_designs.dm" -#include "code\modules\research\designs\autolathe_designs.dm" #include "code\modules\research\designs\biogenerator_designs.dm" #include "code\modules\research\designs\bluespace_designs.dm" -#include "code\modules\research\designs\comp_board_designs.dm" #include "code\modules\research\designs\computer_part_designs.dm" #include "code\modules\research\designs\electronics_designs.dm" #include "code\modules\research\designs\equipment_designs.dm" #include "code\modules\research\designs\limbgrower_designs.dm" -#include "code\modules\research\designs\machine_designs.dm" #include "code\modules\research\designs\mecha_designs.dm" #include "code\modules\research\designs\mechfabricator_designs.dm" #include "code\modules\research\designs\medical_designs.dm" @@ -2499,6 +2524,24 @@ #include "code\modules\research\designs\stock_parts_designs.dm" #include "code\modules\research\designs\telecomms_designs.dm" #include "code\modules\research\designs\weapon_designs.dm" +#include "code\modules\research\designs\autolathe_desings\autolathe_designs_construction.dm" +#include "code\modules\research\designs\autolathe_desings\autolathe_designs_electronics.dm" +#include "code\modules\research\designs\autolathe_desings\autolathe_designs_medical_and_dinnerware.dm" +#include "code\modules\research\designs\autolathe_desings\autolathe_designs_sec_and_hacked.dm" +#include "code\modules\research\designs\autolathe_desings\autolathe_designs_tcomms_and_misc.dm" +#include "code\modules\research\designs\autolathe_desings\autolathe_designs_tools.dm" +#include "code\modules\research\designs\comp_board_designs\comp_board_designs_all_misc.dm" +#include "code\modules\research\designs\comp_board_designs\comp_board_designs_cargo .dm" +#include "code\modules\research\designs\comp_board_designs\comp_board_designs_engi.dm" +#include "code\modules\research\designs\comp_board_designs\comp_board_designs_medical.dm" +#include "code\modules\research\designs\comp_board_designs\comp_board_designs_sci.dm" +#include "code\modules\research\designs\comp_board_designs\comp_board_designs_sec.dm" +#include "code\modules\research\designs\machine_desings\machine_designs_all_misc.dm" +#include "code\modules\research\designs\machine_desings\machine_designs_cargo.dm" +#include "code\modules\research\designs\machine_desings\machine_designs_engi.dm" +#include "code\modules\research\designs\machine_desings\machine_designs_medical.dm" +#include "code\modules\research\designs\machine_desings\machine_designs_sci.dm" +#include "code\modules\research\designs\machine_desings\machine_designs_service.dm" #include "code\modules\research\machinery\_production.dm" #include "code\modules\research\machinery\circuit_imprinter.dm" #include "code\modules\research\machinery\departmental_circuit_imprinter.dm" @@ -2624,6 +2667,7 @@ #include "code\modules\spells\spell_types\shapeshift.dm" #include "code\modules\spells\spell_types\spacetime_distortion.dm" #include "code\modules\spells\spell_types\summonitem.dm" +#include "code\modules\spells\spell_types\taeclowndo.dm" #include "code\modules\spells\spell_types\the_traps.dm" #include "code\modules\spells\spell_types\touch_attacks.dm" #include "code\modules\spells\spell_types\trigger.dm" @@ -2645,6 +2689,7 @@ #include "code\modules\surgery\limb_augmentation.dm" #include "code\modules\surgery\lipoplasty.dm" #include "code\modules\surgery\mechanic_steps.dm" +#include "code\modules\surgery\nutcracker.dm" #include "code\modules\surgery\organ_manipulation.dm" #include "code\modules\surgery\organic_steps.dm" #include "code\modules\surgery\plastic_surgery.dm" @@ -2789,6 +2834,17 @@ #include "modular_citadel\code\datums\wires\airlock.dm" #include "modular_citadel\code\datums\wires\autoylathe.dm" #include "modular_citadel\code\game\area\cit_areas.dm" +#include "modular_citadel\code\game\gamemodes\gangs\dominator.dm" +#include "modular_citadel\code\game\gamemodes\gangs\dominator_countdown.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_datums.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_decals.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_hud.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_items.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_pen.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gangs.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gangtool.dm" +#include "modular_citadel\code\game\gamemodes\gangs\implant_gang.dm" #include "modular_citadel\code\game\gamemodes\miniantags\bot_swarm\swarmer_event.dm" #include "modular_citadel\code\game\gamemodes\revolution\revolution.dm" #include "modular_citadel\code\game\machinery\cryopod.dm" @@ -2954,6 +3010,7 @@ #include "modular_citadel\code\modules\projectiles\guns\ballistic\flechette.dm" #include "modular_citadel\code\modules\projectiles\guns\ballistic\handguns.dm" #include "modular_citadel\code\modules\projectiles\guns\ballistic\magweapon.dm" +#include "modular_citadel\code\modules\projectiles\guns\ballistic\magweapon_energy.dm" #include "modular_citadel\code\modules\projectiles\guns\ballistic\revolver.dm" #include "modular_citadel\code\modules\projectiles\guns\ballistic\rifles.dm" #include "modular_citadel\code\modules\projectiles\guns\ballistic\spinfusor.dm" @@ -2967,7 +3024,6 @@ #include "modular_citadel\code\modules\reagents\reagent container\hypovial.dm" #include "modular_citadel\code\modules\reagents\reagents\cit_reagents.dm" #include "modular_citadel\code\modules\recycling\disposal\bin.dm" -#include "modular_citadel\code\modules\research\designs\autolathe_designs.dm" #include "modular_citadel\code\modules\research\designs\autoylathe_designs.dm" #include "modular_citadel\code\modules\research\designs\machine_designs.dm" #include "modular_citadel\code\modules\research\designs\weapon_designs.dm" diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index c6acd732b0..2eef691676 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -16,6 +16,6 @@ a:{label:"Warning"},f:[{p:[46,4,1989],t:7,e:"span",f:["No launchpad found. Link };for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],418:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,1,91],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"home",params:'{"target" : "mod"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==1?"disabled":null'},p:[5,80,170]}]},f:["Access Modification"]}],n:50,r:"data.have_id_slot",p:[4,1,64]},{p:[7,1,253],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manage"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==2?"disabled":null'},p:[7,90,342]}]},f:["Job Management"]}," ",{p:[8,1,411],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manifest"}',state:[{t:2,x:{r:["data.mmode"],s:'!_0?"disabled":null'},p:[8,92,502]}]},f:["Crew Manifest"]}," ",{t:4,f:[{p:[10,1,593],t:7,e:"ui-button",a:{action:"PRG_print",icon:"print",state:[{t:2,x:{r:["data.has_id","data.mmode"],s:'!_1||_0&&_1==1?null:"disabled"'},p:[10,51,643]}]},f:["Print"]}],n:50,r:"data.have_printer",p:[9,1,566]},{t:4,f:[{p:[14,1,766],t:7,e:"div",a:{"class":"item"},f:[{p:[15,3,788],t:7,e:"h2",f:["Crew Manifest"]}," ",{p:[16,3,814],t:7,e:"br"},"Please use security record computer to modify entries.",{p:[16,61,872],t:7,e:"br"},{p:[16,65,876],t:7,e:"br"}]}," ",{t:4,f:[{p:[19,2,916],t:7,e:"div",a:{"class":"item"},f:[{t:2,r:"name",p:[20,2,937]}," - ",{t:2,r:"rank",p:[20,13,948]}]}],n:52,r:"data.manifest",p:[18,1,890]}],n:50,x:{r:["data.mmode"],s:"!_0"},p:[13,1,745]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.mmode"],s:"_0==2"},f:[{p:[25,1,1008],t:7,e:"div",a:{"class":"item"},f:[{p:[26,3,1030],t:7,e:"h2",f:["Job Management"]}]}," ",{p:[28,1,1063],t:7,e:"table",f:[{p:[29,1,1072],t:7,e:"tr",f:[{p:[29,5,1076],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,27,1098],t:7,e:"b",f:["Job"]}]},{p:[29,42,1113],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,64,1135],t:7,e:"b",f:["Slots"]}]},{p:[29,81,1152],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,103,1174],t:7,e:"b",f:["Open job"]}]},{p:[29,123,1194],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,145,1216],t:7,e:"b",f:["Close job"]}]}]}," ",{t:4,f:[{p:[32,2,1269],t:7,e:"tr",f:[{p:[32,6,1273],t:7,e:"td",f:[{t:2,r:"title",p:[32,10,1277]}]},{p:[32,24,1291],t:7,e:"td",f:[{t:2,r:"current",p:[32,28,1295]},"/",{t:2,r:"total",p:[32,40,1307]}]},{p:[32,54,1321],t:7,e:"td",f:[{p:[32,58,1325],t:7,e:"ui-button",a:{action:"PRG_open_job",params:['{"target" : "',{t:2,r:"title",p:[32,112,1379]},'"}'],state:[{t:2,x:{r:["status_open"],s:'_0?null:"disabled"'},p:[32,132,1399]}]},f:[{t:2,r:"desc_open",p:[32,169,1436]}]},{p:[32,194,1461],t:7,e:"br"}]},{p:[32,203,1470],t:7,e:"td",f:[{p:[32,207,1474],t:7,e:"ui-button",a:{action:"PRG_close_job",params:['{"target" : "',{t:2,r:"title",p:[32,262,1529]},'"}'],state:[{t:2,x:{r:["status_close"],s:'_0?null:"disabled"'},p:[32,282,1549]}]},f:[{t:2,r:"desc_close",p:[32,320,1587]}]}]}]}],n:52,r:"data.slots",p:[30,1,1244]}]}]},{t:4,n:50,x:{r:["data.mmode"],s:"!(_0==2)"},f:[" ",{p:[40,1,1665],t:7,e:"div",a:{"class":"item"},f:[{p:[41,3,1687],t:7,e:"h2",f:["Access Modification"]}]}," ",{t:4,f:[{p:[45,3,1751],t:7,e:"span",a:{"class":"alert"},f:[{p:[45,23,1771],t:7,e:"i",f:["Please insert the ID into the terminal to proceed."]}]},{p:[45,87,1835],t:7,e:"br"}],n:50,x:{r:["data.has_id"],s:"!_0"},p:[44,1,1727]},{p:[48,1,1852],t:7,e:"div",a:{"class":"item"},f:[{p:[49,3,1874],t:7,e:"div",a:{"class":"itemLabel"},f:["Target Identity:"]}," ",{p:[52,3,1930],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[53,2,1958],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "id"}'},f:[{t:2,r:"data.id_name",p:[53,72,2028]}]}]}]}," ",{p:[56,1,2076],t:7,e:"div",a:{"class":"item"},f:[{p:[57,3,2098],t:7,e:"div",a:{"class":"itemLabel"},f:["Auth Identity:"]}," ",{p:[60,3,2152],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[61,2,2180],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "auth"}'},f:[{t:2,r:"data.auth_name",p:[61,74,2252]}]}]}]}," ",{p:[64,1,2302],t:7,e:"hr"}," ",{t:4,f:[{t:4,f:[{p:[68,2,2362],t:7,e:"div",a:{"class":"item"},f:[{p:[69,4,2385],t:7,e:"h2",f:["Details"]}]}," ",{t:4,f:[{p:[73,2,2436],t:7,e:"div",a:{"class":"item"},f:[{p:[74,4,2459],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[77,4,2518],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_owner",p:[78,3,2547]}]}]}," ",{p:[81,2,2587],t:7,e:"div",a:{"class":"item"},f:[{p:[82,4,2610],t:7,e:"div",a:{"class":"itemLabel"},f:["Rank:"]}," ",{p:[85,4,2658],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_rank",p:[86,3,2687]}]}]}," ",{p:[89,2,2726],t:7,e:"div",a:{"class":"item"},f:[{p:[90,4,2749],t:7,e:"div",a:{"class":"itemLabel"},f:["Demote:"]}," ",{p:[93,4,2799],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[94,3,2828],t:7,e:"ui-button",a:{action:"PRG_terminate",icon:"gear",state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Unassigned"?"disabled":null'},p:[94,56,2881]}]},f:["Demote ",{t:2,r:"data.id_owner",p:[94,117,2942]}]}]}]}],n:50,r:"data.minor",p:[72,2,2415]},{t:4,n:51,f:[{p:[99,2,3007],t:7,e:"div",a:{"class":"item"},f:[{p:[100,4,3030],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[103,4,3089],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[104,3,3118],t:7,e:"ui-button",a:{action:"PRG_edit",icon:"pencil",params:'{"name" : "1"}'},f:[{t:2,r:"data.id_owner",p:[104,70,3185]}]}]}]}," ",{p:[108,2,3239],t:7,e:"div",a:{"class":"item"},f:[{p:[109,4,3262],t:7,e:"h2",f:["Assignment"]}]}," ",{p:[111,3,3294],t:7,e:"ui-button",a:{action:"PRG_togglea",icon:"gear"},f:[{t:2,x:{r:["data.assignments"],s:'_0?"Hide assignments":"Show assignments"'},p:[111,47,3338]}]}," ",{p:[112,2,3415],t:7,e:"div",a:{"class":"item"},f:[{p:[113,4,3438],t:7,e:"span",a:{id:"allvalue.jobsslot"},f:[]}]}," ",{p:[117,2,3495],t:7,e:"div",a:{"class":"item"},f:[{t:4,f:[{p:[119,4,3547],t:7,e:"div",a:{id:"all-value.jobs"},f:[{p:[120,3,3576],t:7,e:"table",f:[{p:[121,5,3589],t:7,e:"tr",f:[{p:[122,4,3598],t:7,e:"th",f:["Command"]}," ",{p:[123,4,3619],t:7,e:"td",f:[{p:[124,6,3630],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Captain"}',state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Captain"?"selected":null'},p:[124,83,3707]}]},f:["Captain"]}]}]}," ",{p:[127,5,3804],t:7,e:"tr",f:[{p:[128,4,3813],t:7,e:"th",f:["Special"]}," ",{p:[129,4,3834],t:7,e:"td",f:[{p:[130,6,3845],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Custom"}'},f:["Custom"]}]}]}," ",{p:[133,5,3959],t:7,e:"tr",f:[{p:[134,4,3968],t:7,e:"th",a:{style:"color: '#FFA500';"},f:["Engineering"]}," ",{p:[135,4,4019],t:7,e:"td",f:[{t:4,f:[{p:[137,5,4067],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[137,64,4126]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[137,82,4144]}]},f:[{t:2,r:"display_name",p:[137,127,4189]}]}],n:52,r:"data.engineering_jobs",p:[136,6,4030]}]}]}," ",{p:[141,5,4260],t:7,e:"tr",f:[{p:[142,4,4269],t:7,e:"th",a:{style:"color: '#008000';"},f:["Medical"]}," ",{p:[143,4,4316],t:7,e:"td",f:[{t:4,f:[{p:[145,5,4360],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[145,64,4419]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[145,82,4437]}]},f:[{t:2,r:"display_name",p:[145,127,4482]}]}],n:52,r:"data.medical_jobs",p:[144,6,4327]}]}]}," ",{p:[149,5,4553],t:7,e:"tr",f:[{p:[150,4,4562],t:7,e:"th",a:{style:"color: '#800080';"},f:["Science"]}," ",{p:[151,4,4609],t:7,e:"td",f:[{t:4,f:[{p:[153,5,4653],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[153,64,4712]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[153,82,4730]}]},f:[{t:2,r:"display_name",p:[153,127,4775]}]}],n:52,r:"data.science_jobs",p:[152,6,4620]}]}]}," ",{p:[157,5,4846],t:7,e:"tr",f:[{p:[158,4,4855],t:7,e:"th",a:{style:"color: '#DD0000';"},f:["Security"]}," ",{p:[159,4,4903],t:7,e:"td",f:[{t:4,f:[{p:[161,5,4948],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[161,64,5007]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[161,82,5025]}]},f:[{t:2,r:"display_name",p:[161,127,5070]}]}],n:52,r:"data.security_jobs",p:[160,6,4914]}]}]}," ",{p:[165,5,5141],t:7,e:"tr",f:[{p:[166,4,5150],t:7,e:"th",a:{style:"color: '#cc6600';"},f:["Cargo"]}," ",{p:[167,4,5195],t:7,e:"td",f:[{t:4,f:[{p:[169,5,5237],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[169,64,5296]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[169,82,5314]}]},f:[{t:2,r:"display_name",p:[169,127,5359]}]}],n:52,r:"data.cargo_jobs",p:[168,6,5206]}]}]}," ",{p:[173,5,5430],t:7,e:"tr",f:[{p:[174,4,5439],t:7,e:"th",a:{style:"color: '#808080';"},f:["Civilian"]}," ",{p:[175,4,5487],t:7,e:"td",f:[{t:4,f:[{p:[177,5,5532],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[177,64,5591]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[177,82,5609]}]},f:[{t:2,r:"display_name",p:[177,127,5654]}]}],n:52,r:"data.civilian_jobs",p:[176,6,5498]}]}]}," ",{t:4,f:[{p:[182,4,5757],t:7,e:"tr",f:[{p:[183,6,5768],t:7,e:"th",a:{style:"color: '#A52A2A';"},f:["CentCom"]}," ",{p:[184,6,5817],t:7,e:"td",f:[{t:4,f:[{p:[186,7,5862],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[186,66,5921]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[186,84,5939]}]},f:[{t:2,r:"display_name",p:[186,129,5984]}]}],n:52,r:"data.centcom_jobs",p:[185,5,5827]}]}]}],n:50,r:"data.centcom_access",p:[181,5,5725]}]}]}],n:50,r:"data.assignments",p:[118,4,3518]}]}],r:"data.minor"}," ",{t:4,f:[{p:[198,4,6153],t:7,e:"div",a:{"class":"item"},f:[{p:[199,3,6175],t:7,e:"h2",f:["Central Command"]}]}," ",{p:[201,4,6215],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[203,5,6296],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[204,5,6331],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[204,64,6390]},'", "allowed" : "',{t:2,r:"allowed",p:[204,87,6413]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[204,109,6435]}]},f:[{t:2,r:"desc",p:[204,140,6466]}]}]}],n:52,r:"data.all_centcom_access",p:[202,3,6257]}]}],n:50,r:"data.centcom_access",p:[197,2,6121]},{t:4,n:51,f:[{p:[209,4,6538],t:7,e:"div",a:{"class":"item"},f:[{p:[210,3,6560],t:7,e:"h2",f:[{t:2,r:"data.station_name",p:[210,7,6564]}]}]}," ",{p:[212,4,6606],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[214,5,6676],t:7,e:"div",a:{style:"float: left; width: 175px; min-height: 250px"},f:[{p:[215,4,6739],t:7,e:"div",a:{"class":"average"},f:[{p:[215,25,6760],t:7,e:"ui-button",a:{action:"PRG_regsel",state:[{t:2,x:{r:["selected"],s:'_0?"toggle":null'},p:[215,63,6798]}],params:['{"region" : "',{t:2,r:"regid",p:[215,116,6851]},'"}']},f:[{p:[215,129,6864],t:7,e:"b",f:[{t:2,r:"name",p:[215,132,6867]}]}]}]}," ",{p:[216,4,6902],t:7,e:"br"}," ",{t:4,f:[{p:[218,6,6938],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[219,5,6973],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[219,64,7032]},'", "allowed" : "',{t:2,r:"allowed",p:[219,87,7055]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[219,109,7077]}]},f:[{t:2,r:"desc",p:[219,140,7108]}]}]}],n:52,r:"accesses",p:[217,6,6913]}]}],n:52,r:"data.regions",p:[213,3,6648]}]}],r:"data.centcom_access"}],n:50,r:"data.has_id",p:[67,3,2340]}],n:50,r:"data.authenticated",p:[66,1,2310]}]}],x:{r:["data.mmode"],s:"!_0"}}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],419:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{chargeState:function(t){var e=this.get("data.battery.max");return t>e/2?"good":t>e/4?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,311],t:7,e:"ntosheader"}," ",{p:[17,1,328],t:7,e:"ui-display",f:[{p:[18,2,343],t:7,e:"i",f:["Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device."]},{p:[18,137,478],t:7,e:"hr"}," ",{p:[19,2,485],t:7,e:"ui-display",a:{title:"Power Supply"},f:[{p:[20,3,522],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"data.power_usage",p:[21,4,559]},"W"]}," ",{t:4,f:[{p:[25,4,630],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Active"]}," ",{p:[28,4,701],t:7,e:"ui-section",a:{label:"Battery Rating"},f:[{t:2,r:"data.battery.max",p:[29,5,742]}]}," ",{p:[31,4,785],t:7,e:"ui-section",a:{label:"Battery Charge"},f:[{p:[32,5,826],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.battery.max",p:[32,26,847]}],value:[{t:2,r:"adata.battery.charge",p:[32,56,877]}],state:[{t:2,x:{r:["chargeState","adata.battery.charge"],s:"_0(_1)"},p:[32,89,910]}]},f:[{t:2,x:{r:["adata.battery.charge"],s:"Math.round(_0)"},p:[32,128,949]},"/",{t:2,r:"adata.battery.max",p:[32,165,986]}]}]}],n:50,r:"data.battery",p:[24,3,605]},{t:4,n:51,f:[{p:[35,4,1051],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Not Available"]}],r:"data.battery"}]}," ",{p:[41,2,1156],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,3,1192],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,4,1231],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,25,1252]}],value:[{t:2,r:"adata.disk_used",p:[43,53,1280]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,87,1314]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,123,1350]},"GQ"]}]}]}," ",{p:[47,2,1419],t:7,e:"ui-display",a:{title:"Computer Components"},f:[{t:4,f:[{p:[49,4,1491],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[49,26,1513]}]},f:[{p:[50,5,1529],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"desc",p:[50,59,1583]}]}," ",{p:[52,5,1605],t:7,e:"ui-section",a:{label:"State"},f:[{p:[53,6,1638],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["critical"],s:'_0?"disabled":null'},p:[53,24,1656]}],action:"PC_toggle_component",params:['{"name": "',{t:2,r:"name",p:[53,105,1737]},'"}']},f:[{t:2,x:{r:["enabled"],s:'_0?"Enabled":"Disabled"'},p:[54,7,1757]}]}]}," ",{t:4,f:[{p:[59,6,1868],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"powerusage",p:[60,7,1908]},"W"]}],n:50,r:"powerusage",p:[58,5,1843]}]}," ",{p:[64,4,1985],t:7,e:"br"}],n:52,r:"data.hardware",p:[48,3,1463]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],420:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,3,103],t:7,e:"h2",f:["An error has occurred and this program can not continue."]}," Additional information: ",{t:2,r:"data.error",p:[8,27,196]},{p:[8,41,210],t:7,e:"br"}," ",{p:[9,3,218],t:7,e:"i",f:["Please try again. If the problem persists contact your system administrator for assistance."]}," ",{p:[10,3,320],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["Restart program"]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,f:[{p:[13,4,422],t:7,e:"h2",f:["Viewing file ",{t:2,r:"data.filename",p:[13,21,439]}]}," ",{p:[14,4,466],t:7,e:"div",a:{"class":"item"},f:[{p:[15,4,489],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["CLOSE"]}," ",{p:[16,4,545],t:7,e:"ui-button",a:{action:"PRG_edit"},f:["EDIT"]}," ",{p:[17,4,595],t:7,e:"ui-button",a:{action:"PRG_printfile"},f:["PRINT"]}," "]},{p:[18,10,657],t:7,e:"hr"}," ",{t:3,r:"data.filedata",p:[19,4,666]}],n:50,r:"data.filename",p:[12,3,396]},{t:4,n:51,f:[{p:[21,4,702],t:7,e:"h2",f:["Available files (local):"]}," ",{p:[22,4,740],t:7,e:"table",f:[{p:[23,5,753],t:7,e:"tr",f:[{p:[24,6,764],t:7,e:"th",f:["File name"]}," ",{p:[25,6,789],t:7,e:"th",f:["File type"]}," ",{p:[26,6,814],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[27,6,844],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[30,6,907],t:7,e:"tr",f:[{p:[31,7,919],t:7,e:"td",f:[{t:2,r:"name",p:[31,11,923]}]}," ",{p:[32,7,944],t:7,e:"td",f:[".",{t:2,r:"type",p:[32,12,949]}]}," ",{p:[33,7,970],t:7,e:"td",f:[{t:2,r:"size",p:[33,11,974]},"GQ"]}," ",{p:[34,7,997],t:7,e:"td",f:[{p:[35,8,1010],t:7,e:"ui-button",a:{action:"PRG_openfile",params:['{"name": "',{t:2,r:"name",p:[35,59,1061]},'"}']},f:["VIEW"]}," ",{p:[36,8,1098],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[36,26,1116]}],action:"PRG_deletefile",params:['{"name": "',{t:2,r:"name",p:[36,105,1195]},'"}']},f:["DELETE"]}," ",{p:[37,8,1234],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[37,26,1252]}],action:"PRG_rename",params:['{"name": "',{t:2,r:"name",p:[37,101,1327]},'"}']},f:["RENAME"]}," ",{p:[38,8,1366],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[38,26,1384]}],action:"PRG_clone",params:['{"name": "',{t:2,r:"name",p:[38,100,1458]},'"}']},f:["CLONE"]}," ",{t:4,f:[{p:[40,9,1531],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[40,27,1549]}],action:"PRG_copytousb",params:['{"name": "',{t:2,r:"name",p:[40,105,1627]},'"}']},f:["EXPORT"]}],n:50,r:"data.usbconnected",p:[39,8,1496]}]}]}],n:52,r:"data.files",p:[29,5,880]}]}," ",{t:4,f:[{p:[47,4,1761],t:7,e:"h2",f:["Available files (portable device):"]}," ",{p:[48,4,1809],t:7,e:"table",f:[{p:[49,5,1822],t:7,e:"tr",f:[{p:[50,6,1833],t:7,e:"th",f:["File name"]}," ",{p:[51,6,1858],t:7,e:"th",f:["File type"]}," ",{p:[52,6,1883],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[53,6,1913],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[56,6,1979],t:7,e:"tr",f:[{p:[57,7,1991],t:7,e:"td",f:[{t:2,r:"name",p:[57,11,1995]}]}," ",{p:[58,7,2016],t:7,e:"td",f:[".",{t:2,r:"type",p:[58,12,2021]}]}," ",{p:[59,7,2042],t:7,e:"td",f:[{t:2,r:"size",p:[59,11,2046]},"GQ"]}," ",{p:[60,7,2069],t:7,e:"td",f:[{p:[61,8,2082],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[61,26,2100]}],action:"PRG_usbdeletefile",params:['{"name": "',{t:2,r:"name",p:[61,108,2182]},'"}']},f:["DELETE"]}," ",{t:4,f:[{p:[63,9,2256],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[63,27,2274]}],action:"PRG_copyfromusb",params:['{"name": "',{t:2,r:"name",p:[63,107,2354]},'"}']},f:["IMPORT"]}],n:50,r:"data.usbconnected",p:[62,8,2221]}]}]}],n:52,r:"data.usbfiles",p:[55,5,1949]}]}],n:50,r:"data.usbconnected",p:[46,4,1731]}," ",{p:[70,4,2470],t:7,e:"ui-button",a:{action:"PRG_newtextfile"},f:["NEW DATA FILE"]}],r:"data.filename"}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],421:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["No program loaded. Please select program from list below."]}," ",{p:[6,2,146],t:7,e:"table",f:[{t:4,f:[{p:[8,4,185],t:7,e:"tr",f:[{p:[8,8,189],t:7,e:"td",f:[{p:[8,12,193],t:7,e:"ui-button",a:{action:"PC_runprogram",params:['{"name": "',{t:2,r:"name",p:[8,64,245]},'"}']},f:[{t:2,r:"desc",p:[9,5,263]}]}]},{p:[11,4,293],t:7,e:"td",f:[{p:[11,8,297],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["running"],s:'_0?null:"disabled"'},p:[11,26,315]}],icon:"close",action:"PC_killprogram",params:['{"name": "',{t:2,r:"name",p:[11,114,403]},'"}']}}]}]}],n:52,r:"data.programs",p:[7,3,157]}]}," ",{p:[14,2,454],t:7,e:"br"},{p:[14,6,458],t:7,e:"br"}," ",{t:4,f:[{p:[16,3,491],t:7,e:"ui-button",a:{action:"PC_toggle_light",style:[{t:2,x:{r:["data.light_on"],s:'_0?"selected":null'},p:[16,46,534]}]},f:["Toggle Flashlight"]},{p:[16,114,602],t:7,e:"br"}," ",{p:[17,3,610],t:7,e:"ui-button",a:{action:"PC_light_color"},f:["Change Flashlight Color ",{p:[17,62,669],t:7,e:"span",a:{style:["border:1px solid #161616; background-color: ",{t:2,r:"data.comp_light_color",p:[17,119,726]},";"]},f:["   "]}]}],n:50,r:"data.has_light",p:[15,2,465]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],422:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[6,3,105],t:7,e:"h1",f:["ADMINISTRATIVE MODE"]}],n:50,r:"data.adminmode",p:[5,2,79]}," ",{t:4,f:[{p:[10,3,170],t:7,e:"div",a:{"class":"itemLabel"},f:["Current channel:"]}," ",{p:[13,3,229],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.title",p:[14,4,259]}]}," ",{p:[16,3,287],t:7,e:"div",a:{"class":"itemLabel"},f:["Operator access:"]}," ",{p:[19,3,346],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:[{p:[21,5,406],t:7,e:"b",f:["Enabled"]}],n:50,r:"data.is_operator",p:[20,4,376]},{t:4,n:51,f:[{p:[23,5,439],t:7,e:"b",f:["Disabled"]}],r:"data.is_operator"}]}," ",{p:[26,3,480],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[29,3,532],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[30,4,562],t:7,e:"table",f:[{p:[31,5,575],t:7,e:"tr",f:[{p:[31,9,579],t:7,e:"td",f:[{p:[31,13,583],t:7,e:"ui-button",a:{action:"PRG_speak"},f:["Send message"]}]}]},{p:[32,5,643],t:7,e:"tr",f:[{p:[32,9,647],t:7,e:"td",f:[{p:[32,13,651],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[33,5,719],t:7,e:"tr",f:[{p:[33,9,723],t:7,e:"td",f:[{p:[33,13,727],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]},{p:[34,5,807],t:7,e:"tr",f:[{p:[34,9,811],t:7,e:"td",f:[{p:[34,13,815],t:7,e:"ui-button",a:{action:"PRG_leavechannel"},f:["Leave channel"]}]}]},{p:[35,5,883],t:7,e:"tr",f:[{p:[35,9,887],t:7,e:"td",f:[{p:[35,13,891],t:7,e:"ui-button",a:{action:"PRG_savelog"},f:["Save log to local drive"]}," ",{t:4,f:[{p:[37,6,995],t:7,e:"tr",f:[{p:[37,10,999],t:7,e:"td",f:[{p:[37,14,1003],t:7,e:"ui-button",a:{action:"PRG_renamechannel"},f:["Rename channel"]}]}]},{p:[38,6,1074],t:7,e:"tr",f:[{p:[38,10,1078],t:7,e:"td",f:[{p:[38,14,1082],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}]}]},{p:[39,6,1149],t:7,e:"tr",f:[{p:[39,10,1153],t:7,e:"td",f:[{p:[39,14,1157],t:7,e:"ui-button",a:{action:"PRG_deletechannel"},f:["Delete channel"]}]}]}],n:50,r:"data.is_operator",p:[36,5,964]}]}]}]}]}," ",{p:[43,3,1263],t:7,e:"b",f:["Chat Window"]}," ",{p:[44,4,1286],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[45,4,1342],t:7,e:"div",a:{"class":"item"},f:[{p:[46,5,1366],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"msg",p:[48,7,1450]},{p:[48,14,1457],t:7,e:"br"}],n:52,r:"data.messages",p:[47,6,1419]}]}]}]}," ",{p:[53,3,1516],t:7,e:"b",f:["Connected Users"]},{p:[53,25,1538],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"name",p:[55,4,1573]},{p:[55,12,1581],t:7,e:"br"}],n:52,r:"data.clients",p:[54,3,1546]}],n:50,r:"data.title",p:[9,2,148]},{t:4,n:51,f:[{p:[58,3,1613],t:7,e:"b",f:["Controls:"]}," ",{p:[59,3,1633],t:7,e:"table",f:[{p:[60,4,1645],t:7,e:"tr",f:[{p:[60,8,1649],t:7,e:"td",f:[{p:[60,12,1653],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[61,4,1720],t:7,e:"tr",f:[{p:[61,8,1724],t:7,e:"td",f:[{p:[61,12,1728],t:7,e:"ui-button",a:{action:"PRG_newchannel"},f:["New Channel"]}]}]},{p:[62,4,1791],t:7,e:"tr",f:[{p:[62,8,1795],t:7,e:"td",f:[{p:[62,12,1799],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]}]}," ",{p:[64,3,1889],t:7,e:"b",f:["Available channels:"]}," ",{p:[65,3,1919],t:7,e:"table",f:[{t:4,f:[{p:[67,4,1964],t:7,e:"tr",f:[{p:[67,8,1968],t:7,e:"td",f:[{p:[67,12,1972],t:7,e:"ui-button",a:{action:"PRG_joinchannel",params:['{"id": "',{t:2,r:"id",p:[67,64,2024]},'"}']},f:[{t:2,r:"chan",p:[67,74,2034]}]},{p:[67,94,2054],t:7,e:"br"}]}]}],n:52,r:"data.all_channels",p:[66,3,1930]}]}],r:"data.title"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],423:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:["##SYSTEM ERROR: ",{t:2,r:"data.error",p:[6,19,117]},{p:[6,33,131],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["RESET"]}],n:50,r:"data.error",p:[5,2,79]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.target"],s:"_0"},f:["##DoS traffic generator active. Tx: ",{t:2,r:"data.speed",p:[8,39,243]},"GQ/s",{p:[8,57,261],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"nums",p:[10,4,300]},{p:[10,12,308],t:7,e:"br"}],n:52,r:"data.dos_strings",p:[9,3,269]}," ",{p:[12,3,329],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["ABORT"]}]},{t:4,n:50,x:{r:["data.target"],s:"!(_0)"},f:[" ##DoS traffic generator ready. Select target device.",{p:[14,55,443],t:7,e:"br"}," ",{t:4,f:["Targeted device ID: ",{t:2,r:"data.focus",p:[16,24,494]}],n:50,r:"data.focus",p:[15,3,451]},{t:4,n:51,f:["Targeted device ID: None"],r:"data.focus"}," ",{p:[20,3,564],t:7,e:"ui-button",a:{action:"PRG_execute"},f:["EXECUTE"]},{p:[20,54,615],t:7,e:"div",a:{style:"clear:both"}}," Detected devices on network:",{p:[21,31,677],t:7,e:"br"}," ",{t:4,f:[{p:[23,4,711],t:7,e:"ui-button",a:{action:"PRG_target_relay",params:['{"targid": "',{t:2,r:"id",p:[23,61,768]},'"}']},f:[{t:2,r:"id",p:[23,71,778]}]}],n:52,r:"data.relays",p:[22,3,685]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],424:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["Welcome to software download utility. Please select which software you wish to download."]},{p:[5,97,174],t:7,e:"hr"}," ",{t:4,f:[{p:[7,3,203],t:7,e:"ui-display",a:{title:"Download Error"},f:[{p:[8,4,243],t:7,e:"ui-section",a:{label:"Information"},f:[{t:2,r:"data.error",p:[9,5,281]}]}," ",{p:[11,4,318],t:7,e:"ui-section",a:{label:"Reset Program"},f:[{p:[12,5,358],t:7,e:"ui-button",a:{icon:"times",action:"PRG_reseterror"},f:["RESET"]}]}]}],n:50,r:"data.error",p:[6,2,181]},{t:4,n:51,f:[{t:4,f:[{p:[19,4,516],t:7,e:"ui-display",a:{title:"Download Running"},f:[{p:[20,5,559],t:7,e:"i",f:["Please wait..."]}," ",{p:[21,5,586],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"data.downloadname",p:[22,6,623]}]}," ",{p:[24,5,669],t:7,e:"ui-section",a:{label:"File description"},f:[{t:2,r:"data.downloaddesc",p:[25,6,713]}]}," ",{p:[27,5,759],t:7,e:"ui-section",a:{label:"File size"},f:[{t:2,r:"data.downloadsize",p:[28,6,796]},"GQ"]}," ",{p:[30,5,844],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{t:2,r:"data.downloadspeed",p:[31,6,885]}," GQ/s"]}," ",{p:[33,5,937],t:7,e:"ui-section",a:{label:"Download progress"},f:[{p:[34,6,982],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.downloadsize",p:[34,27,1003]}],value:[{t:2,r:"adata.downloadcompletion",p:[34,58,1034]}],state:"good"},f:[{t:2,x:{r:["adata.downloadcompletion"],s:"Math.round(_0)"},p:[34,101,1077]},"GQ / ",{t:2,r:"adata.downloadsize",p:[34,146,1122]},"GQ"]}]}]}],n:50,r:"data.downloadname",p:[18,3,486]}],r:"data.error"}," ",{t:4,f:[{t:4,f:[{p:[41,4,1270],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,5,1308],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,6,1349],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,27,1370]}],value:[{t:2,r:"adata.disk_used",p:[43,55,1398]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,89,1432]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,125,1468]},"GQ"]}]}]}," ",{p:[47,4,1545],t:7,e:"ui-display",a:{title:"Primary Software Repository"},f:[{t:4,f:[{p:[49,6,1642],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[49,28,1664]}]},f:[{p:[50,7,1686],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[50,61,1740]}]}," ",{p:[52,7,1774],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[53,8,1813]}," (",{t:2,r:"size",p:[53,22,1827]}," GQ)"]}," ",{p:[55,7,1868],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[56,8,1911]}]}," ",{p:[58,7,1957],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[58,80,2030]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[62,6,2113],t:7,e:"br"}],n:52,r:"data.downloadable_programs",p:[48,5,1599]}]}," ",{t:4,f:[{p:[67,5,2194],t:7,e:"ui-display",a:{title:"UNKNOWN Software Repository"},f:[{p:[68,6,2249],t:7,e:"i",f:["Please note that Nanotrasen does not recommend download of software from non-official servers."]}," ",{t:4,f:[{p:[70,7,2395],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[70,29,2417]}]},f:[{p:[71,8,2440],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[71,62,2494]}]}," ",{p:[73,8,2530],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[74,9,2570]}," (",{t:2,r:"size",p:[74,23,2584]}," GQ)"]}," ",{p:[76,8,2627],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[77,9,2671]}]}," ",{p:[79,8,2719],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[79,81,2792]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[83,7,2879],t:7,e:"br"}],n:52,r:"data.hacked_programs",p:[69,6,2357]}]}],n:50,r:"data.hackedavailable",p:[66,4,2160]}],n:50,x:{r:["data.error"],s:"!_0"},p:[40,3,1246]}],n:50,x:{r:["data.downloadname"],s:"!_0"},p:[39,2,1216]}," ",{p:[89,2,2954],t:7,e:"br"},{p:[89,6,2958],t:7,e:"br"},{p:[89,10,2962],t:7,e:"hr"},{p:[89,14,2966],t:7,e:"i",f:["NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559"]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],425:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[6,2,81],t:7,e:"ui-display",a:{title:"WIRELESS CONNECTIVITY"},f:[{p:[8,3,129],t:7,e:"ui-section",a:{label:"Active NTNetRelays"},f:[{p:[9,4,173],t:7,e:"b",f:[{t:2,r:"data.ntnetrelays",p:[9,7,176]}]}]}," ",{t:4,f:[{p:[12,4,250],t:7,e:"ui-section",a:{label:"System status"},f:[{p:[13,6,291],t:7,e:"b",f:[{t:2,x:{r:["data.ntnetstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[13,9,294]}]}]}," ",{p:[15,4,366],t:7,e:"ui-section",a:{label:"Control"},f:[{p:[17,4,401],t:7,e:"ui-button",a:{icon:"plus",action:"toggleWireless"},f:["TOGGLE"]}]}," ",{p:[21,4,500],t:7,e:"br"},{p:[21,8,504],t:7,e:"br"}," ",{p:[22,4,513],t:7,e:"i",f:["Caution - Disabling wireless transmitters when using wireless device may prevent you from re-enabling them again!"]}],n:50,r:"data.ntnetrelays",p:[11,3,221]},{t:4,n:51,f:[{p:[24,4,650],t:7,e:"br"},{p:[24,8,654],t:7,e:"p",f:["Wireless coverage unavailable, no relays are connected."]}],r:"data.ntnetrelays"}]}," ",{p:[29,2,750],t:7,e:"ui-display",a:{title:"FIREWALL CONFIGURATION"},f:[{p:[31,2,798],t:7,e:"table",f:[{p:[32,3,809],t:7,e:"tr",f:[{p:[33,4,818],t:7,e:"th",f:["PROTOCOL"]},{p:[34,4,835],t:7,e:"th",f:["STATUS"]},{p:[35,4,850],t:7,e:"th",f:["CONTROL"]}]},{p:[36,3,865],t:7,e:"tr",f:[" ",{p:[37,4,874],t:7,e:"td",f:["Software Downloads"]},{p:[38,4,901],t:7,e:"td",f:[{t:2,x:{r:["data.config_softwaredownload"],s:'_0?"ENABLED":"DISABLED"'},p:[38,8,905]}]},{p:[39,4,967],t:7,e:"td",f:[" ",{p:[39,9,972],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "1"}'},f:["TOGGLE"]}]}]},{p:[40,3,1051],t:7,e:"tr",f:[" ",{p:[41,4,1060],t:7,e:"td",f:["Peer to Peer Traffic"]},{p:[42,4,1089],t:7,e:"td",f:[{t:2,x:{r:["data.config_peertopeer"],s:'_0?"ENABLED":"DISABLED"'},p:[42,8,1093]}]},{p:[43,4,1149],t:7,e:"td",f:[{p:[43,8,1153], t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "2"}'},f:["TOGGLE"]}]}]},{p:[44,3,1232],t:7,e:"tr",f:[" ",{p:[45,4,1241],t:7,e:"td",f:["Communication Systems"]},{p:[46,4,1271],t:7,e:"td",f:[{t:2,x:{r:["data.config_communication"],s:'_0?"ENABLED":"DISABLED"'},p:[46,8,1275]}]},{p:[47,4,1334],t:7,e:"td",f:[{p:[47,8,1338],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "3"}'},f:["TOGGLE"]}]}]},{p:[48,3,1417],t:7,e:"tr",f:[" ",{p:[49,4,1426],t:7,e:"td",f:["Remote System Control"]},{p:[50,4,1456],t:7,e:"td",f:[{t:2,x:{r:["data.config_systemcontrol"],s:'_0?"ENABLED":"DISABLED"'},p:[50,8,1460]}]},{p:[51,4,1519],t:7,e:"td",f:[{p:[51,8,1523],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "4"}'},f:["TOGGLE"]}]}]}]}]}," ",{p:[55,2,1630],t:7,e:"ui-display",a:{title:"SECURITY SYSTEMS"},f:[{t:4,f:[{p:[58,4,1699],t:7,e:"ui-notice",f:[{p:[59,5,1716],t:7,e:"h1",f:["NETWORK INCURSION DETECTED"]}]}," ",{p:[61,5,1774],t:7,e:"i",f:["An abnormal activity has been detected in the network. Please verify system logs for more information"]}],n:50,r:"data.idsalarm",p:[57,3,1673]}," ",{p:[64,3,1902],t:7,e:"ui-section",a:{label:"Intrusion Detection System"},f:[{p:[65,4,1954],t:7,e:"b",f:[{t:2,x:{r:["data.idsstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[65,7,1957]}]}]}," ",{p:[68,3,2029],t:7,e:"ui-section",a:{label:"Maximal Log Count"},f:[{p:[69,4,2072],t:7,e:"b",f:[{t:2,r:"data.ntnetmaxlogs",p:[69,7,2075]}]}]}," ",{p:[72,3,2125],t:7,e:"ui-section",a:{label:"Controls"},f:[]}," ",{p:[74,4,2176],t:7,e:"table",f:[{p:[75,4,2188],t:7,e:"tr",f:[{p:[75,8,2192],t:7,e:"td",f:[{p:[75,12,2196],t:7,e:"ui-button",a:{action:"resetIDS"},f:["RESET IDS"]}]}]},{p:[76,4,2251],t:7,e:"tr",f:[{p:[76,8,2255],t:7,e:"td",f:[{p:[76,12,2259],t:7,e:"ui-button",a:{action:"toggleIDS"},f:["TOGGLE IDS"]}]}]},{p:[77,4,2316],t:7,e:"tr",f:[{p:[77,8,2320],t:7,e:"td",f:[{p:[77,12,2324],t:7,e:"ui-button",a:{action:"updatemaxlogs"},f:["SET LOG LIMIT"]}]}]},{p:[78,4,2388],t:7,e:"tr",f:[{p:[78,8,2392],t:7,e:"td",f:[{p:[78,12,2396],t:7,e:"ui-button",a:{action:"purgelogs"},f:["PURGE LOGS"]}]}]}]}," ",{p:[81,3,2467],t:7,e:"ui-subdisplay",a:{title:"System Logs"},f:[{p:[82,3,2506],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[83,3,2561],t:7,e:"div",a:{"class":"item"},f:[{p:[84,4,2584],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"entry",p:[86,6,2667]},{p:[86,15,2676],t:7,e:"br"}],n:52,r:"data.ntnetlogs",p:[85,5,2636]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],426:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,2,102],t:7,e:"div",a:{"class":"item"},f:[{p:[8,3,124],t:7,e:"h2",f:["An error has occurred during operation..."]}," ",{p:[9,3,178],t:7,e:"b",f:["Additional information:"]},{t:2,r:"data.error",p:[9,34,209]},{p:[9,48,223],t:7,e:"br"}," ",{p:[10,3,231],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Clear"]}]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.downloading"],s:"_0"},f:[{p:[13,3,321],t:7,e:"h2",f:["Download in progress..."]}," ",{p:[14,3,357],t:7,e:"div",a:{"class":"itemLabel"},f:["Downloaded file:"]}," ",{p:[17,3,416],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_name",p:[18,4,446]}]}," ",{p:[20,3,483],t:7,e:"div",a:{"class":"itemLabel"},f:["Download progress:"]}," ",{p:[23,3,544],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_progress",p:[24,4,574]}," / ",{t:2,r:"data.download_size",p:[24,33,603]}," GQ"]}," ",{p:[26,3,642],t:7,e:"div",a:{"class":"itemLabel"},f:["Transfer speed:"]}," ",{p:[29,3,700],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_netspeed",p:[30,4,730]},"GQ/s"]}," ",{p:[32,3,774],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[35,3,826],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[36,4,856],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Abort download"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading"],s:"(!(_0))&&(_1)"},f:[" ",{p:[39,3,954],t:7,e:"h2",f:["Server enabled"]}," ",{p:[40,3,981],t:7,e:"div",a:{"class":"itemLabel"},f:["Connected clients:"]}," ",{p:[43,3,1042],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_clients",p:[44,4,1072]}]}," ",{p:[46,3,1109],t:7,e:"div",a:{"class":"itemLabel"},f:["Provided file:"]}," ",{p:[49,3,1166],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_filename",p:[50,4,1196]}]}," ",{p:[52,3,1234],t:7,e:"div",a:{"class":"itemLabel"},f:["Server password:"]}," ",{p:[55,3,1293],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ENABLED"],n:50,r:"data.upload_haspassword",p:[56,4,1323]},{t:4,n:51,f:["DISABLED"],r:"data.upload_haspassword"}]}," ",{p:[62,3,1420],t:7,e:"div",a:{"class":"itemLabel"},f:["Commands:"]}," ",{p:[65,3,1472],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[66,4,1502],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[67,4,1567],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Exit server"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(_2))"},f:[" ",{p:[70,3,1668],t:7,e:"h2",f:["File transfer server ready. Select file to upload:"]}," ",{p:[71,3,1732],t:7,e:"table",f:[{p:[72,3,1743],t:7,e:"tr",f:[{p:[72,7,1747],t:7,e:"th",f:["File name"]},{p:[72,20,1760],t:7,e:"th",f:["File size"]},{p:[72,33,1773],t:7,e:"th",f:["Controls ",{t:4,f:[{p:[74,4,1824],t:7,e:"tr",f:[{p:[74,8,1828],t:7,e:"td",f:[{t:2,r:"filename",p:[74,12,1832]}]},{p:[75,4,1849],t:7,e:"td",f:[{t:2,r:"size",p:[75,8,1853]},"GQ"]},{p:[76,4,1868],t:7,e:"td",f:[{p:[76,8,1872],t:7,e:"ui-button",a:{action:"PRG_uploadfile",params:['{"id": "',{t:2,r:"uid",p:[76,59,1923]},'"}']},f:["Select"]}]}]}],n:52,r:"data.upload_filelist",p:[73,3,1789]}]}]}]}," ",{p:[79,3,1981],t:7,e:"hr"}," ",{p:[80,3,1989],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[81,3,2053],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Return"]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(!(_2)))"},f:[" ",{p:[83,3,2116],t:7,e:"h2",f:["Available files:"]}," ",{p:[84,3,2145],t:7,e:"table",a:{border:"1",style:"border-collapse: collapse"},f:[{p:[84,55,2197],t:7,e:"tr",f:[{p:[84,59,2201],t:7,e:"th",f:["Server UID"]},{p:[84,73,2215],t:7,e:"th",f:["File Name"]},{p:[84,86,2228],t:7,e:"th",f:["File Size"]},{p:[84,99,2241],t:7,e:"th",f:["Password Protection"]},{p:[84,122,2264],t:7,e:"th",f:["Operations ",{t:4,f:[{p:[86,5,2311],t:7,e:"tr",f:[{p:[86,9,2315],t:7,e:"td",f:[{t:2,r:"uid",p:[86,13,2319]}]},{p:[87,5,2332],t:7,e:"td",f:[{t:2,r:"filename",p:[87,9,2336]}]},{p:[88,5,2354],t:7,e:"td",f:[{t:2,r:"size",p:[88,9,2358]},"GQ ",{t:4,f:[{p:[90,6,2400],t:7,e:"td",f:["Enabled"]}],n:50,r:"haspassword",p:[89,5,2374]}," ",{t:4,f:[{p:[93,6,2457],t:7,e:"td",f:["Disabled"]}],n:50,x:{r:["haspassword"],s:"!_0"},p:[92,5,2430]}]},{p:[96,5,2494],t:7,e:"td",f:[{p:[96,9,2498],t:7,e:"ui-button",a:{action:"PRG_downloadfile",params:['{"id": "',{t:2,r:"uid",p:[96,62,2551]},'"}']},f:["Download"]}]}]}],n:52,r:"data.servers",p:[85,4,2283]}]}]}]}," ",{p:[99,3,2612],t:7,e:"hr"}," ",{p:[100,3,2620],t:7,e:"ui-button",a:{action:"PRG_uploadmenu"},f:["Send file"]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],427:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[43,1,1082],t:7,e:"ntosheader"}," ",{p:[45,1,1099],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[47,5,1157],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[47,27,1179]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[49,38,1331]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[50,15,1387]}],yinc:"9"}}],n:50,r:"config.fancy",p:[46,3,1131]},{t:4,n:51,f:[{p:[52,5,1437],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[53,7,1475],t:7,e:"span",f:[{t:2,r:"data.supply",p:[53,13,1481]}]}]}," ",{p:[55,5,1528],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[56,9,1563],t:7,e:"span",f:[{t:2,r:"data.demand",p:[56,15,1569]}]}]}],r:"config.fancy"}]}," ",{p:[60,1,1638],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[61,3,1668],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[62,5,1693],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[63,5,1730],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[64,5,1769],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[65,5,1806],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[66,5,1845],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[67,5,1887],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[68,5,1928],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[71,5,2013],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[71,24,2032]}],nowrap:0},f:[{p:[72,7,2057],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[72,28,2078]}," %"]}," ",{p:[73,7,2136],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[73,28,2157]}]}," ",{p:[74,7,2199],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2220],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[74,41,2233]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[74,70,2262]}]}]}," ",{p:[75,7,2309],t:7,e:"div",a:{"class":"content"},f:[{p:[75,28,2330],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[75,41,2343]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[75,64,2366]}," [",{p:[75,87,2389],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[75,93,2395]}]},"]"]}]}," ",{p:[76,7,2444],t:7,e:"div",a:{"class":"content"},f:[{p:[76,28,2465],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[76,41,2478]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[76,64,2501]}," [",{p:[76,87,2524],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[76,93,2530]}]},"]"]}]}," ",{p:[77,7,2579],t:7,e:"div",a:{"class":"content"},f:[{p:[77,28,2600],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[77,41,2613]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[77,64,2636]}," [",{p:[77,87,2659],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[77,93,2665]}]},"]"]}]}]}],n:52,r:"data.areas",p:[70,3,1987]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],428:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"div",a:{"class":"item"},f:[{p:[6,3,101],t:7,e:"div",a:{"class":"itemLabel"},f:["Payload status:"]}," ",{p:[9,3,158],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ARMED"],n:50,r:"data.armed",p:[10,4,188]},{t:4,n:51,f:["DISARMED"],r:"data.armed"}]}," ",{p:[16,3,270],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[19,3,321],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[20,4,351],t:7,e:"table",f:[{p:[21,4,363],t:7,e:"tr",f:[{p:[21,8,367],t:7,e:"td",f:[{p:[21,12,371],t:7,e:"ui-button",a:{action:"PRG_obfuscate"},f:["OBFUSCATE PROGRAM NAME"]}]}]},{p:[22,4,444],t:7,e:"tr",f:[{p:[22,8,448],t:7,e:"td",f:[{p:[22,12,452],t:7,e:"ui-button",a:{action:"PRG_arm",state:[{t:2,x:{r:["data.armed"],s:'_0?"danger":null'},p:[22,47,487]}]},f:[{t:2,x:{r:["data.armed"],s:'_0?"DISARM":"ARM"'},p:[22,81,521]}]}," ",{p:[23,4,571],t:7,e:"ui-button",a:{icon:"radiation",state:[{t:2,x:{r:["data.armed"],s:'_0?null:"disabled"'},p:[23,39,606]}],action:"PRG_activate"},f:["ACTIVATE"]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],429:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,3,95],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[5,22,114]}," Alarms"]},f:[{p:[6,5,138],t:7,e:"ul",f:[{t:4,f:[{p:[8,9,171],t:7,e:"li",f:[{t:2,r:".",p:[8,13,175]}]}],n:52,r:".",p:[7,7,150]},{t:4,n:51,f:[{p:[10,9,211],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[4,1,64]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],430:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{integState:function(t){var e=100;return t==e?"good":t>e/2?"average":"bad"},bigState:function(t,e,n){return charge>n?"bad":t>e?"average":"good"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[23,1,421],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[27,2,462],t:7,e:"ui-button",a:{action:"PRG_clear"},f:["Back to Menu"]},{p:[27,56,516],t:7,e:"br"}," ",{p:[28,3,524],t:7,e:"ui-display",a:{title:"Supermatter Status:"},f:[{p:[29,3,568],t:7,e:"ui-section",a:{label:"Core Integrity"},f:[{p:[30,5,609],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"adata.SM_integrity",p:[30,38,642]}],state:[{t:2,x:{r:["integState","adata.SM_integrity"],s:"_0(_1)"},p:[30,69,673]}]},f:[{t:2,r:"data.SM_integrity",p:[30,105,709]},"%"]}]}," ",{p:[32,3,761],t:7,e:"ui-section",a:{label:"Relative EER"},f:[{p:[33,5,800],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_power"],s:"_0(_1,150,300)"},p:[33,18,813]}]},f:[{t:2,r:"data.SM_power",p:[33,55,850]}," MeV/cm3"]}]}," ",{p:[35,3,903],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[36,5,941],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambienttemp"],s:"_0(_1,4000,5000)"},p:[36,18,954]}]},f:[{t:2,r:"data.SM_ambienttemp",p:[36,63,999]}," K"]}]}," ",{p:[38,3,1052],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[39,5,1087],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambientpressure"],s:"_0(_1,5000,10000)"},p:[39,18,1100]}]},f:[{t:2,r:"data.SM_ambientpressure",p:[39,68,1150]}," kPa"]}]}]}," ",{p:[42,3,1227],t:7,e:"hr"},{p:[42,7,1231],t:7,e:"br"}," ",{p:[43,3,1239],t:7,e:"ui-display",a:{title:"Gas Composition:"},f:[{t:4,f:[{p:[45,5,1307],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[45,24,1326]}]},f:[{t:2,r:"amount",p:[46,6,1343]}," %"]}],n:52,r:"data.gases",p:[44,4,1281]}]}],n:50,r:"data.active",p:[26,1,440]},{t:4,n:51,f:[{p:[51,2,1418],t:7,e:"ui-button",a:{action:"PRG_refresh"},f:["Refresh"]},{p:[51,53,1469],t:7,e:"br"}," ",{p:[52,2,1476],t:7,e:"ui-display",a:{title:"Detected Supermatters"},f:[{t:4,f:[{p:[54,3,1552],t:7,e:"ui-section",a:{label:"Area"},f:[{t:2,r:"area_name",p:[55,5,1583]}," - (#",{t:2,r:"uid",p:[55,23,1601]},")"]}," ",{p:[57,3,1630],t:7,e:"ui-section",a:{label:"Integrity"},f:[{t:2,r:"integrity",p:[58,5,1666]}," %"]}," ",{p:[60,3,1702],t:7,e:"ui-section",a:{label:"Options"},f:[{p:[61,5,1736],t:7,e:"ui-button",a:{action:"PRG_set",params:['{"target" : "',{t:2,r:"uid",p:[61,54,1785]},'"}']},f:["View Details"]}]}],n:52,r:"data.supermatters",p:[53,2,1521]}]}],r:"data.active"}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],431:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"item",style:"float: left"},f:[{p:[2,2,41],t:7,e:"table",f:[{p:[2,9,48],t:7,e:"tr",f:[{t:4,f:[{p:[4,3,113],t:7,e:"td",f:[{p:[4,7,117],t:7,e:"img",a:{src:[{t:2,r:"data.PC_batteryicon",p:[4,17,127]}]}}]}],n:50,x:{r:["data.PC_batteryicon","data.PC_showbatteryicon"],s:"_0&&_1"},p:[3,2,55]}," ",{t:4,f:[{p:[7,3,226],t:7,e:"td",f:[{p:[7,7,230],t:7,e:"b",f:[{t:2,r:"data.PC_batterypercent",p:[7,10,233]}]}]}],n:50,x:{r:["data.PC_batterypercent","data.PC_showbatteryicon"],s:"_0&&_1"},p:[6,2,165]}," ",{t:4,f:[{p:[10,3,305],t:7,e:"td",f:[{p:[10,7,309],t:7,e:"img",a:{src:[{t:2,r:"data.PC_ntneticon",p:[10,17,319]}]}}]}],n:50,r:"data.PC_ntneticon",p:[9,2,276]}," ",{t:4,f:[{p:[13,3,386],t:7,e:"td",f:[{p:[13,7,390],t:7,e:"img",a:{src:[{t:2,r:"data.PC_apclinkicon",p:[13,17,400]}]}}]}],n:50,r:"data.PC_apclinkicon",p:[12,2,355]}," ",{t:4,f:[{p:[16,3,469],t:7,e:"td",f:[{p:[16,7,473],t:7,e:"b",f:[{t:2,r:"data.PC_stationtime",p:[16,10,476]}]}]}],n:50,r:"data.PC_stationtime",p:[15,2,438]}," ",{t:4,f:[{p:[19,3,552],t:7,e:"td",f:[{p:[19,7,556],t:7,e:"img",a:{src:[{t:2,r:"icon",p:[19,17,566]}]}}]}],n:52,r:"data.PC_programheaders",p:[18,2,516]}]}]}]}," ",{p:[23,1,609],t:7,e:"div",a:{style:"float: right; margin-top: 5px"},f:[{p:[24,2,655],t:7,e:"ui-button",a:{action:"PC_shutdown"},f:["Shutdown"]}," ",{t:4,f:[{p:[26,3,745],t:7,e:"ui-button",a:{action:"PC_exit"},f:["EXIT PROGRAM"]}," ",{p:[27,3,801],t:7,e:"ui-button",a:{action:"PC_minimize"},f:["Minimize Program"]}],n:50,r:"data.PC_showexitprogram",p:[25,2,710]}]}," ",{p:[30,1,881],t:7,e:"div",a:{style:"clear: both"}}]},e.exports=a.extend(r.exports)},{341:341}],432:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Auth. Disk:"},f:[{t:4,f:[{p:[3,7,69],t:7,e:"ui-button",a:{icon:"eject",style:"selected",action:"eject_disk"},f:["++++++++++"]}],n:50,r:"data.disk_present",p:[2,3,36]},{t:4,n:51,f:[{p:[5,7,172],t:7,e:"ui-button",a:{icon:"plus",action:"insert_disk"},f:["----------"]}],r:"data.disk_present"}]}," ",{p:[8,1,266],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[9,3,297],t:7,e:"span",f:[{t:2,r:"data.status1",p:[9,9,303]},"-",{t:2,r:"data.status2",p:[9,26,320]}]}]}," ",{p:[11,1,360],t:7,e:"ui-display",a:{title:"Timer"},f:[{p:[12,3,390],t:7,e:"ui-section",a:{label:"Time to Detonation"},f:[{p:[13,5,435],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[13,11,441]}]}]}," ",{t:4,f:[{p:[16,5,540],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[17,7,581],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_default"],s:'_0&&_1&&_2?null:"disabled"'},p:[17,40,614]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[19,7,786],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_min"],s:'_0&&_1&&_2?null:"disabled"'},p:[19,38,817]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[21,7,991],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[21,39,1023]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[22,7,1155],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_max"],s:'_0&&_1&&_2?null:"disabled"'},p:[22,37,1185]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[15,3,518]}," ",{p:[26,3,1394],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[27,5,1426],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[27,38,1459]}],action:"toggle_timer",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.safety"],s:'_0&&_1&&!_2?null:"disabled"'},p:[29,14,1542]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[30,7,1631]}]}]}]}," ",{p:[34,1,1713],t:7,e:"ui-display",a:{title:"Anchoring"},f:[{p:[35,3,1747],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[36,12,1770]}],icon:[{t:2,x:{r:["data.anchored"],s:'_0?"lock":"unlock"'},p:[37,11,1846]}],style:[{t:2,x:{r:["data.anchored"],s:'_0?null:"caution"'},p:[38,12,1897]}],action:"anchor"},f:[{t:2,x:{r:["data.anchored"],s:'_0?"Engaged":"Off"'},p:[39,21,1956]}]}]}," ",{p:[41,1,2022],t:7,e:"ui-display",a:{title:"Safety"},f:[{p:[42,3,2053],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[43,12,2076]}],icon:[{t:2,x:{r:["data.safety"],s:'_0?"lock":"unlock"'},p:[44,11,2152]}],action:"safety",style:[{t:2,x:{r:["data.safety"],s:'_0?"caution":"danger"'},p:[45,12,2217]}]},f:[{p:[46,7,2265],t:7,e:"span",f:[{t:2,x:{r:["data.safety"],s:'_0?"On":"Off"'},p:[46,13,2271]}]}]}]}," ",{p:[49,1,2341],t:7,e:"ui-display",a:{title:"Code"},f:[{p:[50,3,2370],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.message",p:[50,31,2398]}]}," ",{p:[51,3,2431],t:7,e:"ui-section",a:{label:"Keypad"},f:[{p:[52,5,2464],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[52,39,2498]}],params:'{"digit":"1"}'},f:["1"]}," ",{p:[53,5,2583],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[53,39,2617]}],params:'{"digit":"2"}'},f:["2"]}," ",{p:[54,5,2702],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[54,39,2736]}],params:'{"digit":"3"}'},f:["3"]}," ",{p:[55,5,2821],t:7,e:"br"}," ",{p:[56,5,2831],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[56,39,2865]}],params:'{"digit":"4"}'},f:["4"]}," ",{p:[57,5,2950],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[57,39,2984]}],params:'{"digit":"5"}'},f:["5"]}," ",{p:[58,5,3069],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[58,39,3103]}],params:'{"digit":"6"}'},f:["6"]}," ",{p:[59,5,3188],t:7,e:"br"}," ",{p:[60,5,3198],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[60,39,3232]}],params:'{"digit":"7"}'},f:["7"]}," ",{p:[61,5,3317],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[61,39,3351]}],params:'{"digit":"8"}'},f:["8"]}," ",{p:[62,5,3436],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[62,39,3470]}],params:'{"digit":"9"}'},f:["9"]}," ",{p:[63,5,3555],t:7,e:"br"}," ",{p:[64,5,3565],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[64,39,3599]}],params:'{"digit":"R"}'},f:["R"]}," ",{p:[65,5,3684],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[65,39,3718]}],params:'{"digit":"0"}'},f:["0"]}," ",{p:[66,5,3803],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[66,39,3837]}],params:'{"digit":"E"}'},f:["E"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],433:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,25],t:7,e:"ui-button",a:{icon:"undo",action:"change_menu",params:'{"menu": "1"}'},f:["Return"]}," ",{p:[3,2,113],t:7,e:"ui-display",a:{title:"Advanced Surgery Procedures"},f:[{p:[4,3,165],t:7,e:"ui-button",a:{icon:"download",action:"sync"},f:["Sync with research database"]}," ",{t:4,f:[{p:[6,4,278],t:7,e:"ui-display",f:[{p:[7,6,297],t:7,e:"ui-section",f:[{p:[7,18,309],t:7,e:"b",f:[{t:2,r:"name",p:[7,21,312]}]}]}," ",{p:[8,6,344],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[8,18,356]}]}]}],n:52,r:"data.surgeries",p:[5,3,249]}]}],n:50,x:{r:["data.menu"],s:"_0==2"},p:[1,1,0]},{t:4,n:51,f:[{p:[13,2,437],t:7,e:"ui-button",a:{action:"change_menu",params:'{"menu": "2"}'},f:["View Surgery Procedures"]}," ",{t:4,f:[{p:[15,3,556],t:7,e:"ui-notice",f:["No table detected!"]}],n:51,r:"data.table",p:[14,2,530]}," ",{p:[19,2,623],t:7,e:"ui-display",f:[{p:[20,3,639],t:7,e:"ui-display",a:{title:"Patient State"},f:[{t:4,f:[{p:[22,5,704],t:7,e:"ui-section",a:{label:"State"},f:[{p:[23,6,737],t:7,e:"span",a:{"class":[{t:2,r:"data.patient.statstate",p:[23,19,750]}]},f:[{t:2,r:"data.patient.stat",p:[23,47,778]}]}]}," ",{p:[25,5,831],t:7,e:"ui-section",a:{label:"Blood Type"},f:[{p:[26,6,869],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.patient.blood_type",p:[26,28,891]}]}]}," ",{p:[28,5,950],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[29,6,984],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.patient.minHealth",p:[29,19,997]}],max:[{t:2,r:"data.patient.maxHealth",p:[29,52,1030]}],value:[{t:2,r:"data.patient.health",p:[29,87,1065]}],state:[{t:2,x:{r:["data.patient.health"],s:'_0>=0?"good":"average"'},p:[30,13,1103]}]},f:[{t:2,x:{r:["adata.patient.health"],s:"Math.round(_0)"},p:[30,64,1154]}]}]}," ",{t:4,f:[{p:[33,6,1389],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[33,25,1408]}]},f:[{p:[34,7,1427],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.patient.maxHealth",p:[34,28,1448]}],value:[{t:2,rx:{r:"data.patient",m:[{t:30,n:"type"}]},p:[34,63,1483]}],state:"bad"},f:[{t:2,x:{r:["type","adata.patient"],s:"Math.round(_1[_0])"},p:[34,99,1519]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Burn",type:"fireLoss"},{label:"Toxin",type:"toxLoss"},{label:"Respiratory",type:"oxyLoss"}]'},p:[32,5,1224]}],n:50,r:"data.patient",p:[21,4,678]},{t:4,n:51,f:["No patient detected."],r:"data.patient"}]}," ",{p:[41,3,1670],t:7,e:"ui-display",a:{title:"Initiated Procedures"},f:[{t:4,f:[{t:4,f:[{p:[44,6,1777],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[44,28,1799]}]},f:[{p:[45,7,1817],t:7,e:"ui-section",a:{label:"Next Step"},f:[{p:[46,8,1856],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"next_step",p:[46,30,1878]}]}," ",{t:4,f:[{p:[48,9,1937],t:7,e:"span",a:{"class":"content"},f:[{p:[48,31,1959],t:7,e:"b",f:["Required chemicals:"]},{p:[48,57,1985],t:7,e:"br"}," ",{t:2,r:"chems_needed",p:[48,62,1990]}]}],n:50,r:"chems_needed",p:[47,8,1907]}]}," ",{t:4,f:[{p:[52,8,2091],t:7,e:"ui-section",a:{label:"Alternative Step"},f:[{p:[53,9,2138],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"alternative_step",p:[53,31,2160]}]}," ",{t:4,f:[{p:[55,10,2232],t:7,e:"span",a:{"class":"content"},f:[{p:[55,32,2254],t:7,e:"b",f:["Required chemicals:"]},{p:[55,58,2280],t:7,e:"br"}," ",{t:2,r:"chems_needed",p:[55,63,2285]}]}],n:50,r:"alt_chems_needed",p:[54,9,2197]}]}],n:50,r:"alternative_step",p:[51,7,2058]}]}],n:52,r:"data.procedures",p:[43,5,1745]}],n:50,r:"data.procedures",p:[42,4,1716]},{t:4,n:51,f:["No active procedures."],r:"data.procedures"}]}]}],x:{r:["data.menu"],s:"_0==2"}}]},e.exports=a.extend(r.exports)},{341:341}],434:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",f:["This machine only accepts ore. Gibtonite and Slag are not accepted."]}," ",{p:[5,2,117],t:7,e:"ui-section",f:["Current unclaimed points: ",{t:2,r:"data.unclaimedPoints",p:[6,29,159]}," ",{t:4,f:[{p:[8,4,220],t:7,e:"ui-button",a:{action:"Claim"},f:["Claim Points"]}],n:50,r:"data.unclaimedPoints",p:[7,3,187]}]}," ",{p:[13,2,311],t:7,e:"ui-section",f:[{t:4,f:[{p:[15,4,350],t:7,e:"ui-button",a:{action:"Eject"},f:["Eject ID"]}," You have ",{t:2,r:"data.claimedPoints",p:[18,13,421]}," mining points collected."],n:50,r:"data.hasID",p:[14,3,327]},{t:4,n:51,f:[{p:[20,4,485],t:7,e:"ui-button",a:{action:"Insert"},f:["Insert ID"]}],r:"data.hasID"}]}]}," ",{p:[26,1,588],t:7,e:"ui-display",f:[{t:4,f:[{p:[28,3,627],t:7,e:"ui-section",f:[{p:[29,4,644],t:7,e:"ui-button",a:{action:"diskEject",icon:"eject"},f:["Eject Disk"]}]}," ",{t:4,f:[{p:[34,4,772],t:7,e:"ui-section",a:{"class":"candystripe"},f:[{p:[35,5,808],t:7,e:"ui-button",a:{action:"diskUpload",state:[{t:2,x:{r:["canupload"],s:'(_0)?null:"disabled"'},p:[35,42,845]}],icon:"upload",align:"right",params:['{ "design" : "',{t:2,r:"index",p:[35,129,932]},'" }']},f:["Upload"]}," File ",{t:2,r:"index",p:[38,10,988]},": ",{t:2,r:"name",p:[38,21,999]}]}],n:52,r:"data.diskDesigns",p:[33,3,741]}],n:50,r:"data.hasDisk",p:[27,2,603]},{t:4,n:51,f:[{p:[42,3,1053],t:7,e:"ui-section",f:[{p:[43,4,1070],t:7,e:"ui-button",a:{action:"diskInsert",icon:"floppy-o"},f:["Insert Disk"]}]}],r:"data.hasDisk"}]}," ",{t:4,f:[{p:[50,2,1223],t:7,e:"ui-display",f:[{p:[51,3,1239],t:7,e:"ui-section",f:[{p:[52,4,1256],t:7,e:"b",f:["Warning"]},": ",{t:2,r:"data.disconnected",p:[52,20,1272]},". Please contact the quartermaster."]}]}],n:50,r:"data.disconnected",p:[49,1,1195]},{t:4,f:[{p:[57,2,1412],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[58,3,1445],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[59,5,1480],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[62,5,1538],t:7,e:"section",a:{"class":"cell"},f:["Sheets"]}," ",{p:[65,5,1595],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[67,5,1639],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[69,5,1683],t:7,e:"section",a:{"class":"cell"},f:["Ore Value"]}]}," ",{t:4,f:[{p:[74,4,1785],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[75,5,1820],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[76,6,1849]}]}," ",{p:[78,5,1879],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[79,6,1922]}]}," ",{p:[81,5,1954],t:7,e:"section",a:{"class":"cell"},f:[{p:[82,6,1983],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[82,19,1996]}],placeholder:"###","class":"number"}}]}," ",{p:[84,5,2063],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[85,6,2106],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[85,60,2160]}],params:['{ "id" : ',{t:2,r:"id",p:[85,115,2215]},', "sheets" : ',{t:2,r:"sheets",p:[85,134,2234]}," }"]},f:["Release"]}]}," ",{p:[89,5,2305],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"value",p:[90,6,2348]}]}]}],n:52,r:"data.materials",p:[73,3,1756]}," ",{t:4,f:[{p:[95,4,2431],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[96,5,2466],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[97,6,2495]}]}," ",{p:[99,5,2525],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[100,6,2568]}]}," ",{p:[102,5,2600],t:7,e:"section",a:{"class":"cell"},f:[{p:[103,6,2629],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[103,19,2642]}],placeholder:"###","class":"number"}}]}," ",{p:[105,5,2709],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[106,6,2752],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Smelt",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[106,58,2804]}],params:['{ "id" : ',{t:2,r:"id",p:[106,114,2860]},', "sheets" : ',{t:2,r:"sheets",p:[106,133,2879]}," }"]},f:["Smelt"]}]}," ",{p:[110,5,2947],t:7,e:"section",a:{"class":"cell",align:"right"},f:[]}]}],n:52,r:"data.alloys",p:[94,3,2405]}]}],n:50,x:{r:["data.materials","data.alloys"],s:"_0||_1"},p:[56,1,1372]}]},e.exports=a.extend(r.exports)},{341:341}],435:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,4,87],t:7,e:"ui-button",a:{icon:"remove",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[4,36,119]}],action:"empty_eject_beaker"},f:["Empty and eject"]}," ",{p:[7,4,231],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[7,35,262]}],action:"empty_beaker"},f:["Empty"]}," ",{p:[10,4,358],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[10,35,389]}],action:"eject_beaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{t:4,f:[{p:[15,4,528],t:7,e:"ui-section",f:[{t:4,f:[{p:[17,6,578], t:7,e:"span",a:{"class":"bad"},f:["The beaker is empty!"]}],n:50,r:"data.beaker_empty",p:[16,5,546]},{t:4,n:51,f:[{p:[19,6,644],t:7,e:"ui-subdisplay",a:{title:"Blood"},f:[{t:4,f:[{p:[21,8,712],t:7,e:"ui-section",a:{label:"Blood DNA"},f:[{t:2,r:"data.blood.dna",p:[21,38,742]}]}," ",{p:[22,8,782],t:7,e:"ui-section",a:{label:"Blood type"},f:[{t:2,r:"data.blood.type",p:[22,39,813]}]}],n:50,r:"data.has_blood",p:[20,7,681]},{t:4,n:51,f:[{p:[24,8,870],t:7,e:"ui-section",f:[{p:[25,9,892],t:7,e:"span",a:{"class":"average"},f:["No blood sample detected."]}]}],r:"data.has_blood"}]}],r:"data.beaker_empty"}]}],n:50,r:"data.has_beaker",p:[14,3,500]},{t:4,n:51,f:[{p:[32,4,1054],t:7,e:"ui-section",f:[{p:[33,5,1072],t:7,e:"span",a:{"class":"bad"},f:["No beaker loaded."]}]}],r:"data.has_beaker"}]}," ",{t:4,f:[{p:[38,3,1188],t:7,e:"ui-display",a:{title:"Diseases"},f:[{t:4,f:[{p:{button:[{t:4,f:[{p:[43,8,1343],t:7,e:"ui-button",a:{icon:"pencil",action:"rename_disease",state:[{t:2,x:{r:["can_rename"],s:'_0?"":"disabled"'},p:[43,64,1399]}],params:['{"index": ',{t:2,r:"index",p:[43,116,1451]},"}"]},f:["Name advanced disease"]}],n:50,r:"is_adv",p:[42,7,1320]}," ",{p:[47,7,1538],t:7,e:"ui-button",a:{icon:"flask",action:"create_culture_bottle",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[47,69,1600]}],params:['{"index": ',{t:2,r:"index",p:[47,124,1655]},"}"]},f:["Create virus culture bottle"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[40,24,1269]}],button:0},f:[" ",{p:[51,6,1749],t:7,e:"ui-section",a:{label:"Disease agent"},f:[{t:2,r:"agent",p:[51,40,1783]}]}," ",{p:[52,6,1812],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[52,38,1844]}]}," ",{p:[53,6,1879],t:7,e:"ui-section",a:{label:"Spread"},f:[{t:2,r:"spread",p:[53,33,1906]}]}," ",{p:[54,6,1936],t:7,e:"ui-section",a:{label:"Possible cure"},f:[{t:2,r:"cure",p:[54,40,1970]}]}," ",{t:4,f:[{p:[56,7,2021],t:7,e:"ui-section",a:{label:"Symptoms"},f:[{t:4,f:[{p:[58,9,2087],t:7,e:"ui-button",a:{action:"symptom_details",state:"",params:['{"picked_symptom": ',{t:2,r:"sym_index",p:[58,81,2159]},', "index": ',{t:2,r:"index",p:[58,105,2183]},"}"]},f:[{t:2,r:"name",p:[59,10,2206]}," "]},{p:[60,21,2236],t:7,e:"br"}],n:52,r:"symptoms",p:[57,8,2059]}]}," ",{p:[63,7,2289],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[63,38,2320]}]}," ",{p:[64,7,2355],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[64,35,2383]}]}," ",{p:[65,7,2415],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[65,39,2447]}]}," ",{p:[66,7,2483],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[66,44,2520]}]}],n:50,r:"is_adv",p:[55,6,1999]}]}],n:52,r:"data.viruses",p:[39,4,1222]},{t:4,n:51,f:[{p:[70,5,2601],t:7,e:"ui-section",f:[{p:[71,6,2620],t:7,e:"span",a:{"class":"average"},f:["No detectable virus in the blood sample."]}]}],r:"data.viruses"}]}," ",{p:[75,3,2743],t:7,e:"ui-display",a:{title:"Antibodies"},f:[{t:4,f:[{p:[77,5,2811],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[77,24,2830]}]},f:[{p:[78,7,2848],t:7,e:"ui-button",a:{icon:"eyedropper",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[78,43,2884]}],action:"create_vaccine_bottle",params:['{"index": ',{t:2,r:"id",p:[78,129,2970]},"}"]},f:["Create vaccine bottle"]}]}],n:52,r:"data.resistances",p:[76,4,2779]},{t:4,n:51,f:[{p:[83,5,3067],t:7,e:"ui-section",f:[{p:[84,6,3086],t:7,e:"span",a:{"class":"average"},f:["No antibodies detected in the blood sample."]}]}],r:"data.resistances"}]}],n:50,r:"data.has_blood",p:[37,2,1162]}],n:50,x:{r:["data.mode"],s:"_0==1"},p:[1,1,0]},{t:4,n:51,f:[{p:[90,2,3231],t:7,e:"ui-button",a:{icon:"undo",state:"",action:"back"},f:["Back"]}," ",{t:4,f:[{p:[94,4,3330],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[94,23,3349]}]},f:[{p:[95,4,3364],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[96,5,3382]}," ",{t:4,f:[{p:[98,5,3417],t:7,e:"br"}," ",{p:[99,5,3428],t:7,e:"b",f:["This symptom has been neutered, and has no effect. It will still affect the virus' statistics."]}],n:50,r:"neutered",p:[97,4,3395]}]}," ",{p:[102,4,3564],t:7,e:"ui-section",f:[{p:[103,5,3582],t:7,e:"ui-section",a:{label:"Level"},f:[{t:2,r:"level",p:[103,31,3608]}]}," ",{p:[104,5,3636],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[104,36,3667]}]}," ",{p:[105,5,3700],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[105,33,3728]}]}," ",{p:[106,5,3758],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[106,37,3790]}]}," ",{p:[107,5,3824],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[107,42,3861]}]}]}," ",{p:[109,4,3913],t:7,e:"ui-subdisplay",a:{title:"Effect Thresholds"},f:[{p:[110,5,3960],t:7,e:"ui-section",f:[{t:3,r:"threshold_desc",p:[110,17,3972]}]}]}]}],n:53,r:"data.symptom",p:[93,2,3303]}],x:{r:["data.mode"],s:"_0==1"}}]},e.exports=a.extend(r.exports)},{341:341}],436:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(484);e.exports={data:{filter:"",tooltiptext:function(t,e,n){var a="";return t&&(a+="REQUIREMENTS: "+t+" "),e&&(a+="CATALYSTS: "+e+" "),n&&(a+="TOOLS: "+n),a}},oninit:function(){var t=this;this.on({hover:function(t){this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}}),this.observe("filter",function(e,a,r){var i=null;i=t.get("data.display_compact")?t.findAll(".section"):t.findAll(".display:not(:first-child)"),(0,n.filterMulti)(i,t.get("filter").toLowerCase())},{init:!1})}}}(r),r.exports.template={v:3,t:[" ",{p:[48,1,1342],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[48,20,1361]},{t:4,f:[" : ",{t:2,r:"data.subcategory",p:[48,64,1405]}],n:50,r:"data.subcategory",p:[48,37,1378]}]},f:[{t:4,f:[{p:[50,3,1459],t:7,e:"ui-section",f:["Crafting... ",{p:[51,16,1488],t:7,e:"i",a:{"class":"fa-spin fa fa-spinner"}}]}],n:50,r:"data.busy",p:[49,2,1438]},{t:4,n:51,f:[{p:[54,3,1557],t:7,e:"ui-section",f:[{p:[55,4,1574],t:7,e:"table",a:{style:"width:100%"},f:[{p:[56,5,1606],t:7,e:"tr",f:[{p:[57,6,1617],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[58,7,1659],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardCat"},f:[{t:2,r:"data.prev_cat",p:[59,8,1718]}]}]}," ",{p:[62,6,1774],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[63,7,1816],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardCat"},f:[{t:2,r:"data.next_cat",p:[64,7,1874]}]}]}," ",{p:[67,6,1930],t:7,e:"td",a:{style:"float:right!important"},f:[{t:4,f:[{p:[69,7,2014],t:7,e:"ui-button",a:{icon:"lock",action:"toggle_recipes"},f:["Showing Craftable Recipes"]}],n:50,r:"data.display_craftable_only",p:[68,6,1971]},{t:4,n:51,f:[{p:[73,7,2138],t:7,e:"ui-button",a:{icon:"unlock",action:"toggle_recipes"},f:["Showing All Recipes"]}],r:"data.display_craftable_only"}]}," ",{p:[78,6,2268],t:7,e:"td",a:{style:"float:right!important"},f:[{p:[79,7,2310],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.display_compact"],s:'_0?"check-square-o":"square-o"'},p:[79,24,2327]}],action:"toggle_compact"},f:["Compact"]}]}]}," ",{p:[84,5,2474],t:7,e:"tr",f:[{t:4,f:[{p:[86,6,2515],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[87,7,2557],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardSubCat"},f:[{t:2,r:"data.prev_subcat",p:[88,8,2619]}]}]}," ",{p:[91,6,2678],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[92,7,2720],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardSubCat"},f:[{t:2,r:"data.next_subcat",p:[93,8,2782]}]}]}],n:50,r:"data.subcategory",p:[85,5,2484]}]}]}," ",{t:4,f:[{t:4,f:[" ",{p:[101,6,2992],t:7,e:"ui-input",a:{value:[{t:2,r:"filter",p:[101,23,3009]}],placeholder:"Filter.."}}],n:51,r:"data.display_compact",p:[100,5,2902]}],n:50,r:"config.fancy",p:[99,4,2876]}]}," ",{t:4,f:[{p:[106,5,3144],t:7,e:"ui-display",f:[{t:4,f:[{p:[108,6,3193],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[108,25,3212]}]},f:[{p:[109,7,3230],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[109,27,3250]}],"tooltip-side":"right",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[109,135,3358]},'"}'],icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.can_craft",p:[107,5,3162]}," ",{t:4,f:[{t:4,f:[{p:[116,7,3567],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[116,26,3586]}]},f:[{p:[117,8,3605],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[117,28,3625]}],"tooltip-side":"right",state:"disabled",icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.cant_craft",p:[115,6,3534]}],n:51,r:"data.display_craftable_only",p:[114,5,3495]}]}],n:50,r:"data.display_compact",p:[105,4,3110]},{t:4,n:51,f:[{t:4,f:[{p:[126,6,3947],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[126,25,3966]}]},f:[{t:4,f:[{p:[128,8,4009],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[129,9,4052]}]}],n:50,r:"req_text",p:[127,7,3984]}," ",{t:4,f:[{p:[133,8,4139],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[134,9,4179]}]}],n:50,r:"catalyst_text",p:[132,7,4109]}," ",{t:4,f:[{p:[138,8,4267],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[139,9,4303]}]}],n:50,r:"tool_text",p:[137,7,4241]}," ",{p:[142,7,4361],t:7,e:"ui-section",f:[{p:[143,8,4382],t:7,e:"ui-button",a:{icon:"gears",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[143,66,4440]},'"}']},f:["Craft"]}]}]}],n:52,r:"data.can_craft",p:[125,5,3916]}," ",{t:4,f:[{t:4,f:[{p:[151,7,4621],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[151,26,4640]}]},f:[{t:4,f:[{p:[153,9,4685],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[154,10,4729]}]}],n:50,r:"req_text",p:[152,8,4659]}," ",{t:4,f:[{p:[158,9,4820],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[159,10,4861]}]}],n:50,r:"catalyst_text",p:[157,8,4789]}," ",{t:4,f:[{p:[163,9,4953],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[164,10,4990]}]}],n:50,r:"tool_text",p:[162,8,4926]}]}],n:52,r:"data.cant_craft",p:[150,6,4588]}],n:51,r:"data.display_craftable_only",p:[149,5,4549]}],r:"data.display_compact"}],r:"data.busy"}]}]},e.exports=a.extend(r.exports)},{341:341,484:484}],437:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Pump"},f:[{p:[13,3,459],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,491],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,508]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,559]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,616]}]}]}," ",{p:[18,3,675],t:7,e:"ui-section",a:{label:"Direction"},f:[{p:[19,5,711],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"sign-out":"sign-in"'},p:[19,22,728]}],action:"direction"},f:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"Out":"In"'},p:[20,26,808]}]}]}," ",{p:[22,3,883],t:7,e:"ui-section",a:{label:"Target Pressure"},f:[{p:[23,5,925],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.min_pressure",p:[23,18,938]}],max:[{t:2,r:"data.max_pressure",p:[23,46,966]}],value:[{t:2,r:"data.target_pressure",p:[24,14,1003]}]},f:[{t:2,x:{r:["adata.target_pressure"],s:"Math.round(_0)"},p:[24,40,1029]}," kPa"]}]}," ",{p:[26,3,1100],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,1145],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.target_pressure","data.default_pressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,1178]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1328],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.target_pressure","data.min_pressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1359]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1500],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1595],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.target_pressure","data.max_pressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1625]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}," ",{p:{button:[{t:4,f:[{p:[39,7,1891],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[39,38,1922]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[38,5,1863]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[43,3,2042],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[44,4,2073]}]}," ",{p:[46,3,2115],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[47,4,2149]}," kPa"]}],n:50,r:"data.holding",p:[42,3,2018]},{t:4,n:51,f:[{p:[50,3,2223],t:7,e:"ui-section",f:[{p:[51,4,2240],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{341:341}],438:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[3,1,69],t:7,e:"ui-notice",f:[{p:[4,3,84],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[4,23,104]}," connected to a tank."]}]}," ",{p:[6,1,182],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[7,3,220],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[8,5,255],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[8,11,261]}," kPa"]}]}," ",{p:[10,3,323],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[11,5,354],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[11,18,367]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[11,59,408]}]}]}]}," ",{p:[14,1,499],t:7,e:"ui-display",a:{title:"Filter"},f:[{p:[15,3,530],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[16,5,562],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[16,22,579]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[17,14,630]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[18,22,687]}]}]}]}," ",{p:{button:[{t:4,f:[{p:[24,7,856],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[24,38,887]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[23,5,828]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[28,3,1007],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[29,4,1038]}]}," ",{p:[31,3,1080],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[32,4,1114]}," kPa"]}],n:50,r:"data.holding",p:[27,3,983]},{t:4,n:51,f:[{p:[35,3,1188],t:7,e:"ui-section",f:[{p:[36,4,1205],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}," ",{p:[40,1,1293],t:7,e:"ui-display",a:{title:"Filters"},f:[{t:4,f:[{p:[42,5,1345],t:7,e:"filters"}],n:53,r:"data",p:[41,3,1325]}]}]},r.exports.components=r.exports.components||{};var i={filters:t(457)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,457:457}],439:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" ",{p:[42,1,1035],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[44,5,1093],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[44,27,1115]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[46,38,1267]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[47,15,1323]}],yinc:"9"}}],n:50,r:"config.fancy",p:[43,3,1067]},{t:4,n:51,f:[{p:[49,5,1373],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[50,7,1411],t:7,e:"span",f:[{t:2,r:"data.supply",p:[50,13,1417]}]}]}," ",{p:[52,5,1464],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[53,9,1499],t:7,e:"span",f:[{t:2,r:"data.demand",p:[53,15,1505]}]}]}],r:"config.fancy"}]}," ",{p:[57,1,1574],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[58,3,1604],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[59,5,1629],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[60,5,1666],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[61,5,1705],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[62,5,1742],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[63,5,1781],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[64,5,1823],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[65,5,1864],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[68,5,1949],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[68,24,1968]}],nowrap:0},f:[{p:[69,7,1993],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[69,28,2014]}," %"]}," ",{p:[70,7,2072],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[70,28,2093]}]}," ",{p:[71,7,2135],t:7,e:"div",a:{"class":"content"},f:[{p:[71,28,2156],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[71,41,2169]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[71,70,2198]}]}]}," ",{p:[72,7,2245],t:7,e:"div",a:{"class":"content"},f:[{p:[72,28,2266],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[72,41,2279]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[72,64,2302]}," [",{p:[72,87,2325],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[72,93,2331]}]},"]"]}]}," ",{p:[73,7,2380],t:7,e:"div",a:{"class":"content"},f:[{p:[73,28,2401],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[73,41,2414]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[73,64,2437]}," [",{p:[73,87,2460],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[73,93,2466]}]},"]"]}]}," ",{p:[74,7,2515],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2536],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[74,41,2549]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[74,64,2572]}," [",{p:[74,87,2595],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[74,93,2601]}]},"]"]}]}]}],n:52,r:"data.areas",p:[67,3,1923]}]}]},e.exports=a.extend(r.exports)},{341:341}],440:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{readableFrequency:function(){return Math.round(this.get("adata.frequency"))/10}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,177],t:7,e:"ui-display",a:{title:"Settings"},f:[{t:4,f:[{p:[13,5,236],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,7,270],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[14,24,287]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[14,75,338]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"On":"Off"'},p:[16,9,413]}]}]}],n:50,r:"data.headset",p:[12,3,210]},{t:4,n:51,f:[{p:[19,5,494],t:7,e:"ui-section",a:{label:"Microphone"},f:[{p:[20,7,533],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.broadcasting"],s:'_0?"power-off":"close"'},p:[20,24,550]}],style:[{t:2,x:{r:["data.broadcasting"],s:'_0?"selected":null'},p:[20,78,604]}],action:"broadcast"},f:[{t:2,x:{r:["data.broadcasting"],s:'_0?"Engaged":"Disengaged"'},p:[22,9,685]}]}]}," ",{p:[24,5,769],t:7,e:"ui-section",a:{label:"Speaker"},f:[{p:[25,7,805],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[25,24,822]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[25,75,873]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"Engaged":"Disengaged"'},p:[27,9,948]}]}]}],r:"data.headset"}," ",{t:4,f:[{p:[31,5,1064],t:7,e:"ui-section",a:{label:"High Volume"},f:[{p:[32,7,1104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.useCommand"],s:'_0?"power-off":"close"'},p:[32,24,1121]}],style:[{t:2,x:{r:["data.useCommand"],s:'_0?"selected":null'},p:[32,76,1173]}],action:"command"},f:[{t:2,x:{r:["data.useCommand"],s:'_0?"On":"Off"'},p:[34,9,1250]}]}]}],n:50,r:"data.command",p:[30,3,1038]}]}," ",{p:[38,1,1342],t:7,e:"ui-display",a:{title:"Channel"},f:[{p:[39,3,1374],t:7,e:"ui-section",a:{label:"Frequency"},f:[{t:4,f:[{p:[41,7,1439],t:7,e:"span",f:[{t:2,r:"readableFrequency",p:[41,13,1445]}]}],n:50,r:"data.freqlock",p:[40,5,1410]},{t:4,n:51,f:[{p:[43,7,1495],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[43,46,1534]}],action:"frequency",params:'{"adjust": -1}'}}," ",{p:[44,7,1646],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[44,41,1680]}],action:"frequency",params:'{"adjust": -.2}'}}," ",{p:[45,7,1793],t:7,e:"ui-button",a:{icon:"pencil",action:"frequency",params:'{"tune": "input"}'},f:[{t:2,r:"readableFrequency",p:[45,78,1864]}]}," ",{p:[46,7,1905],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[46,40,1938]}],action:"frequency",params:'{"adjust": .2}'}}," ",{p:[47,7,2050],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[47,45,2088]}],action:"frequency",params:'{"adjust": 1}'}}],r:"data.freqlock"}]}," ",{t:4,f:[{p:[51,5,2262],t:7,e:"ui-section",a:{label:"Subspace Transmission"},f:[{p:[52,7,2312],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.subspace"],s:'_0?"power-off":"close"'},p:[52,24,2329]}],style:[{t:2,x:{r:["data.subspace"],s:'_0?"selected":null'},p:[52,74,2379]}],action:"subspace"},f:[{t:2,x:{r:["data.subspace"],s:'_0?"Active":"Inactive"'},p:[53,29,2447]}]}]}],n:50,r:"data.subspaceSwitchable",p:[50,3,2225]}," ",{t:4,f:[{p:[57,5,2578],t:7,e:"ui-section",a:{label:"Channels"},f:[{t:4,f:[{p:[59,9,2656],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["."],s:'_0?"check-square-o":"square-o"'},p:[59,26,2673]}],style:[{t:2,x:{r:["."],s:'_0?"selected":null'},p:[60,18,2730]}],action:"channel",params:['{"channel": "',{t:2,r:"channel",p:[61,49,2806]},'"}']},f:[{t:2,r:"channel",p:[62,11,2833]}]},{p:[62,34,2856],t:7,e:"br"}],n:52,i:"channel",r:"data.channels",p:[58,7,2615]}]}],n:50,x:{r:["data.subspace","data.channels"],s:"_0&&_1"},p:[56,3,2534]}]}]},e.exports=a.extend(r.exports)},{341:341}],441:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," "," "," "," "," "," "," "," ",{p:[11,1,560],t:7,e:"rdheader"}," ",{t:4,f:[{p:[13,2,595],t:7,e:"ui-display",a:{title:"CONSOLE LOCKED"},f:[{p:[14,3,634],t:7,e:"ui-button",a:{action:"Unlock"},f:["Unlock"]}]}],n:50,r:"data.locked",p:[12,1,573]},{t:4,f:[{p:[18,2,729],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[18,17,744]}]},f:[{p:[19,3,763],t:7,e:"tab",a:{name:"Technology"},f:[{p:[20,4,791],t:7,e:"techweb"}]}," ",{p:[22,3,815],t:7,e:"tab",a:{name:"View Node"},f:[{p:[23,4,842],t:7,e:"nodeview"}]}," ",{p:[25,3,867],t:7,e:"tab",a:{name:"View Design"},f:[{p:[26,4,896],t:7,e:"designview"}]}," ",{p:[28,3,923],t:7,e:"tab",a:{name:"Disk Operations - Design"},f:[{p:[29,4,965],t:7,e:"diskopsdesign"}]}," ",{p:[31,3,995],t:7,e:"tab",a:{name:"Disk Operations - Technology"},f:[{p:[32,4,1041],t:7,e:"diskopstech"}]}," ",{p:[34,3,1069],t:7,e:"tab",a:{name:"Deconstructive Analyzer"},f:[{p:[35,4,1110],t:7,e:"destruct"}]}," ",{p:[37,3,1135],t:7,e:"tab",a:{name:"Protolathe"},f:[{p:[38,4,1163],t:7,e:"protolathe"}]}," ",{p:[40,3,1190],t:7,e:"tab",a:{name:"Circuit Imprinter"},f:[{p:[41,4,1225],t:7,e:"circuit"}]}," ",{p:[43,3,1249],t:7,e:"tab",a:{name:"Settings"},f:[{p:[44,4,1275],t:7,e:"settings"}]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[17,1,706]}]},r.exports.components=r.exports.components||{};var i={settings:t(450),circuit:t(442),protolathe:t(448),destruct:t(444),diskopsdesign:t(445),diskopstech:t(446),designview:t(443),nodeview:t(447),techweb:t(451),rdheader:t(449)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,442:442,443:443,444:444,445:445,446:446,447:447,448:448,449:449,450:450,451:451}],442:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:4,f:[{p:[3,3,58],t:7,e:"ui-display",a:{title:"Circuit Imprinter Busy!"}}],n:50,r:"data.circuitbusy",p:[2,2,30]},{t:4,n:51,f:[{p:[5,3,130],t:7,e:"ui-display",f:[{p:[6,4,147],t:7,e:"ui-section",f:["Search Available Designs: ",{p:[7,4,189],t:7,e:"input",a:{value:[{t:2,r:"textsearch",p:[7,17,202]}],placeholder:"Type Here","class":"text"}}," ",{p:[8,5,261],t:7,e:"ui-button",a:{action:"textSearch",params:['{"latheType" : "circuit", "inputText" : ',{t:2,r:"textsearch",p:[8,84,340]},"}"]},f:["Search"]}]}," ",{p:[10,4,398],t:7,e:"ui-section",f:["Materials: ",{t:2,r:"data.circuitmats",p:[10,27,421]}," / ",{t:2,r:"data.circuitmaxmats",p:[10,50,444]}]}," ",{p:[11,4,485],t:7,e:"ui-section",f:["Reagents: ",{t:2,r:"data.circuitchems",p:[11,26,507]}," / ",{t:2,r:"data.circuitmaxchems",p:[11,50,531]}]}," ",{p:[12,3,572],t:7,e:"ui-display",f:[{p:[14,3,590],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.lathe_tabs",p:[14,18,605]}]},f:[{p:[15,4,631],t:7,e:"tab",a:{name:"Category List"},f:[{t:4,f:[{p:[17,6,696],t:7,e:"ui-button",a:{action:"switchcat",state:[{t:2,x:{r:["data.circuitcat"],s:'_0=="{{name}}"?"selected":null'},p:[17,43,733]}],params:['{"type" : "circuit", "cat" : "',{t:2,r:"name",p:[17,135,825]},'"}']},f:[{t:2,r:"name",p:[17,147,837]}]}],n:52,r:"data.circuitcats",p:[16,5,663]}]}," ",{p:[20,4,888],t:7,e:"tab",a:{name:"Selected Category"},f:[{t:4,f:[{p:[22,6,956],t:7,e:"ui-section",f:[{t:2,r:"name",p:[22,18,968]},{t:2,r:"matstring",p:[22,26,976]}," ",{p:[23,7,997],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[23,40,1030]}],params:['{"latheType" : "circuit", "id" : "',{t:2,r:"id",p:[23,119,1109]},'"}']},f:["Print"]}]}],n:52,r:"data.circuitdes",p:[21,5,924]}]}," ",{p:[27,4,1187],t:7,e:"tab",a:{name:"Search Results"},f:[{t:4,f:[{p:[29,6,1254],t:7,e:"ui-section",f:[{t:2,r:"name",p:[29,18,1266]},{t:2,r:"matstring",p:[29,26,1274]}," ",{p:[30,7,1295],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[30,40,1328]}],params:['{"latheType" : "circuit", "id" : "',{t:2,r:"id",p:[30,119,1407]},'"}']},f:["Print"]}]}],n:52,r:"data.circuitmatch",p:[28,5,1220]}]}," ",{p:[34,4,1485],t:7,e:"tab",a:{name:"Materials"},f:[{t:4,f:[{p:[36,6,1550],t:7,e:"ui-section",f:[{t:2,r:"name",p:[36,18,1562]}," : ",{t:2,r:"amount",p:[36,29,1573]}," cm3 - ",{t:4,f:[{p:[38,7,1623],t:7,e:"input",a:{value:[{t:2,r:"number",p:[38,20,1636]}],placeholder:["1-",{t:2,r:"sheets",p:[38,46,1662]}],"class":"number"}}," ",{p:[39,7,1698],t:7,e:"ui-button",a:{action:"releasemats",params:['{"latheType" : "circuit", "mat_id" : ',{t:2,r:"mat_id",p:[39,84,1775]},', "sheets" : ',{t:2,r:"number",p:[39,107,1798]},"}"]},f:["Release"]}],n:50,x:{r:["sheets"],s:"_0>0"},p:[37,6,1597]}]}],n:52,r:"data.circuitmat_list",p:[35,5,1513]}]}," ",{p:[44,4,1895],t:7,e:"tab",a:{name:"Chemicals"},f:[{t:4,f:[{p:[46,6,1961],t:7,e:"ui-section",f:[{t:2,r:"name",p:[46,18,1973]}," : ",{t:2,r:"amount",p:[46,29,1984]}," - ",{p:[47,7,2005],t:7,e:"ui-button",a:{action:"purgechem",params:['{"latheType" : "circuit", "name" : ',{t:2,r:"name",p:[47,80,2078]},', "id" : ',{t:2,r:"reagentid",p:[47,97,2095]},"}"]},f:["Purge"]}]}],n:52,r:"data.circuitchem_list",p:[45,5,1923]}]}]}]}]}],r:"data.circuitbusy"}],n:50,r:"data.circuit_linked",p:[1,1,0]},{t:4,n:51,f:[{p:[55,2,2216],t:7,e:"ui-display",a:{title:"No Linked Circuit Imprinter"}}],r:"data.circuit_linked"}]},e.exports=a.extend(r.exports)},{341:341}],443:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,31],t:7,e:"ui-display",a:{title:[{t:2,r:"data.sdesign_name",p:[2,21,50]}]},f:[{p:[3,3,77],t:7,e:"ui-section",a:{title:"Description"},f:[{t:2,r:"data.sdesign_desc",p:[3,35,109]}]}]}," ",{p:[5,2,162],t:7,e:"ui-display",a:{title:"Lathe Types"},f:[{t:4,f:[{p:[7,4,239],t:7,e:"ui-section",a:{title:"Circuit Imprinter"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&1"},p:[6,3,198]}," ",{t:4,f:[{p:[10,4,346],t:7,e:"ui-section",a:{title:"Protolathe"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&2"},p:[9,3,305]}," ",{t:4,f:[{p:[13,4,446],t:7,e:"ui-section",a:{title:"Autolathe"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&4"},p:[12,3,405]}," ",{t:4,f:[{p:[16,4,545],t:7,e:"ui-section",a:{title:"Crafting Fabricator"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&8"},p:[15,3,504]}," ",{t:4,f:[{p:[19,4,655],t:7,e:"ui-section",a:{title:"Exosuit Fabricator"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&16"},p:[18,3,613]}," ",{t:4,f:[{p:[22,4,764],t:7,e:"ui-section",a:{title:"Biogenerator"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&32"},p:[21,3,722]}," ",{t:4,f:[{p:[25,4,867],t:7,e:"ui-section",a:{title:"Limb Grower"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&64"},p:[24,3,825]}," ",{t:4,f:[{p:[28,4,970],t:7,e:"ui-section",a:{title:"Ore Smelter"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&128"},p:[27,3,927]}]}," ",{p:[31,2,1045],t:7,e:"ui-display",a:{title:"Materials"},f:[{t:4,f:[{p:[33,4,1116],t:7,e:"ui-section",a:{title:[{t:2,r:"matname",p:[33,23,1135]}]},f:[{t:2,r:"matamt",p:[33,36,1148]}," cm^3"]}],n:52,r:"data.sdesign_materials",p:[32,3,1079]}]}],n:50,r:"data.design_selected",p:[1,1,0]},{t:4,f:[{p:[38,2,1248],t:7,e:"ui-display",a:{title:"No Design Selected."}}],n:50,x:{r:["data.design_selected"],s:"!_0"},p:[37,1,1216]}]},e.exports=a.extend(r.exports)},{341:341}],444:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:4,f:[{p:[4,3,60],t:7,e:"ui-display",a:{title:"Destructive Analyzer Busy!"}}],n:50,r:"data.destroybusy",p:[3,2,32]},{t:4,n:51,f:[{t:4,f:[{p:[7,4,168],t:7,e:"ui-display",a:{title:"Destructive Analyzer Unloaded"}}],n:50,x:{r:["data.destroy_loaded"],s:"!_0"},p:[6,3,135]},{t:4,n:51,f:[{p:[9,4,248],t:7,e:"ui-display",a:{title:"Loaded Item"},f:[{p:[10,4,285],t:7,e:"ui-section",a:{title:"Name"},f:[{t:2,r:"data.destroy_name",p:[10,29,310]}]}]}," ",{p:[12,4,367],t:7,e:"ui-display",a:{title:"Boost Nodes"},f:[{t:4,f:[{p:[14,6,438],t:7,e:"ui-section",a:{title:[{t:2,r:"name",p:[14,25,457]}," | ",{t:2,r:"value",p:[14,36,468]}]},f:[{p:[15,7,487],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["allow"],s:'_0?null:"disabled"'},p:[15,25,505]}],action:"deconstruct",params:['{"id":',{t:2,r:"id",p:[15,90,570]},"}"]},f:["Deconstruct and Boost"]}]}],n:52,r:"data.boost_paths",p:[13,5,405]}]}," ",{p:[19,4,670],t:7,e:"ui-button",a:{action:"eject_da"},f:["Eject Item"]}],x:{r:["data.destroy_loaded"],s:"!_0"}}],r:"data.destroybusy"}],n:50,r:"data.destroy_linked",p:[2,1,2]},{t:4,n:51,f:[{p:[23,2,755],t:7,e:"ui-display",a:{title:"No Linked Destructive Analyzer"}}],r:"data.destroy_linked"}]},e.exports=a.extend(r.exports)},{341:341}],445:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[3,2,24],t:7,e:"ui-display",a:{title:"No Design Disk Loaded"}}],n:50,x:{r:["data.ddisk"],s:"!_0"},p:[2,1,2]},{t:4,n:51,f:[{t:4,f:[{p:[6,3,121],t:7,e:"ui-display",a:{title:"Design Disk Updating"}}],n:50,r:"data.ddisk_update",p:[5,2,92]},{t:4,n:51,f:[{ -t:4,f:[{p:[9,4,221],t:7,e:"ui-display",a:{title:"Design Disk"},f:[{p:[10,5,259],t:7,e:"ui-section",a:{title:"Disk Space"},f:["Disk Capacity: ",{t:2,r:"data.ddisk_size",p:[10,51,305]}," blueprints."]}," ",{p:[11,5,355],t:7,e:"ui-section",a:{title:"Disk IO"},f:[{p:[11,33,383],t:7,e:"ui-button",a:{action:"ddisk_upall"},f:["Upload all designs"]}]}," ",{p:[12,5,464],t:7,e:"ui-section",a:{title:"Clear Disk"},f:[{p:[12,36,495],t:7,e:"ui-button",a:{action:"clear_designdisk",style:"danger"},f:["WIPE ALL DATA"]}]}," ",{p:[13,5,591],t:7,e:"ui-section",a:{title:"Eject Disk"},f:[{p:[13,36,622],t:7,e:"ui-button",a:{action:"eject_designdisk"},f:["Eject Disk"]}]}]}," ",{p:[15,4,717],t:7,e:"ui-display",a:{title:"Disk Contents"},f:[{t:4,f:[{p:[17,6,792],t:7,e:"ui-section",a:{title:"Number"},f:["#",{t:2,r:"pos",p:[17,34,820]},": ",{t:4,f:[{p:[19,8,866],t:7,e:"ui-button",a:{action:"upload_empty_ddisk_slot",params:['{"slot": "',{t:2,r:"pos",p:[19,70,928]},'"}']},f:["Upload to Empty Slot"]}],n:50,x:{r:["id"],s:'_0=="null"'},p:[18,7,837]},{t:4,n:51,f:[{p:[21,8,996],t:7,e:"ui-button",a:{action:"select_design",params:['{"id": "',{t:2,r:"id",p:[21,58,1046]},'"}'],state:[{t:2,x:{r:["data.sdesign_id","id"],s:'_0==_1?"selected":null'},p:[21,75,1063]}]},f:[{t:2,r:"name",p:[21,122,1110]}]}," ",{p:[22,8,1139],t:7,e:"ui-button",a:{action:"ddisk_erasepos",style:"danger",params:['{"id": "',{t:2,r:"id",p:[22,74,1205]},'"}'],state:[{t:2,x:{r:["id"],s:'_0=="null"?"disabled":null'},p:[22,91,1222]}]},f:["Delete Slot"]}],x:{r:["id"],s:'_0=="null"'}}]}],n:52,r:"data.ddisk_designs",p:[16,5,757]}]}],n:50,x:{r:["data.ddisk_upload"],s:"!_0"},p:[8,3,190]},{t:4,n:51,f:[{p:[28,4,1367],t:7,e:"ui-display",a:{title:"Upload Design to Disk"},f:[{p:[28,46,1409],t:7,e:"ui-section",f:["Available Designs:"]}]}," ",{t:4,f:[{p:[30,5,1513],t:7,e:"ui-section",f:[{p:[30,17,1525],t:7,e:"ui-button",a:{action:"ddisk_uploaddesign",params:['{"id": "',{t:2,r:"id",p:[30,72,1580]},'"}']},f:[{t:2,r:"name",p:[30,82,1590]}]}]}],n:52,r:"data.ddisk_possible_designs",p:[29,4,1470]}],x:{r:["data.ddisk_upload"],s:"!_0"}}],r:"data.ddisk_update"}],x:{r:["data.ddisk"],s:"!_0"}}]},e.exports=a.extend(r.exports)},{341:341}],446:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[3,2,24],t:7,e:"ui-display",a:{title:"No Technology Disk Loaded"}}],n:50,x:{r:["data.tdisk"],s:"!_0"},p:[2,1,2]},{t:4,n:51,f:[{t:4,f:[{p:[6,3,125],t:7,e:"ui-display",a:{title:"Technology Disk Updating"}}],n:50,r:"data.tdisk_update",p:[5,2,96]},{t:4,n:51,f:[{p:[8,3,198],t:7,e:"ui-display",a:{title:"Technology Disk"},f:[{p:[9,4,239],t:7,e:"ui-section",a:{title:"Disk IO"},f:[{p:[9,32,267],t:7,e:"ui-button",a:{action:"tdisk_down"},f:["Download Research to Disk"]},{p:[9,100,335],t:7,e:"ui-button",a:{action:"tdisk_up"},f:["Upload Research from Disk"]}," ",{p:[10,4,406],t:7,e:"ui-section",a:{title:"Clear Disk"},f:[{p:[10,35,437],t:7,e:"ui-button",a:{action:"clear_techdisk",style:"danger"},f:["WIPE ALL DATA"]}]}," ",{p:[11,4,530],t:7,e:"ui-section",a:{title:"Eject Disk"},f:[{p:[11,35,561],t:7,e:"ui-button",a:{action:"eject_techdisk"},f:["Eject Disk"]}]}]}]}," ",{p:[13,3,652],t:7,e:"ui-display",a:{title:"Disk Contents"},f:[{t:4,f:[{p:[15,5,723],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[15,53,771]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[15,70,788]}]},f:[{t:2,r:"display_name",p:[15,115,833]}]}],n:52,r:"data.tdisk_nodes",p:[14,4,691]}]}],r:"data.tdisk_update"}],x:{r:["data.tdisk"],s:"!_0"}}]},e.exports=a.extend(r.exports)},{341:341}],447:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,29],t:7,e:"ui-display",a:{title:[{t:2,r:"data.snode_name",p:[2,21,48]}]},f:[{p:[3,3,73],t:7,e:"ui-section",a:{title:"Description"},f:["Description: ",{t:2,r:"data.snode_desc",p:[3,48,118]}]}," ",{p:[4,3,154],t:7,e:"ui-section",a:{title:"Point Cost"},f:["Point Cost: ",{t:2,r:"data.snode_cost",p:[4,46,197]}]}," ",{p:[5,3,233],t:7,e:"ui-section",a:{title:"Export Price"},f:["Export Price: ",{t:2,r:"data.snode_export",p:[5,50,280]}]}," ",{p:[6,3,318],t:7,e:"ui-button",a:{action:"research_node",params:['{"id"="',{t:2,r:"id",p:[6,52,367]},'"}'],state:[{t:2,x:{r:["data.snode_researched"],s:'_0?"disabled":null'},p:[6,69,384]}]},f:[{t:2,x:{r:["data.snode_researched"],s:'_0?"Researched":"Research Node"'},p:[6,115,430]}]}]}," ",{p:[8,2,518],t:7,e:"ui-display",a:{title:"Prerequisites"},f:[{t:4,f:[{p:[10,4,588],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[10,52,636]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[10,69,653]}]},f:[{t:2,r:"display_name",p:[10,114,698]}]}],n:52,r:"data.node_prereqs",p:[9,3,556]}]}," ",{p:[13,2,759],t:7,e:"ui-display",a:{title:"Unlocks"},f:[{t:4,f:[{p:[15,4,823],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[15,52,871]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[15,69,888]}]},f:[{t:2,r:"display_name",p:[15,114,933]}]}],n:52,r:"data.node_unlocks",p:[14,3,791]}]}," ",{p:[18,2,994],t:7,e:"ui-display",a:{title:"Designs"},f:[{t:4,f:[{p:[20,4,1058],t:7,e:"ui-button",a:{action:"select_design",params:['{"id": "',{t:2,r:"id",p:[20,54,1108]},'"}'],state:[{t:2,x:{r:["data.sdesign_id","id"],s:'_0==_1?"selected":null'},p:[20,71,1125]}]},f:[{t:2,r:"name",p:[20,118,1172]}]}],n:52,r:"data.node_designs",p:[19,3,1026]}]}],n:50,r:"data.node_selected",p:[1,1,0]},{t:4,f:[{p:[25,2,1263],t:7,e:"ui-display",a:{title:"No Node Selected."}}],n:50,x:{r:["data.node_selected"],s:"!_0"},p:[24,1,1233]}]},e.exports=a.extend(r.exports)},{341:341}],448:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:4,f:[{p:[3,3,59],t:7,e:"ui-display",a:{title:"Protolathe Busy!"}}],n:50,r:"data.protobusy",p:[2,2,33]},{t:4,n:51,f:[{p:[5,3,124],t:7,e:"ui-display",f:[{p:[6,4,141],t:7,e:"ui-section",f:["Search Available Designs: ",{p:[7,4,183],t:7,e:"input",a:{value:[{t:2,r:"textsearch",p:[7,17,196]}],placeholder:"Type Here","class":"text"}}," ",{p:[8,5,255],t:7,e:"ui-button",a:{action:"textSearch",params:['{"latheType" : "proto", "inputText" : ',{t:2,r:"textsearch",p:[8,82,332]},"}"]},f:["Search"]}]}," ",{p:[10,4,390],t:7,e:"ui-section",f:["Materials: ",{t:2,r:"data.protomats",p:[10,27,413]}," / ",{t:2,r:"data.protomaxmats",p:[10,48,434]}]}," ",{p:[11,4,473],t:7,e:"ui-section",f:["Reagents: ",{t:2,r:"data.protochems",p:[11,26,495]}," / ",{t:2,r:"data.protomaxchems",p:[11,48,517]}]}," ",{p:[12,3,556],t:7,e:"ui-display",f:[{p:[14,3,574],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.lathe_tabs",p:[14,18,589]}]},f:[{p:[15,4,615],t:7,e:"tab",a:{name:"Category List"},f:[{t:4,f:[{p:[17,6,678],t:7,e:"ui-button",a:{action:"switchcat",state:[{t:2,x:{r:["data.protocat","name"],s:'_0==_1?"selected":null'},p:[17,43,715]}],params:['{"type" : "proto", "cat" : "',{t:2,r:"name",p:[17,125,797]},'"}']},f:[{t:2,r:"name",p:[17,137,809]}]}],n:52,r:"data.protocats",p:[16,5,647]}]}," ",{p:[20,4,860],t:7,e:"tab",a:{name:"Selected Category"},f:[{t:4,f:[{p:[22,6,926],t:7,e:"ui-section",f:[{t:2,r:"name",p:[22,18,938]},{t:2,r:"matstring",p:[22,26,946]}," ",{t:4,f:[{p:[24,8,996],t:7,e:"input",a:{value:[{t:2,r:"number",p:[24,21,1009]}],placeholder:["1-",{t:2,x:{r:["canprint"],s:"_0>10?10:_0"},p:[24,47,1035]}],"class":"number"}}],n:50,x:{r:["canprint"],s:"_0>1"},p:[23,7,967]}," ",{p:[26,7,1108],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[26,40,1141]}],params:['{"latheType" : "proto", "id" : "',{t:2,r:"id",p:[26,117,1218]},'", "amount" : "',{t:2,r:"number",p:[26,138,1239]},'"}']},f:["Print"]}]}],n:52,r:"data.protodes",p:[21,5,896]}]}," ",{p:[30,4,1321],t:7,e:"tab",a:{name:"Search Results"},f:[{t:4,f:[{p:[32,6,1386],t:7,e:"ui-section",f:[{t:2,r:"name",p:[32,18,1398]},{t:2,r:"matstring",p:[32,26,1406]}," ",{t:4,f:[{p:[34,8,1456],t:7,e:"input",a:{value:[{t:2,r:"number",p:[34,21,1469]}],placeholder:["1-",{t:2,x:{r:["canprint"],s:"_0>10?10:_0"},p:[34,47,1495]}],"class":"number"}}],n:50,x:{r:["canprint"],s:"_0>1"},p:[33,7,1427]}," ",{p:[36,7,1568],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[36,40,1601]}],params:['{"latheType" : "proto", "id" : "',{t:2,r:"id",p:[36,117,1678]},'", "amount" : "',{t:2,r:"number",p:[36,138,1699]},'"}']},f:["Print"]}]}],n:52,r:"data.protomatch",p:[31,5,1354]}]}," ",{p:[40,4,1781],t:7,e:"tab",a:{name:"Materials"},f:[{t:4,f:[{p:[42,6,1844],t:7,e:"ui-section",f:[{t:2,r:"name",p:[42,18,1856]}," : ",{t:2,r:"amount",p:[42,29,1867]}," cm3 - ",{t:4,f:[{p:[44,7,1917],t:7,e:"input",a:{value:[{t:2,r:"number",p:[44,20,1930]}],placeholder:["1-",{t:2,r:"sheets",p:[44,46,1956]}],"class":"number"}}," ",{p:[45,7,1992],t:7,e:"ui-button",a:{action:"releasemats",params:['{"latheType" : "proto", "mat_id" : ',{t:2,r:"mat_id",p:[45,82,2067]},', "sheets" : ',{t:2,r:"number",p:[45,105,2090]},"}"]},f:["Release"]}],n:50,x:{r:["sheets"],s:"_0>0"},p:[43,6,1891]}]}],n:52,r:"data.protomat_list",p:[41,5,1809]}]}," ",{p:[50,4,2187],t:7,e:"tab",a:{name:"Chemicals"},f:[{t:4,f:[{p:[52,6,2251],t:7,e:"ui-section",f:[{t:2,r:"name",p:[52,18,2263]}," : ",{t:2,r:"amount",p:[52,29,2274]}," - ",{p:[53,7,2295],t:7,e:"ui-button",a:{action:"purgechem",params:['{"latheType" : "proto", "name" : ',{t:2,r:"name",p:[53,78,2366]},', "id" : ',{t:2,r:"reagentid",p:[53,95,2383]},"}"]},f:["Purge"]}]}],n:52,r:"data.protochem_list",p:[51,5,2215]}]}]}]}]}],r:"data.protobusy"}],n:50,r:"data.protolathe_linked",p:[1,1,0]},{t:4,n:51,f:[{p:[61,2,2504],t:7,e:"ui-display",a:{title:"No Linked Protolathe"}}],r:"data.protolathe_linked"}]},e.exports=a.extend(r.exports)},{341:341}],449:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,1,14],t:7,e:"span",a:{"class":"memoedit"},f:["Nanotrasen R&D Console"]},{p:[2,53,66],t:7,e:"br"}," Available Points: ",{p:[3,19,91],t:7,e:"ui-section",a:{title:"Research Points"},f:[{t:2,r:"data.research_points_stored",p:[3,55,127]}]}," ",{p:[4,1,173],t:7,e:"ui-section",a:{title:["Page Selection - ",{t:2,r:"page",p:[4,37,209]}]},f:[{p:[4,47,219],t:7,e:"input",a:{value:[{t:2,r:"pageselect",p:[4,60,232]}],placeholder:"1","class":"number"}}," Select Page: ",{p:[5,14,294],t:7,e:"ui-button",a:{action:"page",params:['{"num" : "',{t:2,r:"pageselect",p:[5,57,337]},'"}']},f:["[Go]"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],450:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"span",a:{"class":"bad"},f:["Settings"]},{p:[1,34,33],t:7,e:"br"},{p:[1,39,38],t:7,e:"br"}," ",{p:[2,1,45],t:7,e:"ui-button",a:{action:"Resync"},f:["RESYNC MACHINERY"]},{p:[2,56,100],t:7,e:"br"}," ",{p:[3,1,107],t:7,e:"ui-button",a:{action:"Lock"},f:["LOCK"]}," ",{p:[4,1,150],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "destroy"}',state:[{t:2,x:{r:["data.destroy_linked"],s:'_0?null:"disabled"'},p:[4,71,220]}]},f:["Disconnect Destructive Analyzer"]}," ",{p:[5,1,309],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "lathe"}',state:[{t:2,x:{r:["data.protolathe_linked"],s:'_0?null:"disabled"'},p:[5,69,377]}]},f:["Disconnect Protolathe"]}," ",{p:[6,1,459],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "imprinter"}',state:[{t:2,x:{r:["data.circuit_linked"],s:'_0?null:"disabled"'},p:[6,73,531]}]},f:["Disconnect Circuit Imprinter"]}]},e.exports=a.extend(r.exports)},{341:341}],451:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Available for Research"},f:[{t:4,f:[{p:[3,3,78],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[3,51,126]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[3,68,143]}]},f:[{t:2,r:"display_name",p:[3,113,188]}]}],n:52,r:"data.techweb_avail",p:[2,2,46]}]}," ",{p:[6,1,245],t:7,e:"ui-display",a:{title:"Locked Nodes"},f:[{t:4,f:[{p:[8,3,314],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[8,51,362]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[8,68,379]}]},f:[{t:2,r:"display_name",p:[8,113,424]}]}],n:52,r:"data.techweb_locked",p:[7,2,281]}]}," ",{p:[11,1,482],t:7,e:"ui-display",a:{title:"Researched Nodes"},f:[{t:4,f:[{p:[13,3,559],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[13,51,607]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[13,68,624]}]},f:[{t:2,r:"display_name",p:[13,113,669]}]}],n:52,r:"data.techweb_researched",p:[12,2,522]}]}]},e.exports=a.extend(r.exports)},{341:341}],452:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,25],t:7,e:"ui-notice",f:[{p:[3,3,40],t:7,e:"span",f:["The grinder is currently processing and cannot be used."]}]}],n:50,r:"data.processing",p:[1,1,0]},{p:{button:[{p:[8,5,208],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[8,36,239]}],action:"eject"},f:["Eject Contents"]}]},t:7,e:"ui-display",a:{title:"Processing Chamber",button:0},f:[" ",{p:[10,3,364],t:7,e:"ui-section",a:{label:"Grinding"},f:[{p:[11,5,399],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.operating"],s:'_0?"average":"good"'},p:[11,18,412]}]},f:[{t:2,x:{r:["data.operating"],s:'_0?"Busy":"Ready"'},p:[11,59,453]}]}," ",{p:[12,2,500],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[12,35,533]}],action:"grind"},f:["Activate"]}]}," ",{p:[14,3,653],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[17,9,755],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:["The ",{t:2,r:"name",p:[17,56,802]}]},{p:[17,71,817],t:7,e:"br"}],n:52,r:"adata.contentslist",p:[16,7,717]},{t:4,n:51,f:[{p:[19,9,848],t:7,e:"span",f:["No Contents"]}],r:"adata.contentslist"}],n:50,r:"data.contents",p:[15,5,688]},{t:4,n:51,f:[{p:[22,7,911],t:7,e:"span",f:["No Contents"]}],r:"data.contents"}]}]}," ",{p:{button:[{p:[28,5,1047],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.isBeakerLoaded"],s:'(_0==0)&&_1?null:"disabled"'},p:[28,36,1078]}],action:"detach"},f:["Detach"]}]},t:7,e:"ui-display",a:{title:"Container",button:0},f:[" ",{p:[30,3,1202],t:7,e:"ui-section",a:{label:"Reagents"},f:[{t:4,f:[{p:[32,7,1272],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[32,13,1278]},"/",{t:2,r:"data.beakerMaxVolume",p:[32,55,1320]}," Units"]}," ",{p:[33,7,1365],t:7,e:"br"}," ",{t:4,f:[{p:[35,9,1418],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[35,52,1461]}," units of ",{t:2,r:"name",p:[35,87,1496]}]},{p:[35,102,1511],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[34,7,1378]},{t:4,n:51,f:[{p:[37,9,1542],t:7,e:"span",a:{"class":"bad"},f:["Container Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[31,5,1237]},{t:4,n:51,f:[{p:[40,7,1621],t:7,e:"span",a:{"class":"average"},f:["No Container"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],453:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,64],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,105],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,123]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,195]},', "flipped": ',{t:2,r:"flipped",p:[6,42,215]},"}"]},f:[{p:[6,56,229],t:7,e:"span",a:{"class":["pipes32x32 ",{t:2,r:"dir",p:[6,80,253]},"-",{t:2,r:"icon_state",p:[6,88,261]}],title:[{t:2,r:"dir_name",p:[6,111,284]}]}}]}],n:52,r:"previews",p:[4,4,81]}]}],n:52,r:"data.preview_rows",p:[2,2,33]}]}," ",{t:4,f:[{p:[12,2,406],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[14,4,468],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["@key","data.selected_color"],s:'_0==_1?"selected":null'},p:[14,22,486]}],action:"color",params:['{"paint_color": ',{t:2,r:"@key",p:[15,44,583]},"}"]},f:[{t:2,r:"@key",p:[15,55,594]}]}],n:52,r:"data.paint_colors",p:[13,3,436]}]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[11,1,377]},{p:[19,1,654],t:7,e:"ui-display",a:{title:"Utilities"},f:[{p:[20,2,687],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&1?"check-square-o":"square-o"'},p:[20,19,704]}],action:"mode",params:'{"mode": 1}'},f:["Build"]}," ",{p:[22,2,813],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&2?"check-square-o":"square-o"'},p:[22,19,830]}],action:"mode",params:'{"mode": 2}'},f:["Wrench"]}," ",{p:[24,2,940],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&4?"check-square-o":"square-o"'},p:[24,19,957]}],action:"mode",params:'{"mode": 4}'},f:["Destroy"]}," ",{t:4,f:[{p:[27,3,1098],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&8?"check-square-o":"square-o"'},p:[27,20,1115]}],action:"mode",params:'{"mode": 8}'},f:["Paint"]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[26,2,1068]}]}," ",{p:[31,1,1249],t:7,e:"ui-display",a:{title:"Category"},f:[{p:[32,2,1281],t:7,e:"ui-section",f:[{p:[33,3,1297],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==0?"check-square-o":"square-o"'},p:[33,20,1314]}],state:[{t:2,x:{r:["data.category"],s:'_0<=0?"selected":null'},p:[33,83,1377]}],action:"category",params:'{"category": 0}'},f:["Atmospherics"]}," ",{p:[35,3,1496],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==1?"check-square-o":"square-o"'},p:[35,20,1513]}],state:[{t:2,x:{r:["data.category"],s:'_0==1?"selected":null'},p:[35,83,1576]}],action:"category",params:'{"category": 1}'},f:["Disposals"]}," ",{p:[37,3,1692],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==2?"check-square-o":"square-o"'},p:[37,20,1709]}],state:[{t:2,x:{r:["data.category"],s:'_0==2?"selected":null'},p:[37,83,1772]}],action:"category",params:'{"category": 2}'},f:["Transit Tubes"]}]}," ",{t:4,f:[{p:[41,3,1937],t:7,e:"ui-section",a:{label:"Piping Layer"},f:[{p:[42,4,1975],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==1?"selected":null'},p:[42,22,1993]}],action:"piping_layer",params:'{"piping_layer": 1}'},f:["1"]}," ",{p:[44,4,2115],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==2?"selected":null'},p:[44,22,2133]}],action:"piping_layer",params:'{"piping_layer": 2}'},f:["2"]}," ",{p:[46,4,2255],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==3?"selected":null'},p:[46,22,2273]}],action:"piping_layer",params:'{"piping_layer": 3}'},f:["3"]}]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[40,2,1907]}]}," ",{t:4,f:[{p:[52,2,2462],t:7,e:"ui-display",a:{title:[{t:2,r:"cat_name",p:[52,21,2481]}]},f:[{t:4,f:[{p:[54,4,2521],t:7,e:"ui-section",f:[{p:[55,5,2539],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[55,23,2557]}],action:"pipe_type",params:['{"pipe_type": ',{t:2,r:"pipe_index",p:[56,28,2638]},', "category": ',{t:2,r:"cat_name",p:[56,56,2666]},"}"]},f:[{t:2,r:"pipe_name",p:[56,71,2681]}]}]}],n:52,r:"recipes",p:[53,3,2499]}]}],n:52,r:"data.categories",p:[51,1,2434]}]},e.exports=a.extend(r.exports)},{341:341}],454:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[3,3,60],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[3,21,78]}],action:"color",params:['{"paint_color": ',{t:2,r:"color_name",p:[4,28,155]},"}"]},f:[{t:2,r:"color_name",p:[4,45,172]}]}],n:52,r:"data.paint_colors",p:[2,2,29]}]}]},e.exports=a.extend(r.exports)},{341:341}],455:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,64],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,105],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,123]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,195]},', "flipped": ',{t:2,r:"flipped",p:[6,42,215]},"}"]},f:[{p:[6,56,229],t:7,e:"img",a:{src:["pipe.",{t:2,r:"dir",p:[6,71,244]},".",{t:2,r:"icon_state",p:[6,79,252]},".png"],title:[{t:2,r:"dir_name",p:[6,106,279]}]}}]}],n:52,r:"previews",p:[4,4,81]}]}],n:52,r:"data.preview_rows",p:[2,2,33]}]}]},e.exports=a.extend(r.exports)},{341:341}],456:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Satellite Network Control",button:0},f:[{t:4,f:[{p:[8,4,168],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[9,9,209],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[9,31,231]}]}," ",{p:[10,9,253],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"mode",p:[10,30,274]}]}," ",{p:[11,9,298],t:7,e:"div",a:{"class":"content"},f:[{p:[12,11,331],t:7,e:"ui-button",a:{action:"toggle",params:['{"id": "',{t:2,r:"id",p:[12,54,374]},'"}']},f:[{t:2,x:{r:["active"],s:'_0?"Deactivate":"Activate"'},p:[12,64,384]}]}]}]}],n:52,r:"data.satellites",p:[7,2,138]}]}," ",{t:4,f:[{p:[18,1,528],t:7,e:"ui-display",a:{title:"Station Shield Coverage"},f:[{p:[19,3,576],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.meteor_shield_coverage_max",p:[19,24,597]}],value:[{t:2,r:"data.meteor_shield_coverage",p:[19,68,641]}]},f:[{t:2,x:{r:["data.meteor_shield_coverage","data.meteor_shield_coverage_max"],s:"100*_0/_1"},p:[19,101,674]}," %"]}," ",{p:[20,1,758],t:7,e:"ui-display",f:[]}]}],n:50,r:"data.meteor_shield",p:[17,1,500]}]},e.exports=a.extend(r.exports)},{341:341}],457:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,26],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[2,20,43]}],style:[{t:2,x:{r:["enabled"],s:'_0?"selected":null'},p:[2,72,95]}],action:"toggle_filter",params:['{"id_tag": "',{t:2,r:"id_tag",p:[3,48,176]},'", "val": ',{t:2,r:"gas_id",p:[3,68,196]},"}"]},f:[{t:2,r:"gas_name",p:[3,81,209]}]}],n:52,r:"filter_types",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],458:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," ",{p:[5,1,200],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[5,16,215]}]},f:[{p:[6,2,233],t:7,e:"tab",a:{name:"Status"},f:[{p:[7,3,256],t:7,e:"status"}]}," ",{p:[9,2,277],t:7,e:"tab",a:{name:"Templates"},f:[{p:[10,3,303],t:7,e:"templates"}]}," ",{p:[12,2,327],t:7,e:"tab",a:{name:"Modification"},f:[{t:4,f:[{p:[14,3,381],t:7,e:"modification"}],n:50,r:"data.selected",p:[13,3,356]}," ",{t:4,f:[{p:[17,3,437],t:7,e:"span",a:{"class":"bad"},f:["No shuttle selected."]}],n:50,x:{r:["data.selected"],s:"!_0"},p:[16,3,411]}]}]}]},r.exports.components=r.exports.components||{};var i={modification:t(459),templates:t(461),status:t(460)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,459:459,460:460,461:461}],459:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:["Selected: ",{t:2,r:"data.selected.name",p:[1,30,29]}]},f:[{t:4,f:[{p:[3,5,96],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.selected.description",p:[3,37,128]}]}],n:50,r:"data.selected.description",p:[2,3,57]}," ",{t:4,f:[{p:[6,5,224],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"data.selected.admin_notes",p:[6,37,256]}]}],n:50,r:"data.selected.admin_notes",p:[5,3,185]}]}," ",{t:4,f:[{p:[11,3,361],t:7,e:"ui-display",a:{title:["Existing Shuttle: ",{t:2,r:"data.existing_shuttle.name",p:[11,40,398]}]},f:["Status: ",{t:2,r:"data.existing_shuttle.status",p:[12,13,444]}," ",{t:4,f:["(",{t:2,r:"data.existing_shuttle.timeleft",p:[14,8,526]},")"],n:50,r:"data.existing_shuttle.timer",p:[13,5,482]}," ",{p:[16,5,580],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"data.existing_shuttle.id",p:[17,41,649]},'"}']},f:["Jump To"]}]}],n:50,r:"data.existing_shuttle",p:[10,1,328]},{t:4,f:[{p:[24,3,778],t:7,e:"ui-display",a:{title:"Existing Shuttle: None"}}],n:50,x:{r:["data.existing_shuttle"],s:"!_0"},p:[23,1,744]},{p:[27,1,847],t:7,e:"ui-button",a:{action:"preview",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[28,27,902]},'"}']},f:["Preview"]}," ",{p:[31,1,961],t:7,e:"ui-button",a:{action:"load",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[32,27,1013]},'"}'],style:"danger"},f:["Load"]}," ",{p:[37,1,1089],t:7,e:"ui-display",a:{title:"Status"},f:[]}]},e.exports=a.extend(r.exports)},{341:341}],460:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"table",a:{width:"100%"},f:[{t:4,f:[{p:[3,3,49],t:7,e:"tr",f:[{p:[4,5,59],t:7,e:"td",f:[{p:[5,7,71],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"id",p:[5,69,133]},'"}']},f:["JMP"]}]}," ",{p:[9,5,193],t:7,e:"td",f:[{p:[10,7,205],t:7,e:"ui-button",a:{action:"fly",params:['{"id": "',{t:2,r:"id",p:[10,47,245]},'"}'],state:[{t:2,x:{r:["can_fly"],s:'_0?null:"disabled"'},p:[10,64,262]}]},f:["Fly"]}]}," ",{p:[14,5,345],t:7,e:"td",f:[{t:2,r:"name",p:[15,7,357]}," (",{p:[15,17,367],t:7,e:"code",f:[{t:2,r:"id",p:[15,23,373]}]},")"]}," ",{p:[17,5,404],t:7,e:"td",f:[{t:2,r:"status",p:[18,7,416]}]}," ",{p:[20,5,443],t:7,e:"td",f:[{t:4,f:[{t:2,r:"mode",p:[22,9,477]}],n:50,r:"mode",p:[21,7,455]}," ",{t:4,f:["(",{t:2,r:"timeleft",p:[25,10,532]},") ",{p:[26,9,555],t:7,e:"ui-button",a:{action:"fast_travel",params:['{"id": "',{t:2,r:"id",p:[26,57,603]},'"}'],state:[{t:2,x:{r:["can_fast_travel"],s:'_0?null:"disabled"'},p:[26,74,620]}]},f:["Fast Travel"]}],n:50,r:"timer",p:[24,7,508]}]}]}],n:52,r:"data.shuttles",p:[2,1,22]}]}]},e.exports=a.extend(r.exports)},{341:341}],461:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.templates_tabs",p:[1,16,15]}]},f:[{t:4,f:[{p:[3,5,74],t:7,e:"tab",a:{name:[{t:2,r:"port_id",p:[3,16,85]}]},f:[{t:4,f:[{p:[5,9,135],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[5,28,154]}]},f:[{t:4,f:[{p:[7,13,209],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[7,45,241]}]}],n:50,r:"description",p:[6,11,176]}," ",{t:4,f:[{p:[10,13,333],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"admin_notes",p:[10,45,365]}]}],n:50,r:"admin_notes",p:[9,11,300]}," ",{p:[13,11,426],t:7,e:"ui-button",a:{action:"select_template",params:['{"shuttle_id": "',{t:2,r:"shuttle_id",p:[14,37,499]},'"}'],state:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"selected":null'},p:[15,20,537]}]},f:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"Selected":"Select"'},p:[17,13,630]}]}]}],n:52,r:"templates",p:[4,7,106]}]}],n:52,r:"data.templates",p:[2,3,44]}]}]},e.exports=a.extend(r.exports)},{341:341}],462:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,186],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,220],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,233]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,262]}]}]}," ",{p:[9,5,315],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[10,7,350],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[10,20,363]}],max:[{t:2,r:"data.occupant.maxHealth",p:[10,54,397]}],value:[{t:2,r:"data.occupant.health",p:[10,90,433]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[11,16,475]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[11,68,527]}]}]}," ",{t:4,f:[{p:[14,7,764],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[14,26,783]}]},f:[{p:[15,9,804],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[15,30,825]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[15,66,861]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[15,103,898]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[13,5,598]}," ",{p:[18,5,985],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[19,9,1021],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[19,22,1034]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[19,68,1080]}]}]}," ",{p:[21,5,1163],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[22,9,1199],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[22,22,1212]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[22,68,1258]}]}]}," ",{p:[24,5,1342],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[26,11,1429],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[26,54,1472]}," units of ",{t:2,r:"name",p:[26,89,1507]}]},{p:[26,104,1522],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[25,9,1384]},{t:4,n:51,f:[{p:[28,11,1557],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[5,3,159]}]}," ",{p:[33,1,1653],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[34,2,1685],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[35,5,1716],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[35,22,1733]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[35,71,1782]}]}]}," ",{p:[37,3,1847],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[39,7,1908],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied","allowed"],s:'_0&&_1?null:"disabled"'},p:[39,38,1939]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[39,122,2023]},'"}']},f:[{t:2,r:"name",p:[39,132,2033]}]},{p:[39,152,2053],t:7,e:"br"}],n:52,r:"data.chems",p:[38,5,1880]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],463:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,25],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,44]}],labelcolor:[{t:2,r:"htmlcolor",p:[2,44,66]}],candystripe:0,right:0},f:[{p:[3,5,105],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,32,132],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0=="Dead"?"bad bold":_0=="Unconscious"?"average bold":"good"'},p:[3,45,145]}]},f:[{t:2,r:"status",p:[3,132,232]}]}]}," ",{p:[4,5,268],t:7,e:"ui-section",a:{label:"Jelly"},f:[{t:2,r:"exoticblood",p:[4,31,294]}]}," ",{p:[5,5,328],t:7,e:"ui-section",a:{label:"Location"},f:[{t:2,r:"area",p:[5,34,357]}]}," ",{p:[7,5,386],t:7,e:"ui-button",a:{state:[{t:2,r:"swap_button_state",p:[8,14,411]}],action:"swap",params:['{"ref": "',{t:2,r:"ref",p:[9,38,472]},'"}']},f:[{t:4,f:["You Are Here"],n:50,x:{r:["occupied"],s:'_0=="owner"'},p:[10,7,491]},{t:4,n:51,f:[{t:4,f:["Occupied"],n:50,x:{r:["occupied"],s:'_0=="stranger"'},p:[13,9,566]},{t:4,n:51,f:["Swap"],x:{r:["occupied"],s:'_0=="stranger"'}}],x:{r:["occupied"],s:'_0=="owner"'}}]}]}],n:52,r:"data.bodies",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],464:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,23,82],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.drying"],s:'_0?"stop":"tint"'},p:[4,40,99]}],action:"Dry"},f:[{t:2,x:{r:["data.drying"],s:'_0?"Stop drying":"Dry"'},p:[4,88,147]}]}],n:50,r:"data.isdryer",p:[4,3,62]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[7,3,258],t:7,e:"ui-notice",f:[{p:[8,5,275],t:7,e:"span",f:["Unfortunately, this ",{t:2,r:"data.name",p:[8,31,301]}," is empty."]}]}],n:50,x:{r:["data.contents.length"],s:"_0==0"},p:[6,1,221]},{t:4,n:51,f:[{p:[11,1,359],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[12,2,391],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[13,4,425],t:7,e:"section",a:{"class":"cell bold"},f:["Item"]}," ",{p:[16,4,482],t:7,e:"section",a:{"class":"cell bold"},f:["Quantity"]}," ",{p:[19,4,543],t:7,e:"section",a:{"class":"cell bold",align:"center"},f:[{t:4,f:[{t:2,r:"data.verb", -p:[20,22,608]}],n:50,r:"data.verb",p:[20,5,591]},{t:4,n:51,f:["Dispense"],r:"data.verb"}]}]}," ",{t:4,f:[{p:[24,3,703],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[25,4,737],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[26,5,765]}]}," ",{p:[28,4,793],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[29,5,835]}]}," ",{p:[31,4,865],t:7,e:"section",a:{"class":"table",alight:"right"},f:[{p:[32,5,909],t:7,e:"section",a:{"class":"cell"}}," ",{p:[33,5,947],t:7,e:"section",a:{"class":"cell"},f:[{p:[34,6,976],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[34,45,1015]}],params:['{ "name" : ',{t:2,r:"name",p:[34,102,1072]},', "amount" : 1 }']},f:["One"]}]}," ",{p:[38,5,1151],t:7,e:"section",a:{"class":"cell"},f:[{p:[39,6,1180],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>1)?null:"disabled"'},p:[39,45,1219]}],params:['{ "name" : ',{t:2,r:"name",p:[39,101,1275]}," }"]},f:["Many"]}]}]}]}],n:52,r:"data.contents",p:[23,2,676]}]}],x:{r:["data.contents.length"],s:"_0==0"}}]}]},e.exports=a.extend(r.exports)},{341:341}],465:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{capacityPercentState:function(){var t=this.get("data.capacityPercent");return t>50?"good":t>15?"average":"bad"},inputState:function(){return this.get("data.capacityPercent")>=100?"good":this.get("data.inputting")?"average":"bad"},outputState:function(){return this.get("data.outputting")?"good":this.get("data.charge")>0?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[24,1,663],t:7,e:"ui-display",a:{title:"Storage"},f:[{p:[25,3,695],t:7,e:"ui-section",a:{label:"Stored Energy"},f:[{p:[26,5,735],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.capacityPercent",p:[26,38,768]}],state:[{t:2,r:"capacityPercentState",p:[26,71,801]}]},f:[{t:2,x:{r:["adata.capacityPercent"],s:"Math.fixed(_0)"},p:[26,97,827]},"%"]}]}]}," ",{p:[29,1,908],t:7,e:"ui-display",a:{title:"Input"},f:[{p:[30,3,938],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{p:[31,5,976],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"refresh":"close"'},p:[31,22,993]}],style:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"selected":null'},p:[31,74,1045]}],action:"tryinput"},f:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"Auto":"Off"'},p:[32,25,1113]}]},"   [",{p:[34,6,1182],t:7,e:"span",a:{"class":[{t:2,r:"inputState",p:[34,19,1195]}]},f:[{t:2,x:{r:["data.capacityPercent","data.inputting"],s:'_0>=100?"Fully Charged":_1?"Charging":"Not Charging"'},p:[34,35,1211]}]},"]"]}," ",{p:[36,3,1335],t:7,e:"ui-section",a:{label:"Target Input"},f:[{p:[37,5,1374],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.inputLevelMax",p:[37,26,1395]}],value:[{t:2,r:"data.inputLevel",p:[37,57,1426]}]},f:[{t:2,r:"adata.inputLevel_text",p:[37,78,1447]}]}]}," ",{p:[39,3,1501],t:7,e:"ui-section",a:{label:"Adjust Input"},f:[{p:[40,5,1540],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[40,44,1579]}],action:"input",params:'{"target": "min"}'}}," ",{p:[41,5,1674],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[41,39,1708]}],action:"input",params:'{"adjust": -10000}'}}," ",{p:[42,5,1804],t:7,e:"ui-button",a:{icon:"pencil",action:"input",params:'{"target": "input"}'},f:["Set"]}," ",{p:[43,5,1894],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[43,38,1927]}],action:"input",params:'{"adjust": 10000}'}}," ",{p:[44,5,2039],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[44,43,2077]}],action:"input",params:'{"target": "max"}'}}]}," ",{p:[46,3,2204],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[47,3,2238],t:7,e:"span",f:[{t:2,r:"adata.inputAvailable",p:[47,9,2244]}]}]}]}," ",{p:[50,1,2308],t:7,e:"ui-display",a:{title:"Output"},f:[{p:[51,3,2339],t:7,e:"ui-section",a:{label:"Output Mode"},f:[{p:[52,5,2377],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"power-off":"close"'},p:[52,22,2394]}],style:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"selected":null'},p:[52,77,2449]}],action:"tryoutput"},f:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"On":"Off"'},p:[53,26,2519]}]},"   [",{p:[55,6,2587],t:7,e:"span",a:{"class":[{t:2,r:"outputState",p:[55,19,2600]}]},f:[{t:2,x:{r:["data.outputting","data.charge"],s:'_0?"Sending":_1>0?"Not Sending":"No Charge"'},p:[55,36,2617]}]},"]"]}," ",{p:[57,3,2724],t:7,e:"ui-section",a:{label:"Target Output"},f:[{p:[58,5,2764],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.outputLevelMax",p:[58,26,2785]}],value:[{t:2,r:"data.outputLevel",p:[58,58,2817]}]},f:[{t:2,r:"adata.outputLevel_text",p:[58,80,2839]}]}]}," ",{p:[60,3,2894],t:7,e:"ui-section",a:{label:"Adjust Output"},f:[{p:[61,5,2934],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[61,44,2973]}],action:"output",params:'{"target": "min"}'}}," ",{p:[62,5,3070],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[62,39,3104]}],action:"output",params:'{"adjust": -10000}'}}," ",{p:[63,5,3202],t:7,e:"ui-button",a:{icon:"pencil",action:"output",params:'{"target": "input"}'},f:["Set"]}," ",{p:[64,5,3293],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[64,38,3326]}],action:"output",params:'{"adjust": 10000}'}}," ",{p:[65,5,3441],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[65,43,3479]}],action:"output",params:'{"target": "max"}'}}]}," ",{p:[67,3,3609],t:7,e:"ui-section",a:{label:"Outputting"},f:[{p:[68,3,3644],t:7,e:"span",f:[{t:2,r:"adata.outputUsed",p:[68,9,3650]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],466:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:["\ufeff",{t:4,f:[" ",{p:[2,2,33],t:7,e:"ui-display",a:{title:"Dispersal Tank"},f:[{p:[3,3,73],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[4,4,104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.active"],s:'_0?"power-off":"close"'},p:[4,21,121]}],style:[{t:2,x:{r:["data.active"],s:'_0?"selected":null'},p:[5,12,174]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[6,12,223]}],action:"power"},f:[{t:2,x:{r:["data.active"],s:'_0?"On":"Off"'},p:[7,20,286]}]}]}," ",{p:[10,3,354],t:7,e:"ui-section",a:{label:"Smoke Radius Setting"},f:[{p:[11,5,401],t:7,e:"div",a:{"class":"content",style:"float:left"},f:[{p:[12,6,448],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=1?null:"disabled"'},p:[12,36,478]}],style:[{t:2,x:{r:["data.setting"],s:'_0==1?"selected":null'},p:[12,89,531]}],action:"setting",params:'{"amount": 1}'},f:["3"]}," ",{p:[13,6,634],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=2?null:"disabled"'},p:[13,36,664]}],style:[{t:2,x:{r:["data.setting"],s:'_0==2?"selected":null'},p:[13,89,717]}],action:"setting",params:'{"amount": 2}'},f:["6"]}," ",{p:[14,6,820],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=3?null:"disabled"'},p:[14,36,850]}],style:[{t:2,x:{r:["data.setting"],s:'_0==3?"selected":null'},p:[14,89,903]}],action:"setting",params:'{"amount": 3}'},f:["9"]}," ",{p:[15,6,1006],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=4?null:"disabled"'},p:[15,36,1036]}],style:[{t:2,x:{r:["data.setting"],s:'_0==4?"selected":null'},p:[15,89,1089]}],action:"setting",params:'{"amount": 4}'},f:["12"]}," ",{p:[16,6,1193],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=5?null:"disabled"'},p:[16,36,1223]}],style:[{t:2,x:{r:["data.setting"],s:'_0==5?"selected":null'},p:[16,89,1276]}],action:"setting",params:'{"amount": 5}'},f:["15"]}]}]}," ",{p:[19,3,1410],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[21,6,1476],t:7,e:"span",f:[{t:2,x:{r:["adata.TankCurrentVolume"],s:"Math.round(_0)"},p:[21,12,1482]},"/",{t:2,r:"data.TankMaxVolume",p:[21,52,1522]}," Units"]}," ",{p:[22,6,1564],t:7,e:"br"}," ",{p:[23,5,1575],t:7,e:"br"}," ",{t:4,f:[{p:[25,7,1623],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[25,50,1666]}," units of ",{t:2,r:"name",p:[25,85,1701]}]},{p:[25,100,1716],t:7,e:"br"}],n:52,r:"adata.TankContents",p:[24,6,1587]}],n:50,r:"data.isTankLoaded",p:[20,4,1444]},{t:4,n:51,f:[{p:[28,6,1757],t:7,e:"span",a:{"class":"bad"},f:["Tank Empty"]}],r:"data.isTankLoaded"}," ",{p:[30,4,1809],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Eject":"Close"'},p:[30,21,1826]}],style:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"selected":null'},p:[31,12,1881]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[32,12,1936]}],action:"purge"},f:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Purge Contents":"No chemicals detected"'},p:[33,20,1999]}]}]}]}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,2,1]}]},e.exports=a.extend(r.exports)},{341:341}],467:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{t:2,x:{r:["adata.generated"],s:"Math.round(_0)"},p:[3,5,73]},"W"]}," ",{p:[5,3,126],t:7,e:"ui-section",a:{label:"Orientation"},f:[{p:[6,5,164],t:7,e:"span",f:[{t:2,x:{r:["adata.angle"],s:"Math.round(_0)"},p:[6,11,170]},"° (",{t:2,r:"data.direction",p:[6,45,204]},")"]}]}," ",{p:[8,3,251],t:7,e:"ui-section",a:{label:"Adjust Angle"},f:[{p:[9,5,290],t:7,e:"ui-button",a:{icon:"step-backward",action:"angle",params:'{"adjust": -15}'},f:["15°"]}," ",{p:[10,5,387],t:7,e:"ui-button",a:{icon:"backward",action:"angle",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[11,5,477],t:7,e:"ui-button",a:{icon:"forward",action:"angle",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[12,5,565],t:7,e:"ui-button",a:{icon:"step-forward",action:"angle",params:'{"adjust": 15}'},f:["15°"]}]}]}," ",{p:[15,1,687],t:7,e:"ui-display",a:{title:"Tracking"},f:[{p:[16,3,720],t:7,e:"ui-section",a:{label:"Tracker Mode"},f:[{p:[17,5,759],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==0?"selected":null'},p:[17,36,790]}],action:"tracking",params:'{"mode": 0}'},f:["Off"]}," ",{p:[19,5,907],t:7,e:"ui-button",a:{icon:"clock-o",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==1?"selected":null'},p:[19,38,940]}],action:"tracking",params:'{"mode": 1}'},f:["Timed"]}," ",{p:[21,5,1059],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.connected_tracker","data.tracking_state"],s:'_0?_1==2?"selected":null:"disabled"'},p:[21,38,1092]}],action:"tracking",params:'{"mode": 2}'},f:["Auto"]}]}," ",{p:[24,3,1262],t:7,e:"ui-section",a:{label:"Tracking Rate"},f:[{p:[25,3,1300],t:7,e:"span",f:[{t:2,x:{r:["adata.tracking_rate"],s:"Math.round(_0)"},p:[25,9,1306]},"°/h (",{t:2,r:"data.rotating_way",p:[25,53,1350]},")"]}]}," ",{p:[27,3,1399],t:7,e:"ui-section",a:{label:"Adjust Rate"},f:[{p:[28,5,1437],t:7,e:"ui-button",a:{icon:"fast-backward",action:"rate",params:'{"adjust": -180}'},f:["180°"]}," ",{p:[29,5,1535],t:7,e:"ui-button",a:{icon:"step-backward",action:"rate",params:'{"adjust": -30}'},f:["30°"]}," ",{p:[30,5,1631],t:7,e:"ui-button",a:{icon:"backward",action:"rate",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[31,5,1720],t:7,e:"ui-button",a:{icon:"forward",action:"rate",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[32,5,1807],t:7,e:"ui-button",a:{icon:"step-forward",action:"rate",params:'{"adjust": 30}'},f:["30°"]}," ",{p:[33,5,1901],t:7,e:"ui-button",a:{icon:"fast-forward",action:"rate",params:'{"adjust": 180}'},f:["180°"]}]}]}," ",{p:{button:[{p:[38,5,2088],t:7,e:"ui-button",a:{icon:"refresh",action:"refresh"},f:["Refresh"]}]},t:7,e:"ui-display",a:{title:"Devices",button:0},f:[" ",{p:[40,2,2169],t:7,e:"ui-section",a:{label:"Solar Tracker"},f:[{p:[41,5,2209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_tracker"],s:'_0?"good":"bad"'},p:[41,18,2222]}]},f:[{t:2,x:{r:["data.connected_tracker"],s:'_0?"":"Not "'},p:[41,63,2267]},"Found"]}]}," ",{p:[43,2,2338],t:7,e:"ui-section",a:{label:"Solar Panels"},f:[{p:[44,3,2375],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_panels"],s:'_0?"good":"bad"'},p:[44,16,2388]}]},f:[{t:2,x:{r:["adata.connected_panels"],s:"Math.round(_0)"},p:[44,60,2432]}," Panels Connected"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],468:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,7,87],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[4,38,118]}],action:"eject"},f:["Eject"]}],n:50,r:"data.open",p:[3,5,62]}]},t:7,e:"ui-display",a:{title:"Power",button:0},f:[" ",{p:[7,3,226],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[8,5,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[8,22,275]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[9,14,326]}],state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[9,54,366]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[10,22,431]}]}]}," ",{p:[12,3,490],t:7,e:"ui-section",a:{label:"Cell"},f:[{t:4,f:[{p:[14,7,554],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerLevel",p:[14,40,587]}]},f:[{t:2,x:{r:["adata.powerLevel"],s:"Math.fixed(_0)"},p:[14,61,608]},"%"]}],n:50,r:"data.hasPowercell",p:[13,5,521]},{t:4,n:51,f:[{p:[16,4,667],t:7,e:"span",a:{"class":"bad"},f:["No Cell"]}],r:"data.hasPowercell"}]}]}," ",{p:[20,1,744],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[21,3,779],t:7,e:"ui-section",a:{label:"Current Temperature"},f:[{p:[22,3,823],t:7,e:"span",f:[{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[22,9,829]},"°C"]}]}," ",{p:[24,2,894],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[25,3,937],t:7,e:"span",f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[25,9,943]},"°C"]}]}," ",{t:4,f:[{p:[28,5,1031],t:7,e:"ui-section",a:{label:"Adjust Target"},f:[{p:[29,7,1073],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[29,46,1112]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[30,7,1218],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[30,41,1252]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[31,7,1357],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:["Set"]}," ",{p:[32,7,1450],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[32,40,1483]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[33,7,1587],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[33,45,1625]}],action:"target",params:'{"adjust": 20}'}}]}],n:50,r:"data.open",p:[27,3,1008]}," ",{p:[36,3,1754],t:7,e:"ui-section",a:{label:"Mode"},f:[{t:4,f:[{p:[38,7,1808],t:7,e:"ui-button",a:{icon:"long-arrow-up",state:[{t:2,x:{r:["data.mode"],s:'_0=="heat"?"selected":null'},p:[38,46,1847]}],action:"mode",params:'{"mode": "heat"}'},f:["Heat"]}," ",{p:[39,7,1956],t:7,e:"ui-button",a:{icon:"long-arrow-down",state:[{t:2,x:{r:["data.mode"],s:'_0=="cool"?"selected":null'},p:[39,48,1997]}],action:"mode",params:'{"mode": "cool"}'},f:["Cool"]}," ",{p:[40,7,2106],t:7,e:"ui-button",a:{icon:"arrows-v",state:[{t:2,x:{r:["data.mode"],s:'_0=="auto"?"selected":null'},p:[40,41,2140]}],action:"mode",params:'{"mode": "auto"}'},f:["Auto"]}],n:50,r:"data.open",p:[37,3,1783]},{t:4,n:51,f:[{p:[42,4,2258],t:7,e:"span",f:[{t:2,x:{r:["text","data.mode"],s:"_0.titleCase(_1)"},p:[42,10,2264]}]}],r:"data.open"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],469:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,8,97],t:7,e:"ui-button",a:{action:"jump",params:['{"name" : ',{t:2,r:"name",p:[4,51,140]},"}"]},f:["Jump"]}," ",{p:[7,9,195],t:7,e:"ui-button",a:{action:"spawn",params:['{"name" : ',{t:2,r:"name",p:[7,53,239]},"}"]},f:["Spawn"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[2,22,46]}],button:0},f:[" ",{p:[11,3,308],t:7,e:"ui-section",a:{label:"Description"},f:[{p:[12,5,346],t:7,e:"span",f:[{t:3,r:"desc",p:[12,11,352]}]}]}," ",{p:[14,3,390],t:7,e:"ui-section",a:{label:"Spawners left"},f:[{p:[15,5,430],t:7,e:"span",f:[{t:2,r:"amount_left",p:[15,11,436]}]}]}]}],n:52,r:"data.spawners",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],470:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,31],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[2,22,50]}," Alarms"]},f:[{p:[3,5,74],t:7,e:"ul",f:[{t:4,f:[{p:[5,9,107],t:7,e:"li",f:[{t:2,r:".",p:[5,13,111]}]}],n:52,r:".",p:[4,7,86]},{t:4,n:51,f:[{p:[7,9,147],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],471:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,42],t:7,e:"ui-notice",f:[{p:[3,5,59],t:7,e:"span",f:["Biological entity detected in contents. Please remove."]}]}],n:50,x:{r:["data.occupied","data.safeties"],s:"_0&&_1"},p:[1,1,0]},{t:4,f:[{p:[7,3,179],t:7,e:"ui-notice",f:[{p:[8,5,196],t:7,e:"span",f:["Contents are being disinfected. Please wait."]}]}],n:50,r:"data.uv_active",p:[6,1,153]},{t:4,n:51,f:[{p:{button:[{t:4,f:[{p:[13,25,369],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,42,386]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[13,93,437]}]}],n:50,x:{r:["data.open"],s:"!_0"},p:[13,7,351]}," ",{t:4,f:[{p:[14,27,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"sign-out":"sign-in"'},p:[14,44,536]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Close":"Open"'},p:[14,98,590]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[14,7,499]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[17,7,692],t:7,e:"ui-notice",f:[{p:[18,9,713],t:7,e:"span",f:["Unit Locked"]}]}],n:50,r:"data.locked",p:[16,5,665]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.open"],s:"_0"},f:[{p:[21,9,793],t:7,e:"ui-section",a:{label:"Helmet"},f:[{p:[22,11,832],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.helmet"],s:'_0?"square":"square-o"'},p:[22,28,849]}],state:[{t:2,x:{r:["data.helmet"],s:'_0?null:"disabled"'},p:[22,75,896]}],action:"dispense",params:'{"item": "helmet"}'},f:[{t:2,x:{r:["data.helmet"],s:'_0||"Empty"'},p:[23,59,992]}]}]}," ",{p:[25,9,1063],t:7,e:"ui-section",a:{label:"Suit"},f:[{p:[26,11,1100],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.suit"],s:'_0?"square":"square-o"'},p:[26,28,1117]}],state:[{t:2,x:{r:["data.suit"],s:'_0?null:"disabled"'},p:[26,74,1163]}],action:"dispense",params:'{"item": "suit"}'},f:[{t:2,x:{r:["data.suit"],s:'_0||"Empty"'},p:[27,57,1255]}]}]}," ",{p:[29,9,1324],t:7,e:"ui-section",a:{label:"Mask"},f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mask"],s:'_0?"square":"square-o"'},p:[30,28,1378]}],state:[{t:2,x:{r:["data.mask"],s:'_0?null:"disabled"'},p:[30,74,1424]}],action:"dispense",params:'{"item": "mask"}'},f:[{t:2,x:{r:["data.mask"],s:'_0||"Empty"'},p:[31,57,1516]}]}]}," ",{p:[33,9,1585],t:7,e:"ui-section",a:{label:"Storage"},f:[{p:[34,11,1625],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.storage"],s:'_0?"square":"square-o"'},p:[34,28,1642]}],state:[{t:2,x:{r:["data.storage"],s:'_0?null:"disabled"'},p:[34,77,1691]}],action:"dispense",params:'{"item": "storage"}'},f:[{t:2,x:{r:["data.storage"],s:'_0||"Empty"'},p:[35,60,1789]}]}]}]},{t:4,n:50,x:{r:["data.open"],s:"!(_0)"},f:[" ",{p:[38,7,1873],t:7,e:"ui-button",a:{icon:"recycle",state:[{t:2,x:{r:["data.occupied","data.safeties"],s:'_0&&_1?"disabled":null'},p:[38,40,1906]}],action:"uv"},f:["Disinfect"]}]}],r:"data.locked"}]}],r:"data.uv_active"}]},e.exports=a.extend(r.exports)},{341:341}],472:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,5,18],t:7,e:"ui-section",a:{label:"Dispense"},f:[{p:[3,9,57],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.plasma"],s:'_0?"square":"square-o"'},p:[3,26,74]}],state:[{t:2,x:{r:["data.plasma"],s:'_0?null:"disabled"'},p:[3,74,122]}],action:"plasma"},f:["Plasma (",{t:2,x:{r:["adata.plasma"],s:"Math.round(_0)"},p:[4,37,196]},")"]}," ",{p:[5,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oxygen"],s:'_0?"square":"square-o"'},p:[5,26,264]}],state:[{t:2,x:{r:["data.oxygen"],s:'_0?null:"disabled"'},p:[5,74,312]}],action:"oxygen"},f:["Oxygen (",{t:2,x:{r:["adata.oxygen"],s:"Math.round(_0)"},p:[6,37,386]},")"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],473:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tankPressureState:function(){var t=this.get("data.tankPressure");return t>=200?"good":t>=100?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,295],t:7,e:"ui-notice",f:[{p:[15,3,310],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.connected"],s:'_0?"is":"is not"'},p:[15,23,330]}," connected to a mask."]}]}," ",{p:[17,1,409],t:7,e:"ui-display",f:[{p:[18,3,425],t:7,e:"ui-section",a:{label:"Tank Pressure"},f:[{p:[19,7,467],t:7,e:"ui-bar",a:{min:"0",max:"1013",value:[{t:2,r:"data.tankPressure",p:[19,41,501]}],state:[{t:2,r:"tankPressureState",p:[20,16,540]}]},f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[20,39,563]}," kPa"]}]}," ",{p:[22,3,631],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[23,5,674],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[23,18,687]}],max:[{t:2,r:"data.maxReleasePressure",p:[23,52,721]}],value:[{t:2,r:"data.releasePressure",p:[24,14,764]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[24,40,790]}," kPa"]}]}," ",{p:[26,3,861],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,906],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,939]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1095],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1126]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1273],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1368],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1398]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],474:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,5,33],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[3,9,75],t:7,e:"span",f:[{t:2,x:{r:["adata.temperature"],s:"Math.fixed(_0,2)"},p:[3,15,81]}," K"]}]}," ",{p:[5,5,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,9,190],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.fixed(_0,2)"},p:[6,15,196]}," kPa"]}]}]}," ",{p:[9,1,276],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[10,5,311],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,347],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[11,26,364]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[11,70,408]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[12,28,469]}]}]}," ",{p:[14,5,531],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[15,9,580],t:7,e:"ui-button",a:{icon:"fast-backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[15,48,619]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[17,9,733],t:7,e:"ui-button",a:{icon:"backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[17,43,767]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[19,9,880],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.target"],s:"Math.fixed(_0,2)"},p:[19,79,950]}]}," ",{p:[20,9,1003],t:7,e:"ui-button",a:{icon:"forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[20,42,1036]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[22,9,1148],t:7,e:"ui-button",a:{icon:"fast-forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[22,47,1186]}],action:"target",params:'{"adjust": 20}'}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],475:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 1:return"good";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,173],t:7,e:"ui-notice",f:[{p:[14,2,187],t:7,e:"ui-section",a:{label:"Reconnect"},f:[{p:[15,3,221],t:7,e:"div",a:{style:"float:right"},f:[{p:[16,4,251],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]}]}]}," ",{p:[20,1,359],t:7,e:"ui-display",a:{title:"Turbine Controller"},f:[{p:[21,2,401],t:7,e:"ui-section",a:{label:"Status"},f:[{t:4,f:[{p:[23,4,456],t:7,e:"span",a:{"class":"bad"},f:["Broken"]}],n:50,r:"data.broken",p:[22,3,432]},{t:4,n:51,f:[{p:[25,4,504],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.online"],s:"_0(_1)"},p:[25,17,517]}]},f:[{t:2,x:{r:["data.online","data.compressor_broke","data.turbine_broke"],s:'_0&&!(_1||_2)?"Online":"Offline"'},p:[25,46,546]}]}],r:"data.broken"}," ",{p:[27,3,656],t:7,e:"div",a:{style:"float:right"},f:[{p:[28,4,686],t:7,e:"ui-button",a:{icon:"power-off",action:"power-on",state:[{t:2,r:"data.broken",p:[28,57,739]}],style:[{t:2,x:{r:["data.online"],s:'_0?"selected":""'},p:[28,81,763]}]},f:["On"]}," ",{p:[29,4,817],t:7,e:"ui-button",a:{icon:"close",action:"power-off",state:[{t:2,r:"data.broken",p:[29,54,867]}],style:[{t:2,x:{r:["data.online"],s:'_0?"":"selected"'},p:[29,78,891]}]},f:["Off"]}]}," ",{t:4,f:[{p:[32,4,989],t:7,e:"br"}," [ ",{p:[33,6,1e3],t:7,e:"span",a:{"class":"bad"},f:["Compressor is inoperable"]}," ]"],n:50,r:"data.compressor_broke",p:[31,3,955]}," ",{t:4,f:[{p:[36,4,1097],t:7,e:"br"}," [ ",{p:[37,6,1108],t:7,e:"span",a:{"class":"bad"},f:["Turbine is inoperable"]}," ]"],n:50,r:"data.turbine_broke",p:[35,3,1066]}]}]}," ",{p:[41,1,1200],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[42,2,1230],t:7,e:"ui-section",a:{label:"Turbine Speed"},f:[{p:[43,3,1268],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.rpm"],s:'_0?"--":_1'},p:[43,9,1274]}," RPM"]}]}," ",{p:[45,2,1337],t:7,e:"ui-section",a:{label:"Internal Temp"},f:[{p:[46,3,1375],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.temp"],s:'_0?"--":_1'},p:[46,9,1381]}," K"]}]}," ",{p:[48,2,1443],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{p:[49,3,1483],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.power"],s:'_0?"--":_1'},p:[49,9,1489]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],476:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{},oninit:function(){this.on({hover:function(t){var e=this.get("data.telecrystals");e>=t.context.params.cost&&this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}})}}}(r),r.exports.template={v:3,t:[" ",{p:{button:[{t:4,f:[{p:[23,7,482],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock"]}],n:50,r:"data.lockable",p:[22,5,453]}]},t:7,e:"ui-display",a:{title:"Uplink",button:0},f:[" ",{p:[26,3,568],t:7,e:"ui-section",a:{label:"Telecrystals",right:0},f:[{p:[27,5,613],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.telecrystals"],s:'_0>0?"good":"bad"'},p:[27,18,626]}]},f:[{t:2,r:"data.telecrystals",p:[27,62,670]}," TC"]}]}]}," ",{t:4,f:[{p:[31,3,764],t:7,e:"ui-display",f:[{p:[32,2,779],t:7,e:"ui-button",a:{action:"select",params:['{"category": "',{t:2,r:"name",p:[32,51,828]},'"}']},f:[{t:2,r:"name",p:[32,63,840]}]}," ",{t:4,f:[{p:[34,4,883],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[34,23,902]}],candystripe:0,right:0},f:[{p:[35,3,934],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"name",p:[35,23,954]},": ",{t:2,r:"desc",p:[35,33,964]}],"tooltip-side":"left",state:[{t:2,x:{r:["data.telecrystals","hovered.cost","cost","hovered.item","name"],s:'_0<_2||(_0-_1<_2&&_3!=_4)?"disabled":null'},p:[36,12,1006]}],action:"buy",params:['{"category": "',{t:2,r:"category",p:[37,40,1165]},'", "item": ',{t:2,r:"name",p:[37,63,1188]},', "cost": ',{t:2,r:"cost",p:[37,81,1206]},"}"]},v:{hover:"hover",unhover:"unhover"},f:[{t:2,r:"cost",p:[38,43,1260]}," TC"]}]}],n:52,r:"items",p:[33,2,863]}]}],n:52,r:"data.categories",p:[30,1,735]}]},e.exports=a.extend(r.exports)},{341:341}],477:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{healthState:function(t){var e=this.get("data.vr_avatar.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,292],t:7,e:"ui-display",f:[{t:4,f:[{p:[16,3,331],t:7,e:"ui-notice",f:[{p:[17,4,347],t:7,e:"span",f:["Safety restraints disabled."]}]}],n:50,r:"data.emagged",p:[15,2,307]}," ",{t:4,f:[{p:[21,3,442],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:[{p:[22,4,482],t:7,e:"ui-section",a:{label:"Name"},f:[{t:2,r:"data.vr_avatar.name",p:[23,5,513]}]}," ",{p:[25,4,559],t:7,e:"ui-section",a:{label:"Status"},f:[{t:2,r:"data.vr_avatar.status",p:[26,5,592]}]}," ",{p:[28,4,640],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[29,5,673],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.vr_avatar.maxhealth",p:[29,26,694]}],value:[{t:2,r:"adata.vr_avatar.health",p:[29,64,732]}],state:[{t:2,x:{r:["healthState","adata.vr_avatar.health"],s:"_0(_1)"},p:[29,99,767]}]},f:[{t:2,x:{r:["adata.vr_avatar.health"],s:"Math.round(_0)"},p:[29,140,808]},"/",{t:2,r:"adata.vr_avatar.maxhealth",p:[29,179,847]}]}]}]}],n:50,r:"data.vr_avatar",p:[20,2,416]},{t:4,n:51,f:[{p:[33,3,935],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:["No Virtual Avatar detected"]}],r:"data.vr_avatar"}," ",{p:[37,2,1031],t:7,e:"ui-display",a:{title:"VR Commands"},f:[{p:[38,3,1067],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.toggle_open"],s:'_0?"times":"plus"'},p:[38,20,1084]}],action:"toggle_open"},f:[{t:2,x:{r:["data.toggle_open"],s:'_0?"Close":"Open"'},p:[39,4,1151]}," the VR Sleeper"]}," ",{t:4,f:[{p:[42,4,1253],t:7,e:"ui-button",a:{icon:"signal",action:"vr_connect"},f:["Connect to VR"]}],n:50,r:"data.isoccupant",p:[41,3,1225]}," ",{t:4,f:[{p:[47,4,1376],t:7,e:"ui-button",a:{icon:"ban",action:"delete_avatar"},f:["Delete Virtual Avatar"]}],n:50,r:"data.vr_avatar",p:[46,3,1349]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],478:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{t:4,f:[{p:[3,5,42],t:7,e:"ui-section",a:{label:[{t:2,r:"color",p:[3,24,61]},{t:2,x:{r:["wire"],s:'_0?" ("+_0+")":""'},p:[3,33,70]}],labelcolor:[{t:2,r:"color",p:[3,80,117]}],candystripe:0,right:0},f:[{p:[4,7,154],t:7,e:"ui-button",a:{action:"cut",params:['{"wire":"',{t:2,r:"color",p:[4,48,195]},'"}']},f:[{t:2,x:{r:["cut"],s:'_0?"Mend":"Cut"'},p:[4,61,208]}]}," ",{p:[5,7,252],t:7,e:"ui-button",a:{action:"pulse",params:['{"wire":"',{t:2,r:"color",p:[5,50,295]},'"}']},f:["Pulse"]}," ",{p:[6,7,333],t:7,e:"ui-button",a:{action:"attach",params:['{"wire":"',{t:2,r:"color",p:[6,51,377]},'"}']},f:[{t:2,x:{r:["attached"],s:'_0?"Detach":"Attach"'},p:[6,64,390]}]}]}],n:52,r:"data.wires",p:[2,3,16]}]}," ",{t:4,f:[{p:[11,3,508],t:7,e:"ui-display",f:[{t:4,f:[{p:[13,7,555],t:7,e:"ui-section",f:[{t:2,r:".",p:[13,19,567]}]}],n:52,r:"data.status",p:[12,5,526]}]}],n:50,r:"data.status",p:[10,1,485]}]},e.exports=a.extend(r.exports)},{341:341}],479:[function(t,e,n){(function(e){"use strict";var n=t(341),a=e.interopRequireDefault(n);t(331),t(1),t(327),t(330);var r=t(480),i=e.interopRequireDefault(r),o=t(481),s=t(328),p=t(329),u=e.interopRequireDefault(p);a["default"].DEBUG=/minified/.test(function(){}),Object.assign(Math,t(485)), -window.initialize=function(e){window.tgui=window.tgui||new i["default"]({el:"#container",data:function(){var n=JSON.parse(e);return{constants:t(482),text:t(486),config:n.config,data:n.data,adata:n.data}}})};var c=document.getElementById("data"),l=c.textContent,d=c.getAttribute("data-ref");"{}"!==l&&(window.initialize(l),c.remove()),(0,o.act)(d,"tgui:initialize"),(0,s.loadCSS)("font-awesome.min.css");var f=new u["default"]("FontAwesome");f.check("").then(function(){return document.body.classList.add("icons")})["catch"](function(){return document.body.classList.add("no-icons")})}).call(this,t("babel/external-helpers"))},{1:1,327:327,328:328,329:329,330:330,331:331,341:341,480:480,481:481,482:482,485:485,486:486,"babel/external-helpers":"babel/external-helpers"}],480:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(481),a=t(483);e.exports={components:{"ui-bar":t(342),"ui-button":t(343),"ui-display":t(344),"ui-input":t(345),"ui-linegraph":t(346),"ui-notice":t(347),"ui-section":t(349),"ui-subdisplay":t(350),"ui-tabs":t(351)},events:{enter:t(339).enter,space:t(339).space},transitions:{fade:t(340)},onconfig:function(){var e=this.get("config.interface"),n={ai_airlock:t(355),airalarm:t(356),"airalarm/back":t(357),"airalarm/modes":t(358),"airalarm/scrubbers":t(359),"airalarm/status":t(360),"airalarm/thresholds":t(361),"airalarm/vents":t(362),airlock_electronics:t(363),apc:t(364),atmos_alert:t(365),atmos_control:t(366),atmos_filter:t(367),atmos_mixer:t(368),atmos_pump:t(369),borgopanel:t(370),brig_timer:t(371),bsa:t(372),canister:t(373),cargo:t(374),cargo_express:t(375),cellular_emporium:t(376),centcom_podlauncher:t(377),chem_dispenser:t(378),chem_heater:t(379),chem_master:t(380),chem_synthesizer:t(381),clockwork_slab:t(382),codex_gigas:t(383),computer_fabricator:t(384),crayon:t(385),crew:t(386),cryo:t(387),disposal_unit:t(388),dna_vault:t(389),dogborg_sleeper:t(390),eightball:t(391),emergency_shuttle_console:t(392),engraved_message:t(393),error:t(394),"exofab - Copia":t(395),exonet_node:t(396),firealarm:t(397),gps:t(398),gulag_console:t(399),gulag_item_reclaimer:t(400),holodeck:t(401),implantchair:t(402),intellicard:t(403),keycard_auth:t(404),labor_claim_console:t(405),language_menu:t(406),launchpad_remote:t(407),mech_bay_power_console:t(408),mulebot:t(409),nanite_chamber_control:t(410),nanite_cloud_control:t(411),nanite_program_hub:t(412),nanite_programmer:t(413),nanite_remote:t(414),notificationpanel:t(415),ntnet_relay:t(416),ntos_ai_restorer:t(417),ntos_card:t(418),ntos_configuration:t(419),ntos_file_manager:t(420),ntos_main:t(421),ntos_net_chat:t(422),ntos_net_dos:t(423),ntos_net_downloader:t(424),ntos_net_monitor:t(425),ntos_net_transfer:t(426),ntos_power_monitor:t(427),ntos_revelation:t(428),ntos_station_alert:t(429),ntos_supermatter_monitor:t(430),ntosheader:t(431),nuclear_bomb:t(432),operating_computer:t(433),ore_redemption_machine:t(434),pandemic:t(435),personal_crafting:t(436),portable_pump:t(437),portable_scrubber:t(438),power_monitor:t(439),radio:t(440),rdconsole:t(441),"rdconsole/circuit":t(442),"rdconsole/designview":t(443),"rdconsole/destruct":t(444),"rdconsole/diskopsdesign":t(445),"rdconsole/diskopstech":t(446),"rdconsole/nodeview":t(447),"rdconsole/protolathe":t(448),"rdconsole/rdheader":t(449),"rdconsole/settings":t(450),"rdconsole/techweb":t(451),reagentgrinder:t(452),rpd:t(453),"rpd/colorsel":t(454),"rpd/dirsel":t(455),sat_control:t(456),scrubbing_types:t(457),shuttle_manipulator:t(458),"shuttle_manipulator/modification":t(459),"shuttle_manipulator/status":t(460),"shuttle_manipulator/templates":t(461),sleeper:t(462),slime_swap_body:t(463),smartvend:t(464),smes:t(465),smoke_machine:t(466),solar_control:t(467),space_heater:t(468),spawners_menu:t(469),station_alert:t(470),suit_storage_unit:t(471),tank_dispenser:t(472),tanks:t(473),thermomachine:t(474),turbine_computer:t(475),uplink:t(476),vr_sleeper:t(477),wires:t(478)};e in n?this.components["interface"]=n[e]:this.components["interface"]=n.error},oninit:function(){this.observe("config.style",function(t,e,n){t&&document.body.classList.add(t),e&&document.body.classList.remove(e)})},oncomplete:function(){if(this.get("config.locked")){var t=(0,a.lock)(window.screenLeft,window.screenTop),e=t.x,r=t.y;(0,n.winset)(this.get("config.window"),"pos",e+","+r)}(0,n.winset)("mapwindow.map","focus",!0)}}}(r),r.exports.template={v:3,t:[" "," "," "," ",{p:[56,1,1874],t:7,e:"titlebar",f:[{t:3,r:"config.title",p:[56,11,1884]}]}," ",{p:[57,1,1915],t:7,e:"main",f:[{p:[58,3,1925],t:7,e:"warnings"}," ",{p:[59,3,1940],t:7,e:"interface"}]}," ",{t:4,f:[{p:[62,3,1990],t:7,e:"resize"}],n:50,r:"config.titlebar",p:[61,1,1963]}]},r.exports.components=r.exports.components||{};var i={warnings:t(354),titlebar:t(353),resize:t(348)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{339:339,340:340,341:341,342:342,343:343,344:344,345:345,346:346,347:347,348:348,349:349,350:350,351:351,353:353,354:354,355:355,356:356,357:357,358:358,359:359,360:360,361:361,362:362,363:363,364:364,365:365,366:366,367:367,368:368,369:369,370:370,371:371,372:372,373:373,374:374,375:375,376:376,377:377,378:378,379:379,380:380,381:381,382:382,383:383,384:384,385:385,386:386,387:387,388:388,389:389,390:390,391:391,392:392,393:393,394:394,395:395,396:396,397:397,398:398,399:399,400:400,401:401,402:402,403:403,404:404,405:405,406:406,407:407,408:408,409:409,410:410,411:411,412:412,413:413,414:414,415:415,416:416,417:417,418:418,419:419,420:420,421:421,422:422,423:423,424:424,425:425,426:426,427:427,428:428,429:429,430:430,431:431,432:432,433:433,434:434,435:435,436:436,437:437,438:438,439:439,440:440,441:441,442:442,443:443,444:444,445:445,446:446,447:447,448:448,449:449,450:450,451:451,452:452,453:453,454:454,455:455,456:456,457:457,458:458,459:459,460:460,461:461,462:462,463:463,464:464,465:465,466:466,467:467,468:468,469:469,470:470,471:471,472:472,473:473,474:474,475:475,476:476,477:477,478:478,481:481,483:483}],481:[function(t,e,n){"use strict";function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"byond://"+e+"?"+Object.keys(t).map(function(e){return o(e)+"="+o(t[e])}).join("&")}function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};window.location.href=a(Object.assign({src:t,action:e},n))}function i(t,e,n){var r;window.location.href=a((r={},r[t+"."+e]=n,r),"winset")}n.__esModule=!0,n.href=a,n.act=r,n.winset=i;var o=encodeURIComponent},{}],482:[function(t,e,n){"use strict";n.__esModule=!0;n.UI_INTERACTIVE=2,n.UI_UPDATE=1,n.UI_DISABLED=0,n.UI_CLOSE=-1},{}],483:[function(t,e,n){"use strict";function a(t,e){return 0>t?t=0:t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth),0>e?e=0:e+window.innerHeight>window.screen.availHeight&&(e=window.screen.availHeight-window.innerHeight),{x:t,y:e}}function r(t){if(t.preventDefault(),this.get("drag")){if(this.get("x")){var e=t.screenX-this.get("x")+window.screenLeft,n=t.screenY-this.get("y")+window.screenTop;if(this.get("config.locked")){var r=a(e,n);e=r.x,n=r.y}(0,s.winset)(this.get("config.window"),"pos",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}function i(t,e){return t=Math.clamp(100,window.screen.width,t),e=Math.clamp(100,window.screen.height,e),{x:t,y:e}}function o(t){if(t.preventDefault(),this.get("resize")){if(this.get("x")){var e=t.screenX-this.get("x")+window.innerWidth,n=t.screenY-this.get("y")+window.innerHeight,a=i(e,n);e=a.x,n=a.y,(0,s.winset)(this.get("config.window"),"size",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}n.__esModule=!0,n.lock=a,n.drag=r,n.sane=i,n.resize=o;var s=t(481)},{481:481}],484:[function(t,e,n){"use strict";function a(t,e){for(var n=t,a=Array.isArray(n),i=0,n=a?n:n[Symbol.iterator]();;){var o;if(a){if(i>=n.length)break;o=n[i++]}else{if(i=n.next(),i.done)break;o=i.value}var s=o;s.textContent.toLowerCase().includes(e)?(s.style.display="",r(s,e)):s.style.display="none"}}function r(t,e){for(var n=t.queryAll("section"),a=t.query("header").textContent.toLowerCase().includes(e),r=n,i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var p=s;a||p.textContent.toLowerCase().includes(e)?p.style.display="":p.style.display="none"}}n.__esModule=!0,n.filterMulti=a,n.filter=r},{}],485:[function(t,e,n){"use strict";function a(t,e,n){return Math.max(t,Math.min(n,e))}function r(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return+(Math.round(t+"e"+e)+"e-"+e)}n.__esModule=!0,n.clamp=a,n.fixed=r},{}],486:[function(t,e,n){"use strict";function a(t){return t[0].toUpperCase()+t.slice(1).toLowerCase()}function r(t){return t.replace(/\w\S*/g,a)}function i(t,e){for(t=""+t;t.length1){for(var p=Array(o),u=0;o>u;u++)p[u]=arguments[u+3];n.children=p}return{$$typeof:t,type:e,key:void 0===a?null:""+a,ref:null,props:n,_owner:null}}}(),e.asyncIterator=function(t){if("function"==typeof Symbol){if(Symbol.asyncIterator){var e=t[Symbol.asyncIterator];if(null!=e)return e.call(t)}if(Symbol.iterator)return t[Symbol.iterator]()}throw new TypeError("Object is not async iterable")},e.asyncGenerator=function(){function t(t){this.value=t}function e(e){function n(t,e){return new Promise(function(n,r){var s={key:t,arg:e,resolve:n,reject:r,next:null};o?o=o.next=s:(i=o=s,a(t,e))})}function a(n,i){try{var o=e[n](i),s=o.value;s instanceof t?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):r(o.done?"return":"normal",o.value)}catch(p){r("throw",p)}}function r(t,e){switch(t){case"return":i.resolve({value:e,done:!0});break;case"throw":i.reject(e);break;default:i.resolve({value:e,done:!1})}i=i.next,i?a(i.key,i.arg):o=null}var i,o;this._invoke=n,"function"!=typeof e["return"]&&(this["return"]=void 0)}return"function"==typeof Symbol&&Symbol.asyncIterator&&(e.prototype[Symbol.asyncIterator]=function(){return this}),e.prototype.next=function(t){return this._invoke("next",t)},e.prototype["throw"]=function(t){return this._invoke("throw",t)},e.prototype["return"]=function(t){return this._invoke("return",t)},{wrap:function(t){return function(){return new e(t.apply(this,arguments))}},await:function(e){return new t(e)}}}(),e.asyncGeneratorDelegate=function(t,e){function n(n,a){return r=!0,a=new Promise(function(e){e(t[n](a))}),{done:!1,value:e(a)}}var a={},r=!1;return"function"==typeof Symbol&&Symbol.iterator&&(a[Symbol.iterator]=function(){return this}),a.next=function(t){return r?(r=!1,t):n("next",t)},"function"==typeof t["throw"]&&(a["throw"]=function(t){if(r)throw r=!1,t;return n("throw",t)}),"function"==typeof t["return"]&&(a["return"]=function(t){return n("return",t)}),a},e.asyncToGenerator=function(t){return function(){var e=t.apply(this,arguments);return new Promise(function(t,n){function a(r,i){try{var o=e[r](i),s=o.value}catch(p){return void n(p)}return o.done?void t(s):Promise.resolve(s).then(function(t){a("next",t)},function(t){a("throw",t)})}return a("next")})}},e.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},e.createClass=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,a)&&(n[a]=t[a]);return n},e.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},e.selfGlobal=void 0===t?self:t,e.set=function a(t,e,n,r){var i=Object.getOwnPropertyDescriptor(t,e);if(void 0===i){var o=Object.getPrototypeOf(t);null!==o&&a(o,e,n,r)}else if("value"in i&&i.writable)i.value=n;else{var s=i.set;void 0!==s&&s.call(r,n)}return n},e.slicedToArray=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),e.slicedToArrayLoose=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t)){for(var n,a=[],r=t[Symbol.iterator]();!(n=r.next()).done&&(a.push(n.value),!e||a.length!==e););return a}throw new TypeError("Invalid attempt to destructure non-iterable instance")},e.taggedTemplateLiteral=function(t,e){return Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))},e.taggedTemplateLiteralLoose=function(t,e){return t.raw=e,t},e.temporalRef=function(t,e,n){if(t===n)throw new ReferenceError(e+" is not defined - temporal dead zone");return t},e.temporalUndefined={},e.toArray=function(t){return Array.isArray(t)?t:Array.from(t)},e.toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e10?10:_0"},p:[24,47,1035]}],"class":"number"}}],n:50,x:{r:["canprint"],s:"_0>1"},p:[23,7,967]}," ",{p:[26,7,1108],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[26,40,1141]}],params:['{"latheType" : "proto", "id" : "',{t:2,r:"id",p:[26,117,1218]},'", "amount" : "',{t:2,r:"number",p:[26,138,1239]},'"}']},f:["Print"]}]}],n:52,r:"data.protodes",p:[21,5,896]}]}," ",{p:[30,4,1321],t:7,e:"tab",a:{name:"Search Results"},f:[{t:4,f:[{p:[32,6,1386],t:7,e:"ui-section",f:[{t:2,r:"name",p:[32,18,1398]},{t:2,r:"matstring",p:[32,26,1406]}," ",{t:4,f:[{p:[34,8,1456],t:7,e:"input",a:{value:[{t:2,r:"number",p:[34,21,1469]}],placeholder:["1-",{t:2,x:{r:["canprint"],s:"_0>10?10:_0"},p:[34,47,1495]}],"class":"number"}}],n:50,x:{r:["canprint"],s:"_0>1"},p:[33,7,1427]}," ",{p:[36,7,1568],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[36,40,1601]}],params:['{"latheType" : "proto", "id" : "',{t:2,r:"id",p:[36,117,1678]},'", "amount" : "',{t:2,r:"number",p:[36,138,1699]},'"}']},f:["Print"]}]}],n:52,r:"data.protomatch",p:[31,5,1354]}]}," ",{p:[40,4,1781],t:7,e:"tab",a:{name:"Materials"},f:[{t:4,f:[{p:[42,6,1844],t:7,e:"ui-section",f:[{t:2,r:"name",p:[42,18,1856]}," : ",{t:2,r:"amount",p:[42,29,1867]}," cm3 - ",{t:4,f:[{p:[44,7,1917],t:7,e:"input",a:{value:[{t:2,r:"number",p:[44,20,1930]}],placeholder:["1-",{t:2,r:"sheets",p:[44,46,1956]}],"class":"number"}}," ",{p:[45,7,1992],t:7,e:"ui-button",a:{action:"releasemats",params:['{"latheType" : "proto", "mat_id" : ',{t:2,r:"mat_id",p:[45,82,2067]},', "sheets" : ',{t:2,r:"number",p:[45,105,2090]},"}"]},f:["Release"]}],n:50,x:{r:["sheets"],s:"_0>0"},p:[43,6,1891]}]}],n:52,r:"data.protomat_list",p:[41,5,1809]}]}," ",{p:[50,4,2187],t:7,e:"tab",a:{name:"Chemicals"},f:[{t:4,f:[{p:[52,6,2251],t:7,e:"ui-section",f:[{t:2,r:"name",p:[52,18,2263]}," : ",{t:2,r:"amount",p:[52,29,2274]}," - ",{p:[53,7,2295],t:7,e:"ui-button",a:{action:"purgechem",params:['{"latheType" : "proto", "name" : ',{t:2,r:"name",p:[53,78,2366]},', "id" : ',{t:2,r:"reagentid",p:[53,95,2383]},"}"]},f:["Purge"]}]}],n:52,r:"data.protochem_list",p:[51,5,2215]}]}]}]}]}],r:"data.protobusy"}],n:50,r:"data.protolathe_linked",p:[1,1,0]},{t:4,n:51,f:[{p:[61,2,2504],t:7,e:"ui-display",a:{title:"No Linked Protolathe"}}],r:"data.protolathe_linked"}]},e.exports=a.extend(r.exports)},{341:341}],449:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,1,14],t:7,e:"span",a:{"class":"memoedit"},f:["Nanotrasen R&D Console"]},{p:[2,53,66],t:7,e:"br"}," Available Points: ",{p:[3,19,91],t:7,e:"ui-section",a:{title:"Research Points"},f:[{t:2,r:"data.research_points_stored",p:[3,55,127]}]}," ",{p:[4,1,173],t:7,e:"ui-section",a:{title:["Page Selection - ",{t:2,r:"page",p:[4,37,209]}]},f:[{p:[4,47,219],t:7,e:"input",a:{value:[{t:2,r:"pageselect",p:[4,60,232]}],placeholder:"1","class":"number"}}," Select Page: ",{p:[5,14,294],t:7,e:"ui-button",a:{action:"page",params:['{"num" : "',{t:2,r:"pageselect",p:[5,57,337]},'"}']},f:["[Go]"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],450:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"span",a:{"class":"bad"},f:["Settings"]},{p:[1,34,33],t:7,e:"br"},{p:[1,39,38],t:7,e:"br"}," ",{p:[2,1,45],t:7,e:"ui-button",a:{action:"Resync"},f:["RESYNC MACHINERY"]},{p:[2,56,100],t:7,e:"br"}," ",{p:[3,1,107],t:7,e:"ui-button",a:{action:"Lock"},f:["LOCK"]}," ",{p:[4,1,150],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "destroy"}',state:[{t:2,x:{r:["data.destroy_linked"],s:'_0?null:"disabled"'},p:[4,71,220]}]},f:["Disconnect Destructive Analyzer"]}," ",{p:[5,1,309],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "lathe"}',state:[{t:2,x:{r:["data.protolathe_linked"],s:'_0?null:"disabled"'},p:[5,69,377]}]},f:["Disconnect Protolathe"]}," ",{p:[6,1,459],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "imprinter"}',state:[{t:2,x:{r:["data.circuit_linked"],s:'_0?null:"disabled"'},p:[6,73,531]}]},f:["Disconnect Circuit Imprinter"]}]},e.exports=a.extend(r.exports)},{341:341}],451:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Available for Research"},f:[{t:4,f:[{p:[3,3,78],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[3,51,126]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[3,68,143]}]},f:[{t:2,r:"display_name",p:[3,113,188]}]}],n:52,r:"data.techweb_avail",p:[2,2,46]}]}," ",{p:[6,1,245],t:7,e:"ui-display",a:{title:"Locked Nodes"},f:[{t:4,f:[{p:[8,3,314],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[8,51,362]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[8,68,379]}]},f:[{t:2,r:"display_name",p:[8,113,424]}]}],n:52,r:"data.techweb_locked",p:[7,2,281]}]}," ",{p:[11,1,482],t:7,e:"ui-display",a:{title:"Researched Nodes"},f:[{t:4,f:[{p:[13,3,559],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[13,51,607]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[13,68,624]}]},f:[{t:2,r:"display_name",p:[13,113,669]}]}],n:52,r:"data.techweb_researched",p:[12,2,522]}]}]},e.exports=a.extend(r.exports)},{341:341}],452:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,25],t:7,e:"ui-notice",f:[{p:[3,3,40],t:7,e:"span",f:["The grinder is currently processing and cannot be used."]}]}],n:50,r:"data.processing",p:[1,1,0]},{p:{button:[{p:[8,5,208],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[8,36,239]}],action:"eject"},f:["Eject Contents"]}]},t:7,e:"ui-display",a:{title:"Processing Chamber",button:0},f:[" ",{p:[10,3,364],t:7,e:"ui-section",a:{label:"Grinding"},f:[{p:[11,5,399],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.operating"],s:'_0?"average":"good"'},p:[11,18,412]}]},f:[{t:2,x:{r:["data.operating"],s:'_0?"Busy":"Ready"'},p:[11,59,453]}]}," ",{p:[12,2,500],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[12,35,533]}],action:"grind"},f:["Activate"]}]}," ",{p:[14,3,653],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[17,9,755],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:["The ",{t:2,r:"name",p:[17,56,802]}]},{p:[17,71,817],t:7,e:"br"}],n:52,r:"adata.contentslist",p:[16,7,717]},{t:4,n:51,f:[{p:[19,9,848],t:7,e:"span",f:["No Contents"]}],r:"adata.contentslist"}],n:50,r:"data.contents",p:[15,5,688]},{t:4,n:51,f:[{p:[22,7,911],t:7,e:"span",f:["No Contents"]}],r:"data.contents"}]}]}," ",{p:{button:[{p:[28,5,1047],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.isBeakerLoaded"],s:'(_0==0)&&_1?null:"disabled"'},p:[28,36,1078]}],action:"detach"},f:["Detach"]}]},t:7,e:"ui-display",a:{title:"Container",button:0},f:[" ",{p:[30,3,1202],t:7,e:"ui-section",a:{label:"Reagents"},f:[{t:4,f:[{p:[32,7,1272],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[32,13,1278]},"/",{t:2,r:"data.beakerMaxVolume",p:[32,55,1320]}," Units"]}," ",{p:[33,7,1365],t:7,e:"br"}," ",{t:4,f:[{p:[35,9,1418],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[35,52,1461]}," units of ",{t:2,r:"name",p:[35,87,1496]}]},{p:[35,102,1511],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[34,7,1378]},{t:4,n:51,f:[{p:[37,9,1542],t:7,e:"span",a:{"class":"bad"},f:["Container Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[31,5,1237]},{t:4,n:51,f:[{p:[40,7,1621],t:7,e:"span",a:{"class":"average"},f:["No Container"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],453:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,64],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,105],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,123]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,195]},', "flipped": ',{t:2,r:"flipped",p:[6,42,215]},"}"]},f:[{p:[6,56,229],t:7,e:"span",a:{"class":["pipes32x32 ",{t:2,r:"dir",p:[6,80,253]},"-",{t:2,r:"icon_state",p:[6,88,261]}],title:[{t:2,r:"dir_name",p:[6,111,284]}]}}]}],n:52,r:"previews",p:[4,4,81]}]}],n:52,r:"data.preview_rows",p:[2,2,33]}]}," ",{t:4,f:[{p:[12,2,406],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[14,4,468],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["@key","data.selected_color"],s:'_0==_1?"selected":null'},p:[14,22,486]}],action:"color",params:['{"paint_color": ',{t:2,r:"@key",p:[15,44,583]},"}"]},f:[{t:2,r:"@key",p:[15,55,594]}]}],n:52,r:"data.paint_colors",p:[13,3,436]}]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[11,1,377]},{p:[19,1,654],t:7,e:"ui-display",a:{title:"Utilities"},f:[{p:[20,2,687],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&1?"check-square-o":"square-o"'},p:[20,19,704]}],action:"mode",params:'{"mode": 1}'},f:["Build"]}," ",{p:[22,2,813],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&2?"check-square-o":"square-o"'},p:[22,19,830]}],action:"mode",params:'{"mode": 2}'},f:["Wrench"]}," ",{p:[24,2,940],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&4?"check-square-o":"square-o"'},p:[24,19,957]}],action:"mode",params:'{"mode": 4}'},f:["Destroy"]}," ",{t:4,f:[{p:[27,3,1098],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&8?"check-square-o":"square-o"'},p:[27,20,1115]}],action:"mode",params:'{"mode": 8}'},f:["Paint"]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[26,2,1068]}]}," ",{p:[31,1,1249],t:7,e:"ui-display",a:{title:"Category"},f:[{p:[32,2,1281],t:7,e:"ui-section",f:[{p:[33,3,1297],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==0?"check-square-o":"square-o"'},p:[33,20,1314]}],state:[{t:2,x:{r:["data.category"],s:'_0<=0?"selected":null'},p:[33,83,1377]}],action:"category",params:'{"category": 0}'},f:["Atmospherics"]}," ",{p:[35,3,1496],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==1?"check-square-o":"square-o"'},p:[35,20,1513]}],state:[{t:2,x:{r:["data.category"],s:'_0==1?"selected":null'},p:[35,83,1576]}],action:"category",params:'{"category": 1}'},f:["Disposals"]}," ",{p:[37,3,1692],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==2?"check-square-o":"square-o"'},p:[37,20,1709]}],state:[{t:2,x:{r:["data.category"],s:'_0==2?"selected":null'},p:[37,83,1772]}],action:"category",params:'{"category": 2}'},f:["Transit Tubes"]}]}," ",{t:4,f:[{p:[41,3,1937],t:7,e:"ui-section",a:{label:"Piping Layer"},f:[{p:[42,4,1975],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==1?"selected":null'},p:[42,22,1993]}],action:"piping_layer",params:'{"piping_layer": 1}'},f:["1"]}," ",{p:[44,4,2115],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==2?"selected":null'},p:[44,22,2133]}],action:"piping_layer",params:'{"piping_layer": 2}'},f:["2"]}," ",{p:[46,4,2255],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==3?"selected":null'},p:[46,22,2273]}],action:"piping_layer",params:'{"piping_layer": 3}'},f:["3"]}]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[40,2,1907]}]}," ",{t:4,f:[{p:[52,2,2462],t:7,e:"ui-display",a:{title:[{t:2,r:"cat_name",p:[52,21,2481]}]},f:[{t:4,f:[{p:[54,4,2521],t:7,e:"ui-section",f:[{p:[55,5,2539],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[55,23,2557]}],action:"pipe_type",params:['{"pipe_type": ',{t:2,r:"pipe_index",p:[56,28,2638]},', "category": ',{t:2,r:"cat_name",p:[56,56,2666]},"}"]},f:[{t:2,r:"pipe_name",p:[56,71,2681]}]}]}],n:52,r:"recipes",p:[53,3,2499]}]}],n:52,r:"data.categories",p:[51,1,2434]}]},e.exports=a.extend(r.exports)},{341:341}],454:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[3,3,60],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[3,21,78]}],action:"color",params:['{"paint_color": ',{t:2,r:"color_name",p:[4,28,155]},"}"]},f:[{t:2,r:"color_name",p:[4,45,172]}]}],n:52,r:"data.paint_colors",p:[2,2,29]}]}]},e.exports=a.extend(r.exports)},{341:341}],455:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,64],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,105],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,123]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,195]},', "flipped": ',{t:2,r:"flipped",p:[6,42,215]},"}"]},f:[{p:[6,56,229],t:7,e:"img",a:{src:["pipe.",{t:2,r:"dir",p:[6,71,244]},".",{t:2,r:"icon_state",p:[6,79,252]},".png"],title:[{t:2,r:"dir_name",p:[6,106,279]}]}}]}],n:52,r:"previews",p:[4,4,81]}]}],n:52,r:"data.preview_rows",p:[2,2,33]}]}]},e.exports=a.extend(r.exports)},{341:341}],456:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Satellite Network Control",button:0},f:[{t:4,f:[{p:[8,4,168],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[9,9,209],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[9,31,231]}]}," ",{p:[10,9,253],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"mode",p:[10,30,274]}]}," ",{p:[11,9,298],t:7,e:"div",a:{"class":"content"},f:[{p:[12,11,331],t:7,e:"ui-button",a:{action:"toggle",params:['{"id": "',{t:2,r:"id",p:[12,54,374]},'"}']},f:[{t:2,x:{r:["active"],s:'_0?"Deactivate":"Activate"'},p:[12,64,384]}]}]}]}],n:52,r:"data.satellites",p:[7,2,138]}]}," ",{t:4,f:[{p:[18,1,528],t:7,e:"ui-display",a:{title:"Station Shield Coverage"},f:[{p:[19,3,576],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.meteor_shield_coverage_max",p:[19,24,597]}],value:[{t:2,r:"data.meteor_shield_coverage",p:[19,68,641]}]},f:[{t:2,x:{r:["data.meteor_shield_coverage","data.meteor_shield_coverage_max"],s:"100*_0/_1"},p:[19,101,674]}," %"]}," ",{p:[20,1,758],t:7,e:"ui-display",f:[]}]}],n:50,r:"data.meteor_shield",p:[17,1,500]}]},e.exports=a.extend(r.exports)},{341:341}],457:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,26],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[2,20,43]}],style:[{t:2,x:{r:["enabled"],s:'_0?"selected":null'},p:[2,72,95]}],action:"toggle_filter",params:['{"id_tag": "',{t:2,r:"id_tag",p:[3,48,176]},'", "val": ',{t:2,r:"gas_id",p:[3,68,196]},"}"]},f:[{t:2,r:"gas_name",p:[3,81,209]}]}],n:52,r:"filter_types",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],458:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," ",{p:[5,1,200],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[5,16,215]}]},f:[{p:[6,2,233],t:7,e:"tab",a:{name:"Status"},f:[{p:[7,3,256],t:7,e:"status"}]}," ",{p:[9,2,277],t:7,e:"tab",a:{name:"Templates"},f:[{p:[10,3,303],t:7,e:"templates"}]}," ",{p:[12,2,327],t:7,e:"tab",a:{name:"Modification"},f:[{t:4,f:[{p:[14,3,381],t:7,e:"modification"}],n:50,r:"data.selected",p:[13,3,356]}," ",{t:4,f:[{p:[17,3,437],t:7,e:"span",a:{"class":"bad"},f:["No shuttle selected."]}],n:50,x:{r:["data.selected"],s:"!_0"},p:[16,3,411]}]}]}]},r.exports.components=r.exports.components||{};var i={modification:t(459),templates:t(461),status:t(460)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,459:459,460:460,461:461}],459:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:["Selected: ",{t:2,r:"data.selected.name",p:[1,30,29]}]},f:[{t:4,f:[{p:[3,5,96],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.selected.description",p:[3,37,128]}]}],n:50,r:"data.selected.description",p:[2,3,57]}," ",{t:4,f:[{p:[6,5,224],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"data.selected.admin_notes",p:[6,37,256]}]}],n:50,r:"data.selected.admin_notes",p:[5,3,185]}]}," ",{t:4,f:[{p:[11,3,361],t:7,e:"ui-display",a:{title:["Existing Shuttle: ",{t:2,r:"data.existing_shuttle.name",p:[11,40,398]}]},f:["Status: ",{t:2,r:"data.existing_shuttle.status",p:[12,13,444]}," ",{t:4,f:["(",{t:2,r:"data.existing_shuttle.timeleft",p:[14,8,526]},")"],n:50,r:"data.existing_shuttle.timer",p:[13,5,482]}," ",{p:[16,5,580],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"data.existing_shuttle.id",p:[17,41,649]},'"}']},f:["Jump To"]}]}],n:50,r:"data.existing_shuttle",p:[10,1,328]},{t:4,f:[{p:[24,3,778],t:7,e:"ui-display",a:{title:"Existing Shuttle: None"}}],n:50,x:{r:["data.existing_shuttle"],s:"!_0"},p:[23,1,744]},{p:[27,1,847],t:7,e:"ui-button",a:{action:"preview",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[28,27,902]},'"}']},f:["Preview"]}," ",{p:[31,1,961],t:7,e:"ui-button",a:{action:"load",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[32,27,1013]},'"}'],style:"danger"},f:["Load"]}," ",{p:[37,1,1089],t:7,e:"ui-display",a:{title:"Status"},f:[]}]},e.exports=a.extend(r.exports)},{341:341}],460:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"table",a:{width:"100%"},f:[{t:4,f:[{p:[3,3,49],t:7,e:"tr",f:[{p:[4,5,59],t:7,e:"td",f:[{p:[5,7,71],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"id",p:[5,69,133]},'"}']},f:["JMP"]}]}," ",{p:[9,5,193],t:7,e:"td",f:[{p:[10,7,205],t:7,e:"ui-button",a:{action:"fly",params:['{"id": "',{t:2,r:"id",p:[10,47,245]},'"}'],state:[{t:2,x:{r:["can_fly"],s:'_0?null:"disabled"'},p:[10,64,262]}]},f:["Fly"]}]}," ",{p:[14,5,345],t:7,e:"td",f:[{t:2,r:"name",p:[15,7,357]}," (",{p:[15,17,367],t:7,e:"code",f:[{t:2,r:"id",p:[15,23,373]}]},")"]}," ",{p:[17,5,404],t:7,e:"td",f:[{t:2,r:"status",p:[18,7,416]}]}," ",{p:[20,5,443],t:7,e:"td",f:[{t:4,f:[{t:2,r:"mode",p:[22,9,477]}],n:50,r:"mode",p:[21,7,455]}," ",{t:4,f:["(",{t:2,r:"timeleft",p:[25,10,532]},") ",{p:[26,9,555],t:7,e:"ui-button",a:{action:"fast_travel",params:['{"id": "',{t:2,r:"id",p:[26,57,603]},'"}'],state:[{t:2,x:{r:["can_fast_travel"],s:'_0?null:"disabled"'},p:[26,74,620]}]},f:["Fast Travel"]}],n:50,r:"timer",p:[24,7,508]}]}]}],n:52,r:"data.shuttles",p:[2,1,22]}]}]},e.exports=a.extend(r.exports)},{341:341}],461:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.templates_tabs",p:[1,16,15]}]},f:[{t:4,f:[{p:[3,5,74],t:7,e:"tab",a:{name:[{t:2,r:"port_id",p:[3,16,85]}]},f:[{t:4,f:[{p:[5,9,135],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[5,28,154]}]},f:[{t:4,f:[{p:[7,13,209],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[7,45,241]}]}],n:50,r:"description",p:[6,11,176]}," ",{t:4,f:[{p:[10,13,333],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"admin_notes",p:[10,45,365]}]}],n:50,r:"admin_notes",p:[9,11,300]}," ",{p:[13,11,426],t:7,e:"ui-button",a:{action:"select_template",params:['{"shuttle_id": "',{t:2,r:"shuttle_id",p:[14,37,499]},'"}'],state:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"selected":null'},p:[15,20,537]}]},f:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"Selected":"Select"'},p:[17,13,630]}]}]}],n:52,r:"templates",p:[4,7,106]}]}],n:52,r:"data.templates",p:[2,3,44]}]}]},e.exports=a.extend(r.exports)},{341:341}],462:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,186],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,220],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,233]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,262]}]}]}," ",{p:[9,5,315],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[10,7,350],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[10,20,363]}],max:[{t:2,r:"data.occupant.maxHealth",p:[10,54,397]}],value:[{t:2,r:"data.occupant.health",p:[10,90,433]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[11,16,475]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[11,68,527]}]}]}," ",{t:4,f:[{p:[14,7,764],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[14,26,783]}]},f:[{p:[15,9,804],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[15,30,825]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[15,66,861]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[15,103,898]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[13,5,598]}," ",{t:4,f:[{p:[19,7,1020],t:7,e:"ui-section",a:{label:"Blood"},f:[{p:[20,9,1056],t:7,e:"ui-section",a:{label:"Volume"},f:[{p:[21,11,1095],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.blood.maxBloodVolume",p:[21,32,1116]}],value:[{t:2,r:"data.occupant.blood.currentBloodVolume",p:[21,79,1163]}],state:[{t:2,x:{r:["data.occupant.blood.currentBloodVolume","data.occupant.blood.dangerBloodVolume"],s:'_0<=_1?"bad":"good"'},p:[21,130,1214]}]},f:[{t:3,x:{r:["data.occupant.blood.currentBloodVolume","data.occupant.blood.dangerBloodVolume"],s:'_0<=_1?"LOW":"OK"'},p:[21,232,1316]}," - ",{t:2,x:{r:["data.occupant.blood.currentBloodVolume"],s:"Math.round(_0)"},p:[21,342,1426]}," cl"]}]}," ",{p:[23,9,1525],t:7,e:"ui-section",a:{label:"Type"},f:[{p:[24,11,1562],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:"data.occupant.blood.bloodType",p:[24,35,1586]}]}]}]}],n:50,r:"data.occupant.blood",p:[18,5,985]}," ",{p:[28,5,1689],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[29,9,1725],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[29,22,1738]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[29,68,1784]}]}]}," ",{p:[31,5,1867],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[32,9,1903],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[32,22,1916]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[32,68,1962]}]}]}," ",{p:[34,5,2046],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[36,11,2133],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[36,54,2176]}," units of ",{t:2,r:"name",p:[36,89,2211]}]},{p:[36,104,2226],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[35,9,2088]},{t:4,n:51,f:[{p:[38,11,2261],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[5,3,159]}]}," ",{p:[43,1,2357],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[44,2,2389],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[45,5,2420],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[45,22,2437]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[45,71,2486]}]}]}," ",{p:[47,3,2551],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[49,7,2612],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied","allowed"],s:'_0&&_1?null:"disabled"'},p:[49,38,2643]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[49,122,2727]},'"}']},f:[{t:2,r:"name",p:[49,132,2737]}]},{p:[49,152,2757],t:7,e:"br"}],n:52,r:"data.chems",p:[48,5,2584]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],463:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,25],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,44]}],labelcolor:[{t:2,r:"htmlcolor",p:[2,44,66]}],candystripe:0,right:0},f:[{p:[3,5,105],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,32,132],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0=="Dead"?"bad bold":_0=="Unconscious"?"average bold":"good"'},p:[3,45,145]}]},f:[{t:2,r:"status",p:[3,132,232]}]}]}," ",{p:[4,5,268],t:7,e:"ui-section",a:{label:"Jelly"},f:[{t:2,r:"exoticblood",p:[4,31,294]}]}," ",{p:[5,5,328],t:7,e:"ui-section",a:{label:"Location"},f:[{t:2,r:"area",p:[5,34,357]}]}," ",{p:[7,5,386],t:7,e:"ui-button",a:{state:[{t:2,r:"swap_button_state",p:[8,14,411]}],action:"swap",params:['{"ref": "',{t:2,r:"ref",p:[9,38,472]},'"}']},f:[{t:4,f:["You Are Here"],n:50,x:{r:["occupied"],s:'_0=="owner"'},p:[10,7,491]},{t:4,n:51,f:[{t:4,f:["Occupied"],n:50,x:{r:["occupied"],s:'_0=="stranger"'},p:[13,9,566]},{t:4,n:51,f:["Swap"],x:{r:["occupied"],s:'_0=="stranger"'}}],x:{r:["occupied"],s:'_0=="owner"'}}]}]}],n:52,r:"data.bodies",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],464:[function(t,e,n){var a=t(341),r={exports:{} +};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,23,82],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.drying"],s:'_0?"stop":"tint"'},p:[4,40,99]}],action:"Dry"},f:[{t:2,x:{r:["data.drying"],s:'_0?"Stop drying":"Dry"'},p:[4,88,147]}]}],n:50,r:"data.isdryer",p:[4,3,62]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[7,3,258],t:7,e:"ui-notice",f:[{p:[8,5,275],t:7,e:"span",f:["Unfortunately, this ",{t:2,r:"data.name",p:[8,31,301]}," is empty."]}]}],n:50,x:{r:["data.contents.length"],s:"_0==0"},p:[6,1,221]},{t:4,n:51,f:[{p:[11,1,359],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[12,2,391],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[13,4,425],t:7,e:"section",a:{"class":"cell bold"},f:["Item"]}," ",{p:[16,4,482],t:7,e:"section",a:{"class":"cell bold"},f:["Quantity"]}," ",{p:[19,4,543],t:7,e:"section",a:{"class":"cell bold",align:"center"},f:[{t:4,f:[{t:2,r:"data.verb",p:[20,22,608]}],n:50,r:"data.verb",p:[20,5,591]},{t:4,n:51,f:["Dispense"],r:"data.verb"}]}]}," ",{t:4,f:[{p:[24,3,703],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[25,4,737],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[26,5,765]}]}," ",{p:[28,4,793],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[29,5,835]}]}," ",{p:[31,4,865],t:7,e:"section",a:{"class":"table",alight:"right"},f:[{p:[32,5,909],t:7,e:"section",a:{"class":"cell"}}," ",{p:[33,5,947],t:7,e:"section",a:{"class":"cell"},f:[{p:[34,6,976],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[34,45,1015]}],params:['{ "name" : ',{t:2,r:"name",p:[34,102,1072]},', "amount" : 1 }']},f:["One"]}]}," ",{p:[38,5,1151],t:7,e:"section",a:{"class":"cell"},f:[{p:[39,6,1180],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>1)?null:"disabled"'},p:[39,45,1219]}],params:['{ "name" : ',{t:2,r:"name",p:[39,101,1275]}," }"]},f:["Many"]}]}]}]}],n:52,r:"data.contents",p:[23,2,676]}]}],x:{r:["data.contents.length"],s:"_0==0"}}]}]},e.exports=a.extend(r.exports)},{341:341}],465:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{capacityPercentState:function(){var t=this.get("data.capacityPercent");return t>50?"good":t>15?"average":"bad"},inputState:function(){return this.get("data.capacityPercent")>=100?"good":this.get("data.inputting")?"average":"bad"},outputState:function(){return this.get("data.outputting")?"good":this.get("data.charge")>0?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[24,1,663],t:7,e:"ui-display",a:{title:"Storage"},f:[{p:[25,3,695],t:7,e:"ui-section",a:{label:"Stored Energy"},f:[{p:[26,5,735],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.capacityPercent",p:[26,38,768]}],state:[{t:2,r:"capacityPercentState",p:[26,71,801]}]},f:[{t:2,x:{r:["adata.capacityPercent"],s:"Math.fixed(_0)"},p:[26,97,827]},"%"]}]}]}," ",{p:[29,1,908],t:7,e:"ui-display",a:{title:"Input"},f:[{p:[30,3,938],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{p:[31,5,976],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"refresh":"close"'},p:[31,22,993]}],style:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"selected":null'},p:[31,74,1045]}],action:"tryinput"},f:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"Auto":"Off"'},p:[32,25,1113]}]},"   [",{p:[34,6,1182],t:7,e:"span",a:{"class":[{t:2,r:"inputState",p:[34,19,1195]}]},f:[{t:2,x:{r:["data.capacityPercent","data.inputting"],s:'_0>=100?"Fully Charged":_1?"Charging":"Not Charging"'},p:[34,35,1211]}]},"]"]}," ",{p:[36,3,1335],t:7,e:"ui-section",a:{label:"Target Input"},f:[{p:[37,5,1374],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.inputLevelMax",p:[37,26,1395]}],value:[{t:2,r:"data.inputLevel",p:[37,57,1426]}]},f:[{t:2,r:"adata.inputLevel_text",p:[37,78,1447]}]}]}," ",{p:[39,3,1501],t:7,e:"ui-section",a:{label:"Adjust Input"},f:[{p:[40,5,1540],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[40,44,1579]}],action:"input",params:'{"target": "min"}'}}," ",{p:[41,5,1674],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[41,39,1708]}],action:"input",params:'{"adjust": -10000}'}}," ",{p:[42,5,1804],t:7,e:"ui-button",a:{icon:"pencil",action:"input",params:'{"target": "input"}'},f:["Set"]}," ",{p:[43,5,1894],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[43,38,1927]}],action:"input",params:'{"adjust": 10000}'}}," ",{p:[44,5,2039],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[44,43,2077]}],action:"input",params:'{"target": "max"}'}}]}," ",{p:[46,3,2204],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[47,3,2238],t:7,e:"span",f:[{t:2,r:"adata.inputAvailable",p:[47,9,2244]}]}]}]}," ",{p:[50,1,2308],t:7,e:"ui-display",a:{title:"Output"},f:[{p:[51,3,2339],t:7,e:"ui-section",a:{label:"Output Mode"},f:[{p:[52,5,2377],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"power-off":"close"'},p:[52,22,2394]}],style:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"selected":null'},p:[52,77,2449]}],action:"tryoutput"},f:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"On":"Off"'},p:[53,26,2519]}]},"   [",{p:[55,6,2587],t:7,e:"span",a:{"class":[{t:2,r:"outputState",p:[55,19,2600]}]},f:[{t:2,x:{r:["data.outputting","data.charge"],s:'_0?"Sending":_1>0?"Not Sending":"No Charge"'},p:[55,36,2617]}]},"]"]}," ",{p:[57,3,2724],t:7,e:"ui-section",a:{label:"Target Output"},f:[{p:[58,5,2764],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.outputLevelMax",p:[58,26,2785]}],value:[{t:2,r:"data.outputLevel",p:[58,58,2817]}]},f:[{t:2,r:"adata.outputLevel_text",p:[58,80,2839]}]}]}," ",{p:[60,3,2894],t:7,e:"ui-section",a:{label:"Adjust Output"},f:[{p:[61,5,2934],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[61,44,2973]}],action:"output",params:'{"target": "min"}'}}," ",{p:[62,5,3070],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[62,39,3104]}],action:"output",params:'{"adjust": -10000}'}}," ",{p:[63,5,3202],t:7,e:"ui-button",a:{icon:"pencil",action:"output",params:'{"target": "input"}'},f:["Set"]}," ",{p:[64,5,3293],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[64,38,3326]}],action:"output",params:'{"adjust": 10000}'}}," ",{p:[65,5,3441],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[65,43,3479]}],action:"output",params:'{"target": "max"}'}}]}," ",{p:[67,3,3609],t:7,e:"ui-section",a:{label:"Outputting"},f:[{p:[68,3,3644],t:7,e:"span",f:[{t:2,r:"adata.outputUsed",p:[68,9,3650]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],466:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:["\ufeff",{t:4,f:[" ",{p:[2,2,33],t:7,e:"ui-display",a:{title:"Dispersal Tank"},f:[{p:[3,3,73],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[4,4,104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.active"],s:'_0?"power-off":"close"'},p:[4,21,121]}],style:[{t:2,x:{r:["data.active"],s:'_0?"selected":null'},p:[5,12,174]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[6,12,223]}],action:"power"},f:[{t:2,x:{r:["data.active"],s:'_0?"On":"Off"'},p:[7,20,286]}]}]}," ",{p:[10,3,354],t:7,e:"ui-section",a:{label:"Smoke Radius Setting"},f:[{p:[11,5,401],t:7,e:"div",a:{"class":"content",style:"float:left"},f:[{p:[12,6,448],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=1?null:"disabled"'},p:[12,36,478]}],style:[{t:2,x:{r:["data.setting"],s:'_0==1?"selected":null'},p:[12,89,531]}],action:"setting",params:'{"amount": 1}'},f:["3"]}," ",{p:[13,6,634],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=2?null:"disabled"'},p:[13,36,664]}],style:[{t:2,x:{r:["data.setting"],s:'_0==2?"selected":null'},p:[13,89,717]}],action:"setting",params:'{"amount": 2}'},f:["6"]}," ",{p:[14,6,820],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=3?null:"disabled"'},p:[14,36,850]}],style:[{t:2,x:{r:["data.setting"],s:'_0==3?"selected":null'},p:[14,89,903]}],action:"setting",params:'{"amount": 3}'},f:["9"]}," ",{p:[15,6,1006],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=4?null:"disabled"'},p:[15,36,1036]}],style:[{t:2,x:{r:["data.setting"],s:'_0==4?"selected":null'},p:[15,89,1089]}],action:"setting",params:'{"amount": 4}'},f:["12"]}," ",{p:[16,6,1193],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=5?null:"disabled"'},p:[16,36,1223]}],style:[{t:2,x:{r:["data.setting"],s:'_0==5?"selected":null'},p:[16,89,1276]}],action:"setting",params:'{"amount": 5}'},f:["15"]}]}]}," ",{p:[19,3,1410],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[21,6,1476],t:7,e:"span",f:[{t:2,x:{r:["adata.TankCurrentVolume"],s:"Math.round(_0)"},p:[21,12,1482]},"/",{t:2,r:"data.TankMaxVolume",p:[21,52,1522]}," Units"]}," ",{p:[22,6,1564],t:7,e:"br"}," ",{p:[23,5,1575],t:7,e:"br"}," ",{t:4,f:[{p:[25,7,1623],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[25,50,1666]}," units of ",{t:2,r:"name",p:[25,85,1701]}]},{p:[25,100,1716],t:7,e:"br"}],n:52,r:"adata.TankContents",p:[24,6,1587]}],n:50,r:"data.isTankLoaded",p:[20,4,1444]},{t:4,n:51,f:[{p:[28,6,1757],t:7,e:"span",a:{"class":"bad"},f:["Tank Empty"]}],r:"data.isTankLoaded"}," ",{p:[30,4,1809],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Eject":"Close"'},p:[30,21,1826]}],style:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"selected":null'},p:[31,12,1881]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[32,12,1936]}],action:"purge"},f:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Purge Contents":"No chemicals detected"'},p:[33,20,1999]}]}]}]}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,2,1]}]},e.exports=a.extend(r.exports)},{341:341}],467:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{t:2,x:{r:["adata.generated"],s:"Math.round(_0)"},p:[3,5,73]},"W"]}," ",{p:[5,3,126],t:7,e:"ui-section",a:{label:"Orientation"},f:[{p:[6,5,164],t:7,e:"span",f:[{t:2,x:{r:["adata.angle"],s:"Math.round(_0)"},p:[6,11,170]},"° (",{t:2,r:"data.direction",p:[6,45,204]},")"]}]}," ",{p:[8,3,251],t:7,e:"ui-section",a:{label:"Adjust Angle"},f:[{p:[9,5,290],t:7,e:"ui-button",a:{icon:"step-backward",action:"angle",params:'{"adjust": -15}'},f:["15°"]}," ",{p:[10,5,387],t:7,e:"ui-button",a:{icon:"backward",action:"angle",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[11,5,477],t:7,e:"ui-button",a:{icon:"forward",action:"angle",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[12,5,565],t:7,e:"ui-button",a:{icon:"step-forward",action:"angle",params:'{"adjust": 15}'},f:["15°"]}]}]}," ",{p:[15,1,687],t:7,e:"ui-display",a:{title:"Tracking"},f:[{p:[16,3,720],t:7,e:"ui-section",a:{label:"Tracker Mode"},f:[{p:[17,5,759],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==0?"selected":null'},p:[17,36,790]}],action:"tracking",params:'{"mode": 0}'},f:["Off"]}," ",{p:[19,5,907],t:7,e:"ui-button",a:{icon:"clock-o",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==1?"selected":null'},p:[19,38,940]}],action:"tracking",params:'{"mode": 1}'},f:["Timed"]}," ",{p:[21,5,1059],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.connected_tracker","data.tracking_state"],s:'_0?_1==2?"selected":null:"disabled"'},p:[21,38,1092]}],action:"tracking",params:'{"mode": 2}'},f:["Auto"]}]}," ",{p:[24,3,1262],t:7,e:"ui-section",a:{label:"Tracking Rate"},f:[{p:[25,3,1300],t:7,e:"span",f:[{t:2,x:{r:["adata.tracking_rate"],s:"Math.round(_0)"},p:[25,9,1306]},"°/h (",{t:2,r:"data.rotating_way",p:[25,53,1350]},")"]}]}," ",{p:[27,3,1399],t:7,e:"ui-section",a:{label:"Adjust Rate"},f:[{p:[28,5,1437],t:7,e:"ui-button",a:{icon:"fast-backward",action:"rate",params:'{"adjust": -180}'},f:["180°"]}," ",{p:[29,5,1535],t:7,e:"ui-button",a:{icon:"step-backward",action:"rate",params:'{"adjust": -30}'},f:["30°"]}," ",{p:[30,5,1631],t:7,e:"ui-button",a:{icon:"backward",action:"rate",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[31,5,1720],t:7,e:"ui-button",a:{icon:"forward",action:"rate",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[32,5,1807],t:7,e:"ui-button",a:{icon:"step-forward",action:"rate",params:'{"adjust": 30}'},f:["30°"]}," ",{p:[33,5,1901],t:7,e:"ui-button",a:{icon:"fast-forward",action:"rate",params:'{"adjust": 180}'},f:["180°"]}]}]}," ",{p:{button:[{p:[38,5,2088],t:7,e:"ui-button",a:{icon:"refresh",action:"refresh"},f:["Refresh"]}]},t:7,e:"ui-display",a:{title:"Devices",button:0},f:[" ",{p:[40,2,2169],t:7,e:"ui-section",a:{label:"Solar Tracker"},f:[{p:[41,5,2209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_tracker"],s:'_0?"good":"bad"'},p:[41,18,2222]}]},f:[{t:2,x:{r:["data.connected_tracker"],s:'_0?"":"Not "'},p:[41,63,2267]},"Found"]}]}," ",{p:[43,2,2338],t:7,e:"ui-section",a:{label:"Solar Panels"},f:[{p:[44,3,2375],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_panels"],s:'_0?"good":"bad"'},p:[44,16,2388]}]},f:[{t:2,x:{r:["adata.connected_panels"],s:"Math.round(_0)"},p:[44,60,2432]}," Panels Connected"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],468:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,7,87],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[4,38,118]}],action:"eject"},f:["Eject"]}],n:50,r:"data.open",p:[3,5,62]}]},t:7,e:"ui-display",a:{title:"Power",button:0},f:[" ",{p:[7,3,226],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[8,5,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[8,22,275]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[9,14,326]}],state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[9,54,366]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[10,22,431]}]}]}," ",{p:[12,3,490],t:7,e:"ui-section",a:{label:"Cell"},f:[{t:4,f:[{p:[14,7,554],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerLevel",p:[14,40,587]}]},f:[{t:2,x:{r:["adata.powerLevel"],s:"Math.fixed(_0)"},p:[14,61,608]},"%"]}],n:50,r:"data.hasPowercell",p:[13,5,521]},{t:4,n:51,f:[{p:[16,4,667],t:7,e:"span",a:{"class":"bad"},f:["No Cell"]}],r:"data.hasPowercell"}]}]}," ",{p:[20,1,744],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[21,3,779],t:7,e:"ui-section",a:{label:"Current Temperature"},f:[{p:[22,3,823],t:7,e:"span",f:[{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[22,9,829]},"°C"]}]}," ",{p:[24,2,894],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[25,3,937],t:7,e:"span",f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[25,9,943]},"°C"]}]}," ",{t:4,f:[{p:[28,5,1031],t:7,e:"ui-section",a:{label:"Adjust Target"},f:[{p:[29,7,1073],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[29,46,1112]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[30,7,1218],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[30,41,1252]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[31,7,1357],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:["Set"]}," ",{p:[32,7,1450],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[32,40,1483]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[33,7,1587],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[33,45,1625]}],action:"target",params:'{"adjust": 20}'}}]}],n:50,r:"data.open",p:[27,3,1008]}," ",{p:[36,3,1754],t:7,e:"ui-section",a:{label:"Mode"},f:[{t:4,f:[{p:[38,7,1808],t:7,e:"ui-button",a:{icon:"long-arrow-up",state:[{t:2,x:{r:["data.mode"],s:'_0=="heat"?"selected":null'},p:[38,46,1847]}],action:"mode",params:'{"mode": "heat"}'},f:["Heat"]}," ",{p:[39,7,1956],t:7,e:"ui-button",a:{icon:"long-arrow-down",state:[{t:2,x:{r:["data.mode"],s:'_0=="cool"?"selected":null'},p:[39,48,1997]}],action:"mode",params:'{"mode": "cool"}'},f:["Cool"]}," ",{p:[40,7,2106],t:7,e:"ui-button",a:{icon:"arrows-v",state:[{t:2,x:{r:["data.mode"],s:'_0=="auto"?"selected":null'},p:[40,41,2140]}],action:"mode",params:'{"mode": "auto"}'},f:["Auto"]}],n:50,r:"data.open",p:[37,3,1783]},{t:4,n:51,f:[{p:[42,4,2258],t:7,e:"span",f:[{t:2,x:{r:["text","data.mode"],s:"_0.titleCase(_1)"},p:[42,10,2264]}]}],r:"data.open"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],469:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,8,97],t:7,e:"ui-button",a:{action:"jump",params:['{"name" : ',{t:2,r:"name",p:[4,51,140]},"}"]},f:["Jump"]}," ",{p:[7,9,195],t:7,e:"ui-button",a:{action:"spawn",params:['{"name" : ',{t:2,r:"name",p:[7,53,239]},"}"]},f:["Spawn"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[2,22,46]}],button:0},f:[" ",{p:[11,3,308],t:7,e:"ui-section",a:{label:"Description"},f:[{p:[12,5,346],t:7,e:"span",f:[{t:3,r:"desc",p:[12,11,352]}]}]}," ",{p:[14,3,390],t:7,e:"ui-section",a:{label:"Spawners left"},f:[{p:[15,5,430],t:7,e:"span",f:[{t:2,r:"amount_left",p:[15,11,436]}]}]}]}],n:52,r:"data.spawners",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],470:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,31],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[2,22,50]}," Alarms"]},f:[{p:[3,5,74],t:7,e:"ul",f:[{t:4,f:[{p:[5,9,107],t:7,e:"li",f:[{t:2,r:".",p:[5,13,111]}]}],n:52,r:".",p:[4,7,86]},{t:4,n:51,f:[{p:[7,9,147],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],471:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,42],t:7,e:"ui-notice",f:[{p:[3,5,59],t:7,e:"span",f:["Biological entity detected in contents. Please remove."]}]}],n:50,x:{r:["data.occupied","data.safeties"],s:"_0&&_1"},p:[1,1,0]},{t:4,f:[{p:[7,3,179],t:7,e:"ui-notice",f:[{p:[8,5,196],t:7,e:"span",f:["Contents are being disinfected. Please wait."]}]}],n:50,r:"data.uv_active",p:[6,1,153]},{t:4,n:51,f:[{p:{button:[{t:4,f:[{p:[13,25,369],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,42,386]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[13,93,437]}]}],n:50,x:{r:["data.open"],s:"!_0"},p:[13,7,351]}," ",{t:4,f:[{p:[14,27,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"sign-out":"sign-in"'},p:[14,44,536]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Close":"Open"'},p:[14,98,590]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[14,7,499]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[17,7,692],t:7,e:"ui-notice",f:[{p:[18,9,713],t:7,e:"span",f:["Unit Locked"]}]}],n:50,r:"data.locked",p:[16,5,665]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.open"],s:"_0"},f:[{p:[21,9,793],t:7,e:"ui-section",a:{label:"Helmet"},f:[{p:[22,11,832],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.helmet"],s:'_0?"square":"square-o"'},p:[22,28,849]}],state:[{t:2,x:{r:["data.helmet"],s:'_0?null:"disabled"'},p:[22,75,896]}],action:"dispense",params:'{"item": "helmet"}'},f:[{t:2,x:{r:["data.helmet"],s:'_0||"Empty"'},p:[23,59,992]}]}]}," ",{p:[25,9,1063],t:7,e:"ui-section",a:{label:"Suit"},f:[{p:[26,11,1100],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.suit"],s:'_0?"square":"square-o"'},p:[26,28,1117]}],state:[{t:2,x:{r:["data.suit"],s:'_0?null:"disabled"'},p:[26,74,1163]}],action:"dispense",params:'{"item": "suit"}'},f:[{t:2,x:{r:["data.suit"],s:'_0||"Empty"'},p:[27,57,1255]}]}]}," ",{p:[29,9,1324],t:7,e:"ui-section",a:{label:"Mask"},f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mask"],s:'_0?"square":"square-o"'},p:[30,28,1378]}],state:[{t:2,x:{r:["data.mask"],s:'_0?null:"disabled"'},p:[30,74,1424]}],action:"dispense",params:'{"item": "mask"}'},f:[{t:2,x:{r:["data.mask"],s:'_0||"Empty"'},p:[31,57,1516]}]}]}," ",{p:[33,9,1585],t:7,e:"ui-section",a:{label:"Storage"},f:[{p:[34,11,1625],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.storage"],s:'_0?"square":"square-o"'},p:[34,28,1642]}],state:[{t:2,x:{r:["data.storage"],s:'_0?null:"disabled"'},p:[34,77,1691]}],action:"dispense",params:'{"item": "storage"}'},f:[{t:2,x:{r:["data.storage"],s:'_0||"Empty"'},p:[35,60,1789]}]}]}]},{t:4,n:50,x:{r:["data.open"],s:"!(_0)"},f:[" ",{p:[38,7,1873],t:7,e:"ui-button",a:{icon:"recycle",state:[{t:2,x:{r:["data.occupied","data.safeties"],s:'_0&&_1?"disabled":null'},p:[38,40,1906]}],action:"uv"},f:["Disinfect"]}]}],r:"data.locked"}]}],r:"data.uv_active"}]},e.exports=a.extend(r.exports)},{341:341}],472:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,5,18],t:7,e:"ui-section",a:{label:"Dispense"},f:[{p:[3,9,57],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.plasma"],s:'_0?"square":"square-o"'},p:[3,26,74]}],state:[{t:2,x:{r:["data.plasma"],s:'_0?null:"disabled"'},p:[3,74,122]}],action:"plasma"},f:["Plasma (",{t:2,x:{r:["adata.plasma"],s:"Math.round(_0)"},p:[4,37,196]},")"]}," ",{p:[5,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oxygen"],s:'_0?"square":"square-o"'},p:[5,26,264]}],state:[{t:2,x:{r:["data.oxygen"],s:'_0?null:"disabled"'},p:[5,74,312]}],action:"oxygen"},f:["Oxygen (",{t:2,x:{r:["adata.oxygen"],s:"Math.round(_0)"},p:[6,37,386]},")"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],473:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tankPressureState:function(){var t=this.get("data.tankPressure");return t>=200?"good":t>=100?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,295],t:7,e:"ui-notice",f:[{p:[15,3,310],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.connected"],s:'_0?"is":"is not"'},p:[15,23,330]}," connected to a mask."]}]}," ",{p:[17,1,409],t:7,e:"ui-display",f:[{p:[18,3,425],t:7,e:"ui-section",a:{label:"Tank Pressure"},f:[{p:[19,7,467],t:7,e:"ui-bar",a:{min:"0",max:"1013",value:[{t:2,r:"data.tankPressure",p:[19,41,501]}],state:[{t:2,r:"tankPressureState",p:[20,16,540]}]},f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[20,39,563]}," kPa"]}]}," ",{p:[22,3,631],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[23,5,674],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[23,18,687]}],max:[{t:2,r:"data.maxReleasePressure",p:[23,52,721]}],value:[{t:2,r:"data.releasePressure",p:[24,14,764]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[24,40,790]}," kPa"]}]}," ",{p:[26,3,861],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,906],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,939]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1095],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1126]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1273],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1368],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1398]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],474:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,5,33],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[3,9,75],t:7,e:"span",f:[{t:2,x:{r:["adata.temperature"],s:"Math.fixed(_0,2)"},p:[3,15,81]}," K"]}]}," ",{p:[5,5,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,9,190],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.fixed(_0,2)"},p:[6,15,196]}," kPa"]}]}]}," ",{p:[9,1,276],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[10,5,311],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,347],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[11,26,364]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[11,70,408]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[12,28,469]}]}]}," ",{p:[14,5,531],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[15,9,580],t:7,e:"ui-button",a:{icon:"fast-backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[15,48,619]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[17,9,733],t:7,e:"ui-button",a:{icon:"backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[17,43,767]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[19,9,880],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.target"],s:"Math.fixed(_0,2)"},p:[19,79,950]}]}," ",{p:[20,9,1003],t:7,e:"ui-button",a:{icon:"forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[20,42,1036]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[22,9,1148],t:7,e:"ui-button",a:{icon:"fast-forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[22,47,1186]}],action:"target",params:'{"adjust": 20}'}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],475:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 1:return"good";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,173],t:7,e:"ui-notice",f:[{p:[14,2,187],t:7,e:"ui-section",a:{label:"Reconnect"},f:[{p:[15,3,221],t:7,e:"div",a:{style:"float:right"},f:[{p:[16,4,251],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]}]}]}," ",{p:[20,1,359],t:7,e:"ui-display",a:{title:"Turbine Controller"},f:[{p:[21,2,401],t:7,e:"ui-section",a:{label:"Status"},f:[{t:4,f:[{p:[23,4,456],t:7,e:"span",a:{"class":"bad"},f:["Broken"]}],n:50,r:"data.broken",p:[22,3,432]},{t:4,n:51,f:[{p:[25,4,504],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.online"],s:"_0(_1)"},p:[25,17,517]}]},f:[{t:2,x:{r:["data.online","data.compressor_broke","data.turbine_broke"],s:'_0&&!(_1||_2)?"Online":"Offline"'},p:[25,46,546]}]}],r:"data.broken"}," ",{p:[27,3,656],t:7,e:"div",a:{style:"float:right"},f:[{p:[28,4,686],t:7,e:"ui-button",a:{icon:"power-off",action:"power-on",state:[{t:2,r:"data.broken",p:[28,57,739]}],style:[{t:2,x:{r:["data.online"],s:'_0?"selected":""'},p:[28,81,763]}]},f:["On"]}," ",{p:[29,4,817],t:7,e:"ui-button",a:{icon:"close",action:"power-off",state:[{t:2,r:"data.broken",p:[29,54,867]}],style:[{t:2,x:{r:["data.online"],s:'_0?"":"selected"'},p:[29,78,891]}]},f:["Off"]}]}," ",{t:4,f:[{p:[32,4,989],t:7,e:"br"}," [ ",{p:[33,6,1e3],t:7,e:"span",a:{"class":"bad"},f:["Compressor is inoperable"]}," ]"],n:50,r:"data.compressor_broke",p:[31,3,955]}," ",{t:4,f:[{p:[36,4,1097],t:7,e:"br"}," [ ",{p:[37,6,1108],t:7,e:"span",a:{"class":"bad"},f:["Turbine is inoperable"]}," ]"],n:50,r:"data.turbine_broke",p:[35,3,1066]}]}]}," ",{p:[41,1,1200],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[42,2,1230],t:7,e:"ui-section",a:{label:"Turbine Speed"},f:[{p:[43,3,1268],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.rpm"],s:'_0?"--":_1'},p:[43,9,1274]}," RPM"]}]}," ",{p:[45,2,1337],t:7,e:"ui-section",a:{label:"Internal Temp"},f:[{p:[46,3,1375],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.temp"],s:'_0?"--":_1'},p:[46,9,1381]}," K"]}]}," ",{p:[48,2,1443],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{p:[49,3,1483],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.power"],s:'_0?"--":_1'},p:[49,9,1489]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],476:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{},oninit:function(){this.on({hover:function(t){var e=this.get("data.telecrystals");e>=t.context.params.cost&&this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}})}}}(r),r.exports.template={v:3,t:[" ",{p:{button:[{t:4,f:[{p:[23,7,482],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock"]}],n:50,r:"data.lockable",p:[22,5,453]}]},t:7,e:"ui-display",a:{title:"Uplink",button:0},f:[" ",{p:[26,3,568],t:7,e:"ui-section",a:{label:"Telecrystals",right:0},f:[{p:[27,5,613],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.telecrystals"],s:'_0>0?"good":"bad"'},p:[27,18,626]}]},f:[{t:2,r:"data.telecrystals",p:[27,62,670]}," TC"]}]}]}," ",{t:4,f:[{p:[31,3,764],t:7,e:"ui-display",f:[{p:[32,2,779],t:7,e:"ui-button",a:{action:"select",params:['{"category": "',{t:2,r:"name",p:[32,51,828]},'"}']},f:[{t:2,r:"name",p:[32,63,840]}]}," ",{t:4,f:[{p:[34,4,883],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[34,23,902]}],candystripe:0,right:0},f:[{p:[35,3,934],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"name",p:[35,23,954]},": ",{t:2,r:"desc",p:[35,33,964]}],"tooltip-side":"left",state:[{t:2,x:{r:["data.telecrystals","hovered.cost","cost","hovered.item","name"],s:'_0<_2||(_0-_1<_2&&_3!=_4)?"disabled":null'},p:[36,12,1006]}],action:"buy",params:['{"category": "',{t:2,r:"category",p:[37,40,1165]},'", "item": ',{t:2,r:"name",p:[37,63,1188]},', "cost": ',{t:2,r:"cost",p:[37,81,1206]},"}"]},v:{hover:"hover",unhover:"unhover"},f:[{t:2,r:"cost",p:[38,43,1260]}," TC"]}]}],n:52,r:"items",p:[33,2,863]}]}],n:52,r:"data.categories",p:[30,1,735]}]},e.exports=a.extend(r.exports)},{341:341}],477:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{healthState:function(t){var e=this.get("data.vr_avatar.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,292],t:7,e:"ui-display",f:[{t:4,f:[{p:[16,3,331],t:7,e:"ui-notice",f:[{p:[17,4,347],t:7,e:"span",f:["Safety restraints disabled."]}]}],n:50,r:"data.emagged",p:[15,2,307]}," ",{t:4,f:[{p:[21,3,442],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:[{p:[22,4,482],t:7,e:"ui-section",a:{label:"Name"},f:[{t:2,r:"data.vr_avatar.name",p:[23,5,513]}]}," ",{p:[25,4,559],t:7,e:"ui-section",a:{label:"Status"},f:[{t:2,r:"data.vr_avatar.status",p:[26,5,592]}]}," ",{p:[28,4,640],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[29,5,673],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.vr_avatar.maxhealth",p:[29,26,694]}],value:[{t:2,r:"adata.vr_avatar.health",p:[29,64,732]}],state:[{t:2,x:{r:["healthState","adata.vr_avatar.health"],s:"_0(_1)"},p:[29,99,767]}]},f:[{t:2,x:{r:["adata.vr_avatar.health"],s:"Math.round(_0)"},p:[29,140,808]},"/",{t:2,r:"adata.vr_avatar.maxhealth",p:[29,179,847]}]}]}]}],n:50,r:"data.vr_avatar",p:[20,2,416]},{t:4,n:51,f:[{p:[33,3,935],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:["No Virtual Avatar detected"]}],r:"data.vr_avatar"}," ",{p:[37,2,1031],t:7,e:"ui-display",a:{title:"VR Commands"},f:[{p:[38,3,1067],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.toggle_open"],s:'_0?"times":"plus"'},p:[38,20,1084]}],action:"toggle_open"},f:[{t:2,x:{r:["data.toggle_open"],s:'_0?"Close":"Open"'},p:[39,4,1151]}," the VR Sleeper"]}," ",{t:4,f:[{p:[42,4,1253],t:7,e:"ui-button",a:{icon:"signal",action:"vr_connect"},f:["Connect to VR"]}],n:50,r:"data.isoccupant",p:[41,3,1225]}," ",{t:4,f:[{p:[47,4,1376],t:7,e:"ui-button",a:{icon:"ban",action:"delete_avatar"},f:["Delete Virtual Avatar"]}],n:50,r:"data.vr_avatar",p:[46,3,1349]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],478:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{t:4,f:[{p:[3,5,42],t:7,e:"ui-section",a:{label:[{t:2,r:"color",p:[3,24,61]},{t:2,x:{r:["wire"],s:'_0?" ("+_0+")":""'},p:[3,33,70]}],labelcolor:[{t:2,r:"color",p:[3,80,117]}],candystripe:0,right:0},f:[{p:[4,7,154],t:7,e:"ui-button",a:{action:"cut",params:['{"wire":"',{t:2,r:"color",p:[4,48,195]},'"}'] +},f:[{t:2,x:{r:["cut"],s:'_0?"Mend":"Cut"'},p:[4,61,208]}]}," ",{p:[5,7,252],t:7,e:"ui-button",a:{action:"pulse",params:['{"wire":"',{t:2,r:"color",p:[5,50,295]},'"}']},f:["Pulse"]}," ",{p:[6,7,333],t:7,e:"ui-button",a:{action:"attach",params:['{"wire":"',{t:2,r:"color",p:[6,51,377]},'"}']},f:[{t:2,x:{r:["attached"],s:'_0?"Detach":"Attach"'},p:[6,64,390]}]}]}],n:52,r:"data.wires",p:[2,3,16]}]}," ",{t:4,f:[{p:[11,3,508],t:7,e:"ui-display",f:[{t:4,f:[{p:[13,7,555],t:7,e:"ui-section",f:[{t:2,r:".",p:[13,19,567]}]}],n:52,r:"data.status",p:[12,5,526]}]}],n:50,r:"data.status",p:[10,1,485]}]},e.exports=a.extend(r.exports)},{341:341}],479:[function(t,e,n){(function(e){"use strict";var n=t(341),a=e.interopRequireDefault(n);t(331),t(1),t(327),t(330);var r=t(480),i=e.interopRequireDefault(r),o=t(481),s=t(328),p=t(329),u=e.interopRequireDefault(p);a["default"].DEBUG=/minified/.test(function(){}),Object.assign(Math,t(485)),window.initialize=function(e){window.tgui=window.tgui||new i["default"]({el:"#container",data:function(){var n=JSON.parse(e);return{constants:t(482),text:t(486),config:n.config,data:n.data,adata:n.data}}})};var c=document.getElementById("data"),l=c.textContent,d=c.getAttribute("data-ref");"{}"!==l&&(window.initialize(l),c.remove()),(0,o.act)(d,"tgui:initialize"),(0,s.loadCSS)("font-awesome.min.css");var f=new u["default"]("FontAwesome");f.check("").then(function(){return document.body.classList.add("icons")})["catch"](function(){return document.body.classList.add("no-icons")})}).call(this,t("babel/external-helpers"))},{1:1,327:327,328:328,329:329,330:330,331:331,341:341,480:480,481:481,482:482,485:485,486:486,"babel/external-helpers":"babel/external-helpers"}],480:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(481),a=t(483);e.exports={components:{"ui-bar":t(342),"ui-button":t(343),"ui-display":t(344),"ui-input":t(345),"ui-linegraph":t(346),"ui-notice":t(347),"ui-section":t(349),"ui-subdisplay":t(350),"ui-tabs":t(351)},events:{enter:t(339).enter,space:t(339).space},transitions:{fade:t(340)},onconfig:function(){var e=this.get("config.interface"),n={ai_airlock:t(355),airalarm:t(356),"airalarm/back":t(357),"airalarm/modes":t(358),"airalarm/scrubbers":t(359),"airalarm/status":t(360),"airalarm/thresholds":t(361),"airalarm/vents":t(362),airlock_electronics:t(363),apc:t(364),atmos_alert:t(365),atmos_control:t(366),atmos_filter:t(367),atmos_mixer:t(368),atmos_pump:t(369),borgopanel:t(370),brig_timer:t(371),bsa:t(372),canister:t(373),cargo:t(374),cargo_express:t(375),cellular_emporium:t(376),centcom_podlauncher:t(377),chem_dispenser:t(378),chem_heater:t(379),chem_master:t(380),chem_synthesizer:t(381),clockwork_slab:t(382),codex_gigas:t(383),computer_fabricator:t(384),crayon:t(385),crew:t(386),cryo:t(387),disposal_unit:t(388),dna_vault:t(389),dogborg_sleeper:t(390),eightball:t(391),emergency_shuttle_console:t(392),engraved_message:t(393),error:t(394),"exofab - Copia":t(395),exonet_node:t(396),firealarm:t(397),gps:t(398),gulag_console:t(399),gulag_item_reclaimer:t(400),holodeck:t(401),implantchair:t(402),intellicard:t(403),keycard_auth:t(404),labor_claim_console:t(405),language_menu:t(406),launchpad_remote:t(407),mech_bay_power_console:t(408),mulebot:t(409),nanite_chamber_control:t(410),nanite_cloud_control:t(411),nanite_program_hub:t(412),nanite_programmer:t(413),nanite_remote:t(414),notificationpanel:t(415),ntnet_relay:t(416),ntos_ai_restorer:t(417),ntos_card:t(418),ntos_configuration:t(419),ntos_file_manager:t(420),ntos_main:t(421),ntos_net_chat:t(422),ntos_net_dos:t(423),ntos_net_downloader:t(424),ntos_net_monitor:t(425),ntos_net_transfer:t(426),ntos_power_monitor:t(427),ntos_revelation:t(428),ntos_station_alert:t(429),ntos_supermatter_monitor:t(430),ntosheader:t(431),nuclear_bomb:t(432),operating_computer:t(433),ore_redemption_machine:t(434),pandemic:t(435),personal_crafting:t(436),portable_pump:t(437),portable_scrubber:t(438),power_monitor:t(439),radio:t(440),rdconsole:t(441),"rdconsole/circuit":t(442),"rdconsole/designview":t(443),"rdconsole/destruct":t(444),"rdconsole/diskopsdesign":t(445),"rdconsole/diskopstech":t(446),"rdconsole/nodeview":t(447),"rdconsole/protolathe":t(448),"rdconsole/rdheader":t(449),"rdconsole/settings":t(450),"rdconsole/techweb":t(451),reagentgrinder:t(452),rpd:t(453),"rpd/colorsel":t(454),"rpd/dirsel":t(455),sat_control:t(456),scrubbing_types:t(457),shuttle_manipulator:t(458),"shuttle_manipulator/modification":t(459),"shuttle_manipulator/status":t(460),"shuttle_manipulator/templates":t(461),sleeper:t(462),slime_swap_body:t(463),smartvend:t(464),smes:t(465),smoke_machine:t(466),solar_control:t(467),space_heater:t(468),spawners_menu:t(469),station_alert:t(470),suit_storage_unit:t(471),tank_dispenser:t(472),tanks:t(473),thermomachine:t(474),turbine_computer:t(475),uplink:t(476),vr_sleeper:t(477),wires:t(478)};e in n?this.components["interface"]=n[e]:this.components["interface"]=n.error},oninit:function(){this.observe("config.style",function(t,e,n){t&&document.body.classList.add(t),e&&document.body.classList.remove(e)})},oncomplete:function(){if(this.get("config.locked")){var t=(0,a.lock)(window.screenLeft,window.screenTop),e=t.x,r=t.y;(0,n.winset)(this.get("config.window"),"pos",e+","+r)}(0,n.winset)("mapwindow.map","focus",!0)}}}(r),r.exports.template={v:3,t:[" "," "," "," ",{p:[56,1,1874],t:7,e:"titlebar",f:[{t:3,r:"config.title",p:[56,11,1884]}]}," ",{p:[57,1,1915],t:7,e:"main",f:[{p:[58,3,1925],t:7,e:"warnings"}," ",{p:[59,3,1940],t:7,e:"interface"}]}," ",{t:4,f:[{p:[62,3,1990],t:7,e:"resize"}],n:50,r:"config.titlebar",p:[61,1,1963]}]},r.exports.components=r.exports.components||{};var i={warnings:t(354),titlebar:t(353),resize:t(348)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{339:339,340:340,341:341,342:342,343:343,344:344,345:345,346:346,347:347,348:348,349:349,350:350,351:351,353:353,354:354,355:355,356:356,357:357,358:358,359:359,360:360,361:361,362:362,363:363,364:364,365:365,366:366,367:367,368:368,369:369,370:370,371:371,372:372,373:373,374:374,375:375,376:376,377:377,378:378,379:379,380:380,381:381,382:382,383:383,384:384,385:385,386:386,387:387,388:388,389:389,390:390,391:391,392:392,393:393,394:394,395:395,396:396,397:397,398:398,399:399,400:400,401:401,402:402,403:403,404:404,405:405,406:406,407:407,408:408,409:409,410:410,411:411,412:412,413:413,414:414,415:415,416:416,417:417,418:418,419:419,420:420,421:421,422:422,423:423,424:424,425:425,426:426,427:427,428:428,429:429,430:430,431:431,432:432,433:433,434:434,435:435,436:436,437:437,438:438,439:439,440:440,441:441,442:442,443:443,444:444,445:445,446:446,447:447,448:448,449:449,450:450,451:451,452:452,453:453,454:454,455:455,456:456,457:457,458:458,459:459,460:460,461:461,462:462,463:463,464:464,465:465,466:466,467:467,468:468,469:469,470:470,471:471,472:472,473:473,474:474,475:475,476:476,477:477,478:478,481:481,483:483}],481:[function(t,e,n){"use strict";function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"byond://"+e+"?"+Object.keys(t).map(function(e){return o(e)+"="+o(t[e])}).join("&")}function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};window.location.href=a(Object.assign({src:t,action:e},n))}function i(t,e,n){var r;window.location.href=a((r={},r[t+"."+e]=n,r),"winset")}n.__esModule=!0,n.href=a,n.act=r,n.winset=i;var o=encodeURIComponent},{}],482:[function(t,e,n){"use strict";n.__esModule=!0;n.UI_INTERACTIVE=2,n.UI_UPDATE=1,n.UI_DISABLED=0,n.UI_CLOSE=-1},{}],483:[function(t,e,n){"use strict";function a(t,e){return 0>t?t=0:t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth),0>e?e=0:e+window.innerHeight>window.screen.availHeight&&(e=window.screen.availHeight-window.innerHeight),{x:t,y:e}}function r(t){if(t.preventDefault(),this.get("drag")){if(this.get("x")){var e=t.screenX-this.get("x")+window.screenLeft,n=t.screenY-this.get("y")+window.screenTop;if(this.get("config.locked")){var r=a(e,n);e=r.x,n=r.y}(0,s.winset)(this.get("config.window"),"pos",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}function i(t,e){return t=Math.clamp(100,window.screen.width,t),e=Math.clamp(100,window.screen.height,e),{x:t,y:e}}function o(t){if(t.preventDefault(),this.get("resize")){if(this.get("x")){var e=t.screenX-this.get("x")+window.innerWidth,n=t.screenY-this.get("y")+window.innerHeight,a=i(e,n);e=a.x,n=a.y,(0,s.winset)(this.get("config.window"),"size",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}n.__esModule=!0,n.lock=a,n.drag=r,n.sane=i,n.resize=o;var s=t(481)},{481:481}],484:[function(t,e,n){"use strict";function a(t,e){for(var n=t,a=Array.isArray(n),i=0,n=a?n:n[Symbol.iterator]();;){var o;if(a){if(i>=n.length)break;o=n[i++]}else{if(i=n.next(),i.done)break;o=i.value}var s=o;s.textContent.toLowerCase().includes(e)?(s.style.display="",r(s,e)):s.style.display="none"}}function r(t,e){for(var n=t.queryAll("section"),a=t.query("header").textContent.toLowerCase().includes(e),r=n,i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var p=s;a||p.textContent.toLowerCase().includes(e)?p.style.display="":p.style.display="none"}}n.__esModule=!0,n.filterMulti=a,n.filter=r},{}],485:[function(t,e,n){"use strict";function a(t,e,n){return Math.max(t,Math.min(n,e))}function r(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return+(Math.round(t+"e"+e)+"e-"+e)}n.__esModule=!0,n.clamp=a,n.fixed=r},{}],486:[function(t,e,n){"use strict";function a(t){return t[0].toUpperCase()+t.slice(1).toLowerCase()}function r(t){return t.replace(/\w\S*/g,a)}function i(t,e){for(t=""+t;t.length1){for(var p=Array(o),u=0;o>u;u++)p[u]=arguments[u+3];n.children=p}return{$$typeof:t,type:e,key:void 0===a?null:""+a,ref:null,props:n,_owner:null}}}(),e.asyncIterator=function(t){if("function"==typeof Symbol){if(Symbol.asyncIterator){var e=t[Symbol.asyncIterator];if(null!=e)return e.call(t)}if(Symbol.iterator)return t[Symbol.iterator]()}throw new TypeError("Object is not async iterable")},e.asyncGenerator=function(){function t(t){this.value=t}function e(e){function n(t,e){return new Promise(function(n,r){var s={key:t,arg:e,resolve:n,reject:r,next:null};o?o=o.next=s:(i=o=s,a(t,e))})}function a(n,i){try{var o=e[n](i),s=o.value;s instanceof t?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):r(o.done?"return":"normal",o.value)}catch(p){r("throw",p)}}function r(t,e){switch(t){case"return":i.resolve({value:e,done:!0});break;case"throw":i.reject(e);break;default:i.resolve({value:e,done:!1})}i=i.next,i?a(i.key,i.arg):o=null}var i,o;this._invoke=n,"function"!=typeof e["return"]&&(this["return"]=void 0)}return"function"==typeof Symbol&&Symbol.asyncIterator&&(e.prototype[Symbol.asyncIterator]=function(){return this}),e.prototype.next=function(t){return this._invoke("next",t)},e.prototype["throw"]=function(t){return this._invoke("throw",t)},e.prototype["return"]=function(t){return this._invoke("return",t)},{wrap:function(t){return function(){return new e(t.apply(this,arguments))}},await:function(e){return new t(e)}}}(),e.asyncGeneratorDelegate=function(t,e){function n(n,a){return r=!0,a=new Promise(function(e){e(t[n](a))}),{done:!1,value:e(a)}}var a={},r=!1;return"function"==typeof Symbol&&Symbol.iterator&&(a[Symbol.iterator]=function(){return this}),a.next=function(t){return r?(r=!1,t):n("next",t)},"function"==typeof t["throw"]&&(a["throw"]=function(t){if(r)throw r=!1,t;return n("throw",t)}),"function"==typeof t["return"]&&(a["return"]=function(t){return n("return",t)}),a},e.asyncToGenerator=function(t){return function(){var e=t.apply(this,arguments);return new Promise(function(t,n){function a(r,i){try{var o=e[r](i),s=o.value}catch(p){return void n(p)}return o.done?void t(s):Promise.resolve(s).then(function(t){a("next",t)},function(t){a("throw",t)})}return a("next")})}},e.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},e.createClass=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,a)&&(n[a]=t[a]);return n},e.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},e.selfGlobal=void 0===t?self:t,e.set=function a(t,e,n,r){var i=Object.getOwnPropertyDescriptor(t,e);if(void 0===i){var o=Object.getPrototypeOf(t);null!==o&&a(o,e,n,r)}else if("value"in i&&i.writable)i.value=n;else{var s=i.set;void 0!==s&&s.call(r,n)}return n},e.slicedToArray=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),e.slicedToArrayLoose=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t)){for(var n,a=[],r=t[Symbol.iterator]();!(n=r.next()).done&&(a.push(n.value),!e||a.length!==e););return a}throw new TypeError("Invalid attempt to destructure non-iterable instance")},e.taggedTemplateLiteral=function(t,e){return Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))},e.taggedTemplateLiteralLoose=function(t,e){return t.raw=e,t},e.temporalRef=function(t,e,n){if(t===n)throw new ReferenceError(e+" is not defined - temporal dead zone");return t},e.temporalUndefined={},e.toArray=function(t){return Array.isArray(t)?t:Array.from(t)},e.toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "optional": true + } + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -2917,9 +3409,9 @@ }, "dependencies": { "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3015,9 +3507,9 @@ }, "dependencies": { "gulp-cli": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.0.1.tgz", - "integrity": "sha512-RxujJJdN8/O6IW2nPugl7YazhmrIEjmiVfPKrWt68r71UCaLKS71Hp0gpKT+F6qOUFtr7KqtifDKaAJPRVvMYQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz", + "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==", "requires": { "ansi-colors": "^1.0.1", "archy": "^1.0.0", @@ -3029,7 +3521,7 @@ "gulplog": "^1.0.0", "interpret": "^1.1.0", "isobject": "^3.0.1", - "liftoff": "^2.5.0", + "liftoff": "^3.1.0", "matchdep": "^2.0.0", "mute-stdout": "^1.0.0", "pretty-hrtime": "^1.0.0", @@ -3057,14 +3549,33 @@ } }, "gulp-cssnano": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/gulp-cssnano/-/gulp-cssnano-2.1.2.tgz", - "integrity": "sha1-4IoJdx7FRUpUnxoAW90lbLjl4KM=", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/gulp-cssnano/-/gulp-cssnano-2.1.3.tgz", + "integrity": "sha512-r8qdX5pTXsBb/IRm9loE8Ijz8UiPW/URMC/bKJe4FPNHRaz4aEx8Bev03L0FYHd/7BSGu/ebmfumAkpGuTdenA==", "requires": { + "buffer-from": "^1.0.0", "cssnano": "^3.0.0", - "gulp-util": "^3.0.6", "object-assign": "^4.0.1", + "plugin-error": "^1.0.1", "vinyl-sourcemaps-apply": "^0.2.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "requires": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + } + } } }, "gulp-if": { @@ -3490,9 +4001,9 @@ "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==" }, "html-comment-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", - "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" }, "html5shiv": { "version": "3.7.3", @@ -3586,9 +4097,9 @@ } }, "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" }, "invariant": { "version": "2.2.4", @@ -3855,6 +4366,11 @@ "jsonify": "~0.0.0" } }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", @@ -3972,12 +4488,12 @@ } }, "liftoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", - "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", "requires": { "extend": "^3.0.0", - "findup-sync": "^2.0.0", + "findup-sync": "^3.0.0", "fined": "^1.0.1", "flagged-respawn": "^1.0.0", "is-plain-object": "^2.0.4", @@ -3999,9 +4515,9 @@ } }, "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, "lodash._baseassign": { "version": "3.2.0", @@ -4425,6 +4941,17 @@ } } }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", @@ -4451,6 +4978,19 @@ "kind-of": "^6.0.2" } }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -4747,6 +5287,12 @@ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==" }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -4823,9 +5369,9 @@ } }, "now-and-later": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz", - "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", "requires": { "once": "^1.3.2" } @@ -5017,7 +5563,7 @@ }, "os-locale": { "version": "1.4.0", - "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "requires": { "lcid": "^1.0.0" @@ -5758,14 +6304,263 @@ } }, "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } } }, "rechoir": { @@ -6058,11 +6853,6 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" - }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", @@ -6543,9 +7333,9 @@ } }, "through2-filter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", - "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", "requires": { "through2": "~2.0.0", "xtend": "~4.0.0" @@ -6708,9 +7498,9 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" }, "undertaker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz", - "integrity": "sha1-M52kZGJS0ILcN45wgGcpl1DhG0k=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", + "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", "requires": { "arr-flatten": "^1.0.1", "arr-map": "^2.0.0", @@ -6771,22 +7561,12 @@ "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" }, "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", "requires": { - "json-stable-stringify": "^1.0.0", - "through2-filter": "^2.0.0" - }, - "dependencies": { - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "requires": { - "jsonify": "~0.0.0" - } - } + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" } }, "unset-value": { @@ -6830,6 +7610,11 @@ } } }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==" + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -6877,9 +7662,9 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "v8flags": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.1.tgz", - "integrity": "sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", "requires": { "homedir-polyfill": "^1.0.1" } @@ -6899,9 +7684,9 @@ "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=" }, "vendors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", - "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz", + "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==" }, "vinyl": { "version": "1.2.0", @@ -7081,17 +7866,516 @@ } }, "watchify": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.7.0.tgz", - "integrity": "sha1-7i8sXIw3MSMD+Zi4GLKzRQ7v5kg=", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.11.1.tgz", + "integrity": "sha512-WwnUClyFNRMB2NIiHgJU9RQPQNqVeFk7OmZaWf5dC5EnNa0Mgr7imBydbaJ7tGTuPM2hz1Cb4uiBvK9NVxMfog==", "requires": { - "anymatch": "^1.3.0", - "browserify": "^13.0.0", - "chokidar": "^1.0.0", + "anymatch": "^2.0.0", + "browserify": "^16.1.0", + "chokidar": "^2.1.1", "defined": "^1.0.0", "outpipe": "^1.1.0", "through2": "^2.0.0", "xtend": "^4.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "chokidar": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + } + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==" + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" + } } }, "when": { @@ -7129,7 +8413,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { "string-width": "^1.0.1", diff --git a/tgui/package.json b/tgui/package.json index 38e580823f..f26e29c993 100644 --- a/tgui/package.json +++ b/tgui/package.json @@ -23,7 +23,7 @@ "fontfaceobserver": "1.6.3", "gulp": "git://github.com/gulpjs/gulp.git#v4.0.0-alpha.3", "gulp-bytediff": "1.0.0", - "gulp-cssnano": "2.1.2", + "gulp-cssnano": "^2.1.3", "gulp-if": "2.0.0", "gulp-load-plugins": "1.5.0", "gulp-postcss": "6.1.0", @@ -50,7 +50,7 @@ "stylus": "0.54.5", "vinyl-buffer": "1.0.1", "vinyl-source-stream": "2.0.0", - "watchify": "3.7.0" + "watchify": "^3.11.1" }, "browser": { "ractive": "ractive/ractive-legacy.runtime" diff --git a/tgui/src/interfaces/sleeper.ract b/tgui/src/interfaces/sleeper.ract index e7613c0097..e5bad17461 100644 --- a/tgui/src/interfaces/sleeper.ract +++ b/tgui/src/interfaces/sleeper.ract @@ -15,6 +15,16 @@ {{Math.round(adata.occupant[type])}} {{/each}} + {{#if data.occupant.blood}} + + + {{& data.occupant.blood.currentBloodVolume <= data.occupant.blood.dangerBloodVolume ? "LOW" : "OK"}} - {{Math.round(data.occupant.blood.currentBloodVolume)}} cl + + + {{data.occupant.blood.bloodType}} + + + {{/if}} {{data.occupant.cloneLoss ? "Damaged" : "Healthy"}}